예제 #1
0
        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();
        }
예제 #2
0
        public override string TryInferType(CIntermediateLang cil)
        {
            // TODO: Remove a level of pointers
            var ty = Pointer.TryInferType(cil);

            return(CTypes.DereferenceType(ty));
        }
예제 #3
0
        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());
            }
        }
예제 #4
0
 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"));
 }
예제 #5
0
        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.");
        }
예제 #6
0
        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);
        }
예제 #7
0
 public override void Codegen(CIntermediateLang cil, IndentingStringBuilder sb)
 {
     foreach (var n in Nodes)
     {
         n.Codegen(cil, sb);
     }
 }
예제 #8
0
        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);
        }
예제 #9
0
        private AstFunc CompileGeneric(CIntermediateLang cil, AstFunc func)
        {
            var compiled = func.ConvertFromGenericToActual(cil, Args, SourceInfo);

            LllCompiler.Ast.CompileGeneric(cil, compiled);
            return(compiled);
        }
예제 #10
0
        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();
        }
예제 #11
0
        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);
        }
예제 #12
0
        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));
            }
        }
예제 #13
0
        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);
        }
예제 #14
0
        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);
        }
예제 #15
0
        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);
        }
예제 #16
0
        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));
        }
예제 #17
0
        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;
        }
예제 #18
0
        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;
        }
예제 #19
0
        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());
        }
예제 #20
0
 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));
 }
예제 #21
0
        public CILVariableDecl ToCILVariableDeclAndDecl(CIntermediateLang cil)
        {
            var cilVar = ToCILVariableDecl(cil);

            LllCompiler.SymTable.AddSymbol(new LllSymbol(Name, Name, cilVar.Name, this));
            //cil.DeclareLocalVariable(cilVar);
            return(cilVar);
        }
예제 #22
0
        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));
        }
예제 #23
0
 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));
 }
예제 #24
0
 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)));
 }
예제 #25
0
        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));
        }
예제 #26
0
        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;
        }
예제 #27
0
파일: Ast.cs 프로젝트: traplol/langlanglang
 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>();
 }
예제 #28
0
        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);
        }
예제 #29
0
        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)));
        }
예제 #30
0
        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);
        }