JULI Internal Organization
Phase B: Lexical Analysis
Lexer (lexer.h)
1. Get characters from the Input Buffer Module
2. Eliminates comments
3. Preprocessing: includes files using the "$" command
4. Identifies indentation
ALLOCATING AND FREEING MEMORY
- When allocating memory, always use JALLOC
- When freeing memory, always use JFREE
- The only exception to these rules should be in the "memtrack.h"
module.
ALLOCATING A "Symbol"
- If a module allocates a Symbol and does not delete that Symbol
itself, each allocated Symbol should be added to the end-of-
program deletion list using: scope_add_symbol_to_list (Symbol*)
- If a module allocates a Symbol and deletes the Symbol itself,
the above may be ignored.
ROUTINES
- There are 3 runtime stacks operating concurrently for routines:
Call Stack: Used to hold the return addresses when a routine
is called.
Return Stack: Used to pass parameters to the callee and to
return the return value to the caller.
Local Stack: Used to save local variables and intermediate
variables prior to routine calling and then to
restore those variables at exit.
- Stack Manipulation Order (Routine Call)
pushl a {{ push local vars to LocalStack
pushl b {{ "
pushl c {{ "
pushl T1 {{ push temporaries to LocalStack
pushl T2 {{ "
pushl T3 {{ "
pushr z {{ push parameters to ReturnStack
pushr y {{ "
pushr x {{ "
call test {{ push return address to CallStack, go to "test"
popl T3 {{ pop temporaries from LocalStack
popl T2 {{ "
popl T1 {{ "
popl c {{ pop local vars from LocalStack
popl b {{ "
popl a {{ "
popr r {{ pop returned value from Return Stack
- Stack Manipulation Order (Routine Body)
Example Juliet Code:
rout test:int (x:int, y:int, z:int)
(body)
return r
Corresponding Romeo Code:
popr x {{ pop arguments from ReturnStack
popr y {{ "
popr z {{ "
(body) {{ body of routine
pushr r {{ push return value to ReturnStack
ret {{ go to location popped off of CallStack