From 2ee93444ec38032e5e905f748a43fddd7394b2a9 Mon Sep 17 00:00:00 2001 From: David Van Horn Date: Tue, 16 Sep 2025 10:57:11 -0400 Subject: [PATCH 1/3] Slight tweak to assign 3 write-up. --- www/assignments/3.scrbl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/www/assignments/3.scrbl b/www/assignments/3.scrbl index 6ed3d2c3..725d49a6 100644 --- a/www/assignments/3.scrbl +++ b/www/assignments/3.scrbl @@ -140,7 +140,9 @@ Implement the @racket[cond] expression form as described earlier. To do this, you should: @itemlist[ -@item{Study @tt{ast.rkt} to add appropriate AST nodes.} +@item{Study @tt{ast.rkt} to understand how these new forms of +expression are represented.} + @item{Update @tt{interp-prim.rkt} and @tt{interp.rkt} to correctly interpret @racket[cond] expressions.} @item{Make examples of @racket[cond]-expressions and potential translations of them From 7ba71c4c5639dec172a5e1410b4f52b803a7dbc0 Mon Sep 17 00:00:00 2001 From: David Van Horn Date: Thu, 18 Sep 2025 20:00:19 -0400 Subject: [PATCH 2/3] Fix up for-label in Dupe notes. --- www/notes/dupe.scrbl | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/www/notes/dupe.scrbl b/www/notes/dupe.scrbl index e358c868..cd8bb9ce 100644 --- a/www/notes/dupe.scrbl +++ b/www/notes/dupe.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket ... compile) a86/printer a86/ast)) +@(require (for-label (except-in racket ... compile) a86/printer a86/ast a86/registers a86/interp)) @(require redex/pict racket/runtime-path scribble/examples @@ -271,14 +271,14 @@ To make the problem concrete, consider the Dupe expression that moves this value into the @racket[rax] register: @ex[ -(Mov 'rax 5)] +(Mov rax 5)] But now consider @racket[#t]. The compiler needs to emit an instruction that moves ``@racket[#t]'' into @racket[rax], but the @racket[Mov] instruction doesn't take booleans: @ex[ -(eval:error (Mov 'rax #t))] +(eval:error (Mov rax #t))] We have to move some 64-bit integer into @racket[rax], but the question is: which one? @@ -289,12 +289,12 @@ C tradition and say @racket[#f] will be @racket[0] and @racket[#t] will be 1. So compiling @racket[#t] would emit: @ex[ -(Mov 'rax 1)] +(Mov rax 1)] And compiling @racket[#f] would emit: @ex[ -(Mov 'rax 0)] +(Mov rax 0)] Seems reasonable. Well except that the specification of @racket[if] in our interpreter requires that @racket[(if 0 1 2)] evaluates to @@ -925,12 +925,12 @@ Let's consider some simple examples: @item{@racket[42]: this should compile just like integer literals before, but needs to use the new representation, i.e. the compiler -should produce @racket[(Mov 'rax #,(value->bits 42))], which is +should produce @racket[(Mov rax #,(value->bits 42))], which is @racket[42] shifted to the left @racket[#,int-shift]-bit.} -@item{@racket[#f]: this should produce @racket[(Mov 'rax #,(value->bits #f))].} +@item{@racket[#f]: this should produce @racket[(Mov rax #,(value->bits #f))].} -@item{@racket[#t]: this should produce @racket[(Mov 'rax #,(value->bits #t))].} +@item{@racket[#t]: this should produce @racket[(Mov rax #,(value->bits #t))].} @item{@racket[(add1 _e)]: this should produce the instructions for @racket[_e], which when executed would leave @emph{the encoding of the From a6e3c20c709b8e6038fbf7096e1aec146ca7a053 Mon Sep 17 00:00:00 2001 From: David Van Horn Date: Thu, 18 Sep 2025 20:07:18 -0400 Subject: [PATCH 3/3] Touch up labels and registers in Abscond, Blackmail, and Con notes. --- www/notes/abscond.scrbl | 4 ++-- www/notes/blackmail.scrbl | 12 ++++++------ www/notes/con.scrbl | 16 ++++++++-------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/www/notes/abscond.scrbl b/www/notes/abscond.scrbl index a79f3060..ce9a20b2 100644 --- a/www/notes/abscond.scrbl +++ b/www/notes/abscond.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket compile) a86/ast a86/printer)) +@(require (for-label (except-in racket compile) a86/ast a86/printer a86/registers)) @(require scribble/examples redex/reduction-semantics redex/pict @@ -429,7 +429,7 @@ So the AST representation of our example is: @racketblock[ (list (Label 'entry) - (Mov 'rax 42) + (Mov rax 42) (Ret)) ] diff --git a/www/notes/blackmail.scrbl b/www/notes/blackmail.scrbl index facc1c71..5cd8d4df 100644 --- a/www/notes/blackmail.scrbl +++ b/www/notes/blackmail.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket compile ...) a86/ast a86/printer)) +@(require (for-label (except-in racket compile ...) a86/ast a86/printer a86/registers a86/interp)) @(require scribble/examples redex/pict "../fancyverb.rkt" @@ -238,7 +238,7 @@ Just as we did with Abscond, let's approach writing the compiler by first writing an example. Suppose we want to compile @racket[(add1 (add1 40))]. We already know -how to compile the @racket[40]: @racket[(Mov 'rax 40)]. To do the +how to compile the @racket[40]: @racket[(Mov rax 40)]. To do the increment (and decrement) we need to know a bit more a86. In particular, the @racket[Add] instruction is relevant. It increments the contents of a register by some given amount. @@ -250,9 +250,9 @@ So, a program that adds 1 twice to 40 looks like: (asm-interp (prog (Global 'entry) (Label 'entry) - (Mov 'rax 40) - (Add 'rax 1) - (Add 'rax 1) + (Mov rax 40) + (Add rax 1) + (Add rax 1) (Ret)))] @@ -275,7 +275,7 @@ recursion, much like the interpreter. In the case of a unary primitive @racket[(Prim1 p e)], the compiler first compiles the subexpression @racket[e] obtaining a list of instructions that, when executed, will place @racket[e]'s value in the -@racket['rax] register. After that sequence of instructions, the +@racket[rax] register. After that sequence of instructions, the compiler emits instructions for carrying out the operation @racket[p], defering to a helper function @racket[compile-op1]: diff --git a/www/notes/con.scrbl b/www/notes/con.scrbl index eae2ac33..bb65e94a 100644 --- a/www/notes/con.scrbl +++ b/www/notes/con.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket compile ...) a86/printer a86/ast)) +@(require (for-label (except-in racket compile ...) a86/printer a86/ast a86/registers)) @(require redex/pict racket/runtime-path scribble/examples @@ -191,8 +191,8 @@ We already know how to compile the @racket[8], @racket[2], and What needs to happen? @itemlist[ -@item{Execute the code for @racket[8] leaving the result in @racket['rax],} -@item{check whether @racket['rax] holds zero,} +@item{Execute the code for @racket[8] leaving the result in @racket[rax],} +@item{check whether @racket[rax] holds zero,} @item{if it does, execute the code for @racket[2],} @item{if it doesn't, execute the code for @racket[3].} ] @@ -219,10 +219,10 @@ In total, the code for this example would look like: @racketblock[ (let ((l0 (gensym)) (l1 (gensym))) - (list (Mov 'rax 8) - (Cmp 'rax 0) + (list (Mov rax 8) + (Cmp rax 0) (Je l0) - (Mov 'rax 3) + (Mov rax 3) (Jmp l1) (Label l0) (Mov rax 2) @@ -232,7 +232,7 @@ In total, the code for this example would look like: @section{A Compiler for Con} -Notice that the @racket[(Mov 'rax 8)], @racket[(Mov rax 3)] and +Notice that the @racket[(Mov rax 8)], @racket[(Mov rax 3)] and @racket[(Mov rax 2)] parts are just the instructions generated by compiling @racket[8], @racket[2] and @racket[3]. Generalizing from this, we arrive at the following code for the compiler: @@ -241,7 +241,7 @@ this, we arrive at the following code for the compiler: (let ((l0 (gensym 'if)) (l1 (gensym 'if))) (seq (compile-e e1) - (Cmp 'rax 0) + (Cmp rax 0) (Je l0) (compile-e e3) (Jmp l1)