public static BlockNode ProcessTokens(List <ScriptToken> tokens) { List <AstTreeNode> blockNodes = new List <AstTreeNode>(); AstTreeNode node = new BlockNode(null); int count = 0; StripWhiteSpace(tokens); while (tokens.Count > 0) { count++; if (count > 1000) { break; // Limit to 1000 iterations while in development } if (tokens[0].Type == EScriptTokenType.RETURN) { tokens.RemoveAt(0); // Last value in block is returned by default } ScriptToken scriptToken = tokens[0]; if (scriptToken.Type == EScriptTokenType.NAME) { node = new RootScopeMemberNode( new LiteralNode <string>(scriptToken.Value) ); tokens.RemoveAt(0); } else if (scriptToken.Type == EScriptTokenType.ASSIGN) { node = AssignmentNode.Parse(node, scriptToken, tokens); } else if (scriptToken.Type == EScriptTokenType.IF) { node = IfStatementNode.Parse(node, scriptToken, tokens); blockNodes.Add(node); node = null; } else if (scriptToken.Type == EScriptTokenType.FOR) { node = ForStatementNode.Parse(node, scriptToken, tokens); blockNodes.Add(node); node = null; } else if (scriptToken.Type == EScriptTokenType.STRING_LITERAL) { node = new LiteralNode <string>(scriptToken.Value); tokens.RemoveAt(0); } else if (scriptToken.Type == EScriptTokenType.NUMBER_LITERAL) { AstTreeNode _node; if (scriptToken.Value.Contains(".")) { _node = new FloatLiteralNode(scriptToken.Value); } else { _node = new IntegerLiteralNode(scriptToken.Value); } node = _node; tokens.RemoveAt(0); } else if (scriptToken.Type == EScriptTokenType.PERIOD) { if (tokens[1].Type == EScriptTokenType.NAME) { node = new ScopeMemberNode( node, new LiteralNode <string>(tokens[1].Value) ); tokens.RemoveAt(0); tokens.RemoveAt(0); } } else if (scriptToken.Type == EScriptTokenType.L_BRACKET) { if (node.GetType() == typeof(RootScopeMemberNode)) { // indice } else { node = ArrayNode.Parse(node, scriptToken, tokens); } } else if (scriptToken.Type == EScriptTokenType.L_PAREN) { List <List <ScriptToken> > funcArgs = GetBlockTokens(tokens); List <AstTreeNode> nodes = new List <AstTreeNode>(); ; foreach (List <ScriptToken> arg in funcArgs) { nodes.Add(ProcessTokens(arg)); } node = new FunctionCallNode( node, // Previous node should be a NAME new FunctionArgumentNode(nodes) ); } else if (scriptToken.Type == EScriptTokenType.SEMI_COLON) { if (node != null) { blockNodes.Add(node); } node = null; tokens.RemoveAt(0); } else if (ComparisonNode.Matches(tokens)) { node = ComparisonNode.Parse(node, scriptToken, tokens); } else if (ArithmeticNode.Matches(tokens)) { AstTreeNode _node = ArithmeticNode.Parse(node, scriptToken, tokens); node = _node; } else if (ArithmeticAssignmentNode.Matches(tokens)) { node = ArithmeticAssignmentNode.Parse(node, scriptToken, tokens); } else if (scriptToken.Type == EScriptTokenType.WHITESPACE) { tokens.RemoveAt(0); } else if (scriptToken.Type == EScriptTokenType.BOOLEAN_LITERAL) { node = new BooleanLiteralNode(tokens[0].Value); tokens.RemoveAt(0); } else if (scriptToken.Type == EScriptTokenType.NULL_LITERAL) { node = new LiteralNode <object>(null); tokens.RemoveAt(0); } else { string code = ScriptTree.ToCode(tokens, 10); Console.WriteLine($"Syntax Error.Near {code}"); } } if (node != null) { blockNodes.Add(node); } return(new BlockNode(blockNodes)); }