commit 38057c4b2d3ec3ec77dcd059a98b071da2e1e6fa
parent 94efeaba0d5875aa55fb33da77d7accc402aa4e8
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Tue, 7 Jun 2022 07:23:24 -0400
cc: refactor code generation
Remove ops and ship the IDing to ast.fs and the generation part to gen.fs.
It makes more sense this way.
Also, made code generation recursive. I'm going to need this for me next commit.
Diffstat:
5 files changed, 81 insertions(+), 98 deletions(-)
diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs
@@ -3,6 +3,38 @@
\ An abstract syntax tree, AST, is a hierarchical structure of nodes
\ representing the nodes found in a C source file. See tree.fs for structure.
+\ Unary operators
+\ ID Sym Name
+\ 0 - Negate
+\ 1 ~ Complement
+\ 2 ! Not
+
+3 value UOPSCNT
+create uopssyms ," -~!?"
+
+: uopid ( ta tl -- opid? f )
+ 1 = if c@ uopssyms UOPSCNT [c]? dup 0< if drop 0 else 1 then
+ else drop 0 then ;
+: uopchar ( opid -- c ) UOPSCNT max uopssyms + c@ ;
+
+\ Binary operators
+\ ID Sym Name
+\ 0 + Addition
+\ 1 - Subtraction
+\ 2 * Multiplication
+\ 3 / Division
+
+4 value BOPSCNT
+create bopssyms ," +-*/?"
+\ binary ops precedence. lower means more precedence
+create bopsprectbl 1 c, 1 c, 0 c, 0 c, $ff c,
+
+: bopid ( ta tl -- opid? f )
+ 1 = if c@ bopssyms BOPSCNT [c]? dup 0< if drop 0 else 1 then
+ else drop 0 then ;
+: bopchar ( opid -- c ) BOPSCNT min bopssyms + c@ ;
+: bopprec ( opid -- precedence ) BOPSCNT min bopsprectbl + c@ ;
+
\ AST node types
11 value ASTIDCNT
1 value AST_UNIT
diff --git a/fs/cc/cc.fs b/fs/cc/cc.fs
@@ -3,7 +3,6 @@ f<< wordtbl.fs
f<< asm.fs
f<< cc/tok.fs
f<< cc/tree.fs
-f<< cc/gen.fs
-f<< cc/ops.fs
f<< cc/ast.fs
+f<< cc/gen.fs
f<< cc/cc1.fs
diff --git a/fs/cc/cc1.fs b/fs/cc/cc1.fs
@@ -1,46 +1,6 @@
\ C compiler stage 1
\ Requires cc/gen.fs, cc/ast.fs, asm.fs and wordtbl.fs
-: _err ( node -- ) printast abort" unexpected node" ;
-
-\ Code generation
-\ We have 2 tables below, "post" and "pre". When we perform code generation,
-\ we loop through the nodes, running the "pre" word corresponding to the
-\ AST id of the node, and when we encounter SeqClose, we run the "post"
-\ word of the parent of the SeqClose.
-\ All words below have the same sig: node -- node
-ASTIDCNT wordtbl posttbl
-'w _err
-'w noop ( Unit )
-'w noop ( Function )
-:w ( Return )
- ebp 4 i32 sub,
- [ebp] reg> mov, ;
-'w noop ( Constant )
-:w ( Statements ) ret, ;
-'w noop ( Arguments )
-'w noop ( Expression )
-:w ( UnaryOp ) dup intdata genuop ;
-'w noop ( Factor )
-:w ( BinaryOp ) dup intdata genbop ;
-
-ASTIDCNT wordtbl pretbl
-'w _err
-'w noop ( Unit )
-:w ( Function ) dup strdata entry ;
-'w noop ( Return )
-:w ( Constant ) >reg dup intdata i32 mov, ;
-'w noop ( Statements )
-'w noop ( Arguments )
-'w noop ( Expression )
-'w noop ( UnaryOp )
-'w noop ( Factor )
-'w noop ( BinaryOp )
-
\ Compiles input coming from the cc< alias (defaulting to in<) and writes the
\ result to here. Aborts on error.
-: _ ( node -- )
- pretbl over astid wexec
- dup firstchild ?dup if begin dup _ nextsibling ?dup not until then
- posttbl swap astid wexec ;
-: cc1, ( -- ) parseast curunit _ ;
+: cc1, ( -- ) parseast curunit gennode ;
diff --git a/fs/cc/gen.fs b/fs/cc/gen.fs
@@ -1,5 +1,5 @@
-\ C compile code generation utilities
-\ Requires asm.fs
+\ C compiler code generation
+\ Requires wordtbl asm cc/tree cc/ast
\ Target register stack: AST element setting a value to a register such as
\ Constant don't always push to the same register. During a binary op, we need
@@ -21,3 +21,48 @@
\ use this when you need 2 register at once in the *opposite* order of what
\ you'd get with "reg> curreg". only drops reglvl by 1.
: reg>> reglvl dup 2 > if _regerr then 1+ dup r! dup 1- r! to reglvl ;
+
+\ Code generation
+
+: _err ( node -- ) printast abort" unexpected node" ;
+
+UOPSCNT wordtbl opgentbl ( -- )
+:w ( - ) curreg neg, ;
+:w ( ~ ) curreg not, ;
+:w ( ! ) abort" TODO" ;
+
+: genuop ( opid -- ) opgentbl swap wexec ;
+
+BOPSCNT wordtbl opgentbl ( -- )
+:w ( + ) reg>> add, ;
+:w ( - ) reg>> sub, ;
+:w ( * )
+ eax reg> mov,
+ reg> mul,
+ >reg eax mov, ;
+:w ( / ) abort" TODO" ;
+
+: genbop ( opid -- ) opgentbl swap wexec ;
+
+alias noop gennode ( node -- ) \ forward declaration
+
+: genchildren ( node -- )
+ firstchild ?dup if begin dup gennode nextsibling ?dup not until then ;
+
+ASTIDCNT wordtbl gentbl ( node -- )
+'w _err
+'w genchildren ( Unit )
+:w ( Function ) dup strdata entry genchildren ;
+:w ( Return ) genchildren
+ ebp 4 i32 sub,
+ [ebp] reg> mov, ;
+:w ( Constant ) >reg intdata i32 mov, ;
+:w ( Statements ) genchildren ret, ;
+'w genchildren ( Arguments )
+'w genchildren ( Expression )
+:w ( UnaryOp ) dup genchildren intdata genuop ;
+'w genchildren ( Factor )
+:w ( BinaryOp ) dup genchildren intdata genbop ;
+
+: _ ( node -- ) gentbl over astid wexec ;
+current to gennode
diff --git a/fs/cc/ops.fs b/fs/cc/ops.fs
@@ -1,53 +0,0 @@
-\ C compiler operators
-\ Requires cc/gen.fs wordtbl.fs and asm.fs
-
-\ Unary operators
-\ ID Sym Name
-\ 0 - Negate
-\ 1 ~ Complement
-\ 2 ! Not
-
-3 value UOPSCNT
-create uopssyms ," -~!?"
-
-: uopid ( ta tl -- opid? f )
- 1 = if c@ uopssyms UOPSCNT [c]? dup 0< if drop 0 else 1 then
- else drop 0 then ;
-: uopchar ( opid -- c ) UOPSCNT max uopssyms + c@ ;
-
-UOPSCNT wordtbl opgentbl ( -- )
-:w ( - ) curreg neg, ;
-:w ( ~ ) curreg not, ;
-:w ( ! ) abort" TODO" ;
-
-: genuop ( opid -- ) opgentbl swap wexec ;
-
-\ Binary operators
-\ ID Sym Name
-\ 0 + Addition
-\ 1 - Subtraction
-\ 2 * Multiplication
-\ 3 / Division
-
-4 value BOPSCNT
-create bopssyms ," +-*/?"
-\ binary ops precedence. lower means more precedence
-create bopsprectbl 1 c, 1 c, 0 c, 0 c, $ff c,
-
-: bopid ( ta tl -- opid? f )
- 1 = if c@ bopssyms BOPSCNT [c]? dup 0< if drop 0 else 1 then
- else drop 0 then ;
-: bopchar ( opid -- c ) BOPSCNT min bopssyms + c@ ;
-: bopprec ( opid -- precedence ) BOPSCNT min bopsprectbl + c@ ;
-
-BOPSCNT wordtbl opgentbl ( -- )
-:w ( + ) reg>> add, ;
-:w ( - ) reg>> sub, ;
-:w ( * )
- eax reg> mov,
- reg> mul,
- >reg eax mov, ;
-:w ( / ) abort" TODO" ;
-
-: genbop ( opid -- ) opgentbl swap wexec ;
-