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(); }
public virtual void Visit(FunctionCallStmt stmt) { foreach (var argument in stmt.Arguments) { argument.Accept(this); } }
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); }
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); } }
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 )); } } }
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(); }
public void Visit(FunctionCallStmt stmt) { var arguments = EvaluateArguments(stmt.Arguments); EmitCall(stmt.MethodName, arguments); }
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 }
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; } } }