public static Expression Compile(string exp) { var functions = new FunctionManager(); return(Compile(Tokenize(exp), functions)); }
private static Expression InternalCompile(LinkedListNode <Token> first, LinkedListNode <Token> last, FunctionManager functions, int level = 0) { if (first.Value.Type == TokenType.SBracket && MatchingBracketForward(first) == last) { return(InternalCompile(first.Next, last.Previous, functions, 0)); } LinkedListNode <Token> token; int brackets = 0; switch (level) { case 0: Debug.Assert(level == 0); // Additions and subtractions token = last; while (token != first.Previous) { if (token.Value.Type == TokenType.SBracket) { brackets--; } else if (token.Value.Type == TokenType.EBracket) { brackets++; } else if (brackets == 0) { if (token.Value.Value == "+") { return(functions.Operator("+").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level))); } if (token.Value.Value == "-") { return(functions.Operator("-").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level))); } } else if (brackets <= 0) { throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last)); } token = token.Previous; } Debug.Assert(brackets == 0, "Unbalanced brackets"); level++; goto case 1; case 1: Debug.Assert(level == 1); // Multiplications and divisions token = last; while (token != first.Previous) { if (token.Value.Type == TokenType.SBracket) { brackets--; } else if (token.Value.Type == TokenType.EBracket) { brackets++; } else if (brackets == 0) { if (token.Value.Value == "*") { return(functions.Operator("*").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level))); } if (token.Value.Value == "/") { return(functions.Operator("/").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level))); } } else if (brackets <= 0) { throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last)); } token = token.Previous; } if (brackets != 0) { throw new Exception("Unbalanced brackets"); } level++; goto case 2; case 2: Debug.Assert(level == 2); // Powers token = last; while (token != first.Previous) { if (token.Value.Type == TokenType.SBracket) { brackets--; } else if (token.Value.Type == TokenType.EBracket) { brackets++; } else if (brackets == 0) { if (token.Value.Value == "^") { return(functions.Operator("^").Create(InternalCompile(first, token.Previous, functions, level), InternalCompile(token.Next, last, functions, level))); } } else if (brackets <= 0) { throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last)); } token = token.Previous; } if (brackets != 0) { throw new Exception("Unbalanced brackets"); } level++; goto case 3; case 3: Debug.Assert(level == 3); // Functions & variables token = last; while (token != first.Previous) { if (token.Value.Type == TokenType.SBracket) { brackets--; } else if (token.Value.Type == TokenType.EBracket) { brackets++; } else if (brackets == 0) { if (token.Value.Type == TokenType.Identifier) { if (token.Next != null && token.Next.Value.Type == TokenType.SBracket) { return(functions.Function(token.Value.Value).Create(FunctionArgumentsCompile(token.Next.Next, MatchingBracketForward(token.Next), functions))); } else { return(new Variable(token.Value.Value)); } } } else if (brackets <= 0) { throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last)); } token = token.Previous; } if (brackets != 0) { throw new Exception("Unbalanced brackets"); } level++; goto case 4; case 4: Debug.Assert(level == 4); // Literals token = last; while (token != first.Previous) { if (token.Value.Type == TokenType.SBracket) { brackets--; } else if (token.Value.Type == TokenType.EBracket) { brackets++; } else if (brackets == 0) { if (token.Value.Type == TokenType.Value) { return(new ValueExpression(double.Parse(token.Value.Value))); } } else if (brackets <= 0) { throw new Exception("SumTingWong. Tokens: " + ContainerUtils.AsString(first, last)); } token = token.Previous; } if (brackets != 0) { throw new Exception("Unbalanced brackets"); } //level++; goto default; default: throw new Exception(); } }
private static Expression[] FunctionArgumentsCompile(LinkedListNode <Token> first, LinkedListNode <Token> last, FunctionManager functions) { LinkedListNode <Token> prevComma = first; // Actually just after the previous comma. LinkedListNode <Token> token = first; List <Expression> exps = new List <Expression>(); int brackets = 0; while (token != last) { if (token.Value.Type == TokenType.SBracket) { brackets--; } else if (token.Value.Type == TokenType.EBracket) { brackets++; } else if (brackets == 0 && token.Value.Type == TokenType.Comma) { exps.Add(InternalCompile(prevComma, token.Previous, functions)); prevComma = token.Next; } token = token.Next; } Debug.Assert(brackets == 0); exps.Add(InternalCompile(prevComma, last.Previous, functions)); return(exps.ToArray()); }
public static Expression Compile(LinkedList <Token> tokens, FunctionManager functions) { return(InternalCompile(tokens.First, tokens.Last, functions)); }