예제 #1
0
        private IEnumerable <AstSubroutine> ParseRgSubroutine()
        {
            while (FCurrent(Ktoken.Constructor) || FCurrent(Ktoken.Function) || FCurrent(Ktoken.Method))
            {
                var subroutine = new AstSubroutine();

                subroutine.Ksubroutine =
                    FCurrent(Ktoken.Constructor) ? Ksubroutine.Constructor :
                    FCurrent(Ktoken.Function) ? Ksubroutine.StaticFunction :
                    Ksubroutine.MemberFunction;

                NextToken();

                subroutine.Type = Accept(Ktoken.Void) ? new AstType {
                    Ktype = Ktype.Void, stType = "void"
                } : ParseType();

                subroutine.StName  = Expect(Ktoken.Id).St;
                subroutine.RgParam = ParseParamDefList().ToArray();

                Expect(Ktoken.Lbrace);
                subroutine.RgVarDeclDecl = ParseVarDeclList().ToArray();
                subroutine.Body          = ParseStatementList().ToArray();
                Expect(Ktoken.Rbrace);

                yield return(subroutine);
            }
        }
예제 #2
0
        private void CompileSubroutine(AstSubroutine node, Syt syt, StringBuilder sb)
        {
            var sytFunc = new Syt(syt);

            sb.AppendLine("function {0} {1}".StFormat(node.FQName(), node.RgVarDeclDecl.Length));

            if (node.Ksubroutine == Ksubroutine.Constructor)
            {
                var csize = node.NodeAncestor <AstClass>().RgclassDecl.Length;
                sb.AppendLine("push constant {0}".StFormat(csize));
                sb.AppendLine("call Memory.alloc 1");
                sb.AppendLine("pop pointer 0");
            }
            else if (node.Ksubroutine == Ksubroutine.MemberFunction)
            {
                sb.AppendLine("push argument 0");
                sb.AppendLine("pop pointer 0");
                sytFunc.Add(Ksyte.Arg, "this", node.NodeAncestor <AstClass>().StName);
            }

            CompileRecursive(node.RgParam, sytFunc, sb);
            CompileRecursive(node.RgVarDeclDecl, sytFunc, sb);

            CompileRecursive(node.Body, sytFunc, sb);

            if (node.Type.Ktype == Ktype.Void)
            {
                sb.AppendLine("push constant 0");
                sb.AppendLine("return");
            }
        }