11. Symbols II
Helper Functions
The parser produces (keyword "int")
but you just want "int"
. Write
a function unwrap
to extract the strings from keyword
and
identifier
.
(check-expect (unwrap '(keyword "int"))
"int")
(check-expect (unwrap '(identifier "nums"))
"nums")
To help find bugs later, you can issue warning if you don’t unwrap anything.
(displayln (format "warning: did not unwrap ~a" var))
You can also use the shortcut ~a
function.
The recursive version of this unwrap-recursive
applies unwrap
recursively every time it finds a list?
. Using one of the examples below:
(check-expect (unwrap-recursive VDex)
'(varDec "int" "a" "b"))
Loading Symbols
Use a single variable to represent an entire symbol table. If you want
to hold more than one piece of information, make it a struct or a list.
On this page, we will use all-symbols
to be the variable that holds
the symbol table.
Write a function to update the symbol table based on one line of Jack code.
(update-symbol-table! all-symbols code-line)
Examples:
-
Three variables added to the symbol table in the “class” scope. The variables
"x"
,"y"
, and"z"
are numbered 0, 1, and 2 in thethis
segment.(define cv1 '(classVarDec (keyword "field") (keyword "int") (identifier "x") (identifier "y") (identifier "z")))
-
A single variable “light” is added to the class scope. It is in the
static
scope and is variable number 0.(define cv2 '(classVarDec (keyword "static") (keyword "boolean") (identifier "light")))
-
Variables in a parameterList should go into the
args
segment.(define PLex '(parameterList ((keyword "int") (identifier "n")) ((keyword "boolean") (identifier "bv"))))
-
Variables in a varDec should go into the
local
segment.(define VDex '(varDec (keyword "int") (identifier "a") (identifier "b")))
Notes
The list '(varDec (keyword "int") (identifier "cnt"))
is internally
represented by (list 'varDec (list 'keyword "int") (list 'identifier "cnt"))
. Use the latter form if using match
.
Ways to Match
Here are some ideas for matching.
-
Write everything out with lists.
(match '(keyword "int") [(list 'keyword type)) type]) => "int"
-
Use quasiquote and unquote (the backwards single quote and the comma).
(match '(keyword "int") [`(keyword ,type) type]) => "int"
-
Ellipses make a list of 0 or more repetitions of the preceding pattern.
(match VDex [`(varDec ,type ,ids ...) ids]) => (list (identifier "a") (identifier "b"))
-
Unwrapping everything before matching is also a viable strategy.
(define uPL (unwrap-recursive PLex)) (match uPL [`(parameterList (t1 v1) (t2 v2)) (list t1 t2)]) => (list "int" "boolean")