Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        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));
        }