summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--02/README.md8
-rw-r--r--02/in012
-rw-r--r--03/in02404
-rw-r--r--03/in036
4 files changed, 382 insertions, 38 deletions
diff --git a/02/README.md b/02/README.md
index 1a77e50..d09c7ca 100644
--- a/02/README.md
+++ b/02/README.md
@@ -71,6 +71,7 @@ plus six new ones:
- `--` outputs a label's (absolute) address
- `:-` outputs a label's relative address
- `##` outputs a number
+- `~~` outputs 255 zeros
- `//` is for comments
- `\n\n` does nothing (used for spacing)
@@ -172,6 +173,13 @@ since `0x90` gets inserted between the "load immediate" instruction code and the
`\n\n` works identically, and lets us space out code a bit. But be careful:
the number of blank lines must be a multiple of 3!
+In the middle of the label table, you'll find a mysterious `ff` byte. This is at the position for
+the command `~~` (the end of the command table overlaps with the start of the label table).
+This command is just 255 bytes of zeros. If you defined a label whose position in the label
+table overlaps with these zeros, you'd screw up the command. But fortunately, this will only happen
+if you include `\r` or a non-printing character in your label names.
+This is so that you can have big buffers to put data in (like our label table from this compiler).
+
## limitations
Many of the limitations of our previous compilers apply to this one. Also,
diff --git a/02/in01 b/02/in01
index 723c5e3..c7e1e8d 100644
--- a/02/in01
+++ b/02/in01
@@ -16531,7 +16531,6 @@ unused padding
linux doesn't seem to like writing at addresses
past the end of the file.
so we do have to include this
-;cc;cc;cc;cc;cc;cc;cc;cc;cc;cc;cc;cc;cc;cc;cc;cc
;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00
;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00
;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00
@@ -16640,6 +16639,7 @@ so we do have to include this
;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00
;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00
;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00
+;ff;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00 command ~~ outputs 255 bytes of zeros
;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00
;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00
;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00;00
diff --git a/03/in02 b/03/in02
index c8d0cfd..764a0c3 100644
--- a/03/in02
+++ b/03/in02
@@ -1,36 +1,6 @@
-jm
-:-co
-::if
-'i
-'n
-'0
-'3
-00
-::of
-'o
-'u
-'t
-'0
-'3
-00
-::BD
-'B
-'a
-'d
-20
-'d
-'i
-'g
-'i
-'t
-\n
-//
-//
-//
-::co
// open input file
im
---if
+--IF
JA
zA
IA
@@ -39,7 +9,7 @@ im
sy
// open output file
im
---of
+--OF
JA
im
##241.
@@ -50,14 +20,145 @@ DA
im
##2.
sy
+// read next line
+::rl
+im
+--LI
+RA rbp pointer to line buffer
+::rL read loop
im
-##43.
+##3. input file descriptor
+JA
+IR where to read into
+im
+##1.
+DA read 1 byte
+im
+##0. syscall 0 (read)
+sy
+// check how many bytes were read
+BA
+im
+##1.
+jg if 1 greater than number of bytes read
+:-ef end of file
+BR
+DR pointer to character we just read
+im
+##1.
++B
+RA
+BD
+zA
+lb
+BA
+im
+##a.
+jn
+:-rL keep looping
+// we now have a full line from the file in ::LI
+// the pointer to the end of the line is in rbp
+// look at the first character
+im
+--LI
+BA
+zA
+lb
BA
im
---hx
-cl
+##3b. ascii ';'
+je if it's a comment,
+:-rl jump back to read the next line
+im
+##a. ascii '\n'
+je if it's a blank line,
+:-rl jump back to read the next line
+im
+##3a. ascii ':'
+je
+:-ld label definition
jm
:-ex
+// label definition
+::ld
+// first, check if we're on the second pass.
+im
+--2P
+BA
+zA
+lb
+BA
+zA
+jn if on second pass,
+:-rl ignore this (read next line)
+// first get current address
+im
+##4. output fd
+JA
+zA
+IA offset = 0
+im
+##1. whence = SEEK_CUR
+DA
+im
+##8. syscall 8 = lseek
+sy
+BA
+im
+##400000. address of start of file
++B
+DA put current address in rdx
+im
+--L$
+BA
+lq
+JA
+im
+--LI
+IA
+// copy from rsi to rdi until a newline is reached
+::lc label copy
+BI
+zA
+lb
+BA
+// store in rdi
+AJ
+xc
+sb
+CA put byte in rcx
+// increment rdi,rsi
+BJ
+im
+##1.
++B
+JA
+BI
+im
+##1.
++B
+IA
+BC
+im
+##a.
+jn if byte we read wasn't a newline,
+:-lc keep looping
+// store address of label in rdi
+AD
+BJ
+sd
+// increment rdi by 4, because we stored an 4-byte number
+im
+##4.
++B
+JA
+// now set L$ to rdi
+im
+--L$
+BA
+AJ
+sq
+cc
//
//
// exit with code in rax
@@ -112,3 +213,236 @@ im
##1.
jm
:-ex
+// end of file
+::ef
+// TODO: second pass
+zA exit code 0
+jm
+:-ex
+::2P second pass?
+00
+::IF input file name
+'i
+'n
+'0
+'3
+00
+::OF output file name
+'o
+'u
+'t
+'0
+'3
+00
+::BD bad digit error message
+'B
+'a
+'d
+20
+'d
+'i
+'g
+'i
+'t
+\n
+::LI line buffer
+~~
+::L$ end of current label list
+--LB
+::LB labels
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
+~~
diff --git a/03/in03 b/03/in03
index 87732c8..1fef9b8 100644
--- a/03/in03
+++ b/03/in03
@@ -1,9 +1,11 @@
-J=d0
+:lbab
+;J=d0
+
A=d60
syscall
:label
B+=J
B<<=9
B-=J
-J?<B-label
+J?<B:label