-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Command Line control (with defaults for debugging)
- Loading branch information
Showing
6 changed files
with
197 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
.text | ||
.file "MovForth" | ||
.globl main | ||
.p2align 4, 0x90 | ||
.type main,@function | ||
main: | ||
.cfi_startproc | ||
pushq %rbx | ||
.cfi_def_cfa_offset 16 | ||
.cfi_offset %rbx, -16 | ||
movl $12, %ebx | ||
.p2align 4, 0x90 | ||
.LBB0_1: | ||
movl $.L__unnamed_1, %edi | ||
xorl %eax, %eax | ||
movl %ebx, %esi | ||
callq printf | ||
decl %ebx | ||
jne .LBB0_1 | ||
popq %rbx | ||
retq | ||
.Lfunc_end0: | ||
.size main, .Lfunc_end0-main | ||
.cfi_endproc | ||
|
||
.type .L__unnamed_1,@object | ||
.section .rodata.str1.1,"aMS",@progbits,1 | ||
.L__unnamed_1: | ||
.asciz "%d\n" | ||
.size .L__unnamed_1, 4 | ||
|
||
|
||
.section ".note.GNU-stack","",@progbits |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
|
||
\ Compilation steps: | ||
\ | ||
\ First, this file is interpreted as a typical Forth program. This way, | ||
\ user-defined compiling actions actually do execute during compilation time | ||
\ | ||
\ Next, in main.cpp, we instruct the compiler to compile a chosen word in the | ||
\ dictionary ("test" in this case) | ||
\ | ||
\ Dependency Tree: | ||
\ Then, the compiler builds a dependency tree for the selected word. The word forms | ||
\ the root node and all of its offspring nodes are determined from its definition. | ||
\ This happens recursively until a primitive word, which has no dependecies, is reached | ||
\ | ||
\ As this tree is built, the compiler collapses number data stored in the definition | ||
\ (like the number that proceeds a LITERAL) into the word that owns it | ||
\ | ||
\ When all offspring of a certain node have been built, the compiler searches | ||
\ the node/word's definition for BRANCH and BRANCHIF. The compiler uses this | ||
\ information to make a control flow graph. Each word/node has its own control | ||
\ flow graph | ||
\ | ||
\ A sequence of words that don't include BRANCH or BRANCHIF | ||
\ is a basic block. This is the same defintion that LLVM uses. | ||
\ | ||
\ | ||
\ Stack Graph: | ||
\ This compiler compiles forth to LLVM IR. But LLVM uses SSA, which is a register-based | ||
\ format, and Forth is a stack-based. So a stack graph is needed to | ||
\ link the output of one word to the input of another. | ||
\ | ||
\ Imagine a sequence of words, each with as many input nodes as it | ||
\ takes elements from the stack and as many output nodes as elements that it pushes to the | ||
\ stack. The stack graph algorithm creates an edge between every pair of input/output | ||
\ nodes and assigns a name to the edge. An edge becomes a register in IR. | ||
\ | ||
\ The stack graph is printed out on the console during compilation. | ||
\ | ||
\ Registers are named X-Y, | ||
\ where X is the index of the basic block it is consumed in, | ||
\ and Y is an index that is unique to the register within its basic block | ||
\ | ||
\ | ||
\ Stack Graph with Control Flow | ||
\ The compiler supports not just structured control flow but any CFG | ||
\ that can be represented by BRANCH and BRANCHIF. If two basic blocks | ||
\ merge into the same final BB, they will not push differently named registers, | ||
\ In other words, the registers that cross control flow edges are guaranteed to be the same | ||
\ for all merging basic blocks. | ||
|
||
\ (I made a very elegant solution to this here. It piggybacks on the control | ||
\ flow DFS pass so it doesn't need its own pass) | ||
|
||
|
||
\ BBs that merge together *must* push the same number of | ||
\ stack elements. Making this assumption makes the code much easier to write. | ||
|
||
|
||
|
||
|
||
: ['] immediate ' ; | ||
|
||
: [,] immediate , ; | ||
|
||
: negative -1 * ; | ||
|
||
: jump> | ||
literal branch , | ||
here | ||
0 , ; | ||
|
||
: jumpif> | ||
literal branchif , | ||
here | ||
0 , ; | ||
|
||
: >land | ||
dup | ||
here - negative | ||
swap ! ; | ||
|
||
: land< | ||
here ; | ||
|
||
: <jump | ||
literal branch , | ||
here - , ; | ||
|
||
: <jumpif | ||
literal branchif , | ||
here - , ; | ||
|
||
: if immediate | ||
jumpif> ; | ||
|
||
: else immediate | ||
jump> | ||
swap | ||
>land ; | ||
|
||
: then immediate | ||
>land ; | ||
|
||
: while immediate | ||
land< ; | ||
|
||
: repeat immediate | ||
<jump ; | ||
|
||
: repeatif immediate | ||
literal literal , \ compile `0 =` into word being defined | ||
0 , | ||
literal = , | ||
<jumpif ; | ||
|
||
: until0 immediate | ||
literal literal , \ compile `1 -` into word being defined | ||
1 , | ||
literal - , | ||
|
||
literal dup , \ compile `dup` into word being defined | ||
|
||
literal literal , \ compile `0 =` into word being defined | ||
0 , | ||
literal = , | ||
|
||
<jumpif ; | ||
|
||
|
||
: main | ||
12 while | ||
dup . | ||
1 - dup | ||
repeatif | ||
drop | ||
; | ||
|
||
main | ||
|
||
see | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters