Esempio n. 1
0
    public void Test()
    {
        var variables = new Dictionary <string, float> ();

        variables.Add("x", 3);
        variables.Add("y", -5);

        string code = "-x+7 * 2 - y *-(1+3*(7+x*2)) + 2";
        var    c    = new ValueString(code, variables);
        var    e    = new NumericalExpression(c);
        float  r    = e.Evaluate();

        print(r);
        //print(c.markedString);
        for (int i = 0; i < c.values.Count; i++)
        {
            //print(c.values[i]);
        }
    }
Esempio n. 2
0
    bool GetConditionResult(string line)
    {
        int    startIndex      = line.IndexOf('(') + 1;
        int    endIndex        = line.LastIndexOf(')');
        string conditionString = Substring(line, startIndex, endIndex);

        string[] sections = conditionString.Split(' ');

        var    numericalValues = new List <float>();
        var    operators       = new List <string>();
        string currentString   = "";

        // First simplify the condition by finding and evaluating any/all numerical expressions within it.
        // Store as list of values and operators.
        // For example, "3+2 < 7-1 or 2 > 3-2" will be simplified to [5,6,2,1], ["<", "or", ">"]

        // TODO: Resolve brackets that don't belong to the numerical expression
        // For example, in "if ((3+2>5 or 2<5+2) and 3 < 10)", the inner brackets belong to the 'or'
        for (int i = 0; i < sections.Length; i++)
        {
            string section             = sections[i];
            bool   isConditionOperator = ArrayContainsString(comparisonOperators, section);

            if (isConditionOperator || i == sections.Length - 1)
            {
                if (isConditionOperator)
                {
                    operators.Add(section);
                }

                if (!string.IsNullOrEmpty(currentString))
                {
                    var expression = new NumericalExpression(new ValueString(currentString, variables));
                    numericalValues.Add(expression.Evaluate());
                    currentString = "";
                }
            }
            else
            {
                currentString += section + " ";
            }
        }

        // Evaluate comparisons to bool values
        // e.g. (3 < 2 or 8 > 6) should evalulate to (false or true)
        var boolValues    = new List <bool>();
        var boolOperators = new List <BooleanExpression.Element>();

        for (int i = 0; i < operators.Count; i++)
        {
            float  a  = numericalValues[i];
            float  b  = numericalValues[i + 1];
            string op = operators[i];
            switch (op)
            {
            case "<":
                boolValues.Add(a < b);
                boolOperators.Add(BooleanExpression.Element.Value);
                break;

            case "<=":
                boolValues.Add(a <= b);
                boolOperators.Add(BooleanExpression.Element.Value);
                break;

            case "==":
                boolValues.Add(a == b);
                boolOperators.Add(BooleanExpression.Element.Value);
                break;

            case ">=":
                boolValues.Add(a >= b);
                boolOperators.Add(BooleanExpression.Element.Value);
                break;

            case ">":
                boolValues.Add(a > b);
                boolOperators.Add(BooleanExpression.Element.Value);
                break;

            case "and":
                boolOperators.Add(BooleanExpression.Element.And);
                break;

            case "or":
                boolOperators.Add(BooleanExpression.Element.Or);
                break;
            }
        }

        var  booleanExpression = new BooleanExpression(boolValues, boolOperators);
        bool result            = booleanExpression.Evaluate();

        return(result);
    }
Esempio n. 3
0
    // Runs lines of code from a start to end index
    void RunLines(int lineIndex, int stopIndex)
    {
        if (lineIndex >= lines.Length || lineIndex == stopIndex)
        {
            return;
        }

        string line = lines[lineIndex];

        string[] sections = line.Split(' ');

        //Debug.Log ($"Line: {lineIndex}: " + line + " stop: " + stopIndex);

        // Test if line is an external function call
        if (outputFunctionNames != null)
        {
            for (int i = 0; i < outputFunctionNames.Count; i++)
            {
                //TODO: fix tolower cases etc.
                if (sections[0] == outputFunctionNames[i].ToLower()) //((sections[0].Equals(outputFunctionNames[i])))
                {
                    VirtualFunction outputFunction = new VirtualFunction()
                    {
                        name = outputFunctionNames[i]
                    };

                    string   argumentString   = Substring(line, line.IndexOf('(') + 1, line.LastIndexOf(')'));
                    string[] argumentSections = argumentString.Split(',');

                    //TODO: call these virtual functions in the execute loop
                    //TODO: provide the functions from modules in the virtualOS
                    for (int j = 0; j < argumentSections.Length; j++)
                    {
                        //true or false as parameter for a function
                        if (string.Equals(argumentSections[j].Trim(' '), "true"))
                        {
                            outputFunction.values.Add(true);
                            break;
                        }
                        if (string.Equals(argumentSections[j].Trim(' '), "false"))
                        {
                            outputFunction.values.Add(false);
                            break;
                        }

                        var   valueString = new ValueString(argumentSections[j], variables); //TODO: accept T value as func parameter
                        float value       = new NumericalExpression(valueString).Evaluate();
                        outputFunction.values.Add(value);
                    }

                    //outputFunction.FunctionWithParam = delegate (string s) { return s.ToUpper(); };

                    //outputFunction.delFunc = Delegate.CreateDelegate(typeof(VirtualCompiler), this.GetType().GetMethod(outputFunctionNames[i]));
                    //TODO: robot modules are classes that can be called => parse class attribute calls in user code

                    //Task tt = new Task(); //outputFunction.delFunc = /*class_instance_to_call_here.*/tt.GetType().GetMethod(outputFunctionNames[i]);

                    //foreach (object x in VirtualOS.Instance.availableModules) { x.GetType().GetMethod(outputFunctionNames[i]); }

                    /*Array.ForEach(VirtualOS.Instance.availableModules, x =>
                     * {
                     *  outputFunction.delFunc = x.GetType().GetMethod(outputFunctionNames[i], BindingFlags.Public); //TODO: use getmethods and compare
                     * });*/
                    Array.ForEach(vComputer.availableModules, x =>
                    {
                        if (x != null)
                        {
                            outputFunction.delFunc = x.GetType().GetMethod(outputFunctionNames[i]);
                        }
                        else
                        {
                            //Debug.Log("No available functions");
                        }
                    });

                    if (outputFunction.values.Count <= 1)
                    {
                        availableFuncsWthoutReturnV.TryGetValue(outputFunctionNames[i], out outputFunction.FunctionWithoutParam); //TODO: add function from virtualOS and invoke them from fixedturretgame
                    }
                    else
                    {
                        availableFuncsWthP.TryGetValue(outputFunctionNames[i], out outputFunction.FunctionWithParam); //TODO: either with or without parameters
                    }
                    //outputFunction.FunctionWithoutParam = PlayerCodeCallableFunction;

                    /*
                     * //bind a method from a string using reflection
                     * //MethodInfo mi = this.GetType().GetMethod(outputFunctionNames[i]);
                     * MethodInfo reflectionMethod = typeof(VirtualCompiler).GetMethod("testMethodInfo");
                     * object[] mParams = new object[outputFunction.values.Count];
                     * Array.Copy(outputFunction.values.ToArray(), mParams, outputFunction.values.Count);
                     * Debug.Log(mParams);
                     * reflectionMethod.Invoke(this, mParams);
                     */
                    //save dynamic method alloc to a del to later invoke it
                    //Delegate del = Delegate.CreateDelegate(typeof(VirtualCompiler), reflectionMethod);
                    //del.DynamicInvoke(mParams);



                    outputs.Add(outputFunction);

                    // Run the next line
                    RunLines(lineIndex + 1, stopIndex);
                    return;
                }
            }
        }

        // Test if line is a conditional statement
        if (conditionByLineIndex.ContainsKey(lineIndex))
        {
            var  condition    = conditionByLineIndex[lineIndex];
            bool runCondition = GetConditionResult(line);
            // Else statement has no condition to test, so set run to true by default
            if (condition.type == ConditionBlockInfo.Type.Else)
            {
                runCondition = true;
            }

            // elseif/else conditions only run if all previous conditions in the chain were false
            if (condition.type != ConditionBlockInfo.Type.If)
            {
                var previousInChain = condition.previousInChain;
                while (previousInChain != null)
                {
                    if (previousInChain.lastEvaluation == true)
                    {
                        runCondition = false;
                        break;
                    }
                    previousInChain = previousInChain.previousInChain;
                }
            }

            condition.lastEvaluation = runCondition;
            HandleCondition(runCondition, lineIndex, stopIndex);
            return;
        }

        if (sections[0] == "loop")
        {
            string argumentString = Substring(line, line.IndexOf('(') + 1, line.LastIndexOf(')'));
            var    e          = new NumericalExpression(new ValueString(argumentString, variables));
            int    numRepeats = (int)e.Evaluate();

            // Pass off control to the handle condition function. It will resume the running of lines.
            HandleLoop(numRepeats, lineIndex, stopIndex);
            return;
        }

        // Assignment
        if (sections.Length > 1)
        {
            if (sections[1] == "=")
            {
                ProcessAssignment(line);
            }
        }

        if (sections[0] == "print")
        {
            ProcessPrint(line);
        }

        // Run next line
        RunLines(lineIndex + 1, stopIndex);
    }
Esempio n. 4
0
    // Runs lines of code from a start to end index
    void RunLines(int lineIndex, int stopIndex)
    {
        if (lineIndex >= lines.Length || lineIndex == stopIndex)
        {
            return;
        }

        string line = lines[lineIndex];

        string[] sections = line.Split(' ');

        //Debug.Log ($"Line: {lineIndex}: " + line + " stop: " + stopIndex);

        // Test if line is an external function call
        if (outputFunctionNames != null)
        {
            for (int i = 0; i < outputFunctionNames.Count; i++)
            {
                if (sections[0] == outputFunctionNames[i].ToLower())
                {
                    string   argumentString   = Substring(line, line.IndexOf('(') + 1, line.LastIndexOf(')'));
                    string[] argumentSections = argumentString.Split(',');
                    var      outputFunction   = new VirtualFunction();
                    outputFunction.name = outputFunctionNames[i];

                    for (int j = 0; j < argumentSections.Length; j++)
                    {
                        var   valueString = new ValueString(argumentSections[j], variables);
                        float value       = new NumericalExpression(valueString).Evaluate();
                        outputFunction.values.Add(value);
                    }

                    outputs.Add(outputFunction);

                    // Run the next line
                    RunLines(lineIndex + 1, stopIndex);
                    return;
                }
            }
        }

        // Test if line is a conditional statement
        if (conditionByLineIndex.ContainsKey(lineIndex))
        {
            var  condition    = conditionByLineIndex[lineIndex];
            bool runCondition = GetConditionResult(line);
            // Else statement has no condition to test, so set run to true by default
            if (condition.type == ConditionBlockInfo.Type.Else)
            {
                runCondition = true;
            }

            // elseif/else conditions only run if all previous conditions in the chain were false
            if (condition.type != ConditionBlockInfo.Type.If)
            {
                var previousInChain = condition.previousInChain;
                while (previousInChain != null)
                {
                    if (previousInChain.lastEvaluation == true)
                    {
                        runCondition = false;
                        break;
                    }
                    previousInChain = previousInChain.previousInChain;
                }
            }

            condition.lastEvaluation = runCondition;
            HandleCondition(runCondition, lineIndex, stopIndex);
            return;
        }

        if (sections[0] == "loop")
        {
            string argumentString = Substring(line, line.IndexOf('(') + 1, line.LastIndexOf(')'));
            var    e          = new NumericalExpression(new ValueString(argumentString, variables));
            int    numRepeats = (int)e.Evaluate();

            // Pass off control to the handle condition function. It will resume the running of lines.
            HandleLoop(numRepeats, lineIndex, stopIndex);
            return;
        }

        // Assignment
        if (sections.Length > 1)
        {
            if (sections[1] == "=")
            {
                ProcessAssignment(line);
            }
        }

        if (sections[0] == "print")
        {
            ProcessPrint(line);
        }

        // Run next line
        RunLines(lineIndex + 1, stopIndex);
    }