public static string GetTokensExpression(List <Token> tokens, ref Any alreadyEvaluatedValue) { string expression = ""; for (int i = 0; i < tokens.Count; i++) { string identifier = tokens[i].identifier; Type objectType = null; if (tokens[i].type == TokenType.VariableIdentifier) { Variable var = Interpreter.Vars[identifier]; identifier = Modules.Main._ToString(var.Value); // replace variable name with it's value objectType = var.Type; } switch (tokens[i].type) { case TokenType.WhileConditional: case TokenType.IfConditional: case TokenType.EndBracket: continue; } if (tokens[i].type == TokenType.FunctionCall) { BaseFunction func = Interpreter.Functions[identifier]; Any returned = func.Invoke(identifier); objectType = func.ReturnType; if (tokens.Count == 1) { alreadyEvaluatedValue = returned; return(""); } if (returned != null) { identifier = Modules.Main._ToString(returned.Value); // replace function call with it's return value } else { identifier = ""; } } else if (tokens[i].type == TokenType.FunctionChain) { Any evaluatedChain = FunctionChain.Evaluate(identifier); if (tokens.Count == 1) { alreadyEvaluatedValue = evaluatedChain; return(""); } identifier = Modules.Main._ToString(evaluatedChain.Value); objectType = FunctionChain.GetType(tokens[i].identifier); } if (tokens[i].type == TokenType.StringLiteral || objectType == Types.String) { identifier = "\"" + identifier.Replace("\"", "\\\"") + "\""; } else if (tokens[i].type == TokenType.CharacterLiteral || objectType == Types.Character) { identifier = "\'" + identifier + "\'"; } expression += identifier + (i < tokens.Count - 1 ? " " : ""); } return(expression); }
public Any Execute() { List <Token> toEval = GetRange(0, Count); // get a copy for (int i = 0; i < Count; i++) { if (base[i].type == TokenType.FunctionCall) { if (Interpreter.Functions[base[i].identifier].ReturnType == Types.Void) { if (i - 1 >= 0 && Utils.IsOperator(base[i - 1].type)) { throw new BaseException("Operator '" + base[i - 1].identifier + "' cannot be performed on a void function"); } if (i + 1 < Count && Utils.IsOperator(base[i + 1].type)) { throw new BaseException("Operator '" + base[i + 1].identifier + "' cannot be performed on a void function"); } } } } for (int i = 0; i < Count; i++) { if (base[i].type == TokenType.EqualOperator) { if (i > 0 && base[i - 1].type != TokenType.VariableIdentifier) { throw new BaseException("Cannot assign to a " + base[i - 1].type.ToString() + ", it's a non-modifiable token"); } toEval = GetRange(i + 1, Count - (i + 1)); break; } } // remove the equal sign and everything to the left from the equation if (Count == 2 && base[0].type == TokenType.TypeIdentifier && base[1].type == TokenType.VariableIdentifier) { return(null); // support for uninitialized vars } Any alreadyEvaluatedValue = null; string expression = Utils.GetTokensExpression(toEval, ref alreadyEvaluatedValue); if (alreadyEvaluatedValue != null) { return(alreadyEvaluatedValue); // expression was already evaluated previously } if (expression.Length == 0) { return(null); } var evaluated = Utils.Eval(expression); if (evaluated == null) { return(null); } if (evaluated.GetType() == typeof(uint)) // causes exception sometimes { return(new Any(Types.Integer64, evaluated)); } return(new Any(evaluated)); }