public Expression(object[] tokens) { try { List<object> ex = new List<object>(); for (int i = 0; i < tokens.Length; i++) ex.Add(tokens[i]); int index = 0; for (index = 1; index < ex.Count; index++) { if (ex[index - 1] is NumberToken && ex[index] is IdentifierToken) { var num = ex[index - 1] as NumberToken; var unit = ex[index] as IdentifierToken; ex.RemoveAt(index); var d = new Dictionary<string, Unit>(); d.Add(unit.Text, new Unit(unit.Text, 1)); ex[index - 1] = new NumberType(num.Text, new UnitType(d)); index--; } } for (index = 0; index < ex.Count; index++) { if (ex[index] is ParenthOpenToken) { int ti = index; index++; int nest = 1; List<object> tt = new List<object>(); while (true) { if (ex[index] is ParenthOpenToken) nest++; if (ex[index] is ParenthCloseToken) nest--; if (nest == 0) { index++; break; } tt.Add(ex[index]); index++; } for (int i = index - 1; i > ti; i--) { ex.RemoveAt(i); } ex[ti] = new Expression(tt.ToArray()).RootExpr; index = ti + 1; } } for (index = 0; index < ex.Count - 2; index++) { if (ex[index] is IdentifierToken && ex[index + 1] is ListStartToken) { int ti = index + 2; List<ExprNode> p = new List<ExprNode>(); int nest = 0; while (!(ex[ti] is ListEndToken)) { List<object> tl = new List<object>(); if (ex[ti] is ListSeperatorToken) ti++; while (!(ex[ti] is ListSeperatorToken) && !(ex[ti] is ListEndToken) || nest != 0) { if (ex[ti] is ListStartToken) nest++; if (ex[ti] is ListEndToken) nest--; tl.Add(ex[ti++]); } p.Add(new Expression(tl.ToArray()).RootExpr); } for (int i = ti; i > index; i--) ex.RemoveAt(i); ex[index] = new FunctionNode(((IdentifierToken)ex[index]).Text, p.ToArray()); } } //Number Lists for (index = 0; index < ex.Count - 1; index++) { if (ex[index] is ListStartToken) { int ti = index + 1; List<ExprNode> p = new List<ExprNode>(); int nest = 0; while (!(ex[ti] is ListEndToken)) { List<object> tl = new List<object>(); if (ex[ti] is ListSeperatorToken) ti++; while (!(ex[ti] is ListSeperatorToken) && !(ex[ti] is ListEndToken) || nest != 0) { if (ex[ti] is ListStartToken) nest++; if (ex[ti] is ListEndToken) nest--; tl.Add(ex[ti++]); } p.Add(new Expression(tl.ToArray()).RootExpr); } for (int i = ti; i > index; i--) ex.RemoveAt(i); ex[index] = new ListNode(p.ToArray()); } } //======= for (index = 0; index < ex.Count; index++) { if (ex[index] is PowToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new PowerNode(Expr(left), Expr(right)); index--; } } for (index = 0; index < ex.Count; index++) { if (ex[index] is MulToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new MultiplicationNode(Expr(left), Expr(right)); index--; } if (ex[index] is DivToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new DivisionNode(Expr(left), Expr(right)); index--; } if (ex[index] is ModToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new ModuloNode(Expr(left), Expr(right)); index--; } } for (index = 0; index < ex.Count; index++) { if (ex[index] is AddToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new AdditionNode(Expr(left), Expr(right)); index--; } if (ex[index] is SubToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new SubtractionNode(Expr(left), Expr(right)); index--; } } for (index = 0; index < ex.Count; index++) { if (ex[index] is EqualToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.Equal); index--; } if (ex[index] is NotEqualToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.NotEqual); index--; } if (ex[index] is LessToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.Less); index--; } if (ex[index] is LessEqualToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.LessEqual); index--; } if (ex[index] is GreaterToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.Greater); index--; } if (ex[index] is GreaterEqualToken) { var left = ex[index - 1]; var right = ex[index + 1]; ex.RemoveAt(index + 1); ex.RemoveAt(index); ex[index - 1] = new CompareNode(Expr(left), Expr(right), CompareType.GreaterEqual); index--; } } RootExpr = Expr(ex[0]); Console.WriteLine(RootExpr); } catch (ArgumentOutOfRangeException ex) { throw new ExpressionException(((Token)tokens[0]).Line, -1, "Invalid expression. (Forgot closing parenthesis?)"); } }
/// <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; }