private CILExpression CreateCtorCall(CIntermediateLang cil) { var call = Expression as AstCall; var ctorId = call?.Callee as AstIdent; if (ctorId == null) { throw new NotImplementedException(); } var @sizeof = new AstCall(SourceInfo, new AstIdent(SourceInfo, "sizeof"), new List <AstExpression> { new AstIdent(SourceInfo, ctorId.Name) }); var malloc = new AstCall(SourceInfo, new AstIdent(SourceInfo, "alloc"), new List <AstExpression> { @sizeof }); var tmp = NameGenerator.NewTemp(); var tmpType = new AstType(SourceInfo, ctorId.Name, 1, 0, false, false); var decl = new AstDeclaration(SourceInfo, tmp, tmpType, malloc); var rewrite = new List <CILNode>(); var cdecl = decl.ToCILVariableDeclAndDecl(cil); cil.DeclareLocalVariable(cdecl); rewrite.Add(cdecl); var ctor = call.FixIdent(cil, string.Format("{0}_{1}", ctorId.Name, "Ctor")); call.Args.Insert(0, new AstIdent(SourceInfo, decl.Name)); ctorId.Name = ctor; var ctorCall = call.ToCILExpression(cil); rewrite.Add(ctorCall); var objId = new AstIdent(SourceInfo, decl.Name); rewrite.Add(objId.ToCILExpression(cil)); return(new CILRewriteExpression(SourceInfo, rewrite)); }
public override CILExpression ToCILExpression(CIntermediateLang cil) { var args = Args.Select(a => a.ToCILExpression(cil)).ToList(); for (int i = 0; i < Args.Count; ++i) { var arg = Args[i]; if (arg.TryInferType(cil).IsAReference) { args[i] = new CILDereference(arg.SourceInfo, args[i]); } } var ident = Callee as AstIdent; if (ident != null) { ident.Name = FixIdent(cil, ident.Name); var sym = LllCompiler.SymTable.LookupSymbol(ident.Name) as LllFunction; var func = sym?.Extra as AstFunc; if (func != null) { for (int i = 0; i < func.Params.Count; ++i) { var p = func.Params[i]; if (!p.Type.IsAReference) { continue; } var a = args[i]; args[i] = new CILReference(a.SourceInfo, a); } if (func.IsGeneric) { var actual = CompileGeneric(cil, func); return(new CILCall(SourceInfo, new CILIdent(SourceInfo, actual.CILFunction.Name), args)); } } } var extend = Callee as AstMemberAccess; if (extend != null) { var fromTy = extend.From.TryInferType(cil); var member = extend.MemberIdent; var extName = FixIdent(cil, string.Format("{0}_{1}", fromTy.Name, member)); if (fromTy.Extensions.ContainsKey(extName)) { var ext = fromTy.Extensions[extName]; if (ext.UsesThisPtr) { args.Insert(0, extend.From.ToCILExpression(cil)); } if (ext.IsGeneric) { //ext = ext.ConvertFromGenericToActual(cil, Args, SourceInfo) as AstExtend; //LllCompiler.Ast.CompileGeneric(ext); ext = CompileGeneric(cil, ext) as AstExtend; } for (int i = 0; i < ext.Params.Count; ++i) { var p = ext.Params[i]; if (!p.Type.IsAReference) { continue; } var a = args[i]; args[i] = new CILReference(a.SourceInfo, a); } var extId = new AstIdent(SourceInfo, ext.MangledName); return(new CILCall(SourceInfo, extId.ToCILExpression(cil), args)); } throw new UndefinedSymbolException( string.Format("Error: {0} : type '{1}' does not have extension '{2}'", SourceInfo, fromTy, member)); } var callee = Callee.ToCILExpression(cil); var callee_ = callee as CILCall; if (callee_ != null) { callee_.Args.AddRange(args); return(callee_); } return(new CILCall(SourceInfo, callee, args)); }