/// <summary> /// Builds a StatementList from a set of tokens. /// </summary> /// <param name="tokens">The array of token arrays to build from.</param> /// <returns>A statement list from the tokens.</returns> public static StatementList Build(Token[][] tokens) { var sl = new StatementList(); for (int i = 0; i < tokens.Length; i++) { //if (tokens[i].Length > 2) { if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is AssignmentToken) sl.Add(new AssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2)))); else if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is AddAssignmentToken) sl.Add(new AdditionAssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2)))); else if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is SubAssignmentToken) sl.Add(new SubtractionAssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2)))); if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is MulAssignmentToken) sl.Add(new MultiplicationAssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2)))); if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is DivAssignmentToken) sl.Add(new DivisionAssignmentStatement(tokens[i][0].Text, new Expression(tokens[i].SubArray(2, tokens[i].Length - 2)))); else if (tokens[i].Length > 2 && tokens[i][0] is IdentifierToken && tokens[i][1] is ListStartToken) sl.Add(new FunctionStatement(new Expression(tokens[i]).RootExpr as FunctionNode)); else if (tokens[i].Length > 1 && tokens[i][0] is ReturnToken) sl.Add(new ReturnStatement(new Expression(tokens[i].SubArray(1, tokens[i].Length - 1)))); else if (tokens[i].Length > 4 && tokens[i][0] is DefineToken) { string name = tokens[i][1].Text; if (!(tokens[i][2] is ListStartToken)) throw Err("Expected parameter list.", tokens[i][2]); int ti = 3; List<string> p = new List<string>(); while (!(tokens[i][ti] is ListEndToken)) { if (tokens[i][ti] is ListSeperatorToken) ti++; p.Add(tokens[i][ti++].Text); } if (!(tokens[i][ti + 1] is BodyOpenToken)) throw Err("Expected body open.", tokens[i][ti + 1]); i++; List<Token[]> ftl = ReadBody(tokens, ref i); //i++; sl.Add(new FunctionDefineStatement(name, p.ToArray(), Build(ftl.ToArray()))); } else if (tokens[i][0] is WhileToken) { var conditional = new Expression(tokens[i].SubArray(1, tokens[i].Length - 2)); if (!(tokens[i][tokens[i].Length - 1] is BodyOpenToken)) throw Err("Expected body open.", tokens[i][tokens[i].Length - 1]); i++; List<Token[]> ftl = ReadBody(tokens, ref i); sl.Add(new WhileStatement(conditional.RootExpr, Build(ftl.ToArray()))); } else if (tokens[i][0] is ForToken) { if (!(tokens[i][1] is IdentifierToken)) throw Err("Variable name must follow for token.", tokens[i][1]); var vn = tokens[i][1].Text; if (!(tokens[i][2] is FromToken)) throw Err("From token must follow variable name.", tokens[i][2]); List<Token> fromTokens = new List<Token>(); int n; for (n = 3; n < tokens[i].Length; n++) if (tokens[i][n] is ToToken) break; else fromTokens.Add(tokens[i][n]); if (n == tokens[i].Length) throw Err("To token must follow From expression.", tokens[i][n]); n++; var fromExpr = new Expression(fromTokens.ToArray()); List<Token> toTokens = new List<Token>(); for (; n < tokens[i].Length; n++) if (tokens[i][n] is BodyOpenToken || tokens[i][n] is IncToken) break; else toTokens.Add(tokens[i][n]); if (n == tokens[i].Length) throw Err("Body Open token or Inc token must follow To expression.", tokens[i][n]); var toExpr = new Expression(toTokens.ToArray()); Expression incExpr; if (tokens[i][n] is IncToken) { n++; List<Token> incTokens = new List<Token>(); for (; n < tokens[i].Length; n++) if (tokens[i][n] is BodyOpenToken) break; else incTokens.Add(tokens[i][n]); if (n == tokens[i].Length) throw Err("Body Open token must follow Inc expression.", tokens[i][n]); incExpr = new Expression(incTokens.ToArray()); } else { incExpr = new Expression(new[] { new NumberToken("1") }); } if (!(tokens[i][n] is BodyOpenToken)) throw Err("Body Open token expected.", tokens[i][n]); i++; List<Token[]> ftl = ReadBody(tokens, ref i); sl.Add(new ForStatement(vn, fromExpr.RootExpr, toExpr.RootExpr, incExpr.RootExpr, Build(ftl.ToArray()))); } else if (tokens[i][0] is IfToken) { var conditional = new Expression(tokens[i].SubArray(1, tokens[i].Length - 2)); if (!(tokens[i][tokens[i].Length - 1] is BodyOpenToken)) throw Err("Expected body open.", tokens[i][tokens[i].Length - 1]); i++; List<Token[]> ftl = ReadBody(tokens, ref i); var etl = new List<Token[]>(); if (tokens.Length > i + 1) if (tokens[i + 1].Length > 0 && tokens[i + 1][0] is ElseToken) { i += 2; etl = ReadBody(tokens, ref i); } sl.Add(new IfStatement(conditional.RootExpr, Build(ftl.ToArray()), Build(etl.ToArray()))); } } } return sl; }
private static Exception Err(string v, Token token) { return new StatementException(token.Line, token.Col, v); }
private static List<Token[]> ReadBody(Token[][] tokens, ref int i) { int nest = 1; var ftl = new List<Token[]>(); while (tokens[i].Length == 0 || !(tokens[i][0] is BodyCloseToken && nest == 1)) { for (int y = 0; y < tokens[i].Length; y++) { if (tokens[i][y] is BodyOpenToken) nest++; else if (tokens[i][y] is BodyCloseToken) nest--; } ftl.Add(tokens[i]); i++; } return ftl; }
private Token st(Token token) { lastToken = token; if (token != null) { token.Line = r.Line; token.Col = r.Column; } return token; }