+++ /dev/null
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2014 Johan Kayser <kayser.johan@gmail.com>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# A version of the naive Nit interpreter for PNaCl.
-module pnacl_nit
-
-import nitc::naive_interpreter
-import pnacl
-intrude import nitc::toolcontext
-intrude import nitc::loader
-intrude import core::file
-
-# We redefine exit to start a new thread before killing the one that called exit.
-redef fun exit(exit_value: Int)
-do
- var dictionary = new PepperDictionary
- dictionary["exit"] = exit_value
- dictionary["exit_thread"] = "A new thread has been made available for Nit."
- create_thread
- app.post_dictionary dictionary
- exit_thread exit_value
-end
-
-#hack realpath.
-redef class String
- redef fun realpath do return self
-
- # file_exists looks in the 'files' HashMap.
- redef fun file_exists: Bool
- do
- if sys.files.has_key(self) then return true
- return false
- end
-end
-
-redef class Sys
- # We add two HashMap for temporary file storage.
- # 'lib' stores the lib files.
- var lib = new HashMap[String, String]
- # 'files' stores the "file(s)" you want to interpret + the lib files.
- var files = new HashMap[String, String]
-end
-
-redef class ToolContext
- # We don't need 'the locate_nit_dir'.
- redef fun locate_nit_dir
- do
- return "/pnacl"
- end
-end
-
-# We have to redef some FileReader methods because we don't use NativeFiles anymore.
-redef class FileReader
-
- # Looks in the 'files' HashMap.
- redef init open(path: String)
- do
- self.path = path
- var file = sys.files[path]
- prepare_buffer(file.length)
- path.copy_to_native(_buffer, file.length, 0, 0)
- end
-
- redef fun close
- do
- end_reached = true
- end
-
- redef fun fill_buffer
- do
- buffer_reset
- end_reached = true
- end
-
- redef fun reopen
- do
- _buffer_pos = 0
- end
-end
-
-redef class ModelBuilder
- # We don't use paths as the interpreter, so just return the argument.
- redef fun module_absolute_path(path: String): String do return path
-
- # We don't use paths as the interpreter, so we don't use location or lookpaths args (see the default implementation).
- redef fun search_module_in_paths(location: nullable Location, name: String, lookpaths: Collection[String]): nullable MModule
- do
- var candidate: nullable String = null
- var try_file = "{name}.nit"
- if try_file.file_exists then
- if candidate == null then
- candidate = try_file
- else if candidate != try_file then
- # try to disambiguate conflicting modules
- var abs_candidate = module_absolute_path(candidate)
- var abs_try_file = module_absolute_path(try_file)
- if abs_candidate != abs_try_file then
- toolcontext.error(location, "Error: conflicting module file for {name}: {candidate} {try_file}")
- end
- end
- end
- if candidate == null then return null
- return identify_module(candidate)
- end
-end
-
-class Pnacl_nit
- super PnaclApp
-
- # In handle_dictionary we search for the 'operation' key in dictionaries,
- # 'load' means that we are loading the Nit library,
- # 'interpret' launches the interpreter code.
- redef fun handle_dictionary(dictionary: PepperDictionary)
- do
- var d = dictionary.copy
- var operation = d["operation"]
-
- # If operation = 'intepret' we want to interpret some Nit code, so we execute the same code as in nit.nit.
- if operation == "interpret" then
- var args = d["args"].to_s.split(' ')
- # Create a tool context to handle options and paths
- var toolcontext = new ToolContext
- toolcontext.tooldescription = "Usage: nit [OPTION]... <file.nit>...\nInterprets and debbugs Nit programs."
- # Add an option "-o" to enable compatibilit with the tests.sh script
- var opt = new OptionString("compatibility (does noting)", "-o")
- toolcontext.option_context.add_option(opt)
- var opt_mixins = new OptionArray("Additionals module to min-in", "-m")
- toolcontext.option_context.add_option(opt_mixins)
- # We do not add other options, so process them now!
- toolcontext.process_options(args)
-
- # We need a model to collect stufs
- var model = new Model
- # An a model builder to parse files
- var modelbuilder = new ModelBuilder(model, toolcontext)
-
- var arguments = toolcontext.option_context.rest
- var progname = arguments.first
- sys.files[progname] = d["content"].to_s
-
- # Here we load an process all modules passed on the command line
- var mmodules = modelbuilder.parse([progname])
- mmodules.add_all modelbuilder.parse(opt_mixins.value)
- modelbuilder.run_phases
-
- if toolcontext.opt_only_metamodel.value then exit(0)
-
- var mainmodule: nullable MModule
-
- # Here we launch the interpreter on the main module
- if mmodules.length == 1 then
- mainmodule = mmodules.first
- else
- mainmodule = new MModule(model, null, mmodules.first.name, mmodules.first.location)
- mainmodule.set_imported_mmodules(mmodules)
- end
-
- var self_mm = mainmodule
- var self_args = arguments
-
- modelbuilder.run_naive_interpreter(self_mm, self_args)
- # If operation = 'load', we are loading lib files, so we store them into HashMaps and send a response to JS.
- else if operation == "load" then
- var filename = d["filename"]
- var content = d["content"]
- if filename isa String and content isa String then
- sys.lib[filename] = content
- sys.files[filename] = content
- end
- var response = new PepperDictionary
- response["operation"] = "load_response"
- response["files_number"] = sys.lib.length.to_s
- post_dictionary response
- end
- end
-end
-
-redef fun app do return once new Pnacl_nit
-app.initialize # Needed to correctly set up Nit control over the Pepper API.
-app.run # Wait for dictionaries.