public CILVariableDecl ToCILVariableDecl(CIntermediateLang cil) { // TODO: Do propery type checking between declared type and inferred/rhs type LllType realType; if (Type != null) { realType = Type.ToLllType(); } else { realType = AssigningValue.TryInferType(cil); if (realType.IsAReference) { // Auto-dereference the type... Type = new AstType(SourceInfo, realType.Name, realType.PointerDepth - 1, 0, false, false); } else { Type = new AstType(SourceInfo, realType.Name, realType.PointerDepth, 0, realType.IsAReference, false); } } var cName = NameGenerator.UniqName("var", Name); var cType = cil.SymTable.LookupType(realType.CName); if (IsFixedArray) { if (AssigningValue != null) { throw new NotImplementedException("Assigning to a fixed size array is not implemented."); } return(new CILFixedArray(SourceInfo, cType, realType.PointerDepth, cName, Type.FixedArraySize)); } // covers the case of declaration and function paramters if (AssigningValue == null) { var decl = new CILVariableDecl(SourceInfo, cType, realType.PointerDepth, cName); return(decl); } var val = AssigningValue.ToCILExpression(cil); var srcTy = AssigningValue.TryInferType(cil); var fixedPtrDepth = srcTy.PointerDepth; if (srcTy.IsAReference && !Type.IsAReference) { --fixedPtrDepth; val = new CILDereference(SourceInfo, val); } return(new CILVariableDecl(SourceInfo, cType, fixedPtrDepth, cName, val)); }
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)); }