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.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"); }
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())); }
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"); }
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"); }
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"); }
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.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"); } }