syntax: some cleaning to prepare intermediate code
authorJean Privat <jean@pryen.org>
Fri, 24 Jul 2009 10:15:22 +0000 (06:15 -0400)
committerJean Privat <jean@pryen.org>
Fri, 24 Jul 2009 10:36:57 +0000 (06:36 -0400)
Signed-off-by: Jean Privat <jean@pryen.org>

src/syntax/escape.nit
src/syntax/syntax_base.nit
src/syntax/typing.nit

index dc5ec47..be65285 100644 (file)
@@ -102,12 +102,12 @@ end
 class AEscapeExpr
 special PNode
        # The associated escapable block
-       readable var _escapable_block: nullable EscapableBlock
+       readable var _escapable: nullable EscapableBlock
 
        # The name of the keyword
        fun kwname: String is abstract
 
-       # Compute, set and return the _abelable_node value
+       # Compute, set and return the associated escapable block
        fun compute_escapable_block(lctx: EscapableContext): nullable EscapableBlock
        do
                var block: EscapableBlock
@@ -116,7 +116,7 @@ special PNode
                        return null
                end
                block = lctx.head
-               _escapable_block = block
+               _escapable = block
                return block
        end
 end
index 96cb5f1..cc626c1 100644 (file)
@@ -338,6 +338,15 @@ special Visitor
                return _module.type_none
        end
 
+       fun get_method(recv: MMType, name: Symbol): MMMethod
+       do
+               if not recv.local_class.has_global_property_by_name(name) then
+                       error(current_node, "Fatal Error: {recv} must have a property named {name}.")
+                       exit(1)
+               end
+               return recv.local_class.select_method(name)
+       end
+
        # The current module
        readable var _module: MMSrcModule
 
@@ -493,6 +502,11 @@ redef class PClassdef
        fun local_class: MMSrcLocalClass is abstract
 end
 
+redef class PPropdef
+       # Associated 'self' variable
+       fun self_var: ParamVariable is abstract
+end
+
 redef class AAttrPropdef
        # Associated attribute (MM entity)
        fun prop: MMSrcAttribute is abstract
@@ -512,9 +526,6 @@ end
 redef class AMethPropdef
        # Associated method (MM entity)
        fun method: MMMethSrcMethod is abstract
-
-       # Associated 'self' variable
-       fun self_var: ParamVariable is abstract
 end
 
 redef class ATypePropdef
index c74cd70..e2e6a2f 100644 (file)
@@ -159,11 +159,17 @@ redef class PClassdef
        end
 end
 
+redef class PPropdef
+       redef fun self_var do return _self_var.as(not null)
+       var _self_var: nullable ParamVariable
+end
+
 redef class AAttrPropdef
        redef fun accept_typing(v)
        do
                var old_var_ctx = v.variable_ctx
                v.variable_ctx = old_var_ctx.sub(self)
+               _self_var = v.self_var
                super
                if n_expr != null then
                        v.check_conform_expr(n_expr.as(not null), prop.signature.return_type.as(not null))
@@ -173,8 +179,6 @@ redef class AAttrPropdef
 end
 
 redef class AMethPropdef
-       redef fun self_var do return _self_var.as(not null)
-       var _self_var: nullable ParamVariable
        redef fun accept_typing(v)
        do
                var old_var_ctx = v.variable_ctx
@@ -202,6 +206,11 @@ redef class AConcreteInitPropdef
                v.explicit_super_init_calls = explicit_super_init_calls
                v.explicit_other_init_call = false
                super
+       end
+
+       redef fun after_typing(v)
+       do
+               super
                if v.explicit_other_init_call or method.global.intro != method then
                        # TODO: something?
                else 
@@ -313,6 +322,12 @@ redef class PExpr
        end
        var _stype: nullable MMType
 
+       redef fun after_typing(v)
+       do
+               # Default behavior is to be happy
+               _is_typed = true
+       end
+
        # Is the expression the implicit receiver
        fun is_implicit_self: Bool do return false
 
@@ -439,6 +454,7 @@ redef class AAbortExpr
        redef fun after_typing(v)
        do
                v.variable_ctx.unreash = true
+               _is_typed = true
        end
 end
 
@@ -541,6 +557,7 @@ redef class AForExpr
                _variable = va
                v.variable_ctx.add(va)
 
+               # Process collection
                v.enter_visit(n_expr)
 
                if not v.check_conform_expr(n_expr, v.type_collection) then return
@@ -571,6 +588,7 @@ redef class AForExpr
                if not n_expr.is_self then t = t.not_for_self
                va.stype = t
 
+               # Body evaluation
                if n_block != null then v.enter_visit(n_block)
 
                # pop context
@@ -705,17 +723,28 @@ redef class AIfexprExpr
        do
                var old_var_ctx = v.variable_ctx
 
+               # Process condition
                v.enter_visit(n_expr)
+               v.check_conform_expr(n_expr, v.type_bool)
+
+               # Prepare 'then' context
                v.use_if_true_variable_ctx(n_expr)
+
+               # Process 'then'
                v.enter_visit(n_then)
+
+               # Prepare 'else' context
                v.variable_ctx = old_var_ctx
                v.use_if_false_variable_ctx(n_expr)
+
+               # Process 'else'
                v.enter_visit(n_else)
 
-               v.check_conform_expr(n_expr, v.type_bool)
+               var stype = v.check_conform_multiexpr(null, [n_then, n_else])
+               if stype == null then return
 
-               _stype = v.check_conform_multiexpr(null, [n_then, n_else])
-               _is_typed = _stype != null
+               _stype = stype
+               _is_typed = true
        end
 end
 
@@ -731,12 +760,18 @@ redef class AOrExpr
        redef fun accept_typing(v)
        do
                var old_var_ctx = v.variable_ctx
+               var stype = v.type_bool
+               _stype = stype
 
+               # Process left operand
                v.enter_visit(n_expr)
+
+               # Prepare right operand context
                v.use_if_false_variable_ctx(n_expr)
 
+               # Process right operand
                v.enter_visit(n_expr2)
-               if n_expr2.if_false_variable_ctx != null then 
+               if n_expr2.if_false_variable_ctx != null then
                        _if_false_variable_ctx = n_expr2.if_false_variable_ctx
                else
                        _if_false_variable_ctx = v.variable_ctx
@@ -744,9 +779,9 @@ redef class AOrExpr
 
                v.variable_ctx = old_var_ctx
 
-               v.check_conform_expr(n_expr, v.type_bool)
-               v.check_conform_expr(n_expr2, v.type_bool)
-               _stype = v.type_bool
+               v.check_conform_expr(n_expr, stype)
+               v.check_conform_expr(n_expr2, stype)
+               _stype = stype
                _is_typed = true
        end
 end
@@ -755,12 +790,17 @@ redef class AAndExpr
        redef fun accept_typing(v)
        do
                var old_var_ctx = v.variable_ctx
+               var stype = v.type_bool
 
+               # Process left operand
                v.enter_visit(n_expr)
+
+               # Prepare right operand context
                v.use_if_true_variable_ctx(n_expr)
 
+               # Process right operand
                v.enter_visit(n_expr2)
-               if n_expr2.if_true_variable_ctx != null then 
+               if n_expr2.if_true_variable_ctx != null then
                        _if_true_variable_ctx = n_expr2.if_true_variable_ctx
                else
                        _if_true_variable_ctx = v.variable_ctx
@@ -768,9 +808,9 @@ redef class AAndExpr
 
                v.variable_ctx = old_var_ctx
 
-               v.check_conform_expr(n_expr, v.type_bool)
-               v.check_conform_expr(n_expr2, v.type_bool)
-               _stype = v.type_bool
+               v.check_conform_expr(n_expr, stype)
+               v.check_conform_expr(n_expr2, stype)
+               _stype = stype
                _is_typed = true
        end
 end
@@ -1110,10 +1150,12 @@ redef class AAbsAbsSendExpr
                for c in cs do
                        if not c.is_optional then min_arity += 1
                end
-               if cd != null then
-                       if cs.length == 0 then
-                               v.error(self, "Error: {name} does not require blocks.")
-                       else if cd.length > cs.length or cd.length < min_arity then
+               var arity = 0
+               if cd != null then arity = cd.length
+               if cs.length > 0 then
+                       if arity == 0 and min_arity > 0 then
+                               v.error(self, "Error: {name} requires {cs.length} blocks.")
+                       else if arity > cs.length or arity < min_arity then
                                v.error(self, "Error: {name} requires {cs.length} blocks, {cd.length} found.")
                        else
                                # Initialize the break list if a value is required for breaks (ie. if the method is a function)
@@ -1121,7 +1163,7 @@ redef class AAbsAbsSendExpr
                                if t != null then break_list = new Array[ABreakExpr]
 
                                # Process each closure definition
-                               for i in [0..cd.length[ do
+                               for i in [0..arity[ do
                                        var csi = cs[i]
                                        var cdi = cd[i]
                                        var esc = new EscapableClosure(cdi, csi, break_list)
@@ -1135,8 +1177,8 @@ redef class AAbsAbsSendExpr
                                        t = v.check_conform_multiexpr(t, break_list)
                                end
                        end
-               else if min_arity != 0 then
-                       v.error(self, "Error: {name} requires {cs.length} blocks.")
+               else if arity != 0 then
+                       v.error(self, "Error: {name} does not require blocks.")
                end
                return t
        end
@@ -1449,23 +1491,21 @@ redef class ACallFormExpr
                        var name = n_id.to_symbol
                        var variable = v.variable_ctx[name]
                        if variable != null then
+                               var n: PExpr
                                if variable isa ClosureVariable then
-                                       var n = new AClosureCallExpr.init_aclosurecallexpr(n_id, n_args, n_closure_defs)
-                                       replace_with(n)
+                                       n = new AClosureCallExpr.init_aclosurecallexpr(n_id, n_args, n_closure_defs)
                                        n._variable = variable
-                                       n.after_typing(v)
-                                       return
                                else
                                        if not n_args.is_empty then
                                                v.error(self, "Error: {name} is variable, not a function.")
                                                return
                                        end
-                                       var vform = variable_create(variable)
-                                       vform._variable = variable
-                                       replace_with(vform)
-                                       vform.after_typing(v)
-                                       return
+                                       n = variable_create(variable)
+                                       n._variable = variable
                                end
+                               replace_with(n)
+                               n.after_typing(v)
+                               return
                        end
                end