Clarifying Instructions for Stage 1: Symbol Table Best Practice?

classic Classic list List threaded Threaded
4 messages Options
jrd
Reply | Threaded
Open this post in threaded view
|

Clarifying Instructions for Stage 1: Symbol Table Best Practice?

jrd
(Apologies if this question has been covered in prior posts, but I haven't quite found sufficient feedback in to clarify this concept.)

Assumption #1:

On one hand, it seems to me that the correct way to implement the SymbolTable module is to create a single "Class-scope symbol table" at run time.  That "class scope symbol table" is initialized and never destroyed.  However, in comparison, a given "Subroutine-scope symbol table" within a Class/.jack file is only created (and then destroyed immediately thereafter) when its corresponding subroutine (function/method/constructor) is CALLED within the program flow at run time.  This would generally be via a "do" or "let" statement.

* Is Assumption #1 correct?

On the other hand, if Assumption #1 is correct, that seems to contradict the instructions on Page 243 of Stage 1:

"...whenever an identifier is encountered in the program...have your analyzer output the following information as part of its XML output...(identifier category, defined or used, variable of four kinds w/running index)"  

In order for me to implement these directions properly in conjunction with parsing/XML output, I found that I needed to create "Subroutine-scope symbol tables" at those points where subroutines were initially declared (but not necessarily called).  That was the only way to insure that all parsed identifiers within a program were generated an associated XML tag with the requested info from the book.  

Hypothetically, a good example of the issue I'm trying to explain would be a method "foo" declared as part of a class - but never actually called during program flow.  For "foo," it would seem one needs to create its "Subroutine-scope symbol table" at runtime at the point where "foo" is declared (since "foo" is never called within the program flow) to make sure all foo's contained VAR/ARGS/identifiers receive an annotated XML tag - as the book requests.

** However, creating "Subroutine-scope symbol tables" during subroutine declarations (as opposed to during subroutine calls) doesn't seem compliant with the book's suggested protocol (leading to my Assumption #1 above).

Thoughts pls?  Am I doing something wrong here?  Can you pls clarify?

Thx.

- JRD

Reply | Threaded
Open this post in threaded view
|

Re: Clarifying Instructions for Stage 1: Symbol Table Best Practice?

cadet1620
Administrator
jrd wrote
(Apologies if this question has been covered in prior posts, but I haven't quite found sufficient feedback in to clarify this concept.)

Assumption #1:

On one hand, it seems to me that the correct way to implement the SymbolTable module is to create a single "Class-scope symbol table" at run time.  That "class scope symbol table" is initialized and never destroyed.  However, in comparison, a given "Subroutine-scope symbol table" within a Class/.jack file is only created (and then destroyed immediately thereafter) when its corresponding subroutine (function/method/constructor) is CALLED within the program flow at run time.  This would generally be via a "do" or "let" statement.

* Is Assumption #1 correct?
This is not correct. The function symbol tables have nothing to do with function calling.
On the other hand, if Assumption #1 is correct, that seems to contradict the instructions on Page 243 of Stage 1:

"...whenever an identifier is encountered in the program...have your analyzer output the following information as part of its XML output...(identifier category, defined or used, variable of four kinds w/running index)"  

In order for me to implement these directions properly in conjunction with parsing/XML output, I found that I needed to create "Subroutine-scope symbol tables" at those points where subroutines were initially declared (but not necessarily called).  That was the only way to insure that all parsed identifiers within a program were generated an associated XML tag with the requested info from the book.  
This is correct. The function (and class) symbol tables are only used during compilation. The function symbol table keeps track of the name and type of the function's arguments and var variables. When you get to code generation in stage 2, the function symbol table is where you will get the index values for VM arg and local segments.
Hypothetically, a good example of the issue I'm trying to explain would be a method "foo" declared as part of a class - but never actually called during program flow.  For "foo," it would seem one needs to create its "Subroutine-scope symbol table" at runtime at the point where "foo" is declared (since "foo" is never called within the program flow) to make sure all foo's contained VAR/ARGS/identifiers receive an annotated XML tag - as the book requests.

** However, creating "Subroutine-scope symbol tables" during subroutine declarations (as opposed to during subroutine calls) doesn't seem compliant with the book's suggested protocol (leading to my Assumption #1 above).

Thoughts pls?  Am I doing something wrong here?  Can you pls clarify?

Thx.

- JRD
As a quick example for how the function symbol table will be used, consider this function
    void function foo(int i, Array a)
        {
        var String s;
        var bool b;
        ...

After parsing the second var statement, the symbol table will be
    name  kind  type  index
      a   arg   Array   1
      b   var   bool    1
      i   arg   int     0
      s   var   String  0
This information will then be used by your code generator when it needs to reference the function's locals. For example, the VM code for "let b = i" would be
    push argunemt 0
    pop  local 1

--Mark
jrd
Reply | Threaded
Open this post in threaded view
|

Re: Clarifying Instructions for Stage 1: Symbol Table Best Practice?

jrd
Thank you.  That is very helpful and clarifies situation.

Just to make sure I understand - extending your example below - wouldn't it therefore be correct to say?

1) As soon as the compiler parses to the end of function foo and then encounters function foo2, the Subroutine (foo) Symbol Table is destroyed and a new Subroutine (foo2) Symbol Table is created.  Correct?

2) Furthermore, although there is a now a subroutine call for foo3 within foo (note the additional "do" statement I added below), a Subroutine (foo3) Symbol Table would NOT be created/destroyed at that time.  Rather, Subroutine (foo3) Symbol Table will have been created for its code generation purpose elsewhere in the program, where foo3 is originally declared and the point where the parser first encounters that declaration.  Correct?

void function foo(int i, Array a)
        {
        var String s;
        var bool b;
        ...
        do foo3(x, y);
        }

void function foo2(int j, Array b)
        {
        var String t;
        var bool c;
        ...
        }

Thx again for expedited response.

- JRD
Reply | Threaded
Open this post in threaded view
|

Re: Clarifying Instructions for Stage 1: Symbol Table Best Practice?

cadet1620
Administrator
jrd wrote
Thank you.  That is very helpful and clarifies situation.

Just to make sure I understand - extending your example below - wouldn't it therefore be correct to say?

1) As soon as the compiler parses to the end of function foo and then encounters function foo2, the Subroutine (foo) Symbol Table is destroyed and a new Subroutine (foo2) Symbol Table is created.  Correct?
Correct.
2) Furthermore, although there is a now a subroutine call for foo3 within foo (note the additional "do" statement I added below), a Subroutine (foo3) Symbol Table would NOT be created/destroyed at that time.  Rather, Subroutine (foo3) Symbol Table will have been created for its code generation purpose elsewhere in the program, where foo3 is originally declared and the point where the parser first encounters that declaration.  Correct?
Also correct.
void function foo(int i, Array a)
        {
        var String s;
        var bool b;
        ...
        do foo3(x, y);
        }

void function foo2(int j, Array b)
        {
        var String t;
        var bool c;
        ...
        }

Thx again for expedited response.

- JRD