Пример #1
0
        Ast.Block ParseBlock(ParseTreeNode node)
        {
            Ast.Block block = new Ast.Block();
            block.Statements = new List <Ast.IStatement>();
            foreach (ParseTreeNode child in node.ChildNodes)
            {
                switch (child.Term.Name)
                {
                case "Assignment":
                    block.Statements.Add(ParseAssign(child)); break;

                case "LocalAssignment":
                    block.Statements.Add(ParseLocalAssign(child)); break;

                case "FunctionCall":
                    block.Statements.Add(ParseFunctionCall(child)); break;

                case "ReturnStat":
                    block.Statements.Add(ParseReturnStat(child)); break;

                case "BreakStat":
                    block.Statements.Add(new Ast.BreakStat()); break;

                case "DoBlock":
                    block.Statements.Add(ParseDoBlock(child)); break;

                case "If":
                    block.Statements.Add(ParseIf(child)); break;

                case "While":
                    block.Statements.Add(ParseWhile(child)); break;

                case "Repeat":
                    block.Statements.Add(ParseRepeat(child)); break;

                case "FunctionDecl":
                    block.Statements.Add(ParseFunctionDecl(child)); break;

                case "For":
                    block.Statements.Add(ParseFor(child)); break;

                case "OopCall":
                    block.Statements.Add(ParseOopCall(child)); break;

                case ";":
                    break;

                default:
                    throw new NotImplementedException("Node not yet implemented");
                }
            }
            return(block);
        }
Пример #2
0
        Ast.Assignment ParseFunctionDecl(ParseTreeNode node)
        {
            if (node.Term.Name == "FunctionDecl")
            {
                Ast.IAssignable expr = ParseVariable(node.ChildNodes[1]);

                ParseTreeNode argsNode  = node.ChildNodes[3].ChildNodes[0];
                ParseTreeNode chunkNode = node.ChildNodes[4];

                Ast.Block block            = ParseBlock(chunkNode);
                Ast.FunctionDefinition def = new Ast.FunctionDefinition();
                def.Arguments = new List <Ast.Argument>();

                var nameNode = node.ChildNodes[2];
                if (nameNode.ChildNodes.Count > 0)
                {
                    def.Arguments.Add(new Ast.Argument()
                    {
                        Name = "self"
                    });
                    expr = new Ast.Variable()
                    {
                        Name   = nameNode.ChildNodes[0].Token.ValueString,
                        Prefix = expr
                    };
                }
                def.Body = block;
                if (argsNode.ChildNodes.Count > 0)
                {
                    argsNode = argsNode.ChildNodes[0];
                    while (argsNode.ChildNodes.Count > 0)
                    {
                        string ident = argsNode.ChildNodes[0].Token.ValueString;
                        def.Arguments.Add(new Ast.Argument()
                        {
                            Name = ident
                        });
                        if (argsNode.ChildNodes.Count == 1)
                        {
                            break;
                        }
                        argsNode = argsNode.ChildNodes[1];
                    }
                }
                Ast.Assignment assign = new Ast.Assignment();
                assign.Variables.Add(expr);
                assign.Expressions.Add(def);
                return(assign);
            }
            throw new Exception("Invalid FunctionDecl node");
        }
Пример #3
0
        static Expression CompileBlock(Ast.Block block, LabelTarget returnTarget, LabelTarget breakTarget, Expression Context)
        {
            var exprs = new List <Expression>();
            var scope = Expression.Parameter(LuaContext_Type);

            exprs.Add(Expression.Assign(scope, Context));

            foreach (IStatement s in block.Statements)
            {
                exprs.Add(CompileStatement(s, returnTarget, breakTarget, scope));
            }

            return(Expression.Block(new[] { scope }, exprs.ToArray()));
        }
Пример #4
0
        Ast.RepeatStat ParseRepeat(ParseTreeNode node)
        {
            if (node.Term.Name == "Repeat")
            {
                Ast.Block       block     = ParseBlock(node.ChildNodes[1]);
                Ast.IExpression condition = ParseExpression(node.ChildNodes[3]);

                return(new Ast.RepeatStat()
                {
                    Block = block,
                    Condition = condition
                });
            }
            throw new Exception("Invalid Repeat node");
        }
Пример #5
0
        Ast.FunctionDefinition ParseFunctionDef(ParseTreeNode node)
        {
            if (node.Term.Name == "FunctionDef")
            {
                ParseTreeNode argsNode  = node.ChildNodes[1].ChildNodes[0];
                ParseTreeNode chunkNode = node.ChildNodes[2];

                Ast.Block block            = ParseBlock(chunkNode);
                Ast.FunctionDefinition def = new Ast.FunctionDefinition();
                def.Body      = block;
                def.Arguments = new List <Ast.Argument>();

                if (argsNode.ChildNodes.Count == 0)
                {
                    return(def);
                }
                if (argsNode.ChildNodes.Count > 0)
                {
                    argsNode = argsNode.ChildNodes[0];
                    while (argsNode.ChildNodes.Count > 0)
                    {
                        var argsNodeChild = argsNode.ChildNodes[0];
                        if (argsNodeChild.Token == null)
                        {
                            def.Arguments.Add(new Ast.Argument()
                            {
                                Name = "...", Span = argsNodeChild.Span
                            });
                        }
                        else
                        {
                            string ident = argsNodeChild.Token.ValueString;
                            def.Arguments.Add(new Ast.Argument()
                            {
                                Name = ident, Span = argsNodeChild.Span
                            });
                        }
                        if (argsNode.ChildNodes.Count == 1)
                        {
                            break;
                        }
                        argsNode = argsNode.ChildNodes[1];
                    }
                }
                return(def);
            }
            throw new Exception("Invalid FunctionDef node");
        }
Пример #6
0
        Ast.IfStat ParseIf(ParseTreeNode node)
        {
            if (node.Term.Name == "If")
            {
                Ast.IExpression condition = ParseExpression(node.ChildNodes[1]);
                Ast.Block       block     = ParseBlock(node.ChildNodes[3]);

                Ast.IfStat If = new Ast.IfStat();
                If.Block     = block;
                If.Condition = condition;
                If.ElseIfs   = new List <Ast.IfStat>();
                If.Span      = node.Span;

                ParseTreeNode ElseifNode = node.ChildNodes[4];
                ParseTreeNode ElseNode   = node.ChildNodes[5];

                while (ElseifNode.ChildNodes.Count != 0)
                {
                    var        childnode = ElseifNode.ChildNodes[0];
                    Ast.IfStat elseif    = new Ast.IfStat();
                    elseif.Span      = childnode.Span;
                    elseif.Condition = ParseExpression(childnode.ChildNodes[1]);
                    elseif.Block     = ParseBlock(childnode.ChildNodes[3]);

                    If.ElseIfs.Add(elseif);

                    ElseifNode = childnode.ChildNodes[4];
                }

                if (ElseNode.ChildNodes.Count != 0)
                {
                    If.ElseBlock = ParseBlock(ElseNode.ChildNodes[0].ChildNodes[1]);
                }

                return(If);
            }
            throw new Exception("Invalid If node");
        }
Пример #7
0
 Ast.Block ParseBlock(ParseTreeNode node)
 {
     Ast.Block block = new Ast.Block();
     block.Statements = new List<Ast.IStatement>();
     foreach (ParseTreeNode child in node.ChildNodes)
     {
         switch (child.Term.Name)
         {
             case "Assignment":
                 block.Statements.Add(ParseAssign(child)); break;
             case "LocalAssignment":
                 block.Statements.Add(ParseLocalAssign(child)); break;
             case "FunctionCall":
                 block.Statements.Add(ParseFunctionCall(child)); break;
             case "ReturnStat":
                 block.Statements.Add(ParseReturnStat(child)); break;
             case "BreakStat":
                 block.Statements.Add(new Ast.BreakStat()); break;
             case "DoBlock":
                 block.Statements.Add(ParseDoBlock(child)); break;
             case "If":
                 block.Statements.Add(ParseIf(child)); break;
             case "While":
                 block.Statements.Add(ParseWhile(child)); break;
             case "Repeat":
                 block.Statements.Add(ParseRepeat(child)); break;
             case "FunctionDecl":
                 block.Statements.Add(ParseFunctionDecl(child)); break;
             case "For":
                 block.Statements.Add(ParseFor(child)); break;
             case "OopCall":
                 block.Statements.Add(ParseOopCall(child)); break;
             case ";":
                 break;
             default:
                 throw new NotImplementedException("Node not yet implemented");
         }
     }
     return block;
 }
Пример #8
0
        Ast.IExpression ParseExpression(ParseTreeNode node)
        {
            if (node.Term.Name == "Expression")
            {
                ParseTreeNode child = node.ChildNodes[0];
                if (child.Token != null && child.Token.Terminal is NumberLiteral)
                {
                    return(new Ast.NumberLiteral()
                    {
                        Span = child.Span, Value = (child.Token.Value is double?(double)(child.Token.Value) : (int)(child.Token.Value))
                    });
                }
                else if (child.Token != null && child.Token.Terminal is StringLiteral)
                {
                    return(new Ast.StringLiteral()
                    {
                        Span = child.Span, Value = (string)(child.Token.Value)
                    });
                }
                else if (child.Token != null && child.Token.Terminal is KeyTerm)
                {
                    string val = child.Token.ValueString;
                    if (val == "true")
                    {
                        return new Ast.BoolLiteral()
                               {
                                   Span = child.Span, Value = true
                               }
                    }
                    ;
                    else if (val == "false")
                    {
                        return new Ast.BoolLiteral()
                               {
                                   Span = child.Span, Value = false
                               }
                    }
                    ;
                    else if (val == "nil")
                    {
                        return new Ast.NilLiteral()
                               {
                                   Span = child.Span
                               }
                    }
                    ;
                }
                else if (child.Term != null && child.Term.Name == "Prefix")
                {
                    return(ParsePrefix(child));
                }
                else if (child.Term != null && child.Term.Name == "OrOp")
                {
                    return(ParseOrOp(child));
                }
                else if (child.Term != null && child.Term.Name == "FunctionDef")
                {
                    return(ParseFunctionDef(child));
                }
                else if (child.Term != null && child.Term.Name == "UnaryExpr")
                {
                    return(ParseUnaryExpr(child));
                }
                else if (child.Term != null && child.Term.Name == "TableConstruct")
                {
                    return(ParseTableConstruct(child));
                }
                else if (child.Term != null && child.Term.Name == "OopCall")
                {
                    return(ParseOopCall(child));
                }
                else if (child.Term != null && child.Term.Name == "Varargs")
                {
                    return(new Ast.VarargsLiteral());
                }
            }
            throw new Exception("Invalid Expression node");
        }

        #endregion

        Ast.Block ParseBlock(ParseTreeNode node)
        {
            Ast.Block block = new Ast.Block();
            block.Statements = new List <Ast.IStatement>();
            foreach (ParseTreeNode child in node.ChildNodes)
            {
                switch (child.Term.Name)
                {
                case "Assignment":
                    block.Statements.Add(ParseAssign(child)); break;

                case "LocalAssignment":
                    block.Statements.Add(ParseLocalAssign(child)); break;

                case "FunctionCall":
                    block.Statements.Add(ParseFunctionCall(child)); break;

                case "ReturnStat":
                    block.Statements.Add(ParseReturnStat(child)); break;

                case "BreakStat":
                    block.Statements.Add(new Ast.BreakStat()); break;

                case "DoBlock":
                    block.Statements.Add(ParseDoBlock(child)); break;

                case "If":
                    block.Statements.Add(ParseIf(child)); break;

                case "While":
                    block.Statements.Add(ParseWhile(child)); break;

                case "Repeat":
                    block.Statements.Add(ParseRepeat(child)); break;

                case "FunctionDecl":
                    block.Statements.Add(ParseFunctionDecl(child)); break;

                case "For":
                    block.Statements.Add(ParseFor(child)); break;

                case "OopCall":
                    block.Statements.Add(ParseOopCall(child)); break;

                case ";":
                    break;

                default:
                    throw new NotImplementedException("Node not yet implemented");
                }
            }
            return(block);
        }

        Ast.IStatement ParseFor(ParseTreeNode node)
        {
            if (node.Term.Name == "For")
            {
                var block = ParseDoBlock(node.ChildNodes[2]);
                var type  = node.ChildNodes[1].ChildNodes[0];
                if (type.Term.Name == "NumericFor")
                {
                    var cycle = new Ast.NumericFor();
                    cycle.Span     = node.Span;
                    cycle.Block    = block;
                    cycle.Variable = type.ChildNodes[0].Token.ValueString;
                    cycle.Var      = ParseExpression(type.ChildNodes[1]);
                    cycle.Limit    = ParseExpression(type.ChildNodes[2]);
                    cycle.Step     = new Ast.NumberLiteral()
                    {
                        Span = new SourceSpan(cycle.Limit.Span.Location, 0), Value = 1
                    };
                    if (type.ChildNodes[3].ChildNodes.Count > 0)
                    {
                        var child = type.ChildNodes[3].ChildNodes[0];

                        cycle.Step = ParseExpression(child);
                    }

                    return(cycle);
                }
                else
                {
                    var cycle = new Ast.GenericFor()
                    {
                        Span = node.Span
                    };
                    cycle.Block = block;

                    var nameList = type.ChildNodes[0];
                    var exprList = type.ChildNodes[2];

                    while (true)
                    {
                        var name = nameList.ChildNodes[0].Token.ValueString;
                        cycle.Variables.Add(name);
                        var child = nameList.ChildNodes[1];
                        if (child.ChildNodes.Count > 0)
                        {
                            nameList = child.ChildNodes[0];
                        }
                        else
                        {
                            break;
                        }
                    }

                    while (true)
                    {
                        var expr = ParseExpression(exprList.ChildNodes[0]);
                        cycle.Expressions.Add(expr);
                        var child = exprList.ChildNodes[1];
                        if (child.ChildNodes.Count > 0)
                        {
                            exprList = child.ChildNodes[0];
                        }
                        else
                        {
                            break;
                        }
                    }

                    return(cycle);
                }
            }
            throw new Exception("Invalid For node");
        }
    }