From f1247c2c16bf348f5dc81af30a8fda513e0d8d9b Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Thu, 4 Dec 2014 14:32:27 -0500 Subject: [PATCH] modelize: add and use method mpropdef2node Signed-off-by: Jean Privat --- src/compiler/abstract_compiler.nit | 23 +++++++++++------------ src/interpreter/debugger.nit | 21 +++++++-------------- src/interpreter/naive_interpreter.nit | 20 +++++++++++--------- src/modelize/modelize_property.nit | 15 +++++++++++++++ src/rapid_type_analysis.nit | 32 +++++++++++++++----------------- 5 files changed, 59 insertions(+), 52 deletions(-) diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index abfbf3f..a6d6d86 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -1857,10 +1857,10 @@ redef class MMethodDef do if is_abstract then return true var modelbuilder = v.compiler.modelbuilder - if modelbuilder.mpropdef2npropdef.has_key(self) then - var npropdef = modelbuilder.mpropdef2npropdef[self] - return npropdef.can_inline - else if self.mproperty.is_root_init then + var node = modelbuilder.mpropdef2node(self) + if node isa APropdef then + return node.can_inline + else if node isa AClassdef then # Automatic free init is always inlined since it is empty or contains only attribtes assigments return true else @@ -1873,19 +1873,18 @@ redef class MMethodDef do var modelbuilder = v.compiler.modelbuilder var val = constant_value - if modelbuilder.mpropdef2npropdef.has_key(self) then - var npropdef = modelbuilder.mpropdef2npropdef[self] + var node = modelbuilder.mpropdef2node(self) + if node isa APropdef then var oldnode = v.current_node - v.current_node = npropdef + v.current_node = node self.compile_parameter_check(v, arguments) - npropdef.compile_to_c(v, self, arguments) + node.compile_to_c(v, self, arguments) v.current_node = oldnode - else if self.mproperty.is_root_init then - var nclassdef = modelbuilder.mclassdef2nclassdef[self.mclassdef] + else if node isa AClassdef then var oldnode = v.current_node - v.current_node = nclassdef + v.current_node = node self.compile_parameter_check(v, arguments) - nclassdef.compile_to_c(v, self, arguments) + node.compile_to_c(v, self, arguments) v.current_node = oldnode else if val != null then v.ret(v.value_instance(val)) diff --git a/src/interpreter/debugger.nit b/src/interpreter/debugger.nit index 684ea87..58a49d1 100644 --- a/src/interpreter/debugger.nit +++ b/src/interpreter/debugger.nit @@ -280,20 +280,13 @@ class Debugger assert args.length == mpropdef.msignature.arity + 1 else debug("Invalid arity for {mpropdef}. {args.length} arguments given.") # Look for the AST node that implements the property - var mproperty = mpropdef.mproperty - if self.modelbuilder.mpropdef2npropdef.has_key(mpropdef) then - var npropdef = self.modelbuilder.mpropdef2npropdef[mpropdef] - self.parameter_check(npropdef, mpropdef, args) - if npropdef isa AMethPropdef then - return npropdef.rt_call(self, mpropdef, args) - else - print "Error, invalid propdef to call at runtime !" - return null - end - else if mproperty.is_root_init then - var nclassdef = self.modelbuilder.mclassdef2nclassdef[mpropdef.mclassdef] - self.parameter_check(nclassdef, mpropdef, args) - return nclassdef.call(self, mpropdef, args) + var node = modelbuilder.mpropdef2node(mpropdef) + if node isa AMethPropdef then + self.parameter_check(node, mpropdef, args) + return node.rt_call(self, mpropdef, args) + else if node isa AClassdef then + self.parameter_check(node, mpropdef, args) + return node.call(self, mpropdef, args) else fatal("Fatal Error: method {mpropdef} not found in the AST") abort diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index 476608c..da8d02e 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -383,16 +383,18 @@ class NaiveInterpreter assert args.length == mpropdef.msignature.arity + 1 else debug("Invalid arity for {mpropdef}. {args.length} arguments given.") # Look for the AST node that implements the property - var mproperty = mpropdef.mproperty var val = mpropdef.constant_value - if self.modelbuilder.mpropdef2npropdef.has_key(mpropdef) then - var npropdef = self.modelbuilder.mpropdef2npropdef[mpropdef] - self.parameter_check(npropdef, mpropdef, args) - return npropdef.call(self, mpropdef, args) - else if mproperty.is_root_init then - var nclassdef = self.modelbuilder.mclassdef2nclassdef[mpropdef.mclassdef] - self.parameter_check(nclassdef, mpropdef, args) - return nclassdef.call(self, mpropdef, args) + + var node = modelbuilder.mpropdef2node(mpropdef) + if node isa APropdef then + self.parameter_check(node, mpropdef, args) + return node.call(self, mpropdef, args) + else if node isa AClassdef then + self.parameter_check(node, mpropdef, args) + return node.call(self, mpropdef, args) + else if node != null then + fatal("Fatal Error: method {mpropdef} associated to unexpected AST node {node.location}") + abort else if val != null then return value_instance(val) else diff --git a/src/modelize/modelize_property.nit b/src/modelize/modelize_property.nit index 757f85d..faaf149 100644 --- a/src/modelize/modelize_property.nit +++ b/src/modelize/modelize_property.nit @@ -40,6 +40,21 @@ redef class ModelBuilder # FIXME: why not refine the `MPropDef` class with a nullable attribute? var mpropdef2npropdef = new HashMap[MPropDef, APropdef] + # Retrieve the associated AST node of a mpropertydef. + # This method is used to associate model entity with syntactic entities. + # + # If the property definition is not associated with a node, returns node. + fun mpropdef2node(mpropdef: MPropDef): nullable ANode + do + var res: nullable ANode = mpropdef2npropdef.get_or_null(mpropdef) + if res != null then return res + if mpropdef isa MMethodDef and mpropdef.mproperty.is_root_init then + res = mclassdef2nclassdef.get_or_null(mpropdef.mclassdef) + if res != null then return res + end + return null + end + # Build the properties of `nclassdef`. # REQUIRE: all superclasses are built. private fun build_properties(nclassdef: AClassdef) diff --git a/src/rapid_type_analysis.nit b/src/rapid_type_analysis.nit index 9f97e45..7fcb4bc 100644 --- a/src/rapid_type_analysis.nit +++ b/src/rapid_type_analysis.nit @@ -215,7 +215,7 @@ class RapidTypeAnalysis var vararg_rank = mmethoddef.msignature.vararg_rank if vararg_rank > -1 then - var node = self.modelbuilder.mpropdef2npropdef[mmethoddef] + var node = self.modelbuilder.mpropdef2node(mmethoddef) var elttype = mmethoddef.msignature.mparameters[vararg_rank].mtype #elttype = elttype.anchor_to(self.mainmodule, v.receiver) var vararg = self.mainmodule.get_primitive_class("Array").get_mtype([elttype]) @@ -235,27 +235,25 @@ class RapidTypeAnalysis add_cast(paramtype) end - if not modelbuilder.mpropdef2npropdef.has_key(mmethoddef) then - # It is an init for a class? - if mmeth.is_root_init then - var nclassdef = self.modelbuilder.mclassdef2nclassdef[mmethoddef.mclassdef] - assert mmethoddef == nclassdef.mfree_init + var npropdef = modelbuilder.mpropdef2node(mmethoddef) - if mmethoddef.mproperty.is_root_init and not mmethoddef.is_intro then - self.add_super_send(v.receiver, mmethoddef) - end - else if mmethoddef.constant_value != null then - # Make the return type live - v.add_type(mmethoddef.msignature.return_mtype.as(MClassType)) - else - abort + if npropdef isa AClassdef then + # It is an init for a class + assert mmethoddef == npropdef.mfree_init + + if mmethoddef.mproperty.is_root_init and not mmethoddef.is_intro then + self.add_super_send(v.receiver, mmethoddef) end continue + else if mmethoddef.constant_value != null then + # Make the return type live + v.add_type(mmethoddef.msignature.return_mtype.as(MClassType)) + continue + else if npropdef == null then + abort end - var npropdef = modelbuilder.mpropdef2npropdef[mmethoddef] - - if npropdef isa AMethPropdef then + if npropdef isa AMethPropdef then var auto_super_inits = npropdef.auto_super_inits if auto_super_inits != null then for auto_super_init in auto_super_inits do -- 1.7.9.5