예제 #1
0
 public void WritePopIdentifier(Identifier identifier)
 {
     if (identifier.Kind == Kind.Var)
     {
         this.WritePop(Segment.Local, identifier.Index);
     }
     else if (identifier.Kind == Kind.Arg)
     {
         this.WritePop(Segment.Argument, identifier.Index);
     }
     else if (identifier.Kind == Kind.Static)
     {
         // p.131 static variables are shared by all functions in the same vm file.
         this.WritePop(Segment.Static, identifier.Index);
     }
     else if (identifier.Kind == Kind.Field)
     {
         this.WritePop(Segment.This, identifier.Index);
     }
 }
예제 #2
0
 public void WritePushIdentifier(Identifier identifier)
 {
     // dont think this is necessary see page 136
     // ithink the vm handles local variables - then you just "pop local 1" etc to use them
     if(identifier.Kind == Kind.Var)
     {
         this.WritePush(Segment.Local, identifier.Index);
     }
     else if(identifier.Kind == Kind.Arg)
     {
         this.WritePush(Segment.Argument, identifier.Index);
     }
     else if (identifier.Kind == Kind.Static)
     {
         // p.131 static variables are shared by all functions in the same vm file.
         this.WritePush(Segment.Static, identifier.Index);
     }
     else if (identifier.Kind == Kind.Field)
     {
         this.WritePush(Segment.This, identifier.Index);
     }
 }
예제 #3
0
        /// <summary>
        /// Builds an identifer obj and also identifier.
        /// Only use this method for compiling class variables and subroutine variables
        /// Not parameter lists!
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <returns></returns>
        private void CompileClassOrSubRoutineLevelVarDeclarationAndAddToSymbolTable(XElement parent)
        {
            Pair<string, string> kindToken = this.CompileTerminal(parent);
            Pair<string, string> typeToken = this.CompileTerminal(parent);
            Pair<string, string> nameToken = this.classTokens.Pop();

            Identifier identifier = new Identifier();
            identifier.Kind = (Kind)Enum.Parse(typeof(Kind), kindToken.Value2, true);
            identifier.Name = nameToken.Value2;
            identifier.Type = typeToken.Value2;
            identifier.Usage = IdentifierUsage.Defined;

            this.symbolTable.Define(identifier);

            this.CreateIdentifierElementWithAttributes(parent, identifier, nameToken);

            // check for comma, i.e comma separated list of variables
            if (this.classTokens.Peek().Value2 == ",")
            {
                // compile the comma
                this.CompileTerminal(parent);

                while (this.classTokens.Peek().Value2 != ";")
                {
                    Pair<string, string> commaSeparatedIdentifierToken = this.classTokens.Pop();

                    // set the next identifier in comma separated list to same type kind etc as fisrt
                    Identifier commaSeparatedIdentier = new Identifier();
                    commaSeparatedIdentier.Kind = identifier.Kind;
                    commaSeparatedIdentier.Type = identifier.Type;
                    commaSeparatedIdentier.Name = commaSeparatedIdentifierToken.Value2;
                    commaSeparatedIdentier.Usage = IdentifierUsage.Defined;

                    this.symbolTable.Define(commaSeparatedIdentier);

                    this.CreateIdentifierElementWithAttributes(parent, commaSeparatedIdentier, commaSeparatedIdentifierToken);

                    if (this.classTokens.Peek().Value2 == ",")
                    {
                        // compile comma
                        this.CompileTerminal(parent);
                    }
                }
            }

            // compile the ending ;
            this.CompileTerminal(parent);
        }
예제 #4
0
 private void CreateIdentifierElementWithAttributes(XElement parent, Identifier identifier, Pair<string, string> identifierToken)
 {
     // quick hack with the category - if the identifier is not a method or a class name the category will be the same as kind
     // see page p243's confusing spec.
     parent.Add(new XElement(identifierToken.Value1, identifierToken.Value2,
                       new XAttribute("type", identifier.Type),
                       new XAttribute("usage", identifier.Usage),
                       new XAttribute("kind", identifier.Kind),
                       new XAttribute("category", identifier.Kind),
                       new XAttribute("index", identifier.Index)));
 }
예제 #5
0
        /// <summary>
        /// Compiles the parameter list of a method/function/constructor
        /// </summary>
        /// <param name="parentElement">The parent element.</param>
        private void CompileParameterList(XElement parentElement)
        {
            // add param list as child
            XElement parameterList = new XElement("parameterList");
            parentElement.Add(parameterList);

            // add the params

            while (this.classTokens.Peek().Value2 != ")")
            {
                Pair<string, string> token = null;

                Identifier identifier = new Identifier();
                identifier.Kind = Kind.Arg;
                for (int i = 0; i <= 2; i++)
                {
                    if (this.classTokens.Peek().Value2 != ")")
                    {
                        token = this.classTokens.Pop();
                        if (i == 0)
                        {
                            identifier.Type = token.Value2;
                            parameterList.Add(new XElement(token.Value1, token.Value2));
                        }
                        else if (i == 1)
                        {
                            identifier.Name = token.Value2;
                            identifier.Usage = IdentifierUsage.Defined;
                            this.symbolTable.Define(identifier);
                            this.CreateIdentifierElementWithAttributes(parameterList, identifier, token);
                        }
                        else if (i == 2)
                        {
                            //add the comma
                            parameterList.Add(new XElement(token.Value1, token.Value2));
                        }
                    }
                }
            }
        }
예제 #6
0
            public readonly Identifier type;         // identifier (variable / method / operator / etc...)

            public Piece(string name, Identifier type)
            {
                this.name = name;
                this.type = type;
            }
예제 #7
0
        /// <summary>
        /// Compiles the parameter list of a method/function/constructor
        /// </summary>
        /// <param name="parentElement">The parent element.</param>
        private void CompileParameterList(bool isInstanceMethod)
        {
            // add the params

            if (isInstanceMethod)
            {
                Identifier hiddenThisArg = new Identifier();
                hiddenThisArg.Type = "this";
                hiddenThisArg.Name = "this";
                hiddenThisArg.Usage = IdentifierUsage.Defined;
                hiddenThisArg.Kind = Kind.Arg;
                this.symbolTable.Define(hiddenThisArg);
            }

            while (this.classTokens.Peek().Value2 != ")")
            {
                Pair<string, string> token = null;

                Identifier identifier = new Identifier();
                identifier.Kind = Kind.Arg;
                for (int i = 0; i <= 2; i++)
                {
                    if (this.classTokens.Peek().Value2 != ")")
                    {
                        token = this.classTokens.Pop();
                        if (i == 0)
                        {
                            identifier.Type = token.Value2;
                        }
                        else if (i == 1)
                        {
                            identifier.Name = token.Value2;
                            identifier.Usage = IdentifierUsage.Defined;
                            this.symbolTable.Define(identifier);
                        }
                        else if (i == 2)
                        {
                            //add the comma - relic from xml output
                            //parameterList.Add(new XElement(token.Value1, token.Value2));
                        }
                    }
                }
            }
        }