X-Git-Url: http://nitlanguage.org diff --git a/src/astbuilder.nit b/src/astbuilder.nit index fa1d188..1e1a235 100644 --- a/src/astbuilder.nit +++ b/src/astbuilder.nit @@ -15,10 +15,10 @@ # Instantiation and transformation of semantic nodes in the AST of expressions and statements module astbuilder -intrude import typing +intrude import semantize::typing intrude import literal intrude import parser -intrude import scope +intrude import semantize::scope # General factory to build semantic nodes in the AST of expressions class ASTBuilder @@ -30,23 +30,21 @@ class ASTBuilder var anchor: nullable MClassType # Make a new Int literal - fun make_int(value: Int): AIntExpr + fun make_int(value: Int): AIntegerExpr do - return new ADecIntExpr.make(value, mmodule.get_primitive_class("Int").mclass_type) + return new AIntegerExpr.make(value, mmodule.int_type) end # Make a new instatiation - fun make_new(mtype: MClassType, constructor: MMethod, args: nullable Array[AExpr]): ANewExpr + fun make_new(callsite: CallSite, args: nullable Array[AExpr]): ANewExpr do - return new ANewExpr.make(mtype, constructor, args) + return new ANewExpr.make(callsite, args) end # Make a new message send - fun make_call(recv: AExpr, mmethod: MMethod, args: nullable Array[AExpr]): ACallExpr + fun make_call(recv: AExpr, callsite: CallSite, args: nullable Array[AExpr]): ACallExpr do - var mtype = mmethod.intro.msignature.return_mtype - if mtype != null then mtype = mtype.resolve_for(recv.mtype.as(not null), anchor, mmodule, true) - return new ACallExpr.make(recv, mmethod, args, mtype) + return new ACallExpr.make(recv, callsite, args) end # Make a new, empty, sequence of statements @@ -55,6 +53,12 @@ class ASTBuilder return new ABlockExpr.make end + # Make a new, empty, loop of statements + fun make_loop: ALoopExpr + do + return new ALoopExpr.make + end + # Make a new variable read fun make_var_read(variable: Variable, mtype: MType): AVarExpr do @@ -86,6 +90,12 @@ class ASTBuilder return new ADoExpr.make end + # Make a new break for a given escapemark + fun make_break(escapemark: EscapeMark): ABreakExpr + do + return new ABreakExpr.make(escapemark) + end + # Make a new condinionnal # `mtype` is the return type of the whole if, in case of a ternary operator. fun make_if(condition: AExpr, mtype: nullable MType): AIfExpr @@ -124,11 +134,13 @@ redef class AExpr # To create the new node `n`, we need to attach the child to it. # But, to put `n` where `c` was in `p`, the place has to be remembered. # - # var p: AExpr - # var c = p.c - # var h = c.detach_with_placeholder - # var n = astbuilder.make_XXX(c) - # h.replace_with(n) + # ~~~nitish + # var p: AExpr + # var c = p.c + # var h = c.detach_with_placeholder + # var n = astbuilder.make_XXX(c) + # h.replace_with(n) + # ~~~ fun detach_with_placeholder: AExpr do var h = new APlaceholderExpr.make @@ -144,6 +156,7 @@ redef class AExpr # Note: this method, aimed to `ABlockExpr` is promoted to `AExpr` because of the limitations of the hierarchies generated by sablecc3 fun add(expr: AExpr) do + print "add not implemented in {inspect}" abort end end @@ -174,29 +187,54 @@ redef class ABlockExpr end end +redef class ALoopExpr + private init make + do + _n_kwloop = new TKwloop + self.is_typed = true + n_block = new ABlockExpr + n_block.is_typed = true + end + + redef fun add(expr: AExpr) + do + n_block.add expr + end +end + redef class ADoExpr private init make do _n_kwdo = new TKwdo - escapemark = new EscapeMark(null, false) + self.is_typed = true + n_block = new ABlockExpr + n_block.is_typed = true end # Make a new break expression of the given do fun make_break: ABreakExpr do - var escapemark = self.escapemark + var escapemark = self.break_mark if escapemark == null then - escapemark = new EscapeMark(null, false) - self.escapemark = escapemark + escapemark = new EscapeMark(null) + self.break_mark = escapemark end return new ABreakExpr.make(escapemark) end + + redef fun add(expr: AExpr) + do + n_block.add expr + end end redef class ABreakExpr private init make(escapemark: EscapeMark) do + _n_kwbreak = new TKwbreak self.escapemark = escapemark + escapemark.escapes.add self + self.is_typed = true end end @@ -206,7 +244,9 @@ redef class AIfExpr _n_kwif = new TKwif _n_expr = condition _n_expr.parent = self + _n_kwthen = new TKwthen _n_then = new ABlockExpr.make + _n_kwelse = new TKwelse _n_else = new ABlockExpr.make self.mtype = mtype self.is_typed = true @@ -220,17 +260,17 @@ redef class AType end end -redef class ADecIntExpr +redef class AIntegerExpr private init make(value: Int, t: MType) do self.value = value - self._n_number = new TNumber # dummy + self._n_integer = new TInteger # dummy self.mtype = t end end redef class ANewExpr - private init make(mtype: MClassType, mmethod: MMethod, args: nullable Array[AExpr]) + private init make(callsite: CallSite, args: nullable Array[AExpr]) do _n_kwnew = new TKwnew _n_type = new AType.make @@ -238,25 +278,29 @@ redef class ANewExpr if args != null then n_args.n_exprs.add_all(args) end - callsite = new CallSite(self, mtype, mmethod.intro.mclassdef.mmodule, mtype, true, mmethod, mmethod.intro, mmethod.intro.msignature.as(not null), false) - self.mtype = mtype + self.callsite = callsite + self.recvtype = callsite.recv.as(MClassType) + if callsite.mproperty.is_new then + self.mtype = callsite.msignature.return_mtype + else + self.mtype = callsite.recv + end + self.is_typed = true end end redef class ACallExpr - private init make(recv: AExpr, mmethod: MMethod, args: nullable Array[AExpr], t: nullable MType) + private init make(recv: AExpr, callsite: CallSite, args: nullable Array[AExpr]) do self._n_expr = recv - recv.parent = self - self.raw_arguments = args or else new Array[AExpr] _n_args = new AListExprs - _n_id = new TId + _n_qid = new AQid + _n_qid.n_id = new TId if args != null then self.n_args.n_exprs.add_all(args) end - var mtype = recv.mtype.as(not null) - callsite = new CallSite(self, mtype, mmethod.intro.mclassdef.mmodule, mmethod.intro.mclassdef.bound_mtype, true, mmethod, mmethod.intro, mmethod.intro.msignature.as(not null), false) - self.mtype = t + self.callsite = callsite + self.mtype = callsite.msignature.return_mtype self.is_typed = true end end