commit b4d34d17bd62e9cab9862492ea44efc0af74081f
parent 7912e92df0558c6d8578fa860f7067eb176d79a7
Author: Henry Wilson <m3henry@googlemail.com>
Date: Tue, 1 Aug 2017 00:30:57 +0100
split source file up in to categories
Diffstat:
A | boolean.s | | | 46 | ++++++++++++++++++++++++++++++++++++++++++++++ |
A | compiler.s | | | 49 | +++++++++++++++++++++++++++++++++++++++++++++++++ |
A | dictionary.s | | | 43 | +++++++++++++++++++++++++++++++++++++++++++ |
A | extras.s | | | 26 | ++++++++++++++++++++++++++ |
A | input.s | | | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | input.txt | | | 2 | +- |
A | interpreter.s | | | 87 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | main.s | | | 710 | ++----------------------------------------------------------------------------- |
A | maths.s | | | 120 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | memory.s | | | 104 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | output.s | | | 85 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | stack.s | | | 76 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
12 files changed, 702 insertions(+), 701 deletions(-)
diff --git a/boolean.s b/boolean.s
@@ -0,0 +1,46 @@
+# Logic
+
+verb code TRUE
+ _dup
+ movq $-1, TOS
+ jmp next
+
+verb code FALSE "0"
+ _dup
+ xor TOS, TOS
+ jmp next
+
+verb code lshift "<<"
+ minstk 1
+ shl TOS
+ jmp next
+
+verb code rshift ">>"
+ minstk 1
+ shr TOS
+ jmp next
+
+verb code halve "2/"
+ minstk 1
+ sar TOS
+ jmp next
+
+verb code NOT
+ minstk 1
+ not TOS
+ jmp next
+
+verb code AND
+ minstk 2
+ and TOS, (SP)
+ jmp _drop
+
+verb code OR
+ minstk 2
+ or TOS, (SP)
+ jmp _drop
+
+verb code XOR
+ minstk 2
+ xor TOS, (SP)
+ jmp _drop
diff --git a/compiler.s b/compiler.s
@@ -0,0 +1,49 @@
+# Compiler
+
+verb forth HERE
+ variable
+ endword
+
+verb forth modeI "[" immediate
+ set MODE 0
+ endword
+
+verb forth modeC "]"
+ set MODE -1
+ endword
+
+verb forth ALLOT
+ get HERE
+ do plus
+ set HERE
+ endword
+
+verb forth COMPILE "COMPILE" immediate
+ get HERE
+ do store
+ const 8
+ do ALLOT
+ endword
+
+verb forth compnew "\x3A" # :
+ do modeC
+ get HERE
+ get LAST
+ do COMPILE
+ do WORD
+ do fetch
+ const 8
+ do plus
+ do ALLOT
+ do TRUE
+ do COMPILE
+ const enter
+ do COMPILE
+ endword
+
+verb forth compend "\x3B" immediate # ;
+ const EXIT
+ do COMPILE
+ do modeI
+ set LAST
+ endword
diff --git a/dictionary.s b/dictionary.s
@@ -0,0 +1,43 @@
+# Dictionary
+
+verb forth LAST
+ variable
+ endword
+
+verb forth DICTIONARY
+ get LAST
+2: do DUP
+ do fetch
+ const 0
+ do equal
+ if 1f
+ do DUP
+ const 8
+ do plus
+ do PRINT
+ do fetch
+ do SPACE
+ goto 2b
+1: do DROP
+ endword
+
+verb forth FIND
+ get LAST
+2: do dup2
+ const 8
+ do plus
+ do STRCMP
+ unless 1f
+ const 24
+ do plus
+ do SWAP
+ do fetch
+ do plus
+ do TRUE
+ endword
+1: do fetch
+ do DUP
+ if 2b
+ do DROP
+ do FALSE
+ endword
diff --git a/extras.s b/extras.s
@@ -0,0 +1,26 @@
+# User Words
+
+verb forth greet GREET
+ say "Hello, World!"
+ do CR
+ endword
+
+verb forth FLAG
+ 1: do OVER
+ do line
+ do dec
+ do DUP
+ if 1b
+ do DROP
+ do DROP
+ endword
+
+line: forthword
+ 1: const '*'
+ do EMIT
+ do dec
+ do DUP
+ if 1b
+ do DROP
+ do CR
+ endword
diff --git a/input.s b/input.s
@@ -0,0 +1,55 @@
+# Input
+
+verb forth TIB
+ scratch 80
+ endword
+
+verb forth numtib "\#TIB"
+ variable
+ endword
+
+verb forth numin "\#IN"
+ variable
+ endword
+
+verb code ACCEPT
+ minstk 2
+ mov $0, CMD
+ mov $0, ARGA
+ mov (SP), ARGB
+ mov TOS, ARGC
+ syscall
+ mov CMD, (SP)
+ jmp _drop
+
+verb forth WORD
+ get HERE
+ const 0
+ do OVER
+ do store
+ const 8
+ do plus
+1: get numin
+ get numtib
+ do gequal
+ if 3f
+ do TIB
+ get numin
+ do plus
+ do fetchb
+ do numin
+ do incaddr
+ do DUP
+ const ' '
+ do lequal
+ if 2f
+ get HERE
+ do incaddr
+ do OVER
+ do storeb
+ do inc
+ goto 1b
+ 2: do DROP
+3: do DROP
+ get HERE
+ endword
diff --git a/input.txt b/input.txt
@@ -4,4 +4,4 @@ GREET
8 3 FLAG
: SQUARE DUP * ;
12 SQUARE . CR
-HALT
+CR DICTIONARY CR
diff --git a/interpreter.s b/interpreter.s
@@ -0,0 +1,87 @@
+# Interpreter
+
+verb forth MODE
+ variable
+ endword
+
+verb forth INTERPRET
+ set numin 0
+ 3: do WORD
+ do DUP
+ do fetch
+ if 0f
+ do DROP
+ goto 2f
+ 0: do FIND
+ if 1f
+ const 0
+ do SWAP
+ do DUP
+ const 8
+ do plus
+ do SWAP
+ do fetch
+ do CONVERT
+ do drop2
+ test greater 0 2f
+ do DROP
+ get HERE
+ escape 91
+ say "Unknown token: "
+ do PRINT
+ do CR
+ do ABORT
+ goto 2f
+ 1: do DUP
+ const 8
+ do minus
+ do fetch
+ get MODE
+ do AND
+ if 1f
+ do EXECUTE
+ goto 2f
+ 1: do COMPILE
+ 2: get numin
+ get numtib
+ do less
+ if 3b
+ escape 92
+ do DEPTH
+ test equal 0 4f
+ say " ⏎ "
+ test equal 1 5f
+ do DUP
+ do dot
+5: do DROP
+ say "["
+ do DUP
+ do dot
+ saycr "]"
+ endword
+4: do DROP
+ saycr " 🗸"
+ endword
+
+verb forth CONVERT
+2: test equal 0 1f
+ do pushret
+ do DUP
+ do pushret
+ do fetchb
+ const '0'
+ do minus
+ test greater 9 0f
+ do SWAP
+ const 10
+ do mult
+ do plus
+ do popret
+ do inc
+ do popret
+ do dec
+ goto 2b
+0: do DROP
+ do popret
+ do popret
+1: endword
diff --git a/main.s b/main.s
@@ -76,518 +76,20 @@ verb forth QUIT
escape 0
do HALT
-# Interpreter
-
-verb forth PAD
- scratch 90
- endword
-
-verb forth TIB
- scratch 80
- endword
-
-verb forth numtib "\#TIB"
- variable
- endword
-
-verb forth numin "\#IN"
- variable
- endword
-
-verb forth MODE
- variable
- endword
-
-verb forth INTERPRET
- set numin 0
- 3: do WORD
- do DUP
- do fetch
- if 0f
- do DROP
- goto 2f
- 0: do FIND
- if 1f
- const 0
- do SWAP
- do DUP
- const 8
- do plus
- do SWAP
- do fetch
- do CONVERT
- do drop2
- test greater 0 2f
- do DROP
- get HERE
- escape 91
- say "Unknown token: "
- do PRINT
- do CR
- do ABORT
- goto 2f
- 1: do DUP
- const 8
- do minus
- do fetch
- get MODE
- do AND
- if 1f
- do EXECUTE
- goto 2f
- 1: do COMPILE
- 2: get numin
- get numtib
- do less
- if 3b
- escape 92
- do DEPTH
- test equal 0 4f
- say " ⏎ "
- test equal 1 5f
- do DUP
- do dot
-5: do DROP
- say "["
- do DUP
- do dot
- saycr "]"
- endword
-4: do DROP
- saycr " 🗸"
- endword
-
-verb forth CONVERT
-2: test equal 0 1f
- do pushret
- do DUP
- do pushret
- do fetchb
- const '0'
- do minus
- test greater 9 0f
- do SWAP
- const 10
- do mult
- do plus
- do popret
- do inc
- do popret
- do dec
- goto 2b
-0: do DROP
- do popret
- do popret
-1: endword
-
-verb forth WORD
- get HERE
- const 0
- do OVER
- do store
- const 8
- do plus
-1: get numin
- get numtib
- do gequal
- if 3f
- do TIB
- get numin
- do plus
- do fetchb
- do numin
- do incaddr
- do DUP
- const ' '
- do lequal
- if 2f
- get HERE
- do incaddr
- do OVER
- do storeb
- do inc
- goto 1b
- 2: do DROP
-3: do DROP
- get HERE
- endword
-
-verb forth LAST
- variable
- endword
-
-verb forth DICTIONARY
- get LAST
-2: do DUP
- do fetch
- const 0
- do equal
- if 1f
- do DUP
- const 8
- do plus
- do PRINT
- do fetch
- do SPACE
- goto 2b
-1: do DROP
- endword
-
-verb forth FIND
- get LAST
-2: do dup2
- const 8
- do plus
- do STRCMP
- unless 1f
- const 24
- do plus
- do SWAP
- do fetch
- do plus
- do TRUE
- endword
-1: do fetch
- do DUP
- if 2b
- do DROP
- do FALSE
- endword
-
-# Compiler
-
-verb forth HERE
- variable
- endword
-
-verb forth modeI "[" immediate
- set MODE 0
- endword
-
-verb forth modeC "]"
- set MODE -1
- endword
-
-verb forth ALLOT
- get HERE
- do plus
- set HERE
- endword
-
-verb forth COMPILE "COMPILE" immediate
- get HERE
- do store
- const 8
- do ALLOT
- endword
-
-verb forth compnew "\x3A" # :
- do modeC
- get HERE
- get LAST
- do COMPILE
- do WORD
- do fetch
- const 8
- do plus
- do ALLOT
- do TRUE
- do COMPILE
- const enter
- do COMPILE
- endword
-
-verb forth compend "\x3B" immediate # ;
- const EXIT
- do COMPILE
- do modeI
- set LAST
- endword
-
-# User Words
-
-verb forth greet GREET
- say "Hello, World!"
- do CR
- endword
-
-verb forth FLAG
- 1: do OVER
- do line
- do dec
- do DUP
- if 1b
- do DROP
- do DROP
- endword
-
-line: forthword
- 1: const '*'
- do EMIT
- do dec
- do DUP
- if 1b
- do DROP
- do CR
- endword
-
-verb forth SPACE
- const ' '
- do EMIT
- endword
-
-verb forth CR
- const '\n'
- do EMIT
- endword
-
-verb forth dot "."
- test gequal 0 1f
- const '-'
- do EMIT
- do NEGATE
-1: do _dot
- endword
-
-_dot: forthword
- test less 10 1f
- const 10
- do divmod
- do SWAP
- do _dot
-1:
- const '0'
- do plus
- do EMIT
- endword
-
-verb forth dotdot "..."
- say "..."
- do top
- const stack
- do nequal
- if 1f
- say "Stack Empty"
-1: do _dotdot
- saycr "..."
- endword
-
-_dotdot: forthword
- do top
- const stack
- do equal
- if 1f
- do pushret # Top of stack
- do _dotdot #
- do popret #
- const '\t'
- do EMIT
- do DUP
- do dot
-1: endword
-
-verb forth dup2 "2DUP"
- do OVER
- do OVER
- endword
-
-verb forth MIN
- do dup2
- do less
- if 1f
- do SWAP
-1: do DROP
- endword
-
-verb forth MAX
- do dup2
- do greater
- if 1f
- do SWAP
-1: do DROP
- endword
-
-verb forth STRCMP
- do dup2
- do fetch
- do SWAP
- do fetch
- do equal
- unless 0f
- do OVER
- do fetch
- const 8
- do divmod
- do SWAP
- do pushret # Quotient
- do DUP #
- do pushret # # Remainder
- do plus # #
- do SWAP # #
- do popret # #
- do plus #
- do popret #
- do inc
- do QUADCMP
- endword
-0: do drop2
- do FALSE
- endword
-
-verb forth QUADCMP
-2: do DUP
- if 1f
- do drop2
- do DROP
- do TRUE
- endword
-1: do pushret # Count
- do dup2 #
- do indneq #
- if 0f #
- do inc #
- do SWAP #
- do inc #
- do SWAP #
- do popret #
- do dec
- goto 2b
+.include "stack.s"
+.include "memory.s"
+.include "boolean.s"
+.include "maths.s"
+.include "input.s"
+.include "dictionary.s"
+.include "interpreter.s"
+.include "compiler.s"
+.include "output.s"
+.include "extras.s"
-0: do drop2 # (Count)
- do popret #
- do DROP
- do FALSE
- endword
-
-verb forth divide "/"
- do divmod
- do DROP
- endword
-
-verb forth mod "%"
- do divmod
- do SWAP
- do DROP
- endword
-
-verb forth muldiv "*/"
- do muldivmod
- do DROP
- endword
-
-verb forth iszero "0="
- do FALSE
- do equal
- endword
-
-verb forth CMOVE
-2: test equal 0 1f
- do dec
- do pushret # Count
- do OVER #
- do fetchb #
- do OVER #
- do storeb #
- const 8 #
- do plus #
- do SWAP #
- const 8 #
- do plus #
- do SWAP #
- do popret #
- goto 2
-1: do DROP
- do drop2
- endword
-
-verb forth STRMOVE
- do OVER
- do fetch
- const 8
- do plus
- do CMOVE
- endword
# "CODEWORDS"
-
-# Stack manipulation
-
-verb code RESETDATA
- mov $stack, SP
- jmp next
-
-verb code RESETRETURN
- mov rspbk, %rsp
- jmp next
-
-verb code DUP
- minstk 1
- _dup
- jmp next
-
-verb code drop2 "2DROP"
- minstk 2
-_drop2: advance SP
- mov (SP), TOS
- advance SP
- jmp next
-
-verb code DROP
- minstk 1
-_drop: mov (SP), TOS
- advance SP
- jmp next
-
-_uflow: do RESETDATA
- saycr "\x1B[91m Stack underflow!"
- do QUIT
-
-verb code SWAP
- minstk 2
- push TOS
- mov (SP), TOS
- pop (SP)
- jmp next
-
-verb code OVER
- minstk 2
- push (SP)
- _dup
- pop TOS
- jmp next
-
-# Output
-
-verb code EMIT
- minstk 1
- movq TOS, buff
- mov $1, CMD # system call 1 is write
- mov $1, ARGA # file handle 1 is stdout
- mov $buff, ARGB # address of string to output
- mov $1, ARGC # number of bytes
- syscall
- jmp _drop
-
-verb code PRINT
- minstk 1
- mov $1, CMD
- mov $1, ARGA
- mov (TOS), ARGC
- advance TOS
- mov TOS, ARGB
- syscall
- jmp _drop
-
-verb code TYPE
- minstk 2
- mov $1, CMD
- mov $1, ARGA
- mov (SP), ARGB
- mov TOS, ARGC
- syscall
- jmp _drop2
-
verb code HALT
_halt: xor ARGA, ARGA # default return code 0
sub $stack, SP
@@ -596,18 +98,6 @@ _halt: xor ARGA, ARGA # default return code 0
1: mov $60, CMD # system call 60 is exit
syscall
-# Input
-
-verb code ACCEPT
- minstk 2
- mov $0, CMD
- mov $0, ARGA
- mov (SP), ARGB
- mov TOS, ARGC
- syscall
- mov CMD, (SP)
- jmp _drop
-
# Do Stuff
docon: codeword
@@ -649,186 +139,6 @@ dountil: codeword
sub (IP), IP
jmp _drop
-# Memory management
-
-verb code DEPTH
- mov $stack, ACC
- sub SP, ACC
- shr ACC
- shr ACC
- shr ACC
- _dup
- mov ACC, TOS
- jmp next
-
-verb code fetch "@>"
- minstk 1
- mov (TOS), TOS
- jmp next
-
-fetchb: codeword
- minstk 1
- movb (TOS), TOSB
- and $0xFF, TOS
- jmp next
-
-verb code store ">@"
- minstk 2
- mov (SP), ACC
- mov ACC, (TOS)
- jmp _drop2
-
-storeb: codeword
- minstk 2
- mov (SP), ACC
- movb ACCB, (TOS)
- jmp _drop2
-
-top: codeword
- push SP
- _dup
- pop TOS
- jmp next
-
-verb code pushret ">R"
- minstk 1
- push TOS
- jmp _drop
-
-verb code popret "R>"
- _dup
- pop TOS
- jmp next
-
-# Logic
-
-verb code TRUE
- _dup
- movq $-1, TOS
- jmp next
-
-verb code FALSE "0"
- _dup
- xor TOS, TOS
- jmp next
-
-verb code lshift "<<"
- minstk 1
- shl TOS
- jmp next
-
-verb code rshift ">>"
- minstk 1
- shr TOS
- jmp next
-
-verb code halve "2/"
- minstk 1
- sar TOS
- jmp next
-
-verb code NOT
- minstk 1
- not TOS
- jmp next
-
-verb code AND
- minstk 2
- and TOS, (SP)
- jmp _drop
-
-verb code OR
- minstk 2
- or TOS, (SP)
- jmp _drop
-
-verb code XOR
- minstk 2
- xor TOS, (SP)
- jmp _drop
-
-# Maths
-
-verb code plus "+"
- minstk 2
- add TOS, (SP)
- jmp _drop
-
-verb code minus "-"
- minstk 2
- sub TOS, (SP)
- jmp _drop
-
-verb code inc "1+"
- minstk 1
- inc TOS
- jmp next
-
-verb code dec "1-"
- minstk 1
- dec TOS
- jmp next
-
-verb code incaddr "@1+"
- minstk 1
- incq (TOS)
- jmp _drop
-
-verb code decaddr "@1-"
- minstk 1
- decq (TOS)
- jmp _drop
-
-verb code NEGATE
- minstk 1
- neg TOS
- jmp next
-
-verb code mult "*"
- minstk 2
- mov (SP), %rax
- mul TOS
- mov %rax, (SP)
- jmp _drop
-
-verb code divmod "/%"
- minstk 2
- xor %rdx, %rdx
- mov (SP), %rax
- div TOS
- mov %rax, (SP)
- mov %rdx, TOS
- jmp next
-
-verb code muldivmod "*/%"
- minstk 3
- mov (SP), %rax
- mul TOS
- divq -8(SP)
- mov %rax, -8(SP)
- mov %rdx, (SP)
- jmp _drop
-
-# Comparison
-
-truecmp:
- movq $-1, (SP)
- jmp _drop
-
-compare je equal "\="
-compare jne nequal "<>"
-compare jg greater ">"
-compare jl less "<"
-compare jge gequal ">="
-compare jle lequal "<="
-compare ja above "S>"
-compare jb below "S<"
-compare jae aequal "S>="
-compare jbe bequal "S<="
-
-cmpaddr je indeq "@="
-cmpaddr jne indneq "@<>"
-
# Kernel
verb code EXIT
diff --git a/maths.s b/maths.s
@@ -0,0 +1,120 @@
+# Maths
+
+verb code plus "+"
+ minstk 2
+ add TOS, (SP)
+ jmp _drop
+
+verb code minus "-"
+ minstk 2
+ sub TOS, (SP)
+ jmp _drop
+
+verb code inc "1+"
+ minstk 1
+ inc TOS
+ jmp next
+
+verb code dec "1-"
+ minstk 1
+ dec TOS
+ jmp next
+
+verb code incaddr "@1+"
+ minstk 1
+ incq (TOS)
+ jmp _drop
+
+verb code decaddr "@1-"
+ minstk 1
+ decq (TOS)
+ jmp _drop
+
+verb code NEGATE
+ minstk 1
+ neg TOS
+ jmp next
+
+verb code mult "*"
+ minstk 2
+ mov (SP), %rax
+ mul TOS
+ mov %rax, (SP)
+ jmp _drop
+
+verb code divmod "/%"
+ minstk 2
+ xor %rdx, %rdx
+ mov (SP), %rax
+ div TOS
+ mov %rax, (SP)
+ mov %rdx, TOS
+ jmp next
+
+verb forth divide "/"
+ do divmod
+ do DROP
+ endword
+
+verb forth mod "%"
+ do divmod
+ do SWAP
+ do DROP
+ endword
+
+verb code muldivmod "*/%"
+ minstk 3
+ mov (SP), %rax
+ mul TOS
+ divq -8(SP)
+ mov %rax, -8(SP)
+ mov %rdx, (SP)
+ jmp _drop
+
+verb forth muldiv "*/"
+ do muldivmod
+ do DROP
+ endword
+
+# Functions
+
+verb forth MIN
+ do dup2
+ do less
+ if 1f
+ do SWAP
+1: do DROP
+ endword
+
+verb forth MAX
+ do dup2
+ do greater
+ if 1f
+ do SWAP
+1: do DROP
+ endword
+
+# Comparison
+
+verb forth iszero "0="
+ do FALSE
+ do equal
+ endword
+
+truecmp:
+ movq $-1, (SP)
+ jmp _drop
+
+compare je equal "\="
+compare jne nequal "<>"
+compare jg greater ">"
+compare jl less "<"
+compare jge gequal ">="
+compare jle lequal "<="
+compare ja above "S>"
+compare jb below "S<"
+compare jae aequal "S>="
+compare jbe bequal "S<="
+
+cmpaddr je indeq "@="
+cmpaddr jne indneq "@<>"
diff --git a/memory.s b/memory.s
@@ -0,0 +1,104 @@
+# Memory management
+
+verb code fetch "@>"
+ minstk 1
+ mov (TOS), TOS
+ jmp next
+
+fetchb: codeword
+ minstk 1
+ movb (TOS), TOSB
+ and $0xFF, TOS
+ jmp next
+
+verb code store ">@"
+ minstk 2
+ mov (SP), ACC
+ mov ACC, (TOS)
+ jmp _drop2
+
+storeb: codeword
+ minstk 2
+ mov (SP), ACC
+ movb ACCB, (TOS)
+ jmp _drop2
+
+verb forth QUADCMP
+2: do DUP
+ if 1f
+ do drop2
+ do DROP
+ do TRUE
+ endword
+1: do pushret # Count
+ do dup2 #
+ do indneq #
+ if 0f #
+ do inc #
+ do SWAP #
+ do inc #
+ do SWAP #
+ do popret #
+ do dec
+ goto 2b
+
+0: do drop2 # (Count)
+ do popret #
+ do DROP
+ do FALSE
+ endword
+
+verb forth STRCMP
+ do dup2
+ do fetch
+ do SWAP
+ do fetch
+ do equal
+ unless 0f
+ do OVER
+ do fetch
+ const 8
+ do divmod
+ do SWAP
+ do pushret # Quotient
+ do DUP #
+ do pushret # # Remainder
+ do plus # #
+ do SWAP # #
+ do popret # #
+ do plus #
+ do popret #
+ do inc
+ do QUADCMP
+ endword
+0: do drop2
+ do FALSE
+ endword
+
+verb forth CMOVE
+2: test equal 0 1f
+ do dec
+ do pushret # Count
+ do OVER #
+ do fetchb #
+ do OVER #
+ do storeb #
+ const 8 #
+ do plus #
+ do SWAP #
+ const 8 #
+ do plus #
+ do SWAP #
+ do popret #
+ goto 2
+1: do DROP
+ do drop2
+ endword
+
+verb forth STRMOVE
+ do OVER
+ do fetch
+ const 8
+ do plus
+ do CMOVE
+ endword
diff --git a/output.s b/output.s
@@ -0,0 +1,85 @@
+# Output
+
+verb code EMIT
+ minstk 1
+ movq TOS, buff
+ mov $1, CMD # system call 1 is write
+ mov $1, ARGA # file handle 1 is stdout
+ mov $buff, ARGB # address of string to output
+ mov $1, ARGC # number of bytes
+ syscall
+ jmp _drop
+
+verb forth CR
+ const '\n'
+ do EMIT
+ endword
+
+verb forth SPACE
+ const ' '
+ do EMIT
+ endword
+
+verb code PRINT
+ minstk 1
+ mov $1, CMD
+ mov $1, ARGA
+ mov (TOS), ARGC
+ advance TOS
+ mov TOS, ARGB
+ syscall
+ jmp _drop
+
+verb code TYPE
+ minstk 2
+ mov $1, CMD
+ mov $1, ARGA
+ mov (SP), ARGB
+ mov TOS, ARGC
+ syscall
+ jmp _drop2
+
+verb forth dot "."
+ test gequal 0 1f
+ const '-'
+ do EMIT
+ do NEGATE
+1: do _dot
+ endword
+
+_dot: forthword
+ test less 10 1f
+ const 10
+ do divmod
+ do SWAP
+ do _dot
+1:
+ const '0'
+ do plus
+ do EMIT
+ endword
+
+verb forth dotdot "..."
+ say "..."
+ do top
+ const stack
+ do nequal
+ if 1f
+ say "Stack Empty"
+1: do _dotdot
+ saycr "..."
+ endword
+
+_dotdot: forthword
+ do top
+ const stack
+ do equal
+ if 1f
+ do pushret # Top of stack
+ do _dotdot #
+ do popret #
+ const '\t'
+ do EMIT
+ do DUP
+ do dot
+1: endword
diff --git a/stack.s b/stack.s
@@ -0,0 +1,76 @@
+# Stack manipulation
+
+verb code RESETDATA
+ mov $stack, SP
+ jmp next
+
+verb code RESETRETURN
+ mov rspbk, %rsp
+ jmp next
+
+verb code DUP
+ minstk 1
+ _dup
+ jmp next
+
+verb forth dup2 "2DUP"
+ do OVER
+ do OVER
+ endword
+
+verb code drop2 "2DROP"
+ minstk 2
+_drop2: advance SP
+ mov (SP), TOS
+ advance SP
+ jmp next
+
+verb code DROP
+ minstk 1
+_drop: mov (SP), TOS
+ advance SP
+ jmp next
+
+_uflow: do RESETDATA
+ saycr "\x1B[91m Stack underflow!"
+ do QUIT
+
+verb code SWAP
+ minstk 2
+ push TOS
+ mov (SP), TOS
+ pop (SP)
+ jmp next
+
+verb code OVER
+ minstk 2
+ push (SP)
+ _dup
+ pop TOS
+ jmp next
+
+verb code DEPTH
+ mov $stack, ACC
+ sub SP, ACC
+ shr ACC
+ shr ACC
+ shr ACC
+ _dup
+ mov ACC, TOS
+ jmp next
+
+top: codeword
+ push SP
+ _dup
+ pop TOS
+ jmp next
+
+verb code pushret ">R"
+ minstk 1
+ push TOS
+ jmp _drop
+
+verb code popret "R>"
+ _dup
+ pop TOS
+ jmp next