Beispiel #1
0
        //sub-body ::= '{' <local-var-decl>* <statement>* '}'
        private void ParseSubBody()
        {
            Match(new Token(TokenType.Symbol, "{"));
            ParseLocalVarDecls();

            //Notify the code generator -- now _currentSub has full information
            //about the subroutine's parameters and local variables.
            switch (_currentSub.Kind)
            {
            case SubroutineKind.Constructor:
                _codeGenerator.ConstructorDeclaration(_currentSub);
                break;

            case SubroutineKind.Function:
                _codeGenerator.FunctionDeclaration(_currentSub);
                break;

            case SubroutineKind.Method:
                _codeGenerator.MethodDeclaration(_currentSub);
                break;

            default:
                ThrowCompilationException("Invalid value for _currentSub.Kind: " + _currentSub.Kind);
                break;
            }

            ParseStatements();

            //Make sure the method ends with 'return'. If the method is void,
            //return an an arbitrary value. This could be left to the CG's
            //discretion as well.
            if (!_wasLastStatementReturn)
            {
                if (_currentSub.ReturnType == "void")
                {
                    _codeGenerator.IntConst(0);
                    _codeGenerator.Return();
                    //NOTE: This is a deviation from the original Jack syntax,
                    //in which all methods must end with a 'return' statement,
                    //even void methods.
                }
                else
                {
                    ThrowCompilationException("Non-void method must return a value");
                }
            }
            _wasLastStatementReturn = false;
            _codeGenerator.EndSubroutine();

            //This is the last thing we do because it may advance us to the
            //next line, but we want accurate compilation errors.
            Match(new Token(TokenType.Symbol, "}"));
        }