Beispiel #1
0
    public void InterpretLine(string line)
    {
        //Debug.Log("Parsing: " + line + " line number " + currentLineNumber + " Block type = " + currentType + " Block States " + BlockStates.Count + " Escape LVL " + escapeLevel);

        if(line.Equals("end", System.StringComparison.OrdinalIgnoreCase))
        {
            if(currentType == BlockType.function)
            {
                functions.Add(currentFunction.name, currentFunction);
                Debug.Log("Added function " + currentFunction.name + " to repertoire.");
                currentFunction = null;

                PopBlockState();
            }

            else if(currentType == BlockType.loop)
            {
                //go back to the WHILE line
                currentLineNumber = loopState.startLine - 1;
                Debug.Log("Looping to " + currentLineNumber);

                PopBlockState();
            }

            else if (currentType == BlockType.skip)
            {
                /*if (--escapeLevel == 0)
                    PopBlockState();
                if (escapeLevel < 0)
                    throw new InterpreterException("There is an end statement without an accompanying block start statement.", currentLineNumber);*/
                if (escapeLevel > 0)
                {
                    escapeLevel--;
                }
                else
                {
                    PopBlockState();
                }
            }

            else if (currentType == BlockType.conditional)
            {
                PopBlockState();
            }

            return;
        }
        if(currentType != BlockType.none)
        {
            //still processing block
            if(currentType == BlockType.function)
            {
                currentFunction.AddLine(line);
                return;
            }
            else if (currentType == BlockType.block)
            {
                currentBlock.AddLine(line);
                return;
            }
            else if (currentType == BlockType.loop)
            {
                //do nothing and continue
                Debug.Log("Continuing loop line " + currentLineNumber);
            }
            else if (currentType == BlockType.conditional)
            {
                //do nothing and continue
                Debug.Log("Continuing conditional line " + currentLineNumber);
            }
            else if (currentType == BlockType.skip)
            {
                //skip do nothing
                string[] tokens = line.Split(' ');
                if (IsBlockStart(tokens[0]))
                    escapeLevel++;
                return;
            }
            else
            {
                //nothing
            }
            /*string[] tokens = line.Split(' ');
            if (IsBlockStart(tokens[0]))
                escapeLevel++;*/

            Debug.Log("Processed line in block [" + line + "]");
        }

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

        double delayTime = 0;
        if(pieces[0].Equals("delay", System.StringComparison.OrdinalIgnoreCase))
        {
            //if the first word is delay
            //start coroutine with that delay
            if (numbers.ContainsKey(pieces[1]))
            {
                numbers.TryGetValue(pieces[1], out delayTime);
            }
            else
            {
                if (!double.TryParse(pieces[1], out delayTime))
                    throw (new InterpreterException("Cannot parse the delay time. [" + pieces[1] + "]", currentLineNumber));
            }

            string[] npieces = new string[pieces.Length - 2];
            for(int i = 0; i < pieces.Length - 2; i++)
            {
                npieces[i] = pieces[i + 2];
            }
            pieces = npieces;
        }

        if (pieces[0].Equals("return", System.StringComparison.OrdinalIgnoreCase))
        {
            if (delayTime > 0)
                throw (new InterpreterException("A return statement cannot succeed a delay statement", currentLineNumber));

            returnStatement = true;

            if(pieces.Length > 2)
                throw (new InterpreterException("The return statement can only be followed by a single token", currentLineNumber));

            TokenType type = GetType(pieces[1]);

            string value = "";

            //Unknown = 0,
            //XBObject = 1,
            //SceneObject = 2,
            //Number = 3,
            //NumberValue = 4,
            //Text = 5,
            //Function = 6
            //Debug.Log("Returning raw [" + pieces[1] + "]");

            switch(type)
            {
                case (TokenType.XBObject):
                case (TokenType.SceneObject):
                case (TokenType.NumberValue):
                case (TokenType.Text):
                    returnValue = pieces[1];
                    break;
                case (TokenType.Number):
                    if(numbers.ContainsKey(pieces[1]))
                    {
                        double n = 0;
                        numbers.TryGetValue(pieces[1], out n);
                        returnValue = "" + n;
                    }
                    else
                    {
                        throw (new InterpreterException("Cannot return value, the number variable has not been initialized.", currentLineNumber));
                    }
                    break;
                case (TokenType.Function):
                    throw (new InterpreterException("Returning a function is not supported.", currentLineNumber));
                    break;
                case (TokenType.Unknown):
                    throw (new InterpreterException("Cannot return a value of unknown type.", currentLineNumber));
                    break;
            }
            //Debug.Log("Returning value [" + returnValue + "]");
            return;
        }

        if (pieces[0].Equals("print", System.StringComparison.OrdinalIgnoreCase))
        {
            pieces = ReplaceToValues(pieces, 1);
            Debug.Log("PRINT [" + GetString(pieces) + "]");
            PrintToDebugUI ("PRINT [" + GetString(pieces) + "]");
            return;
        }

        if(variables.ContainsKey(pieces[0]))
        {

            XBGameObject obj;
            variables.TryGetValue(pieces[0], out obj);

            InterpreterDesc desc;
            objectDescs.TryGetValue(obj.datatype, out desc);

            printDebug(pieces[0] + " is a variable of type " + obj.datatype, currentLineNumber);

            InterpreterInterface script = null;

            if (InfixPrefix.equal(obj.datatype, "rocket"))
            {
                RocketBoosterScript rbscript = obj.gameObject.GetComponent<RocketBoosterScript>();
                script = (InterpreterInterface)rbscript;
            }
            else if (InfixPrefix.equal(obj.datatype, "missile"))
            {
                MissileGeneratorScript mgscript = obj.gameObject.transform.GetChild(0).GetComponent<MissileGeneratorScript>();
                script = (InterpreterInterface)mgscript;
            }
            else
            {
                throw (new InterpreterException("The block type " + pieces[0] + " does not have a programmable interface. ", currentLineNumber));
            }

            if(Contains(desc.methods, pieces[1]))
            {
                //invoke the method
                //RKT START
                printDebug(pieces[1] + " is a method of " + obj.datatype, currentLineNumber);
                script.command((float)delayTime, pieces[1], null);
            }
            else if (Contains(desc.variables, pieces[1]))
            {
                //set variable
                //RKT FORCE 100
                printDebug(pieces[1] + " is a variable of " + obj.datatype, currentLineNumber);

                if (numbers.ContainsKey(pieces[2]))
                    numbers.TryGetValue(pieces[2], out delayTime);

                script.set((float)delayTime, pieces[1], pieces[2]);
            }
            else
            {
                throw (new InterpreterException("The block named " + pieces[0] + " of the " + obj.datatype +
                    " type does not have a function or variable named " + pieces[1], currentLineNumber));
            }
        } else if(objectDescs.ContainsKey(pieces[0]))
        {
            //check if it's a datatype
            //which means object initialization

            //get object of type
            //EG syntax: ROCKET RKT <- GETOBJECT rocketbooster

            if (variables.ContainsKey(pieces[1]))
                throw (new InterpreterException("Cannot initialize a variable that already exists", currentLineNumber));

            if(objects.ContainsKey(pieces[4]))
            {
                GameObject obj;
                objects.TryGetValue(pieces[4], out obj);
                XBGameObject xbobj;
                xbobj.gameObject = obj;
                xbobj.datatype = pieces[0];

                variables.Add(pieces[1], xbobj);

                if(pieces[0].Equals("radar", System.StringComparison.OrdinalIgnoreCase))
                {
                    sensors.Add(pieces[1]);
                    UpdateSensorData();
                }
            }
            else
            {
                //there is no gameObject in the scene with this name
                throw (new NoBlockWithNameFoundError("There was no block with the name " + pieces[4], currentLineNumber));
            }
        }
        else if (numbers.ContainsKey(pieces[0]))
        {
            //Arithmetic evaluations on existing number
            if(pieces.Length < 3)
            {
                throw (new InterpreterException("There are not enough arguments for this Arithmetic operation.", currentLineNumber));
            }
            double value = arithmetic.EvaluateArithExpression(pieces, 2);
            numbers[pieces[0]] = value;
            //throw (new InterpreterException("Evaluated number " + pieces[0] + " to " + value, currentLineNumber));
        }
        else if (pieces[0].Equals("number", System.StringComparison.OrdinalIgnoreCase))
        {
            //Arithmetic evaluations on Initialization of number
            if (pieces.Length < 4)
            {
                throw (new InterpreterException("There are not enough arguments for this Arithmetic initialization.", currentLineNumber));
            }
            double value = arithmetic.EvaluateArithExpression(pieces, 3);
            numbers.Add(pieces[1], value);
            //throw (new InterpreterException("Evaluated number " + pieces[1] + " to " + value, currentLineNumber));
        }
        else if (pieces[0].Equals("struct", System.StringComparison.OrdinalIgnoreCase))
        {
            /* create a new struct
             * Format: STRUCT NAME KEY=VALUE KEY=VALUE KEY=VALUE...
             * NAME SET KEY=VALUE
             * NAME[KEY]
             */
            string[] kvs = new string[pieces.Length - 2];
            for (int i = 2; i < pieces.Length; i++)
                kvs[i - 2] = pieces[i];

            CreateStructure(pieces[1], kvs);
        }
        else if (structures.ContainsKey(pieces[0]))
        {
            switch(pieces[1].ToLowerInvariant())
            {
                case("set"):
                    if(pieces.Length < 4)
                        throw (new InterpreterException("There are not enough arguments for this set operation.", currentLineNumber));
                    XBStructure XBS;
                    structures.TryGetValue(pieces[0], out XBS);
                    string[] pair = pieces[2].Split('=');
                    if (pair.Length != 2)
                        throw new InterpreterException("Incoherent key value, must be in format (key=value) [" + pieces[2] + "]", currentLineNumber);
                    XBS.Set(pair[0], pair[1]);
                    break;
                default:
                    break;
            }
        }
        else if (functions.ContainsKey(pieces[0]))
        {
            CallFunction(pieces);
        }
        else if (IsBlockStart(pieces[0]))
        {
            if (pieces[0].Equals("function", System.StringComparison.OrdinalIgnoreCase))
            {
                if(currentType == BlockType.function)
                {
                    throw (new InterpreterException("You cannot define a function within a function.", currentLineNumber));
                }

                //function definition
                blockInstruction = line;

                //create the block for this
                //XBFunction(string name, string[] args, int lineNumber)
                List<string> args = new List<string>();
                if(pieces.Length > 2)
                {
                    if(pieces.Length % 2 != 0)
                    {
                        throw (new InterpreterException("The function declaration has improper arguments.", currentLineNumber));
                    }

                    for(int i = 2; i < pieces.Length; i = i + 2)
                    {
                        args.Add(pieces[i] + " " + pieces[i+1]);
                    }

                }
                if(functions.ContainsKey(pieces[1]))
                {
                    throw (new InterpreterException("The function " + pieces[1] + " has already been declared.", currentLineNumber));
                    return;
                }
                currentFunction = new XBFunction(this, pieces[1], args.ToArray(), currentLineNumber);
                PushBlockState(BlockType.function);
            }
            else if (pieces[0].Equals("if", System.StringComparison.OrdinalIgnoreCase))
            {
                pieces = ReplaceNumberValue(pieces, 0);
                Debug.Log (String.Join(",", pieces));
                pieces = ReplaceStructValue(pieces, 0);
                Debug.Log (String.Join(",", pieces));
                pieces = ReplacePrimitiveFunctionValue(pieces, 0);
                Debug.Log (String.Join(",", pieces));
                //conditional string
                if(pieces.Length < 4 && !functions.ContainsKey(pieces[1]))
                {
                    throw (new InterpreterException("[Basic Check] Invalid conditional statement.", currentLineNumber));
                }

                //get the results of each function called in the conditional statement
                bool eval = logic.EvaluateLogic(pieces, 1);
                if (!eval)
                    PushBlockState(BlockType.skip);
                else
                    PushBlockState(BlockType.conditional);
            }
            else
            {
                //WHILE LOOP
                //check if already inside a loop if so push the current LoopState into stack
                if(currentType == BlockType.loop)
                {
                    loopStates.Push(loopState);
                }

                loopState.startLine = currentLineNumber;

                //check the conditional
                bool eval = logic.EvaluateLogic(pieces, 1);
                if (!eval)
                {
                    PushBlockState(BlockType.skip);
                    Debug.Log("Setting type to SKIP");
                }
                else
                {
                    PushBlockState(BlockType.loop);
                    Debug.Log("Setting type to LOOP");
                }

            }
        }
        /* These cases cover reserved commands such as
         * TARGET - Look at a target
         * TURN - turn to angle position
         */
        else if (pieces[0].Equals("target", System.StringComparison.OrdinalIgnoreCase))
        {
            Debug.Log ("Target: " + pieces[1]);
            pieces = ReplaceToValues(pieces, 0);
            Debug.Log ("Target: " + pieces[1]);
            GameObject target;
            if (pieces[1].Equals("none", System.StringComparison.OrdinalIgnoreCase))
            {
                Root.LookAtTransform = null;
            }
            else if(objects.TryGetValue(pieces[1], out target))
            {
                Root.LookAtTransform = target.transform;
            }
            else
            {
                throw (new InterpreterException("Target object not recognized.", currentLineNumber));
            }
        }
        else if(pieces[0].Equals("turn", System.StringComparison.OrdinalIgnoreCase))
        {
           // Root.gameObject.transform.Rotate(Vector3.Forward,)
        }
        else
        {
            //Something else
            throw (new InterpreterException("[" + line + "] Syntax not recognized.", currentLineNumber));
        }
    }
Beispiel #2
0
    public void PopInterpreterState()
    {
        XBInterpreterState xbis = StateStack.Pop();

        currentLineNumber = xbis.currentLineNumber;
        blockInstruction = xbis.blockInstruction;
        currentBlock = xbis.currentBlock;
        currentFunction = xbis.currentFunction;
        currentType = xbis.currentType;
        numbers = xbis.numbers;
        variables = xbis.variables;
    }