Esempio n. 1
0
        public void Visit(FunctionCallStmt funcCallStmt, object[] args)
        {
            FormalScope formalScope = new FormalScope();

            foreach (KeyValuePair <string, Expr.Expression> actual in funcCallStmt.ParamMap)
            {
                Expr.RightValue rightValue = exprProcessor.Eval(actual.Value);
                formalScope.SetValue(actual.Key, rightValue);
            }
            kernel.RuntimeData.ScopeStack.Open(formalScope);
            kernel.RuntimeData.ScopeStack.Open(new LocalScope());

            kernel.RuntimeData.InstructionStack.Push(InstructionStack.CALL_FLAG);
            kernel.RuntimeData.InstructionStack.Push(InstructionStack.CLOSE_LOCAL_SCOPE_FLAG);
            kernel.RuntimeData.InstructionStack.Push(InstructionStack.CLOSE_FORMAL_SCOPE_FLAG);

            kernel.RuntimeData.InstructionStack.Push(root.FuncDefMap[funcCallStmt.Name].FuncDefContent);

            CallStackElement elem = new CallStackElement();

            elem.Destination = root.FuncDefMap[funcCallStmt.Name];
            elem.Location    = funcCallStmt.Location;
            elem.ReturnDest  = exprProcessor.GetVarName(funcCallStmt.ReturnDest);
            kernel.RuntimeData.CallStack.Push(elem);

            kernel.Next();
        }
Esempio n. 2
0
 public virtual void Visit(FunctionCallStmt stmt)
 {
     foreach (var argument in stmt.Arguments)
     {
         argument.Accept(this);
     }
 }
Esempio n. 3
0
        public Statement ParseFunctionCallStatement()
        {
            string function = ConsumeToken(TokenKind.Identifier).Source;

            ConsumeToken(TokenKind.OpenParen);

            var arguments = ParseArgumentList();

            ConsumeToken(TokenKind.CloseParen);

            var call = new FunctionCallStmt {
                MethodName = function,
                Arguments  = arguments.ToArray()
            };

            switch (CurrentToken.Kind)
            {
            case TokenKind.Semicolon:
                ConsumeToken();
                break;

            case TokenKind.OpenBrace:
                if (function.Equals("if", StringComparison.CurrentCultureIgnoreCase))
                {
                    var       body     = ParseBlockStatement();
                    BlockStmt elseBody = null;

                    if (CurrentToken.Kind == TokenKind.Identifier && CurrentToken.Source.Equals("else", StringComparison.CurrentCultureIgnoreCase))
                    {
                        ConsumeToken();
                        elseBody = ParseBlockStatement();
                    }

                    return(new IfStmt {
                        Function = call,
                        Body = body,
                        ElseBody = elseBody
                    });
                }

                return(new BodyFunctionStmt {
                    Function = call,
                    Body = ParseBlockStatement()
                });

            default:
                throw new UnexpectedTokenException(CurrentToken, TokenKind.Semicolon, TokenKind.OpenBrace);
            }

            return(call);
        }
Esempio n. 4
0
        public override void Visit(FunctionCallStmt stmt)
        {
            if (stmt.MethodName.IsOneOf(Options.YkdLineMethods))
            {
                // externalize line of text
                foreach (var argument in stmt.Arguments)
                {
                    if (argument is StringLiteral literal)
                    {
                        ExternalizeStringLiteral(literal, StringCategory.L, true);
                    }
                    else
                    {
                        argument.Accept(this);
                    }
                }
            }
            else if (stmt.MethodName.IsOneOf(Options.YkdNameMethods))
            {
                // externalize name
                foreach (var argument in stmt.Arguments)
                {
                    if (argument is StringLiteral literal)
                    {
                        // set current speaker
                        _currentSpeaker = literal.Value;

                        ExternalizeStringLiteral(literal, StringCategory.N);
                    }
                    else if (argument is Variable)
                    {
                        // variable name probably refers to the protagonist
                        _currentSpeaker = "me";
                    }
                    else
                    {
                        argument.Accept(this);
                    }
                }
            }
            else
            {
                if (stmt.MethodName.IsOneOf(Options.YkdResetSpeakerMethods))
                {
                    _currentSpeaker = null;
                }
                base.Visit(stmt);
            }
        }
Esempio n. 5
0
        public void Visit(FunctionCallStmt funcCallStmt, object[] args)
        {
            //检查存在性!
            funcCallStmt.Name     = reader.Name;
            funcCallStmt.ParamMap = new Dictionary <string, FireEngine.FireMLEngine.Expr.Expression>();

            int attCount = reader.AttributeCount;

            for (int i = 0; i < attCount; i++)
            {
                reader.MoveToAttribute(i);
                if (reader.Name == "return")
                {
                    funcCallStmt.ReturnDest = exprParser.ParseLeftValueExpr(reader.Value,
                                                                            new Location(file, reader.LineNumber, reader.LinePosition).Offset(reader.Name.Length + 2)); //TODO: Location
                }
                else if (reader.Name == "par")
                {
                    //FINISH: 解析参数字串!
                    string[] paraStrList = ParaStrProcessor.ReadParaCallList(reader.Value);
                    if (paraStrList == null)
                    {
                        kernel.IssueError(ErrorType.ParaStrCallFormatError, getCurrentLoc(), reader.Value);
                    }
                    else
                    {
                        funcCallStmt.ParaStr = paraStrList;
                    }
                }
                else
                {
                    //先把实参按字符串暂存,之后扫描AST树时再按指定类型解析
                    funcCallStmt.ParamMap.Add(reader.Name,
                                              exprParser.CreateStringConst(reader.Value,
                                                                           new Location(file, reader.LineNumber, reader.LinePosition).Offset(reader.Name.Length + 2) //TODO: Location
                                                                           ));
                }
            }
        }
Esempio n. 6
0
        protected Statement ReadStatement()
        {
            var instruction = ReadInstruction();

            switch (instruction)
            {
            case LabelInstruction label:
                Debug.Assert(label.Name != "else" && label.Name != "}");
                if (label.Name == "{")
                {
                    return(ReadBlockStatement());
                }
                return(new JumpLabelStmt {
                    Name = label.Name.EscapeIdentifier()
                });

            case CallInstruction func:

                #region Handle assignments
                if (func.Name == "=")
                {
                    if (_currentAssignmentTarget == null)
                    {
                        throw new FormatException("No assignment target set");
                    }

                    Expression expr;
                    if (func.Arguments.Length == 0)
                    {
                        // a call to =() with no arguments means the result of the following function call is assigned
                        if (CurrentInstruction is CallInstruction callInstruction)
                        {
                            expr = new FunctionCallExpr {
                                CallStmt = new FunctionCallStmt {
                                    MethodName = callInstruction.Name, Arguments = MapToExpressions(callInstruction.Arguments)
                                }
                            };
                            _currentInstructionOffset++;
                        }
                        else
                        {
                            throw new FormatException("A parameterless call to =() must be followed by a function call, found " + CurrentInstruction);
                        }
                    }
                    else
                    {
                        // otherwise, the arguments are alternating operands and operators
                        expr = ToExpression(func.Arguments);
                    }

                    if (_currentAssignmentTarget is AssignmentTarget.Local local)
                    {
                        _locals[local.Id]        = expr;
                        _currentAssignmentTarget = null;
                        return(null);
                    }

                    var assigment = new AssignmentStmt {
                        Target = _currentAssignmentTarget, Expression = expr
                    };
                    _currentAssignmentTarget = null;
                    return(assigment);
                }
                #endregion

                var callStatement = new FunctionCallStmt {
                    MethodName = func.Name, Arguments = MapToExpressions(func.Arguments)
                };

                #region Handle body functions

                if (CurrentInstruction is LabelInstruction startLabel && startLabel.Name == "{")
                {
                    _currentInstructionOffset++;                             // skip opening brace

                    var body = ReadBlockStatement();

                    #region Handle if statements

                    if (callStatement.MethodName.ToLower() == "if")
                    {
                        if (Script.InstructionList.Count <= _currentInstructionOffset ||
                            !(Script.InstructionList[_currentInstructionOffset] is LabelInstruction elseKeyword) ||
                            elseKeyword.Name != "else")
                        {
                            // no else block
                            return new IfStmt {
                                       Function = callStatement, Body = body
                            }
                        }
                        ;

                        BlockStmt elseBody;
                        // skip else keyword
                        _currentInstructionOffset++;
                        if (Script.InstructionList[_currentInstructionOffset] is LabelInstruction elseStart && elseStart.Name == "{")
                        {
                            // skip opening brace
                            _currentInstructionOffset++;

                            elseBody = ReadBlockStatement();
                        }
                        else
                        {
                            // "Kimi o Aogi Otome wa Hime ni" has these bodyless else keywords in data01:system/selectjumpstart.yks
                            Console.WriteLine("Warning: Loose else keyword without body");
                            elseBody = new BlockStmt();
                            //throw new FormatException("Else keyword must be followed by an opening brace");
                        }

                        return(new IfStmt {
                            Function = callStatement, Body = body, ElseBody = elseBody
                        });
                    }

                    #endregion

                    return(new BodyFunctionStmt {
                        Function = callStatement, Body = body
                    });
                }

                #endregion

                return(callStatement);

            case TargetInstruction target:
                SetAssignmentTarget(target);
                return(null);

            default:
                throw new FormatException("Invalid statement instruction: " + instruction);
            }
        }
 public void Visit(FunctionCallStmt funcCallStmt, object[] args)
 {
     throw new NotImplementedException();
 }
Esempio n. 8
0
        public void Visit(FunctionCallStmt stmt)
        {
            var arguments = EvaluateArguments(stmt.Arguments);

            EmitCall(stmt.MethodName, arguments);
        }
Esempio n. 9
0
        public override void Visit(FunctionCallStmt funcCallStmt, object[] args)
        {
            if (!root.FuncDefMap.ContainsKey(funcCallStmt.Name))
            {
                kernel.IssueError(ErrorType.FunctionNotExist, funcCallStmt.Location, funcCallStmt.Name);
                return;
            }

            FunctionDef def = root.FuncDefMap[funcCallStmt.Name];

            //解析ParaStr
            if (funcCallStmt.ParaStr != null)
            {
                int count = funcCallStmt.ParaStr.Length;
                if (def.ParaStrMap.ContainsKey(count))
                {
                    for (int i = 0; i < funcCallStmt.ParaStr.Length; i++)
                    {
                        string varName = def.ParaStrMap[count][i];
                        string content = funcCallStmt.ParaStr[i];
                        if (funcCallStmt.ParamMap.ContainsKey(varName))
                        {
                            kernel.IssueError(ErrorType.DuplicatedParaAndParaStr, funcCallStmt.Location, varName);
                        }
                        else
                        {
                            funcCallStmt.ParamMap.Add(varName, exprParser.CreateStringConst(content, funcCallStmt.Location));
                        }
                    }
                }
                else
                {
                    kernel.IssueError(ErrorType.NoMatchedParaStrDef, funcCallStmt.Location);
                }
            }

            //解析实参
            List <KeyValuePair <string, Expression> > toModify = new List <KeyValuePair <string, Expression> >();

            foreach (KeyValuePair <string, Expression> actual in funcCallStmt.ParamMap)
            {
                ParameterDef paramDef  = def.ParaMap[actual.Key];
                string       actualStr = ((actual.Value as RightValueExpr).RightValue as StringConst).Value;
                Location     loc       = actual.Value.Location;

                RightValue     parsedValue    = null;
                RightValueExpr rightValueExpr = new RightValueExpr();

                switch (paramDef.ParameterType)
                {
                case ParameterDef.ParameterTypeEnum.Auto:
                    parsedValue = exprParser.ParseValue(actualStr, loc);
                    break;

                case ParameterDef.ParameterTypeEnum.String:
                    continue;

                case ParameterDef.ParameterTypeEnum.Expression:
                    toModify.Add(new KeyValuePair <string, Expression>(actual.Key, exprParser.ParseExpr(actualStr, loc)));
                    continue;

                case ParameterDef.ParameterTypeEnum.Int:
                    parsedValue = exprParser.ParseValue(actualStr, DataType.Int, loc);
                    break;

                case ParameterDef.ParameterTypeEnum.Float:
                    parsedValue = exprParser.ParseValue(actualStr, DataType.Float, loc);
                    break;

                case ParameterDef.ParameterTypeEnum.Bool:
                    parsedValue = exprParser.ParseValue(actualStr, DataType.Bool, loc);
                    break;
                }

                rightValueExpr.RightValue = parsedValue;
                rightValueExpr.Location   = loc;
                toModify.Add(new KeyValuePair <string, Expression>(actual.Key, rightValueExpr));
            }

            foreach (KeyValuePair <string, Expression> elem in toModify)
            {
                funcCallStmt.ParamMap[elem.Key] = elem.Value;
            }

            //添加默认值
            foreach (KeyValuePair <string, ParameterDef> pDef in def.ParaMap)
            {
                if (!funcCallStmt.ParamMap.ContainsKey(pDef.Key) && pDef.Value.Default != null)
                {
                    RightValueExpr expr = new RightValueExpr();
                    expr.RightValue = pDef.Value.Default;
                    funcCallStmt.ParamMap.Add(pDef.Key, expr);
                }
            }

            //参数完整性检查
            foreach (KeyValuePair <string, ParameterDef> pDef in def.ParaMap)
            {
                if (!funcCallStmt.ParamMap.ContainsKey(pDef.Key))
                {
                    kernel.IssueError(ErrorType.ParameterNotDefined, funcCallStmt.Location, pDef.Key);
                }
            }

            base.Visit(funcCallStmt, args);

            //TODO: 刷新Expression的DataType
        }
Esempio n. 10
0
        private void visitMainContent(ASTNode parent, List <Statement> content)
        {
            bool endWithBr = false;

            while (reader.Read())
            {
                reader.MoveToContent();
                Location location = new Location(file, reader.LineNumber, reader.LinePosition);
                switch (reader.NodeType)
                {
                case XmlNodeType.Text:
                    string   text  = reader.Value;
                    string[] lines = text.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string line in lines)
                    {
                        string trimed = line.Trim();
                        if (trimed.Length == 0)
                        {
                            continue;
                        }

                        if (endWithBr && content.Count > 0 && content[content.Count - 1] is DialogStmt)
                        {
                            DialogStmt dialog = content[content.Count - 1] as DialogStmt;
                            dialog.Text += Environment.NewLine + trimed;
                        }
                        else
                        {
                            DialogStmt dialog = new DialogStmt();
                            dialog.Parent   = parent;
                            dialog.Location = location;

                            dialog.Text = trimed;
                            content.Add(dialog);
                        }
                        endWithBr = false;
                    }
                    break;

                case XmlNodeType.Element:
                    Statement statement = null;
                    switch (dic[reader.Name])
                    {
                    case "br":
                        endWithBr = true;
                        continue;

                    case "expr":
                        statement = new ExpressionStmt();
                        break;

                    case "return":
                        statement = new ReturnStmt();
                        break;

                    case "include":
                        statement = new IncludeStmt();
                        break;

                    case "actor":
                        statement = new ActorStmt();
                        break;

                    case "bg":
                        statement = new BackgroundStmt();
                        break;

                    case "echo":
                        statement = new EchoStmt();
                        break;

                    case "select":
                        statement = new SelectStmt();
                        break;

                    case "selectWithValue":
                        statement = new SelectStmt();
                        break;

                    case "if":
                        statement = new IfStmt();
                        break;

                    case "else":
                        return;

                    case "elseif":
                        return;

                    case "switch":
                        statement = new SwitchStmt();
                        break;

                    case "break":
                        statement = new BreakStmt();
                        break;

                    case "continue":
                        statement = new ContinueStmt();
                        break;

                    case "loop":
                        statement = new LoopStmt();
                        break;

                    case "music":
                        statement = new MusicStmt();
                        break;

                    case "musicStop":
                        statement = new MusicStopStmt();
                        break;

                    case "musicVol":
                        statement = new MusicVolStmt();
                        break;

                    default:
                        statement = new FunctionCallStmt();
                        break;
                    }
                    statement.Parent   = parent;
                    statement.Location = location;
                    statement.Accept(this);
                    content.Add(statement);
                    break;

                case XmlNodeType.EndElement:
                    //reader.Read();  //MainContent结束
                    return;
                }
            }
        }