debugger: Added dynamic evaluation of a Nit module.
authorLucas Bajolet <r4pass@hotmail.com>
Thu, 16 Jan 2014 20:33:18 +0000 (15:33 -0500)
committerLucas Bajolet <r4pass@hotmail.com>
Fri, 17 Jan 2014 22:37:30 +0000 (17:37 -0500)
Signed-off-by: Lucas Bajolet <r4pass@hotmail.com>

src/debugger.nit
src/modelbuilder.nit

index a9e9033..f2fcf71 100644 (file)
@@ -299,6 +299,55 @@ class Debugger
                end
        end
 
+       # Evaluates dynamically a snippet of Nit code
+       # `nit_code` : Nit code to be executed
+       fun eval(nit_code: String)
+       do
+               var local_toolctx = modelbuilder.toolcontext
+               local_toolctx.dbg = self
+               var e = local_toolctx.parse_something(nit_code)
+               if e isa AExpr then
+                       nit_code = "print " + nit_code
+                       e = local_toolctx.parse_something(nit_code)
+               end
+               if e isa AModule then
+                       local_toolctx.had_error = false
+                       modelbuilder.load_rt_module(self.mainmodule, e, "rt_module")
+                       local_toolctx.run_phases([e])
+                       if local_toolctx.had_error then
+                               modelbuilder.model.try_remove_module(e.mmodule.as(not null))
+                               local_toolctx.dbg = null
+                               return
+                       end
+                       var mmod = e.mmodule
+                       if mmod != null then
+                               self.mainmodule = mmod
+                               var local_classdefs = mmod.mclassdefs
+                               var sys_type = mmod.sys_type
+                               if sys_type == null then
+                                       print "Fatal error, cannot find Class Sys !\nAborting"
+                                       abort
+                               end
+                               var mobj = new MutableInstance(sys_type)
+                               init_instance(mobj)
+                               var initprop = mmod.try_get_primitive_method("init", sys_type.mclass)
+                               if initprop != null then
+                                       self.send(initprop, [mobj])
+                               end
+                               self.check_init_instance(mobj)
+                               var mainprop = mmod.try_get_primitive_method("main", sys_type.mclass)
+                               if mainprop != null then
+                                       self.rt_send(mainprop, [mobj])
+                               end
+                       else
+                               print "Error while loading_rt_module"
+                       end
+               else
+                       print "Error when parsing, e = {e.class_name}"
+               end
+               local_toolctx.dbg = null
+       end
+
        # Encpasulates the behaviour for step over/out
        private fun steps_fun_call(n: AExpr)
        do
index bc049ab..bb7d46c 100644 (file)
@@ -390,7 +390,33 @@ class ModelBuilder
                var parser = new Parser(lexer)
                var tree = parser.parse
                file.close
+               var mod_name = filename.basename(".nit")
+               return load_module_commons(owner, tree, mod_name)
+       end
+
+       fun load_rt_module(owner: MModule, nmodule: AModule, mod_name: String): nullable AModule
+       do
+               # Create the module
+               var mmodule = new MModule(model, owner, mod_name, nmodule.location)
+               nmodule.mmodule = mmodule
+               nmodules.add(nmodule)
+               self.mmodule2nmodule[mmodule] = nmodule
+
+               var imported_modules = new Array[MModule]
 
+               imported_modules.add(owner)
+               mmodule.set_visibility_for(owner, intrude_visibility)
+
+               mmodule.set_imported_mmodules(imported_modules)
+
+               return nmodule
+       end
+
+       # Try to load a module using a path.
+       # Display an error if there is a problem (IO / lexer / parser) and return null
+       # Note: usually, you do not need this method, use `get_mmodule_by_name` instead.
+       private fun load_module_commons(owner: nullable MModule, tree: Start, mod_name: String): nullable AModule
+       do
                # Handle lexer and parser error
                var nmodule = tree.n_base
                if nmodule == null then
@@ -401,7 +427,6 @@ class ModelBuilder
                end
 
                # Check the module name
-               var mod_name = filename.basename(".nit")
                var decl = nmodule.n_moduledecl
                if decl == null then
                        #warning(nmodule, "Warning: Missing 'module' keyword") #FIXME: NOT YET FOR COMPATIBILITY
@@ -417,7 +442,6 @@ class ModelBuilder
                nmodule.mmodule = mmodule
                nmodules.add(nmodule)
                self.mmodule2nmodule[mmodule] = nmodule
-               self.loaded_nmodules[module_path] = nmodule
 
                build_module_importation(nmodule)