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 static Any[] ParseParameters(string s_parameters) { if (s_parameters == "()") { return(new Any[0]); // no parameters } List <Any> parameters = new List <Any>(); s_parameters = s_parameters.Substring(1, s_parameters.Length - 2); // remove parentheses s_parameters = Utils.ReplaceBetween(s_parameters, ',', '(', ')', (char)0x1a); // prevent splitting of commas in nested parentheses string[] splitParams = Regex.Split(s_parameters, ","); // split by each comma/space (each item is a parameter) for (int i = 0; i < splitParams.Length; i++) { splitParams[i] = splitParams[i].Replace(((char)0x1a).ToString(), ","); if (splitParams[i][0] == ',') { splitParams[i] = splitParams[i].Substring(1, splitParams[i].Length - 1); } } // splitting has been done so we can revert placeholders back for (int i = 0; i < splitParams.Length; i++) { string parameter = splitParams[i]; while (parameter.Length > 0 && parameter[0] == ' ') { parameter = parameter.Remove(0, 1); // remove beginning spaces } while (parameter.Length > 0 && parameter[parameter.Length - 1] == ' ') { parameter = parameter.Remove(parameter.Length - 1, 1); // remove trailing spaces } string cleanedUp; if ((parameter[0] == '\"' || parameter[0] == '\'') && (parameter[parameter.Length - 1] == '\"' || parameter[parameter.Length - 1] == '\'')) { cleanedUp = parameter.Substring(1, parameter.Length - 2); // remove quotes/apostrophes } else { cleanedUp = parameter; } Token token = null; if (parameter.OccurrencesOf("\"") <= 2) { token = Lexer.ParseToken(parameter, false); // a flaw in the parsing function for strings would take a string chain if it starts and ends with a string as 1 string (this is a janky workaround) } Type vtype = null; if (token == null) { // unknown identifier, could be an equation waiting to be solved Line tl = new Line(Lexer.ParseLine(parameter)); parameters.Add(tl.Execute()); continue; } else if (token.type == TokenType.VariableIdentifier) { Variable _var = Interpreter.Vars[token.identifier]; parameters.Add(new Any(_var.Type, _var.Value)); continue; } else if (token.type == TokenType.FunctionCall) { while (token.identifier[0] < 'A' || token.identifier[0] > 'z') { token.identifier = token.identifier.Remove(0, 1); // i don't remember why this is here tbh } BaseFunction func = Interpreter.Functions[token.identifier]; if (func.ReturnType == Types.Void) { throw new BaseException("Cannot pass void function as a parameter"); } parameters.Add(new Any(func.ReturnType, func.Invoke(token.identifier).Value)); continue; } else if (token.type == TokenType.FunctionChain) { parameters.Add(FunctionChain.Evaluate(token.identifier)); continue; } else if (token.type == TokenType.StringLiteral || token.type == TokenType.CharacterLiteral) { switch (token.type) { case TokenType.StringLiteral: vtype = Types.String; break; case TokenType.CharacterLiteral: vtype = Types.Character; break; } if (cleanedUp.Length > 2) { cleanedUp = cleanedUp.FromBase64().Replace("\\\"", "\"").Replace("\\'", "\'"); // convert encoded base64 text given it's not an empty literal & do literal conversions (\" -> ") and (\' -> ') } } else if (token.type == TokenType.Integer64Literal || token.type == TokenType.IntegerLiteral || token.type == TokenType.DecimalLiteral) { if (Interpreter.Definitions.ContainsKey(cleanedUp)) { cleanedUp = Interpreter.Definitions[cleanedUp].To; } // get the appropriate type for the literal switch (token.type) { case TokenType.DecimalLiteral: vtype = Types.Decimal; break; case TokenType.IntegerLiteral: vtype = Types.Integer; if (Utils.IsHexadecimal(cleanedUp)) { cleanedUp = int.Parse(cleanedUp.Substring(2), NumberStyles.HexNumber).ToString(); } break; case TokenType.Integer64Literal: vtype = Types.Integer64; if (Utils.IsHexadecimal(cleanedUp)) { cleanedUp = long.Parse(cleanedUp.Substring(2), NumberStyles.HexNumber).ToString(); } break; } } else if (token.type == TokenType.BooleanLiteral) { vtype = Types.Boolean; } if (vtype == null) { throw new BaseException("Unknown type passed as parameter: " + token.type); } parameters.Add(new Any(vtype, Convert.ChangeType(cleanedUp, vtype.CSharpType))); } return(parameters.ToArray()); }
public static Token ParseToken(string token, bool @throw = true, int index = -1) { while (token.Length > 0 && token[0] == ' ') { token = token.Remove(0); } if (token.Length > 0) { if (Interpreter.Definitions.ContainsKey(token)) { token = Interpreter.Definitions[token].To; } if (Utils.IsHexadecimal(token)) { token = long.Parse(token.Substring(2), NumberStyles.HexNumber).ToString(); } Type type = Type.GetType(token, false); if (type != null) { return(new Token(TokenType.TypeIdentifier, token, index)); } switch (token) { case "true": case "false": return(new Token(TokenType.BooleanLiteral, token, index)); case Syntax.Statements.Return: return(new Token(TokenType.ReturnStatement, token, index)); case Syntax.Operators.Or: return(new Token(TokenType.OrOperator, token, index)); case Syntax.Operators.BitwiseOR: return(new Token(TokenType.BitwiseOROperator, token, index)); case Syntax.Operators.BitwiseAND: return(new Token(TokenType.BitwiseANDOperator, token, index)); case Syntax.Comparators.IsEqual: return(new Token(TokenType.IsEqualOperator, token, index)); case Syntax.Comparators.IsNotEqual: return(new Token(TokenType.IsNotEqualOperator, token, index)); case Syntax.Comparators.IsGreaterThan: return(new Token(TokenType.IsGreaterThanOperator, token, index)); case Syntax.Comparators.IsLessThan: return(new Token(TokenType.IsLessThanOperator, token, index)); case Syntax.Comparators.IsGreaterThanOrEqual: return(new Token(TokenType.IsGreaterThanOrEqualOperator, token, index)); case Syntax.Comparators.IsLessThanOrEqual: return(new Token(TokenType.IsLessThanOrEqualOperator, token, index)); case Syntax.Operators.Add: return(new Token(TokenType.AddOperator, token, index)); case Syntax.Operators.And: return(new Token(TokenType.AndOperator, token, index)); case Syntax.Operators.Subtract: return(new Token(TokenType.SubtractOperator, token, index)); case Syntax.Operators.Multiply: return(new Token(TokenType.MultiplyOperator, token, index)); case Syntax.Operators.Divide: return(new Token(TokenType.DivideOperator, token, index)); case Syntax.Operators.Modulo: return(new Token(TokenType.ModuloOperator, token, index)); case Syntax.Operators.Equal: return(new Token(TokenType.EqualOperator, token, index)); case "''": return(new Token(TokenType.CharacterLiteral, "", index)); // support empty Characters ('') case "{": return(new Token(TokenType.StartBracket, token, index)); case "}": return(new Token(TokenType.EndBracket, token, index)); case "(": case ")": return(new Token(TokenType.Parenthesis, token, index)); case Syntax.Conditionals.Else: return(new Token(TokenType.ElseConditional, token, index)); } if (token[0] == '\"' && token[token.Length - 1] == '\"' && token.OccurrencesOf("\"") == 2) { return(new Token(TokenType.StringLiteral, token.Substring(1, token.Length - 2).FromBase64().Replace("\\\"", "\""), index)); } else if (token[0] == '\'' && token[token.Length - 1] == '\'') // we can't ensure the length here because the contents are encoded { return(new Token(TokenType.CharacterLiteral, token.Substring(1, token.Length - 2).FromBase64(), index)); } else if (token.IndexOf(Syntax.Conditionals.If + "(") == 0 && token[token.Length - 1] == ')') { return(new Token(TokenType.IfConditional, token, index)); } else if (token.IndexOf(Syntax.Conditionals.While + "(") == 0 && token[token.Length - 1] == ')') { return(new Token(TokenType.WhileConditional, token, index)); } else if (token.IndexOf(Syntax.Conditionals.Loop + "(") == 0 && token[token.Length - 1] == ')') { return(new Token(TokenType.LoopConditional, token, index)); } else if (Utils.IsNumber(token)) { try { if (token.OccurrencesOf(".") == 1) { Convert.ToDecimal(token); return(new Token(TokenType.DecimalLiteral, token, index)); } else { long number = Convert.ToInt64(token); if (number <= int.MaxValue && number >= int.MinValue) { return(new Token(TokenType.IntegerLiteral, token, index)); } else { return(new Token(TokenType.Integer64Literal, token, index)); } } } catch (FormatException) { throw new BaseException("Number literal is in a invalid format"); } catch (OverflowException) { throw new BaseException("Number literal is either too large or small to be parsed"); } } else if (FunctionChain.IsChain(token)) { return(new Token(TokenType.FunctionChain, token, index)); } else if (BaseFunction.IsFunctionCall(token)) { return(new Token(TokenType.FunctionCall, token, index)); } else if (FastStruct.IsFastStruct(token)) { return(new Token(TokenType.FastStruct, token, index)); } else if (Utils.IsValidObjectName(token) || FastStruct.IsValidMemberAccessor(token)) { return(new Token(TokenType.VariableIdentifier, token, index)); } } if (@throw) { throw new BaseException("Unknown token: " + token); } return(null); }