X-Git-Url: http://nitlanguage.org diff --git a/src/syntax/icode_generation.nit b/src/syntax/icode_generation.nit index afb15b7..f8a07e4 100644 --- a/src/syntax/icode_generation.nit +++ b/src/syntax/icode_generation.nit @@ -15,7 +15,7 @@ # limitations under the License. # Things needed by typing.nit to generate intermediate code from AST -package icode_generation +module icode_generation import icode import syntax_base @@ -82,6 +82,9 @@ class A2IContext # The method associated to the iroutine (if any) readable var _method: nullable MMMethod + # The register of self (if any) + var selfreg: nullable IRegister writable + init(visitor: AbsSyntaxVisitor, r: IRoutine, m: nullable MMMethod) do super(visitor.mmmodule, r) @@ -177,8 +180,8 @@ redef class MMSrcModule fun generate_icode(tc: ToolContext) do var v = new A2IVisitor(tc, self) - for c in src_local_classes do - for p in c.src_local_properties do + for c in src_local_classes.values do + for p in c.src_local_properties.values do if p isa MMSrcMethod then p.generate_iroutine(v) else if p isa MMSrcAttribute then @@ -368,6 +371,7 @@ redef class AConcreteMethPropdef var params = v.iroutine.params.to_a var selfreg = v.variable(self_var) v.stmt(new IMove(selfreg, params[0])) + v.selfreg = selfreg params.shift var orig_meth: MMLocalProperty = method.global.intro @@ -383,6 +387,39 @@ redef class AConcreteMethPropdef if n_block != null then v.generate_stmt(n_block) end + v.selfreg = null + end +end + +redef class AExternPropdef + redef fun fill_iroutine(v, method) + do + # add all explicit extern calls for this extern method + for explicit_import in method.as(MMMethSrcMethod).explicit_imports + do + var prop = explicit_import.method + var ic : IAbsCall + if prop.is_init then + ic = new INew(prop.signature.recv, prop, new List[IRegister]) + else + ic = new ICall(prop, new List[IRegister]) + end + ic.is_explicit_from_extern = true + v.stmt(ic) + end + end +end + +redef class AExternInitPropdef + redef fun fill_iroutine(v, method) + do + var params = v.iroutine.params + var sig = method.signature + assert params.length == sig.arity + 1 + var rtype = sig.recv # sig.return_type + v.add_assignment(new IRegister(rtype), v.expr(new INative(method, params), rtype)) + + super end end @@ -403,6 +440,8 @@ redef class AExternMethPropdef else v.stmt(new INative(method, params)) end + + super end end @@ -625,7 +664,9 @@ redef class AForExpr v.seq = iclos.body escapable.continue_seq = iclos.body escapable.continue_value = null - v.stmt(new IMove(v.variable(variable), iclos.params.first)) + for i in [0..variables.length[ do + v.stmt(new IMove(v.variable(variables[i]), iclos.params[i])) + end v.generate_stmt(n_block) # Call closure @@ -650,7 +691,7 @@ redef class AAssertExpr if id == null then v.add_abort("Assert failed") else - v.add_abort("Assert %s failed", id.to_s) + v.add_abort("Assert '%s' failed", id.text.to_s) end v.seq = seq_old return null @@ -746,6 +787,28 @@ redef class AOrExpr end end +redef class AImpliesExpr + redef fun generate_icode(v) + do + # Prepare result + var reg = v.new_register(stype) + + # Process left operand (in a if/then) + var iif = new IIf(v.generate_expr(n_expr)) + v.stmt(iif) + var seq_old = v.seq + v.seq = iif.else_seq + v.add_assignment(reg, v.lit_true_reg) + + # Process right operand (in the else) + v.seq = iif.then_seq + v.add_assignment(reg, v.generate_expr(n_expr2)) + + v.seq = seq_old + return reg + end +end + redef class AAndExpr redef fun generate_icode(v) do @@ -810,7 +873,7 @@ redef class AIsaExpr redef fun generate_icode(v) do var e = v.generate_expr(n_expr) - return v.expr(new ITypeCheck(e, n_type.stype), stype) + return v.expr(new ITypeCheck(v.selfreg.as(not null), e, n_type.stype), stype) end end @@ -875,10 +938,11 @@ redef class AStringFormExpr var ionce = new IOnce var reg = v.expr(ionce, stype) v.seq = ionce.body - var ns = v.expr(new IStringValue(_cstring.as(not null)), v.visitor.type_nativestring) + var native_type = v.visitor.type_nativestring + var ns = v.expr(new IStringValue(_cstring.as(not null)), native_type) var ni = v.expr(new IIntValue(_cstring_length.to_s), v.visitor.type_int) - var prop = v.visitor.get_method(stype, once "with_native".to_symbol) - var e = v.expr(new INew(stype, prop, [ns, ni]), stype) + var prop = v.visitor.get_method(native_type, once "to_s_with_length".to_symbol) + var e = v.expr(new ICall(prop, [ns, ni]), stype) v.add_assignment(reg, e) v.seq = old_seq return reg @@ -896,9 +960,14 @@ redef class AStringFormExpr # Compute _cstring and _cstring_length using string_text protected fun compute_string_infos do - var len = 0 - var str = string_text + var str = n_string.text + if str.length >= 6 and str[0] == str[1] then + str = str.substring(3, str.length - 6) + else + str = str.substring(1, str.length - 2) + end var res = new Buffer + var len = 0 var i = 0 while i < str.length do var c = str[i] @@ -909,6 +978,11 @@ redef class AStringFormExpr res.add(c) end c = c2 + else if c == '"' then + res.add('\\') + else if c == '\n' then + res.add('\\') + c = 'n' end len = len + 1 res.add(c) @@ -958,8 +1032,9 @@ end redef class AArrayExpr redef fun generate_icode(v) do - var recv = v.add_new_array(stype, n_exprs.length) - for ne in n_exprs do + var nes = n_exprs.n_exprs + var recv = v.add_new_array(stype, nes.length) + for ne in nes do var e = v.generate_expr(ne) v.add_call_array_add(recv, e) end @@ -996,12 +1071,13 @@ redef class ASuperExpr end var args = new Array[IRegister].with_capacity(arity + 1) args.add(v.iroutine.params[0]) - if n_args.length != arity then + var nas = n_args.n_exprs + if nas.length != arity then for i in [0..arity[ do args.add(v.iroutine.params[i + 1]) end else - for na in n_args do + for na in nas do args.add(v.generate_expr(na)) end end @@ -1318,3 +1394,11 @@ redef class AClosureCallExpr return r end end + +redef class ADebugTypeExpr + redef fun generate_icode(v) + do + # Do nothing. + return null + end +end