public override LllType TryInferType(CIntermediateLang cil) { var sym = LllCompiler.SymTable.LookupSymbol(Name); if (sym is LllType) { return((LllType)sym); } var decl = sym.Extra as AstDeclaration; if (decl != null) { if (decl.Type == null) { return(null); } return(decl.GetRealType()); } var func = sym.Extra as AstFunc; if (func != null) { return(func.GetRealReturnType()); } throw new NotImplementedException(); }
public override string TryInferType(CIntermediateLang cil) { // TODO: Remove a level of pointers var ty = Pointer.TryInferType(cil); return(CTypes.DereferenceType(ty)); }
public virtual void CDecl(CIntermediateLang cil) { if (LllCompiler.SymTable.LookupSymbol(MangledName) != null) { var func = LllCompiler.SymTable.LookupFunction(MangledName); var funcAst = func.Extra as AstFunc; if (funcAst != null) { CILFunction = funcAst.CILFunction; } return; } var cName = NameGenerator.UniqName("func", Name); LllCompiler.SymTable.AddSymbolAtGlobalScope(new LllFunction(cName, this)); if (!IsGeneric) { var retType = ReturnType.ToLllType(); CILFunction = cil.CreateFunction( SourceInfo, retType.CName, retType.PointerDepth, cName, Params.Select(p => p.ToCILVariableDecl(cil)).ToList()); } }
public override LllType TryInferType(CIntermediateLang cil) { if (Number % 1 == 0) { //if (IsBetweenInclusive(sbyte.MinValue, sbyte.MaxValue)) //{ // return LllCompiler.SymTable.LookupType("i8"); //} //if (IsBetweenInclusive(short.MinValue, short.MaxValue)) //{ // return LllCompiler.SymTable.LookupType("short"); //} if (IsBetweenInclusive(int.MinValue, int.MaxValue)) { return(LllCompiler.SymTable.LookupType("int")); } if (IsBetweenInclusive(long.MinValue, long.MaxValue)) { return(LllCompiler.SymTable.LookupType("long")); } } if (Number > Convert.ToDecimal(double.MaxValue) || Number < Convert.ToDecimal(double.MinValue)) { throw new NotImplementedException("TODO: Exception for number overflow"); } return(LllCompiler.SymTable.LookupType("double")); }
public override string TryInferType(CIntermediateLang cil) { switch (Op) { case OpType.Add: case OpType.Sub: case OpType.Mul: case OpType.Div: return(CTypes.BestNumberType(Lhs.TryInferType(cil), Rhs.TryInferType(cil))); case OpType.Mod: case OpType.And: case OpType.Or: case OpType.Xor: case OpType.LShift: case OpType.RShift: return(CTypes.LargerIntegerType(Lhs.TryInferType(cil), Rhs.TryInferType(cil))); case OpType.Equals: case OpType.NotEquals: case OpType.LessThan: case OpType.LessThanEquals: case OpType.GreaterThan: case OpType.GreaterThanEquals: return("int"); } throw new NotImplementedException("TODO: Exception for type inference failing."); }
private static void Test1() { var cil = new CIntermediateLang(); var myStruct = cil.CreateStruct(tsi, "String"); var testFunc = cil.CreateFunction(tsi, "String", 1, "testFunc", new List <CILVariableDecl>()); var main = cil.CreateFunction(tsi, "int", 0, "main", new List <CILVariableDecl> { new CILVariableDecl(tsi, cil.SymTable.LookupType("int"), 0, "argc"), new CILVariableDecl(tsi, cil.SymTable.LookupType("char"), 2, "argv"), }); main.AddBodyNode(new CILCall(tsi, new CILIdent(tsi, "testFunc"), new List <CILExpression>() { new CILIdent(tsi, "argc"), new CILIdent(tsi, "argv"), })); testFunc.AddBodyNode(new CILVariableDecl(tsi, cil.SymTable.LookupType("String"), 1, "testStr")); var ret = new CILReturn(tsi, new CILIdent(tsi, "testStr")); var branch = new CILBranch(tsi, new CILIdent(tsi, "testStr")); branch.AddTrueBranchStmt(ret); var loop = new CILLoop(tsi, new CILInteger(tsi, 42)); loop.Body.Add(new CILReturn(tsi, new CILIdent(tsi, "testStr"))); loop.Before.Add(new CILCall(tsi, new CILIdent(tsi, "testFunc"), new List <CILExpression>())); loop.After.Add(new CILCall(tsi, new CILIdent(tsi, "testFunc"), new List <CILExpression>())); branch.AddFalseBranchStmt(loop); branch.AddFalseBranchStmt(ret); testFunc.AddBodyNode(branch); myStruct.AddMember( new CILVariableDecl( tsi, cil.SymTable.LookupType("int"), 0, "length")); myStruct.AddMember( new CILVariableDecl( tsi, cil.SymTable.LookupType("char"), 1, "string")); myStruct.AddMember( new CILVariableDecl( tsi, myStruct, 1, "test")); testFunc.AddBodyNode( new CILAssignment(tsi, new CILMemberAccess(tsi, new CILMemberAccess(tsi, new CILCall(tsi, new CILIdent(tsi, "testFunc")), "test"), "length"), new CILInteger(tsi, 42))); testFunc.AddBodyNode( new CILAssignment(tsi, new CILMemberAccess(tsi, new CILCall(tsi, new CILIdent(tsi, "testFunc")), "string"), new CILStringLiteral(tsi, "hello world"))); Console.WriteLine(cil); }
public override void Codegen(CIntermediateLang cil, IndentingStringBuilder sb) { foreach (var n in Nodes) { n.Codegen(cil, sb); } }
public override AstFunc ConvertFromGenericToActual(CIntermediateLang cil, List <AstExpression> args, SourceInfo si) { AstFunc tmpFunc; if (!UsesThisPtr) { tmpFunc = base.ConvertFromGenericToActual(cil, args, si); } else { // hacky way to deal with thisptr... var thisptr = Params[0]; Params.RemoveAt(0); tmpFunc = base.ConvertFromGenericToActual(cil, args, si); tmpFunc.Params.Insert(0, thisptr); Params.Insert(0, thisptr); } var actualFunc = new AstExtend( SourceInfo, Extends, Name, UsesThisPtr, tmpFunc.Params, tmpFunc.ReturnType, tmpFunc.Body) { Name = Name, MangledName = GetMangledName(Name, tmpFunc.Params), CILFunction = tmpFunc.CILFunction, }; return(actualFunc); }
private AstFunc CompileGeneric(CIntermediateLang cil, AstFunc func) { var compiled = func.ConvertFromGenericToActual(cil, Args, SourceInfo); LllCompiler.Ast.CompileGeneric(cil, compiled); return(compiled); }
public override void Codegen(CIntermediateLang cil, IndentingStringBuilder sb) { cil.PushScope(); sb.AppendLine("{"); sb.Indent(); Condition.Codegen(cil, sb); sb.LineDecl(SourceInfo); sb.AppendLine(string.Format("if ({0})", cil.LastUsedVar)); sb.AppendLine("{"); sb.Indent(); foreach (var stmt in TrueBranch) { stmt.Codegen(cil, sb); } sb.Dedent(); sb.AppendLine("}"); if (FalseBranch.Count > 0) { sb.AppendLine("else"); sb.AppendLine("{"); sb.Indent(); foreach (var stmt in FalseBranch) { stmt.Codegen(cil, sb); } sb.Dedent(); sb.AppendLine("}"); } sb.Dedent(); sb.AppendLine("}"); cil.PopScope(); }
public override bool MatchesArgsWeak(CIntermediateLang cil, List <AstExpression> args) { if (!UsesThisPtr) { return(base.MatchesArgsWeak(cil, args)); } if (Params.Count != args.Count + 1) { return(false); } var matches = true; for (int i = 0; matches && i < args.Count; ++i) { // for something to weakly match, the parameter needs to either be generic or // both the param and arg need to be integers var par = Params[i + 1]; if (par.IsGeneric) { continue; } var arg = args[i]; var argType = arg.TryInferType(cil); var parType = par.GetRealType(); var argType_ = argType as LllIntegerType; var parType_ = parType as LllIntegerType; if (argType_ != null && parType_ != null) { matches = argType_.PointerDepth == 0 && parType_.PointerDepth == 0; continue; } matches = argType.Equals(parType); } return(matches); }
public override void Codegen(CIntermediateLang cil, IndentingStringBuilder sb) { if (cil.CurrentFunction == null) { throw new NotImplementedException("TODO: Exception for return not in function"); } var funcType = cil.CurrentFunction.TryInferType(cil); if (ReturnExpression == null) { if (funcType != "void") { throw new CILTypeMismatchException(SourceInfo, funcType, "void"); } sb.LineDecl(SourceInfo); sb.AppendLine("return;"); } else { var retType = ReturnExpression.TryInferType(cil); if ((!CTypes.IsIntegerType(retType) && !CTypes.IsIntegerType(funcType)) && retType != funcType) { throw new CILTypeMismatchException(SourceInfo, funcType, retType); } ReturnExpression.Codegen(cil, sb); sb.LineDecl(SourceInfo); sb.AppendLine(string.Format("return {0};", cil.LastUsedVar)); } }
public string FixIdent(CIntermediateLang cil, string ident) { // check againt concrete symbols var concretWithThisName = LllCompiler.SymTable.WithName(ident); var match = MatchAgainst(cil, concretWithThisName); if (match != null) { return(match); } // maybe a generic exists? var genericsWithThisName = LllCompiler.SymTable.Generics(ident); match = MatchAgainst(cil, genericsWithThisName); if (match != null) { return(match); } var sb = new StringBuilder(); sb.Append(ident); foreach (var a in Args) { var t = a.TryInferType(cil); sb.Append(string.Format("_{0}{1}", t.Name, new string('p', t.PointerDepth))); } if (LllCompiler.SymTable.LookupSymbol(sb.ToString()) != null) { return(sb.ToString()); } return(ident); }
public override CILStatement ToCILStatement(CIntermediateLang cil) { var loop = new CILLoop(SourceInfo, Condition.ToCILExpression(cil)); loop.Body.AddRange(Body.Select(n => n.ToCILNode(cil))); return(loop); }
public override bool MatchesArgsExact(CIntermediateLang cil, List <AstExpression> args) { if (!UsesThisPtr) { return(base.MatchesArgsExact(cil, args)); } if (Params.Count != args.Count + 1) { return(false); } if (IsGeneric) { return(false); } for (int i = 0; i < args.Count; ++i) { // +1 to ignore thisptr var par = Params[i + 1]; var arg = args[i]; var pTy = par.GetRealType(); var aTy = arg.TryInferType(cil); if (!pTy.Equals(aTy)) { return(false); } } return(true); }
public virtual AstFunc ConvertFromGenericToActual(CIntermediateLang cil, List <AstExpression> args, SourceInfo si) { if (args.Count != Params.Count) { throw new NotImplementedException("TODO: Exception for ConvertFronGenericToActual where args and pars mismatch count"); } var clonedPars = Params.Select(p => p.ShallowClone()).ToList(); var retType = ReturnType.TypeName; var retPtrDepth = ReturnType.PointerDepth; var genericTypes = new Dictionary <string, LllType>(); for (int i = 0; i < clonedPars.Count; ++i) { var p = clonedPars[i]; if (p.IsGeneric) { var arg = args[i]; var argTy = arg.TryInferType(cil); var alreadyAdded = genericTypes.ContainsKey(p.Type.TypeName); if (alreadyAdded) { var pType = genericTypes[p.Type.TypeName]; if (argTy.TryCast(pType)) { argTy = pType; } else { throw new NotImplementedException("TODO: Error for using the same generic identifier for differing argument types."); } } if (argTy is LllIntegerType && argTy.PointerDepth == 0) { if (argTy.TryCast(LllIntegerType.I32)) { argTy = LllIntegerType.I32; } } if (!alreadyAdded) { //genericTypes.Add(p.Type, arg.TryInferType(cil).Clone(argTy.PointerDepth)); genericTypes.Add(p.Type.TypeName, arg.TryInferType(cil)); } var newType = new AstType(p.SourceInfo, argTy.Name, argTy.PointerDepth, 0, argTy.IsAReference, false); p.Type = newType; } } if (genericTypes.ContainsKey(retType)) { var type = genericTypes[retType]; retType = type.Name; retPtrDepth = type.PointerDepth; } var fixedRetType = new AstType(ReturnType.SourceInfo, retType, retPtrDepth, 0, ReturnType.IsAReference, false); // TODO: Deep copy the body. return(new AstFunc(si, Name, clonedPars, fixedRetType, Body)); }
public override void Codegen(CIntermediateLang cil, IndentingStringBuilder sb) { var tmp = NameGenerator.NewTemp(); sb.LineDecl(SourceInfo); sb.AppendLine(string.Format("{0} {1} = {2:R}", TryInferType(cil), tmp, Number)); cil.LastUsedVar = tmp; }
public override void Codegen(CIntermediateLang cil, IndentingStringBuilder sb) { What.Codegen(cil, sb); var id = cil.LastUsedVar; var deref = string.Format("(*({0}))", id); cil.LastUsedVar = deref; }
public override string TryInferType(CIntermediateLang cil) { var thingTy = Thing.TryInferType(cil); var @struct = cil.SymTable.LookupStruct(thingTy); // TODO: Handle key not found exception return(@struct.Members[Member].TryInferType()); }
public override CILExpression ToCILExpression(CIntermediateLang cil) { if (Number % 1 == 0 && Math.Abs(Number) <= long.MaxValue) { return(new CILInteger(SourceInfo, (long)Number)); } return(new CILFloatingPoint(SourceInfo, (double)Number)); }
public CILVariableDecl ToCILVariableDeclAndDecl(CIntermediateLang cil) { var cilVar = ToCILVariableDecl(cil); LllCompiler.SymTable.AddSymbol(new LllSymbol(Name, Name, cilVar.Name, this)); //cil.DeclareLocalVariable(cilVar); return(cilVar); }
public override void Codegen(CIntermediateLang cil, IndentingStringBuilder sb) { Value.Codegen(cil, sb); var valTmp = cil.LastUsedVar; Destination.Codegen(cil, sb); sb.LineDecl(SourceInfo); sb.AppendLine(string.Format("{0} = {1};", cil.LastUsedVar, valTmp)); }
public override LllType TryInferType(CIntermediateLang cil) { if (Op == TokenType.New) { var ty = Expression.TryInferType(cil); return(ty.Clone(ty.PointerDepth + 1, ty.IsAReference)); } return(Expression.TryInferType(cil)); }
public override CILStatement ToCILStatement(CIntermediateLang cil) { if (LllCompiler.CurrentFunction.ReturnType.IsAReference) { return(new CILReturn(SourceInfo, new CILReference(SourceInfo, ExpressionToReturn?.ToCILExpression(cil)))); } return(new CILReturn(SourceInfo, ExpressionToReturn?.ToCILExpression(cil))); }
public override LllType TryInferType(CIntermediateLang cil) { var ty = From.TryInferType(cil); if (ty.IsPrimitive) { return(ty.Clone(ty.PointerDepth - 1, ty.IsAReference)); } return(CreateCallAst().TryInferType(cil)); }
public override void Codegen(CIntermediateLang cil, IndentingStringBuilder sb) { Subscription.Codegen(cil, sb); var subTmp = cil.LastUsedVar; Pointer.Codegen(cil, sb); var sub = string.Format("{0}[{1}]", cil.LastUsedVar, subTmp); cil.LastUsedVar = sub; }
public Ast() { _cil = new CIntermediateLang(); Roots = new List <AstNode>(); TopLevelStatements = new List <AstNode>(); Foreigns = new List <AstForeign>(); Functions = new List <AstFunc>(); //GenericFunctions = new List<AstFunc>(); //Extends = new List<AstExtend>(); Structs = new List <AstStruct>(); }
public override CILStatement ToCILStatement(CIntermediateLang cil) { LllCompiler.SymTable.Push(); var pre = Pre.Select(p => p.ToCILNode(cil)).ToList(); var cond = Condition.ToCILExpression(cil); var update = Update.Select(u => u.ToCILExpression(cil)).ToList(); var body = Body.Select(b => b.ToCILNode(cil)).ToList(); var loop = new CILLoop(SourceInfo, pre, cond, update, body); LllCompiler.SymTable.Push(); return(loop); }
private CILExpression ToCILCondition(CIntermediateLang cil) { var condOp = (Op == TokenType.LogicAnd) ? CILCondition.CondType.And : CILCondition.CondType.Or; return(new CILCondition( SourceInfo, Lhs.ToCILExpression(cil), condOp, Rhs.ToCILExpression(cil))); }
public override void Codegen(CIntermediateLang cil, IndentingStringBuilder sb) { var ty = Thing.TryInferType(cil); var separator = CTypes.IsPointerType(ty) ? "->" : "."; var @struct = cil.SymTable.LookupStruct(ty); // TODO: Handle key not found exception var member = @struct.Members[Member]; Thing.Codegen(cil, sb); var thingVar = cil.LastUsedVar; cil.LastUsedVar = string.Format("{0}{1}{2}", thingVar, separator, member.Name); }