Beispiel #1
0
        private NovelExpression HandleOperand(NovelExpression expression, string operand)
        {
            int index = -1;

            if (IsVariable(operand))
            {
                expression.Term.Add(new NovelExpressionVariable(operand, Variables.GetStackIndex(operand)));
            }
            else if (IsFunction(operand))
            {
                //TODO update offset???
                expression.Term.Add(new NovelExpressionFunctionCall(operand, 0, false));
            }
            else if ((index = IsDelegateFunction(operand)) >= 0)
            {
                expression.Term.Add(new NovelExpressionFunctionCall(operand, index, true));
            }
            else if (IsLiteral(operand))
            {
                expression.Term.Add(new NovelExpressionLiteral(GetLiteral(operand)));
            }
            else if (IsString(operand))
            {
                expression.Term.Add(new NovelExpressionLiteral(operand.Substring(1, operand.Count() - 2)));
            }
            else
            {
                throw new NovelException("Undefined object " + operand + ".", ParsedFile, ParsedLine);
            }
            return(expression);
        }
        public NovelCondition ParseCondition(string text, out int conditionLevel, ref List <NovelInstruction> instructions)
        {
            conditionLevel = -1;
            var conditionStart = new string [] { "if", "else if", "else" };

            for (int i = 0; i < conditionStart.Length; i++)
            {
                if (text.IndexOf(conditionStart[i]) == 0)
                {
                    conditionLevel = i;
                    break;
                }
            }

            var conditionText = text.Substring(
                conditionStart[conditionLevel].Length).Trim();

            var novelCondition = new NovelCondition();

            if (conditionLevel == 0 || conditionLevel == 1)
            {
                var unfold = ParseExpression(conditionText);

                if (unfold.Last() is NovelExpandStack)
                {
                    for (int i = 0; i < unfold.Count - 1; i++)
                    {
                        instructions.Add(unfold[i]);
                    }

                    novelCondition.StackInstruction = unfold.Last() as NovelExpandStack;
                    var lastExpression = unfold[unfold.Count - 2] as NovelExpression;
                    novelCondition.ConditionOperand = lastExpression.Term[0] as NovelExpressionOperand;
                }
                else
                {
                    var lastExpression = unfold.Last() as NovelExpression;
                    novelCondition.ConditionOperand = lastExpression.Term[0] as NovelExpressionOperand;
                }
            }
            else if (conditionLevel == 2)
            {
                var expression = new NovelExpression();
                expression.Term.Add(new NovelExpressionLiteral(true));
                novelCondition.ConditionOperand = new NovelExpressionLiteral(true);
            }
            return(novelCondition);
        }
        private void ExecuteExpression(NovelExpression expression)
        {
            if (expression.Term.Count == 5)
            {
                var result     = expression.Term[0] as NovelExpressionOperand;
                var operand1   = expression.Term[1] as NovelExpressionOperand;
                var operand2   = expression.Term[2] as NovelExpressionOperand;
                var oper       = expression.Term[3] as NovelExpressionOperator;
                var assignOper = expression.Term[4] as NovelExpressionOperator;
                //Assuming that assign operator is =
                if (assignOper is NovelAssignOperator)
                {
                    var var1 = OperandToValue(operand1);
                    var var2 = OperandToValue(operand2);

                    //TODO EXECUTION TIME EXCEPTIONS
                    if (var1 == null)
                    {
                        throw new NovelException("Object " + var1.ToString() + " is undefined", "", 0);
                    }

                    if (var2 == null)
                    {
                        throw new NovelException("Object " + var2.ToString() + " is undefined", "", 0);
                    }

                    var varRes = oper.Operate(var1, var2);
                    Stack.SetVariableAt(StackPointer,
                                        (result as NovelExpressionVariable).StackOffset,
                                        varRes);
                }
            }
            else if (expression.Term.Count == 3)
            {
                var result     = expression.Term[0] as NovelExpressionOperand;
                var operand1   = expression.Term[1] as NovelExpressionOperand;
                var assignOper = expression.Term[2] as NovelExpressionOperator;
                //Assuming that assign operator is =
                if (assignOper is NovelAssignOperator)
                {
                    var var1 = OperandToValue(operand1);
                    //TODO EXECUTION TIME EXCEPTIONS
                    if (var1 == null)
                    {
                        throw new NovelException("Object " + var1.ToString() + " is undefined", "", 0);
                    }

                    Stack.SetVariableAt(StackPointer,
                                        (result as NovelExpressionVariable).StackOffset,
                                        var1);
                }
            }
            else if (expression.Term.Count == 1)
            {
                if (expression.Term[0] is NovelExpressionFunctionCall)
                {
                    var exprFunc = expression.Term[0] as NovelExpressionFunctionCall;
                    var argList  = new List <object>();
                    foreach (var arg in exprFunc.Arguments)
                    {
                        argList.Add(OperandToValue(arg).Value);
                    }

                    if (!exprFunc.IsDelegated)
                    {
                        CallScriptFunction(exprFunc.Name, argList.ToArray());
                        InstructionPointer--;
                    }
                    else
                    {
                        Stack.ExpandStack(1);
                        var result = Script.DelegateFunctionList.Call(exprFunc.Offset, argList.ToArray());

                        //Possible for Actions that returns null
                        if (result == null)
                        {
                            result = new int();
                            result = 0;
                        }

                        Stack.SetVariableAtLast(new NovelVariable(result));
                    }
                }
            }
        }
Beispiel #4
0
    void Advance(bool doNotIncrement = false)
    {
        //Debug.Log("advance:"+doNotIncrement);
        lastToken = currentBranch.frames[currentFrame].token;
        if (!doNotIncrement)
        {
            currentFrame++;
        }

        if (currentFrame >= currentBranch.frames.Count)
        {
            running = false;
            characterGraphic.gameObject.SetActive(false);
            if (callBack != null)
            {
                callBack.Invoke();
            }
            return;
        }

        NovelFrame frame = currentBranch.frames[currentFrame];

        switch (frame.token)
        {
        case Tokens.background:
        {
            title.text        = string.Empty;
            message.text      = string.Empty;
            background.sprite = marshal.Background((string)frame.payload);
            StartTimer();
        } break;

        case Tokens.monologue:
        {
            title.text   = "monologue";
            message.text = (string)frame.payload;
            state        = RunnerStates.waitOnInput;
        } break;

        case Tokens.character:
        {
            NovelCharacter character = ((NovelCharacter)frame);
            if (character.name != "You" && character.name != "player")
            {
                characterGraphic.gameObject.SetActive(true);
                characterGraphic.sprite = marshal.Character(character.name, null);
                characterGraphic.rectTransform.sizeDelta = Scale(characterGraphic.sprite.rect.size.y, 1080,
                                                                 characterGraphic.sprite.rect.size);
            }
            title.text   = ((NovelCharacter)frame).name;
            message.text = string.Empty;
            state        = RunnerStates.waitOnTimer;
        } break;

        case Tokens.expression:
        {
            NovelExpression expression = ((NovelExpression)frame);
            if (expression.character != "You" && expression.character != "player")
            {
                characterGraphic.gameObject.SetActive(true);
                characterGraphic.sprite = marshal.Character(expression.character, (string)expression.payload);
                characterGraphic.rectTransform.sizeDelta = Scale(characterGraphic.sprite.rect.size.y, 1080,
                                                                 characterGraphic.sprite.rect.size);
            }

            title.text = ((NovelExpression)frame).character;
            StartTimer();
        } break;

        case Tokens.line:
        {
            if (lastToken == Tokens.character || lastToken == Tokens.expression || lastToken == Tokens.line)
            {                     /* Do Nothing */
            }
            else
            {
                title.text = ((NovelExpression)frame).character + " " + ((NovelExpression)frame).payload;
            }
            message.text = (string)frame.payload;
            state        = RunnerStates.waitOnInput;
        } break;

        case Tokens.hidecharacter:
        {
            characterGraphic.gameObject.SetActive(false);
            StartTimer();
        } break;

        case Tokens.directive:
        {
            marshal.ExecuteProcedure((string)frame.payload);
            state = RunnerStates.waitOnTimer;
            StartTimer();
        } break;

        case Tokens.jump:
        {
            StartTimer();
            Jump((string)frame.payload);
        } break;

        case Tokens.TEXT:
        {
            NovelText text = (NovelText)frame;
            state = RunnerStates.waitOnInput;
            phone.PostTextMessage(text.character == "You", text.character, text.line);
        } break;

        case Tokens.options:
        {
            novelAssembly.SetActive(true);
            state = RunnerStates.waitOnChoice;
            NovelOptions options = (NovelOptions)frame;

            normalDisplay.SetActive(false);
            optionDisplay.SetActive(true);

            Transform[] old = optionContent.GetComponentsInChildren <Transform>();
            Debug.Log(old.Length);

            foreach (Transform go in old)
            {
                if (go == optionContent.transform)
                {
                    continue;
                }
                go.transform.parent = null;
                GameObject.Destroy(go.gameObject);
            }

            foreach (NovelOption option in options.options)
            {
                GameObject g = GameObject.Instantiate(providedButton, optionContent.transform.position,
                                                      optionContent.transform.rotation, optionContent.transform);
                g.GetComponentInChildren <Text>().text = (string)option.payload;
                g.GetComponent <Button>().onClick.AddListener(
                    () => { Jump(option.target); EndOptions(); }                              /// CLOSURE! to the rescue!!
                    );
            }
        } break;

        default:
        {
            throw new System.Exception("Unexpected token " + frame.token + " in switch statement.");
        }
        }
    }
Beispiel #5
0
        public List <NovelInstruction> ParseExpression(string text)
        {
            //Trim the expression
            text = text.Trim();

            //Create empty expression object
            NovelExpression novelExpression = new NovelExpression();

            //Declare instructions
            List <NovelInstruction> instructions = new List <NovelInstruction>();

            //For RPN algorithm purpose
            string output = "";
            string buffer = "";

            for (int i = 0; i < text.Length; i++)
            {
                //Check if the i is pointing at operator name
                var operatorIndex = IsOperator(text, i);

                //operatorIndex = -1 means that its regular character
                if (operatorIndex >= 0)
                {
                    //Build expression here based on whats in buffer
                    if (!buffer.Equals(""))
                    {
                        if (IsDeclaredVariable(buffer))
                        {
                            buffer = buffer.Substring(3);

                            if (!Variables.ContainsVariable(buffer))
                            {
                                instructions.Add(new NovelExpandStack(1));
                                Variables.AddVaraible(buffer);
                            }
                            //TODO functions name
                            else
                            {
                                throw new NovelException("Variable or function name " + buffer + " already exists.", ParsedFile, ParsedLine);
                            }
                        }

                        //Handle the operands
                        novelExpression = HandleOperand(novelExpression, buffer);

                        //Push variable to the output
                        output += buffer;
                        buffer  = "";
                    }

                    //Get the new operator
                    var op = Operators[operatorIndex];

                    //Parentheses close operator
                    if (op is NovelCloseCurvedParenthesesOperator)
                    {
                        //Pop all operators till (
                        while (OperatorStack.Count() > 0)
                        {
                            var opFromStack = OperatorStack.Pop();
                            if (opFromStack is NovelOpenCurvedParenthesesOperator)
                            {
                                var parentheses = parenthesesType.Pop();

                                if (parentheses == ParenthesesType.Function)
                                {
                                    novelExpression.Term.Add(new NovelFunctionEndOperator());
                                }

                                break;
                            }
                            else
                            {
                                if (!(opFromStack is NovelOpenCurvedParenthesesOperator ||
                                      opFromStack is NovelCloseCurvedParenthesesOperator))
                                {
                                    novelExpression.Term.Add(opFromStack);
                                }
                            }
                        }
                    }
                    //If every other operator
                    else
                    {
                        //Iteratore over OperatorStack
                        while (OperatorStack.Count() > 0)
                        {
                            //If priority of new operator is lower or equal pop stack operators
                            //
                            if (op.GetPriority() <= OperatorStack.First().GetPriority() &&
                                !(op is NovelOpenCurvedParenthesesOperator))
                            {
                                var opFromStack = OperatorStack.Pop();

                                if (!(opFromStack is NovelOpenCurvedParenthesesOperator ||
                                      opFromStack is NovelCloseCurvedParenthesesOperator))
                                {
                                    novelExpression.Term.Add(opFromStack);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    //Now put the operator on the stack if not close curved
                    if (!(op is NovelCloseCurvedParenthesesOperator))
                    {
                        //If previous term part was function call
                        if (novelExpression.Term.Count >= 1 &&
                            op is NovelOpenCurvedParenthesesOperator &&
                            novelExpression.Term[novelExpression.Term.Count - 1] is NovelExpressionFunctionCall)
                        {
                            parenthesesType.Push(ParenthesesType.Function);
                            novelExpression.Term.Add(new NovelFunctionStartOperator());
                        }
                        //If normal paretheses
                        else if (op is NovelOpenCurvedParenthesesOperator)
                        {
                            parenthesesType.Push(ParenthesesType.Normal);
                        }

                        OperatorStack.Push(op);
                    }

                    //Move pointer by a length of operator
                    i += op.GetName().Length - 1;
                }
                //If its not an operator
                else
                {
                    if (text[i].Equals(' '))
                    {
                        continue;
                    }
                    else if (text[i].Equals('\t'))
                    {
                        continue;
                    }
                    else if (text[i].Equals('\r'))
                    {
                        continue;
                    }
                    else if (text[i].Equals('\n'))
                    {
                        continue;
                    }

                    //If its a quote
                    if (text[i].Equals('\"'))
                    {
                        int len = text.IndexOf('\"', i + 1) - i + 1;
                        buffer += text.Substring(i, len);
                        i      += len - 1;
                    }
                    //If its not add single character
                    else
                    {
                        buffer += text[i];
                    }
                }
            }

            //Empty buffer first
            if (!buffer.Equals(""))
            {
                novelExpression = HandleOperand(novelExpression, buffer);
            }

            //Empty operator stack
            while (OperatorStack.Count() > 0)
            {
                var opFromStack = OperatorStack.Pop();
                if (!(opFromStack is NovelOpenCurvedParenthesesOperator ||
                      opFromStack is NovelCloseCurvedParenthesesOperator))
                {
                    novelExpression.Term.Add(opFromStack);
                }
            }

            Variables.AddScope();
            int reservedVariables = Variables.GetStackVariables();

            while (novelExpression.Term.Count > 0)
            {
                novelExpression = UnfoldOperations(novelExpression, ref instructions);
                novelExpression = UnfoldArguments(novelExpression, ref instructions);
                //For single variables or literals
                if (novelExpression.Term.Count == 1)
                {
                    var newExpression = new NovelExpression();
                    newExpression.Term.Add(novelExpression.Term[0]);
                    instructions.Add(newExpression);
                    novelExpression.Term.Clear();
                }
            }

            //How many of temporary variables expression has
            reservedVariables = Variables.GetStackVariables() - reservedVariables;

            //Shrink stack to remove them
            if (reservedVariables > 0)
            {
                instructions.Add(new NovelExpandStack(-reservedVariables));
            }

            Variables.RemoveScope();

            foreach (var instruction in instructions)
            {
                string buff = "";
                buff += " " + instruction;
                Console.WriteLine(buff);
            }
            Console.WriteLine("");

            return(instructions);
        }
Beispiel #6
0
        private NovelExpression UnfoldArguments(NovelExpression expression, ref List <NovelInstruction> instructions)
        {
            //Get the term
            var term = expression.Term;

            for (int i = 0; i < term.Count; i++)
            {
                int functionEndIndex = -1;
                int functionElements = 2;
                //Look for function start operator
                if (term[i] is NovelFunctionStartOperator && term[i - 1] is NovelExpressionFunctionCall)
                {
                    //Check if inside function are only comma characters
                    bool onlyCommas = true;
                    for (int j = i + 1; j < term.Count; j++)
                    {
                        var test = term[j];
                        functionElements++;

                        //Read until novel function end
                        if (term[j] is NovelFunctionEndOperator)
                        {
                            functionEndIndex = j;
                            break;
                        }

                        //If its an operator
                        if (term[j] is NovelExpressionOperator)
                        {
                            //If its different than comma
                            if (!(term[j] is NovelCommaOperator))
                            {
                                onlyCommas = false;
                                break;
                            }
                        }
                    }

                    if (onlyCommas)
                    {
                        //Fill function with arguments
                        var function = term[i - 1] as NovelExpressionFunctionCall;
                        for (int j = i; j < functionEndIndex; j++)
                        {
                            if (term[j] is NovelExpressionOperand)
                            {
                                function.Arguments.Add(term[j] as NovelExpressionOperand);
                            }
                        }
                        //TODO
                        //here i have number of arguments in function
                        //so i can check if its the right number
                        int newIndex = ParsedScript.DelegateFunctionList.
                                       ContainsFunction(function.Name, function.Arguments.Count);

                        //If found new delegated function
                        if (newIndex > -1)
                        {
                            function.Offset = newIndex;
                        }
                        else
                        {
                            throw new NovelException("Could not find delegated method "
                                                     + function.Name + " with " + function.Arguments.Count() +
                                                     " arguments.", "", 0);
                        }

                        //Now create new expression
                        var lastStackOperator = Variables.GetStackVariables();
                        var temporaryVariable = new NovelExpressionVariable("temp_" + lastStackOperator, lastStackOperator);
                        Variables.AddVaraible(temporaryVariable.Name);

                        //instructions.Add(new NovelExpandStack(1));
                        var newExpression = new NovelExpression();
                        //newExpression.Term.Add(temporaryVariable);
                        newExpression.Term.Add(function);
                        //newExpression.Term.Add(new NovelAssignOperator());
                        instructions.Add(newExpression);

                        //Remove from expression
                        for (int j = 0; j < functionElements; j++)
                        {
                            expression.Term.RemoveAt(i - 1);
                        }

                        if (expression.Term.Count > 0)
                        {
                            expression.Term.Insert(i - 1, temporaryVariable);
                        }

                        i -= 1;
                    }
                }
            }
            return(expression);
        }
Beispiel #7
0
        private NovelExpression UnfoldOperations(NovelExpression expression, ref List <NovelInstruction> instructions)
        {
            //Get the term
            var term = expression.Term;

            //Look for
            for (int i = 0; i < term.Count; i++)
            {
                var part = term[i];
                //Look for operator different
                //comma
                //fnc start
                //fnc end
                //fnc call
                if (part is NovelExpressionOperator)
                {
                    if (!(part is NovelExpressionFunctionCall) &&
                        !(part is NovelCommaOperator) &&
                        !(part is NovelFunctionStartOperator) &&
                        !(part is NovelFunctionEndOperator))
                    {
                        //If its one argument operator
                        if (part is NovelNegationOperator &&
                            term[i - 1] is NovelExpressionOperand)
                        {
                            var operand           = term[i - 1] as NovelExpressionOperand;
                            var lastStackOperator = Variables.GetStackVariables();
                            var temporaryVariable = new NovelExpressionVariable("temp_" + lastStackOperator, lastStackOperator);
                            Variables.AddVaraible(temporaryVariable.Name);

                            instructions.Add(new NovelExpandStack(1));
                            var newExpression = new NovelExpression();
                            newExpression.Term.Add(temporaryVariable);
                            newExpression.Term.Add(operand);
                            newExpression.Term.Add(part);
                            newExpression.Term.Add(new NovelAssignOperator());
                            instructions.Add(newExpression);
                            //Replace last operation with temporary variable
                            expression.Term.RemoveAt(i - 1);
                            expression.Term.RemoveAt(i - 1);
                            //Don't put temporary variable to expression if its empty
                            if (expression.Term.Count > 0)
                            {
                                expression.Term.Insert(i - 1, temporaryVariable);
                            }

                            i -= 1;
                        }
                        //Get the two operands if its not negation
                        else
                        {
                            //If its the end of expression
                            if (part is NovelAssignOperator &&
                                expression.Term.Count == 3 &&
                                term[i - 1] is NovelExpressionOperand &&
                                term[i - 2] is NovelExpressionOperand)
                            {
                                var newExpression = new NovelExpression();
                                newExpression.Term.Add(term[i - 2]);
                                newExpression.Term.Add(term[i - 1]);
                                newExpression.Term.Add(part);
                                instructions.Add(newExpression);
                                expression.Term.Clear();
                            }
                            //If both previous parts in term are operands
                            else if (
                                term[i - 1] is NovelExpressionOperand &&
                                term[i - 2] is NovelExpressionOperand)
                            {
                                var operandLeft  = term[i - 2] as NovelExpressionOperand;
                                var operandRight = term[i - 1] as NovelExpressionOperand;

                                var lastStackOperator = Variables.GetStackVariables();
                                var temporaryVariable = new NovelExpressionVariable("temp_" + lastStackOperator, lastStackOperator);
                                Variables.AddVaraible(temporaryVariable.Name);

                                instructions.Add(new NovelExpandStack(1));
                                //Create new operation of two operands
                                //and assign the result to temporary variable
                                var newExpression = new NovelExpression();
                                newExpression.Term.Add(temporaryVariable);
                                newExpression.Term.Add(operandLeft);
                                newExpression.Term.Add(operandRight);
                                newExpression.Term.Add(part);
                                newExpression.Term.Add(new NovelAssignOperator());
                                instructions.Add(newExpression);
                                //Replace last operation with temporary variable
                                expression.Term.RemoveAt(i - 2);
                                expression.Term.RemoveAt(i - 2);
                                expression.Term.RemoveAt(i - 2);
                                if (expression.Term.Count > 0)
                                {
                                    expression.Term.Insert(i - 2, temporaryVariable);
                                }

                                i -= 2;
                            }
                        }
                    }
                }
            }
            return(expression);
        }