public static bool HasSameReturnValue(AstReturn returnA, AstReturn returnB) { // Both return undefined if (returnA.Value == null && returnB.Value == null) { return(true); } // Only one of them is undefined if (returnA.Value == null || returnB.Value == null) { return(false); } // Both is SymbolRef if (returnA.Value is AstSymbolRef symbolA && returnB.Value is AstSymbolRef symbolB) { return(IsSameReference(symbolA, symbolB)); } // Both is Call if (returnA.Value is AstCall callA && returnB.Value is AstCall callB) { return(IsSameCall(callA, callB)); } // Both is constants with same value var constReturnA = returnA.Value.ConstValue(); var constReturnB = returnB.Value.ConstValue(); return(constReturnA != null && constReturnB != null && constReturnA.Equals(constReturnB)); }
private static EvalValue CalcReturn(IEnvironment env, AstReturn ast) { var ret = ast.result.Eval(env); env.Set("return@" + env.GetScopeName(), ret); // 中断执行 throw new ReturnException(ast); }
/// <summary> /// 解析语句state /// </summary> /// <returns></returns> private AstStatement DoStatement() { // state ::== <while><expr><do>{<expr>|<state>}<end>';' // | <if><expr><do>{<expr>|<state>}<end>';' // | <return><expr>';' if (Is("while", TokenType.KEYWORD)) { // while语句 Pass("while", TokenType.KEYWORD); AstExpression condition = DoExpression(); Pass("do", TokenType.KEYWORD); List <AstNode> list = DoBlock(); Pass("end", TokenType.KEYWORD); Pass(";", TokenType.SEPERATOR); var ret = new AstWhile(list, condition); Utils.LogDebug("[P] while语句: {0}", ret.ToString()); return(ret); } if (Is("if", TokenType.KEYWORD)) { // if语句 Pass("if", TokenType.KEYWORD); AstExpression condition = DoExpression(); Pass("do", TokenType.KEYWORD); List <AstNode> list = DoBlock(); List <AstNode> elseList = null; if (Is("else", TokenType.KEYWORD)) { // 有else块 Pass("else", TokenType.KEYWORD); elseList = DoBlock(); } Pass("end", TokenType.KEYWORD); Pass(";", TokenType.SEPERATOR); var ret = new AstIf(list, condition, elseList); Utils.LogDebug("[P] if语句: {0}", ret.ToString()); return(ret); } if (Is("return", TokenType.KEYWORD)) { // return语句 Pass("return", TokenType.KEYWORD); AstExpression expr = DoExpression(); var ret = new AstReturn(new List <AstNode>(), expr); Utils.LogDebug("[P] return语句: {0}", ret.ToString()); return(ret); } throw new ParseException(m_scanner.Peek(0), "未知语句"); }
public ReturnInfo(AstReturn returnStatement, AstBlock parentBlock, AstIf?ifStatement) { ReturnStatement = returnStatement; ParentBlock = parentBlock; IfStatement = ifStatement; }
private void CompileReturn(AstReturn node, Syt syt, StringBuilder sb) { var nodeFnc = node.NodeAncestor<AstSubroutine>(); if (nodeFnc.Type.Ktype == Ktype.Void) { if (node.expr != null) throw new Erparse(node, "void method cannot return value"); sb.AppendLine("push constant 0"); } else { if (node.expr == null) throw new Erparse(node, "void method must return value"); CompileRecursive(node.expr, syt, sb); } sb.AppendLine("return"); }