Example #1
0
        public static Token ExecuteUserFunction(string funcName, List <Token> arguments)
        {
            functionCallNumber++;
            Token result = Token.Error("Invalid call to user function");

            if (!userFunctions.ContainsKey(variables.GetStringData(funcName)))
            {
                return(result);
            }
            UserFunction userFunc             = userFunctions[variables.GetStringData(funcName)];
            Dictionary <string, string> names = new Dictionary <string, string>();

            for (int i = 0; i < arguments.Count; i++)
            {
                //var tempName = "_" + Guid.NewGuid().ToString("N");
                var tempName = GenerateRandomName(); //This is much faster than Guid due to smaller string length
                names.Add(tempName, arguments[i].TokenName);
                arguments[i].TokenName = tempName;
                variables.AddToken(arguments[i]);
            }
            string executbleCode = ReplaceNames(arguments, userFunc);
            Token  temp          = new Token(TokenType.Block, "", executbleCode);

            callDepth++;
            if (callDepth == 0)
            {
                variables.RemoveReservedWord("return");
            }
            try
            {
                temp = BlockCommands.ExecuteBlock(temp);
            }
            catch (Exception)
            {
                temp = Token.Error("An error occured while performaing the operation");
            }
            callDepth--;
            if (callDepth < 0)
            {
                variables.AddReservedWord("return");
            }
            foreach (var pair in names)
            {
                var item = variables.GetToken(pair.Key);
                item.TokenName = pair.Value;
                variables.Remove(pair.Key);
            }
            if (userFunc.returns && temp.TokenType != TokenType.Error)
            {
                try
                {
                    temp = variables.GetToken("return");
                }
                catch (Exception)
                {
                    temp = Token.Error("Return value not valid in function definition");
                }
            }
            return(temp);
        }
Example #2
0
        public static Token TokenizeString(String expression, out List <Token> tokens) //str --> a trimmed string
        {
            tokens = new List <Token>();
            int    i = 0;
            String nextTokenStr;
            bool   unaryFlag = true;

            while (i < expression.Length)
            {
                nextTokenStr = "";
                while (i < expression.Length && Char.IsWhiteSpace(expression[i]))
                {
                    i++;
                }
                if (i == expression.Length)
                {
                    break;
                }
                nextTokenStr += expression[i++].ToString();
                OpEnum opEnum = IsOperator(nextTokenStr);
                if (opEnum == OpEnum.Yes || opEnum == OpEnum.YesKeepGo)
                {
                    if (opEnum == OpEnum.YesKeepGo)
                    {
                        if (i < expression.Length)
                        {
                            String tempStr = nextTokenStr + expression[i].ToString();
                            if (IsOperator(tempStr) == OpEnum.Yes)
                            {
                                tokens.Add(new Token(TokenType.Operator, tempStr));
                                i++;
                                unaryFlag = true;
                                continue;
                            }
                        }
                        if (nextTokenStr == "!")
                        {
                            nextTokenStr = "~";
                        }
                    }
                    if (((nextTokenStr == "+" || nextTokenStr == "-") && unaryFlag) || nextTokenStr == "~")
                    {
                        tokens.Add(new Token(TokenType.Operator, "u" + nextTokenStr));
                    }
                    else
                    {
                        tokens.Add(new Token(TokenType.Operator, nextTokenStr));
                    }
                    if (expression[i - 1] != ')')
                    {
                        unaryFlag = true;
                    }
                    else
                    {
                        unaryFlag = false;
                    }
                    continue;
                }
                else
                {
                    unaryFlag = false;
                }
                if (nextTokenStr == "\"")
                {
                    i = SkipString(i, ref nextTokenStr, expression, false);
                    if (i < 0)
                    {
                        return(Token.Error("Bad input. Input not valid: [ " + nextTokenStr + " ]"));
                    }
                    tokens.Add(new Token(TokenType.Text, nextTokenStr.Substring(1, nextTokenStr.Length - 2)));
                    continue;
                }
                if (nextTokenStr == "{")
                {
                    int startedCount = 1;
                    while (i < expression.Length)
                    {
                        nextTokenStr += expression[i++].ToString();
                        if (expression[i - 1] == '\"')
                        {
                            i = SkipString(i, ref nextTokenStr, expression, true);
                            if (i < 0)
                            {
                                return(Token.Error("Bad input. Input not valid: [ " + nextTokenStr + " ]"));
                            }
                            continue;
                        }

                        if (expression[i - 1] == '}')
                        {
                            startedCount--;
                            if (startedCount == 0)
                            {
                                break;
                            }
                        }
                        else if (expression[i - 1] == '{')
                        {
                            startedCount++;
                        }
                    }
                    if (startedCount != 0)
                    {
                        return(Token.Error("Bad input. Bracket mismatch :[ " + nextTokenStr + " ]"));
                    }
                    tokens.Add(new Token(TokenType.Block, "", nextTokenStr.Substring(1, nextTokenStr.Length - 2)));
                    continue;
                }
                while (i < expression.Length && !Char.IsWhiteSpace(expression[i]) && (IsOperator(expression[i].ToString()) == OpEnum.No) && expression[i] != '"' && expression[i] != '{')
                {
                    nextTokenStr += expression[i++].ToString();
                }
                if (Char.IsDigit(nextTokenStr[0]) || nextTokenStr[0] == '.')
                {
                    try
                    {
                        Double.Parse(nextTokenStr);
                        tokens.Add(new Token(TokenType.Vector, Double.Parse(nextTokenStr)));
                    }
                    catch (Exception)
                    {
                        return(Token.Error("Bad input: [ " + nextTokenStr + " ]"));
                    }
                }
                else if (variables.Contains(nextTokenStr))
                {
                    tokens.Add(variables.GetToken(nextTokenStr));
                }
                else
                {
                    if (Function.IsDirective(nextTokenStr))
                    {
                        tokens.Add(new Token(TokenType.Directive, nextTokenStr));
                    }
                    else if (Function.IsFuction(nextTokenStr))
                    {
                        tokens.Add(new Token(TokenType.Function, nextTokenStr));
                    }
                    else if (BlockCommands.IsConditionCommand(nextTokenStr))
                    {
                        tokens.Add(new Token(TokenType.Condition, nextTokenStr));
                        if (nextTokenStr == "else")
                        {
                            tokens.Add(new Token(TokenType.Operator, "("));
                            tokens.Add(new Token(TokenType.Bool, 0, 1));
                            tokens.Add(new Token(TokenType.Operator, ")"));
                        }
                    }
                    else if (BlockCommands.IsLoopCommand(nextTokenStr))
                    {
                        tokens.Add(new Token(TokenType.Loop, nextTokenStr));
                        if (nextTokenStr == "while")
                        {
                            nextTokenStr = "";
                            while (i < expression.Length && Char.IsWhiteSpace(expression[i]))
                            {
                                i++;
                            }
                            if (i == expression.Length || expression[i++] != '(')
                            {
                                return(Token.Error("Wrong use of 'while' statement."));
                            }
                            int closeCount = -1;
                            while (i < expression.Length)
                            {
                                if (expression[i] == ')')
                                {
                                    ++closeCount;
                                }
                                else if (expression[i] == '(')
                                {
                                    --closeCount;
                                }
                                if (closeCount == 0)
                                {
                                    i++;
                                    break;
                                }
                                nextTokenStr += expression[i++].ToString();
                            }
                            if (closeCount == 0)
                            {
                                tokens.Add(new Token(TokenType.Text, "("));
                                tokens.Add(new Token(TokenType.Text, nextTokenStr, nextTokenStr));
                                tokens.Add(new Token(TokenType.Text, ")"));
                            }
                            else
                            {
                                return(Token.Error("Wrong use of 'while' statement. () mismatch."));
                            }
                        }
                    }
                    else if (nextTokenStr == "break")
                    {
                        tokens.Add(new Token(TokenType.Break, nextTokenStr));
                    }
                    else if (nextTokenStr == "function")
                    {
                        tokens.Add(new Token(TokenType.FunctionDefiner, nextTokenStr));
                    }
                    else
                    {
                        tokens.Add(new Token(TokenType.Text, nextTokenStr));
                    }
                }
            }
            return(Token.Void);
        }
Example #3
0
        public static Token Calculate(List <Token> postfixTokens)
        {
            Stack <Token> operands = new Stack <Token>();
            Token         result   = Token.Void;

            try
            {
                for (int index = 0; index < postfixTokens.Count; index++)
                {
                    Token t = postfixTokens[index];
                    if (t.TokenType == TokenType.Vector || t.TokenType == TokenType.Text ||
                        t.TokenType == TokenType.Bool || t.TokenType == TokenType.Block ||
                        t.TokenType == TokenType.Break || t.TokenType == TokenType.Matrix ||
                        t.TokenType == TokenType.Custom)
                    {
                        operands.Push(t);
                    }
                    else if (t.TokenType == TokenType.Function || t.TokenType == TokenType.Loop || t.TokenType == TokenType.Condition ||
                             t.TokenType == TokenType.UserFunction || t.TokenType == TokenType.FunctionDefiner)
                    {
                        int          paramCount = (int)(operands.Pop().FirstValue);
                        List <Token> parameters = new List <Token>();
                        for (int i = 0; i < paramCount; i++)
                        {
                            parameters.Add(operands.Pop());
                        }
                        parameters.Reverse();
                        Token resultToken;
                        if (t.TokenType == TokenType.Function)
                        {
                            resultToken = Function.InvokeFunction(t.TokenName, parameters);
                            if (resultToken.TokenType == TokenType.Error)
                            {
                                return(resultToken);
                            }
                        }
                        else if (t.TokenType == TokenType.UserFunction)
                        {
                            resultToken = FunctionDefiner.ExecuteUserFunction(t.TokenName, parameters);
                            if (resultToken.TokenType == TokenType.Error)
                            {
                                return(resultToken);
                            }
                        }
                        else if (t.TokenType == TokenType.Loop)
                        {
                            loopDepth++;
                            resultToken = BlockCommands.ExecuteLoop(t.TokenName, parameters);
                            if (resultToken.TokenType == TokenType.Error)
                            {
                                loopDepth = 0;
                                return(resultToken);
                            }
                            loopDepth--;
                        }
                        else if (t.TokenType == TokenType.Condition)
                        {
                            Token param = Token.Void;
                            if (t.TokenName == "elseif" || t.TokenName == "else")
                            {
                                param = operands.Pop();
                            }
                            resultToken = BlockCommands.ExecuteCondition(t.TokenName, param, parameters);
                            if (resultToken.TokenType == TokenType.Error)
                            {
                                return(resultToken);
                            }
                        }
                        else
                        {
                            if (operands.Count == 0)
                            {
                                return(Token.Error("User function must be assigned to a name"));
                            }
                            resultToken = FunctionDefiner.CreateUserFunction(parameters);
                            if (resultToken.TokenType == TokenType.Error)
                            {
                                return(resultToken);
                            }
                        }
                        operands.Push(resultToken);
                    }
                    else if (operands.Count >= 1 && t.TokenName.StartsWith("u"))
                    {
                        if (operands.Peek().TokenType != TokenType.Vector && operands.Peek().TokenType != TokenType.Bool &&
                            operands.Peek().TokenType != TokenType.Matrix)
                        {
                            return(Token.Error("Operand not valid for [ " + t.TokenName + " ]"));
                        }
                        Token firstParam = operands.Pop();
                        Token temp       = null;
                        if (!DoCalculateUnary(t.TokenName, firstParam, out temp))
                        {
                            return(Token.Error("Operand not valid for [ " + t.TokenName + " ]"));
                        }
                        operands.Push(temp);
                    }
                    else if (operands.Count > 1)
                    {
                        Token temp        = null;
                        Token firstParam  = operands.Pop();
                        Token secondParam = operands.Pop();
                        switch (t.TokenName)
                        {
                        case "*":
                        case "/":
                        case "%":
                        case "+":
                        case "-":
                        case "^":
                        case "==":
                        case "!=":
                        case "?":
                        case "??":
                        case "<":
                        case ">":
                        case ">=":
                        case "<=":
                            if (firstParam.TokenType == TokenType.Text && secondParam.TokenType == TokenType.Text)
                            {
                                temp = new Token(TokenType.Bool, 1, firstParam.StrData == secondParam.StrData ? 1 : 0);
                            }
                            else if (firstParam.TokenType == TokenType.Custom && secondParam.TokenType == TokenType.Custom &&
                                     firstParam.IsOfType(typeof(StringsToken)) && secondParam.IsOfType(typeof(StringsToken)))
                            {
                                List <string> first  = (List <string>)firstParam.CustomData;
                                List <string> second = (List <string>)secondParam.CustomData;
                                if (first.Count == second.Count)
                                {
                                    for (var i = 0; i < first.Count; i++)
                                    {
                                        if (first[i] != second[i])
                                        {
                                            temp = new Token(TokenType.Bool, 1, 0);
                                        }
                                    }
                                }
                                else
                                {
                                    temp = new Token(TokenType.Bool, 1, 0);
                                }
                                temp = new Token(TokenType.Bool, 1, 1);
                            }
                            else if ((firstParam.TokenType != TokenType.Vector && firstParam.TokenType != TokenType.Bool && firstParam.TokenType != TokenType.Matrix) ||
                                     (secondParam.TokenType != TokenType.Vector && secondParam.TokenType != TokenType.Bool && secondParam.TokenType != TokenType.Matrix)
                                     )
                            {
                                return(Token.Error("Operands not valid for [ " + t.TokenName + " ]. Both must be the same type."));
                            }
                            else
                            {
                                temp = DoCalculate(t.TokenName, secondParam, firstParam);
                            }
                            if (temp.TokenType == TokenType.Error)     //yep stack is upside down!
                            {
                                return(temp);
                            }
                            break;

                        case "=":
                            if (firstParam.TokenType == TokenType.Void || string.IsNullOrEmpty(secondParam.TokenName))
                            {
                                return(Token.Error("Assignment not valid."));
                            }
                            secondParam.ResetValues(firstParam);
                            if (variables.Contains(secondParam.TokenName))
                            {
                                temp = variables.SetTokenVerify(secondParam);
                            }
                            else
                            {
                                temp = variables.AddTokenVerify(secondParam);
                            }
                            if (temp.TokenType == TokenType.Error)
                            {
                                return(temp);
                            }
                            else
                            {
                                temp = secondParam;
                            }
                            if (secondParam.TokenType == TokenType.UserFunction)
                            {
                                if (operands.Count == 0)
                                {
                                    return(new Token(TokenType.Text, "", "User function named [ " + temp.TokenName + " ] added"));
                                }
                                else
                                {
                                    return(Token.Error("Bad definition of User function"));
                                }
                            }
                            break;

                        default:
                            return(Token.Error("Error in expression"));
                        }
                        operands.Push(temp);
                    }
                    else
                    {
                        return(Token.Error("Error in expression"));
                    }
                }
                if (operands.Count != 1)
                {
                    return(Token.Error("Error in expression"));
                }
                result = operands.Pop();
                if (result.TokenType == TokenType.Block)
                {
                    result = BlockCommands.ExecuteBlock(result);
                    if (result.TokenType != TokenType.Error)
                    {
                        return(Token.Void);
                    }
                }
                else if (result.TokenType == TokenType.Operator || result.TokenType == TokenType.Loop || result.TokenType == TokenType.Condition)
                {
                    return(Token.Error("Error in expression"));
                }
            }
            catch (Exception)
            {
                return(Token.Error("Error in expression"));
            }
            if (result.TokenType == TokenType.ConditionExecuted)
            {
                return(Token.Void);
            }
            return(result);
        }
Example #4
0
        private static string ReplaceNames(List <Token> arguments, UserFunction userFunc)
        {
            executbleCode.Clear();
            string str = userFunc.data;

            for (int j = 0; j < str.Length;)
            {
                int k = BlockCommands.SkipString(j, str);
                if (k > j)
                {
                    executbleCode.Append(str.Substring(j, k - j));
                    j = k;
                    continue;
                }
                while (j < str.Length && Char.IsWhiteSpace(str[j]))
                {
                    j++;
                }
                if (j < str.Length)
                {
                    k = j;
                    string currentStr = null;
                    var    isOp       = Tokenizer.IsOperator(str[j].ToString());
                    if (isOp != OpEnum.No)
                    {
                        if (isOp == OpEnum.YesKeepGo && j < str.Length - 1)
                        {
                            isOp = Tokenizer.IsOperator(str.Substring(j, 2));
                            if (isOp == OpEnum.Yes)
                            {
                                j++;
                            }
                        }
                        j++;
                        currentStr = str.Substring(k, j - k);
                    }
                    else
                    {
                        //executbleCode.Append(" ");
                        while (j < str.Length && !Char.IsWhiteSpace(str[j]) &&
                               str[j] != ';' && str[j] != ':' && str[j] != '{' && str[j] != '}' && Tokenizer.IsOperator(str[j].ToString()) == OpEnum.No)
                        {
                            j++;
                        }
                        if (k == j)
                        {
                            j++;
                        }
                        currentStr = str.Substring(k, j - k);
                        for (int i = 0; i < arguments.Count; i++)
                        {
                            string oldStr = userFunc.signatureList[i];
                            if (currentStr == oldStr)
                            {
                                currentStr = arguments[i].TokenName;
                                break;
                            }
                        }
                    }
                    executbleCode.Append(currentStr);
                }
            }
            return(executbleCode.ToString());
        }