From 295bcef229abe4d6b2635f59e0039ea6f129afd1 Mon Sep 17 00:00:00 2001 From: David Van Horn Date: Fri, 5 Sep 2025 17:17:29 -0400 Subject: [PATCH] Fixing up a bunch of reference; move a86 reference to own chapter. There were a bunch of undefined tags because requiring a86 for-label wasn't actually resolving things correctly, so requiring a86/ast etc. for label fixes that. The a86 reference document has been pulled out to a "chapter" level in the notes. Replaced some uses of the undocumented `Plus` constructor with @. --- www/assignments/3.scrbl | 2 +- www/assignments/4.scrbl | 2 +- www/assignments/5.scrbl | 2 +- www/notes.scrbl | 1 + www/notes/a86.scrbl | 16 +++++++++------- www/notes/abscond.scrbl | 10 +++++----- www/notes/blackmail.scrbl | 9 ++++++--- www/notes/con.scrbl | 2 +- www/notes/dodger.scrbl | 2 +- www/notes/dupe.scrbl | 2 +- www/notes/evildoer.scrbl | 2 +- www/notes/extort.scrbl | 4 ++-- www/notes/fraud.scrbl | 21 +++++++++++---------- www/notes/hoax.scrbl | 2 +- www/notes/hustle.scrbl | 19 ++++++++++--------- www/notes/iniquity.scrbl | 2 +- www/notes/jig.scrbl | 2 +- www/notes/knock.scrbl | 2 +- www/notes/loot.scrbl | 2 +- www/notes/mountebank.scrbl | 2 +- www/notes/mug.scrbl | 19 ++++++++++--------- www/notes/neerdowell.scrbl | 2 +- www/notes/outlaw.scrbl | 2 +- www/notes/utils.rkt | 4 ++-- 24 files changed, 71 insertions(+), 62 deletions(-) diff --git a/www/assignments/3.scrbl b/www/assignments/3.scrbl index 4ac51298..a56cb4a4 100644 --- a/www/assignments/3.scrbl +++ b/www/assignments/3.scrbl @@ -2,7 +2,7 @@ @(require "../defns.rkt") @title[#:tag "Assignment 3" #:style 'unnumbered]{Assignment 3: Primitives, conditionals} -@(require (for-label a86 (except-in racket ...))) +@(require (for-label a86/ast (except-in racket ...))) @bold{Due: @assign-deadline[3]} diff --git a/www/assignments/4.scrbl b/www/assignments/4.scrbl index a52a7ac6..fa331721 100644 --- a/www/assignments/4.scrbl +++ b/www/assignments/4.scrbl @@ -2,7 +2,7 @@ @(require "../defns.rkt") @title[#:tag "Assignment 4" #:style 'unnumbered]{Assignment 4: Case} -@(require (for-label a86 (except-in racket ...))) +@(require (for-label a86/ast (except-in racket ...))) @bold{Due: @assign-deadline[4]} diff --git a/www/assignments/5.scrbl b/www/assignments/5.scrbl index d754d1fd..12192892 100644 --- a/www/assignments/5.scrbl +++ b/www/assignments/5.scrbl @@ -2,7 +2,7 @@ @(require "../defns.rkt") @title[#:tag "Assignment 5" #:style 'unnumbered]{Assignment 5: When and unless} -@(require (for-label a86 (except-in racket ...))) +@(require (for-label a86/ast (except-in racket ...))) @bold{Due: @assign-deadline[5]} diff --git a/www/notes.scrbl b/www/notes.scrbl index 63d97142..48a9efc7 100644 --- a/www/notes.scrbl +++ b/www/notes.scrbl @@ -14,6 +14,7 @@ suggestions for improving the material, @bold{please}, @include-section{notes/1/what-is-a-compiler.scrbl} @include-section{notes/1/ocaml-to-racket.scrbl} @include-section{notes/a86.scrbl} +@include-section[(lib "a86/scribblings/a86.scrbl")] @include-section{notes/abscond.scrbl} @include-section{notes/blackmail.scrbl} @include-section{notes/con.scrbl} diff --git a/www/notes/a86.scrbl b/www/notes/a86.scrbl index d8723a0d..b0607713 100644 --- a/www/notes/a86.scrbl +++ b/www/notes/a86.scrbl @@ -1,7 +1,7 @@ #lang scribble/manual @(require (for-label (except-in racket compile) - a86)) + a86/printer a86/ast a86/interp)) @(require scribble/examples redex/reduction-semantics @@ -121,7 +121,8 @@ of x86-64 to a small, core language (which we call @bold{ to x86 as the last step in the compiler pipeline will be dead simple. -This chapter describes the a86 language. +This chapter describes the a86 language at a high-level. See +@secref["a86_Reference"] for a complete reference manual. @section{Giving x86 a try} @@ -418,9 +419,9 @@ Notice how this generates exactly what you saw in @tt{tri.s}. From here, we can assemble, link, and execute. -We can also, since we have a general purpose programming -language at our disposal in the meta-language, write a -program to do all that for us: +We can also, since we have a general purpose programming language at +our disposal in the meta-language, write a program to do all that for +us, which what the implementors of the a86 library have done: @ex[ (asm-interp (tri 36)) @@ -436,5 +437,6 @@ interactively exploring the a86 language (you can write assembly in a REPL), but also an important tool when it comes time to test the compilers we write. - -@include-section[(lib "a86/scribblings/a86.scrbl")] +There is more to a86, which you can find documented in the +@secref["a86_Reference"], although we try to introduce features of a86 +as we encounter them. \ No newline at end of file diff --git a/www/notes/abscond.scrbl b/www/notes/abscond.scrbl index 30ddd741..a79f3060 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)) +@(require (for-label (except-in racket compile) a86/ast a86/printer)) @(require scribble/examples redex/reduction-semantics redex/pict @@ -34,12 +34,12 @@ @(shell-expand "cat 42.rkt | racket -t compile-stdin.rkt -m > 42.s") -@title[#:tag "Abscond"]{Abscond: a language of numbers} +@(define this-lang "Abscond") +@(define prefix (string-append this-lang "-")) -@(define lang-name "abscond") -@(define prefix (string-append lang-name "-")) +@title[#:tag this-lang]{@|this-lang|: a language of numbers} -@src-code[lang-name] +@src-code[this-lang] @emph{Let's Make a Programming Language!} diff --git a/www/notes/blackmail.scrbl b/www/notes/blackmail.scrbl index 0492230f..facc1c71 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)) +@(require (for-label (except-in racket compile ...) a86/ast a86/printer)) @(require scribble/examples redex/pict "../fancyverb.rkt" @@ -31,9 +31,12 @@ @;{ Have to compile 42.s (at expand time) before listing it } @(shell-expand "cat add1-add1-40.rkt | racket -t compile-stdin.rkt -m > add1-add1-40.s") -@title[#:tag "Blackmail"]{Blackmail: incrementing and decrementing} +@(define this-lang "Blackmail") +@(define prefix (string-append this-lang "-")) -@src-code["blackmail"] +@title[#:tag this-lang]{@|this-lang|: incrementing and decrementing} + +@src-code[this-lang] @emph{Let's Do It Again!} diff --git a/www/notes/con.scrbl b/www/notes/con.scrbl index 5365b33c..eae2ac33 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)) +@(require (for-label (except-in racket compile ...) a86/printer a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/dodger.scrbl b/www/notes/dodger.scrbl index ae85114a..608bf583 100644 --- a/www/notes/dodger.scrbl +++ b/www/notes/dodger.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket ... compile) a86)) +@(require (for-label (except-in racket ... compile) a86/printer a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/dupe.scrbl b/www/notes/dupe.scrbl index 20535ce0..e358c868 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)) +@(require (for-label (except-in racket ... compile) a86/printer a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/evildoer.scrbl b/www/notes/evildoer.scrbl index 1b2a4ecc..f481ef76 100644 --- a/www/notes/evildoer.scrbl +++ b/www/notes/evildoer.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket ... compile) a86)) +@(require (for-label (except-in racket ... compile) a86/printer a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/extort.scrbl b/www/notes/extort.scrbl index 0e4d0c03..47e79036 100644 --- a/www/notes/extort.scrbl +++ b/www/notes/extort.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket ... compile))) +@(require (for-label (except-in racket ... compile) a86/printer a86/ast)) @(require redex/pict racket/runtime-path scribble/examples @@ -202,7 +202,7 @@ encodes an integer, and if it doesn't, it should somehow stop the computation and signal that an error has occurred. The checking part is fairly easy. Our encoding of values, first -discussed in @secref["dupe"], devotes some number of bits within a +discussed in @secref["Dupe"], devotes some number of bits within a value to indicate the type. Checking whether something is an integer involves inspecting just those parts of the value. diff --git a/www/notes/fraud.scrbl b/www/notes/fraud.scrbl index 2ee0f6f0..bb11cd0b 100644 --- a/www/notes/fraud.scrbl +++ b/www/notes/fraud.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket ... compile) a86)) +@(require (for-label (except-in racket ... compile) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples @@ -20,6 +20,7 @@ @(define this-lang "Fraud") +@(define prefix (string-append this-lang "-")) @title[#:tag this-lang]{@|this-lang|: local binding, variables, and binary operations} @@ -29,7 +30,7 @@ @table-of-contents[] -@section{Binding, variables, and binary operations} +@section[#:tag-prefix prefix]{Binding, variables, and binary operations} Let's now consider add a notion of @bold{local binding} and the ability to use @bold{binary operations} to our target @@ -134,7 +135,7 @@ We can model it as a datatype as usual: -@section{Syntax matters} +@section[#:tag-prefix prefix]{Syntax matters} With the introduction of variables comes the issue of expressions that have @bold{free} and @bold{bound variables}. A bound variable is a @@ -210,7 +211,7 @@ relevant part of the input where the variable is bound: @codeblock-include["fraud/parse.rkt"] -@section{Meaning of @this-lang programs} +@section[#:tag-prefix prefix]{Meaning of @this-lang programs} The meaning of @this-lang programs depends on the form of the expression and in the case of integers, increments, and decrements, the meaning is @@ -353,7 +354,7 @@ examples given earlier: ] -@section{Lexical Addressing} +@section[#:tag-prefix prefix]{Lexical Addressing} Just as we did with @seclink["Dupe"], the best way of understanding the forthcoming compiler is to write a ``low-level'' interpreter that @@ -508,7 +509,7 @@ Try to convince yourself that the two version of @racket[interp] compute the same function. -@section{Compiling lets and variables} +@section[#:tag-prefix prefix]{Compiling lets and variables} Suppose we want to compile @racket[(let ((x 7)) (add1 x))]. There are two new forms we need to compile: the @racket[(let ((x ...)) @@ -592,7 +593,7 @@ compute the lexical address of variable references just like the interpreter. The only (trivial) difference is the addresses are given in word offsets, i.e. each binding adds @racket[8] to the address. -@section{Compiling binary operations} +@section[#:tag-prefix prefix]{Compiling binary operations} Binary expressions are easy to deal with at the level of the semantics and interpreter. However things are more complicated at the level of @@ -717,7 +718,7 @@ the same thing by sticking in something that no variable is equal to: With variables, @racket[let]s, and binary operations in place, we can complete the compiler. -@section{The wrinkle of stack alignment} +@section[#:tag-prefix prefix]{The wrinkle of stack alignment} There is a wrinkle that comes from using the stack to hold variable bindings and intermediate results, which has to do with how it @@ -818,7 +819,7 @@ stack-alignment issues, but is otherwise the same as before: @filebox-include[codeblock fraud "compile-ops.rkt"] -@section{Complete @this-lang compiler} +@section[#:tag-prefix prefix]{Complete @this-lang compiler} We can now take a look at the main compiler for expressions. Notice the compile-time environment which is weaved through out the @@ -885,7 +886,7 @@ Finally, we can see the stack alignment issues in action: (show '(add1 #f) '(x)) ] -@section{Correctness} +@section[#:tag-prefix prefix]{Correctness} For the statement of compiler correctness, we must now restrict the domain of expressions to be just @bold{closed expressions}, i.e. those diff --git a/www/notes/hoax.scrbl b/www/notes/hoax.scrbl index 4552fba8..2a606f9d 100644 --- a/www/notes/hoax.scrbl +++ b/www/notes/hoax.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket ... compile) a86)) +@(require (for-label (except-in racket ... compile) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/hustle.scrbl b/www/notes/hustle.scrbl index 66952b61..8fa4100d 100644 --- a/www/notes/hustle.scrbl +++ b/www/notes/hustle.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket ... compile) a86)) +@(require (for-label (except-in racket ... compile) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples @@ -20,6 +20,7 @@ '("main.rkt" "heap.rkt" "unload.rkt" "interp-prims-heap.rkt")) @(define this-lang "Hustle") +@(define prefix (string-append this-lang "-")) @title[#:tag this-lang]{@|this-lang|: heaps and lists} @@ -31,7 +32,7 @@ makes an inundation.} @table-of-contents[] -@section{Inductive data} +@section[#:tag-prefix prefix]{Inductive data} So far all of the data we have considered can fit in a single machine word (64-bits). Well, integers can't, but we truncated them and only @@ -99,7 +100,7 @@ These features will operate like their Racket counterparts: (cons? '#&7) ] -@section{Empty lists can be all and end all} +@section[#:tag-prefix prefix]{Empty lists can be all and end all} While we've introduced pairs, you may wonder what about @emph{lists}? Just as in Racket, lists can be represented by idiomatic uses of @@ -124,7 +125,7 @@ We use the following AST data type for @|this-lang|: ;; type Op2 = ... | 'cons } -@section{Parsing} +@section[#:tag-prefix prefix]{Parsing} Mostly the parser updates for @|this-lang| are uninteresting. The only slight twist is the addition of compound literal datums. @@ -259,7 +260,7 @@ things like @racket[cons], @racket[car], @racket[cons?], etc. -@section{Meaning of @this-lang programs, implicitly} +@section[#:tag-prefix prefix]{Meaning of @this-lang programs, implicitly} To extend our interpreter, we can follow the same pattern we've been following so far. We have new kinds of values such as pairs, boxes, @@ -324,7 +325,7 @@ the interpreter that makes explicit a representation of memory and is able to interpret programs that construct and manipulate inductive data without itself relying on those mechanisms. -@section{Meaning of @this-lang programs, explicitly} +@section[#:tag-prefix prefix]{Meaning of @this-lang programs, explicitly} Let's develop an alternative interpreter that describes constructing inductive data without itself constructing inductive data. @@ -524,7 +525,7 @@ the final answer from the result: @;codeblock-include["hustle/interp.rkt"] -@section{Representing @this-lang values} +@section[#:tag-prefix prefix]{Representing @this-lang values} The first thing do is make another distinction in the kind of values in our language. Up until now, each value could be represented in a @@ -670,7 +671,7 @@ From here, writing the compiler for @racket[box], @racket[unbox], putting together pieces we've already seen such as evaluating multiple subexpressions and type tag checking before doing projections. -@section{A Compiler for @this-lang} +@section[#:tag-prefix prefix]{A Compiler for @this-lang} The compiler for @this-lang is essentially the same as for Fraud, although now with support for the new primitives: @racket[box], @racket[unbox], @@ -788,7 +789,7 @@ printing of proper and improper lists is different: @filebox-include[fancy-c hustle "print.c"] -@section{Correctness} +@section[#:tag-prefix prefix]{Correctness} The statement of correctness for the @|this-lang| compiler is the same as the previous one: diff --git a/www/notes/iniquity.scrbl b/www/notes/iniquity.scrbl index 7e6ebfac..8577f0bb 100644 --- a/www/notes/iniquity.scrbl +++ b/www/notes/iniquity.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket ...))) +@(require (for-label (except-in racket ...) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/jig.scrbl b/www/notes/jig.scrbl index b0e41c76..7f91e65a 100644 --- a/www/notes/jig.scrbl +++ b/www/notes/jig.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket ... compile) a86)) +@(require (for-label (except-in racket ... compile) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/knock.scrbl b/www/notes/knock.scrbl index c8a4fc5b..efd517f3 100644 --- a/www/notes/knock.scrbl +++ b/www/notes/knock.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket compile ...) a86)) +@(require (for-label (except-in racket compile ...) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/loot.scrbl b/www/notes/loot.scrbl index 6ab0db22..501e3176 100644 --- a/www/notes/loot.scrbl +++ b/www/notes/loot.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket compile ...) a86)) +@(require (for-label (except-in racket compile ...) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/mountebank.scrbl b/www/notes/mountebank.scrbl index a0e9f75b..fc06a805 100644 --- a/www/notes/mountebank.scrbl +++ b/www/notes/mountebank.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket compile ...) a86)) +@(require (for-label (except-in racket compile ...) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/mug.scrbl b/www/notes/mug.scrbl index 0f4192c1..00429f99 100644 --- a/www/notes/mug.scrbl +++ b/www/notes/mug.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket compile ...) a86)) +@(require (for-label (except-in racket compile ...) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples @@ -190,12 +190,13 @@ computed at link time. Here is a version of the same program that avoids the @racket[Or] instruction, instead computing that type tagging at link time: + @ex[ (bits->value (asm-interp (seq (Global 'entry) (Label 'entry) - (Lea 'rax (Plus 'hi type-str)) + (Lea 'rax (|@| (+ 'hi type-str))) (Ret) (Data) (Label 'hi) @@ -222,7 +223,7 @@ efficient to evaluate string literals. We could replace the old (Dq (string-length s)) (map Dd (map char->integer (string->list s))) (Text) - (Lea 'rax (Plus l type-str))))) + (Lea 'rax (|@| (+ l type-str)))))) (compile-string "Hello!") @@ -344,11 +345,11 @@ association needs to be maintained explicity. (racketblock ;; String -> Asm (define (compile-string s) - (seq (Lea 'rax (Plus (symbol->label (string->symbol s)) type-str)))) + (seq (Lea 'rax (|@| (+ (symbol->label (string->symbol s)) type-str))))) ) @(ev '(define (compile-string s) - (seq (Lea 'rax (Plus (symbol->label (string->symbol s)) type-str))))) + (seq (Lea 'rax (|@| (+ (symbol->label (string->symbol s)) type-str)))))) So here's how an occurrence of @racket["Hello!"] is compiled: @@ -572,7 +573,7 @@ The key additions are a function for compiling symbol occurrences: (racketblock ;; Symbol -> Asm (define (compile-symbol s) - (seq (Lea 'rax (Plus (symbol->data-label s) type-symb)))) + (seq (Lea 'rax (|@| (+ (symbol->data-label s) type-symb))))) ) Which works as follows: @@ -892,7 +893,7 @@ Extending the interpreter is straightforward: Extending the compiler is more involved, but essentially boils down to doing exactly what the interpreter is doing above: -@filebox-include-fake[codeblock "mug/compile-expr.rkt"]{ +@filebox-include-fake[codeblock "mug/compile-expr.rkt"]|{ ;; Pat CEnv Symbol -> (list Asm Asm CEnv) (define (compile-pattern p cm next) (match p @@ -917,14 +918,14 @@ doing exactly what the interpreter is doing above: cm))] [(PSymb s) (let ((fail (gensym))) - (list (seq (Lea r9 (Plus (symbol->data-label s) type-symb)) + (list (seq (Lea r9 (@ (+ (symbol->data-label s) type-symb))) (Cmp rax r9) (Jne fail)) (seq (Label fail) (Add rsp (* 8 (length cm))) (Jmp next)) cm))])) -} +}| The implementation of string matching uses the @tt{symb_cmp} function from the run-time system, checking whether it returns @racket[0] to diff --git a/www/notes/neerdowell.scrbl b/www/notes/neerdowell.scrbl index c52ffab7..b71dab49 100644 --- a/www/notes/neerdowell.scrbl +++ b/www/notes/neerdowell.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket compile ... struct?) a86)) +@(require (for-label (except-in racket compile ... struct?) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/outlaw.scrbl b/www/notes/outlaw.scrbl index f59781a2..d3c14acc 100644 --- a/www/notes/outlaw.scrbl +++ b/www/notes/outlaw.scrbl @@ -1,6 +1,6 @@ #lang scribble/manual -@(require (for-label (except-in racket compile ... struct?) a86)) +@(require (for-label (except-in racket compile ... struct?) a86/ast)) @(require redex/pict racket/runtime-path scribble/examples diff --git a/www/notes/utils.rkt b/www/notes/utils.rkt index e8c7e8ce..552be1f9 100644 --- a/www/notes/utils.rkt +++ b/www/notes/utils.rkt @@ -24,9 +24,9 @@ (syntax->datum #'fn))))) #`(filebox (link (string-append "code/" fn) (tt fn)) (form #,(datum->syntax #'form s)))))])) -(define ((make-codeblock-include ctxt) fn) ;; Should h be ctxt!? Seems like a bug +(define ((make-codeblock-include ctxt) fn) (filebox (link (string-append "code/" fn) (tt fn)) - (typeset-code #:context #'h (file->string (build-path langs fn))))) + (typeset-code #:context ctxt (file->string (build-path langs fn))))) (define-syntax (filebox-include-fake stx) (syntax-case stx ()