checked in the toolchain
This commit is contained in:
parent
e003b50fa2
commit
96a148f58f
8
Makefile
8
Makefile
|
@ -2,12 +2,10 @@
|
|||
|
||||
UNAME := $(shell uname)
|
||||
|
||||
all: forth
|
||||
all: nforth
|
||||
|
||||
clean:
|
||||
rm -f *.lst *~ *#
|
||||
|
||||
forth: macros.asm forth.asm
|
||||
fasm forth.asm -s forth.sym
|
||||
fasmlist -a forth.sym forth.lst
|
||||
rm forth.sym
|
||||
nforth: macros.asm nforth.asm
|
||||
./build nforth
|
||||
|
|
|
@ -16,6 +16,8 @@ To avoid the whole state morass, nForth is *always* in compile mode. Words are
|
|||
### Hashes not Names
|
||||
Names are not stored in the dictionary. Names are hashed at definition time using FNV1a algo to a 32-bit value and stored. Dictionary searches are simplified to a 32-bit comparison instead of a string comparison, and heads are always 8 bytes long.
|
||||
|
||||
## Getting Started
|
||||
|
||||
## Internals
|
||||
|
||||
Tokens are 32-bit references to the XT of each words. NEXT is a 3-byte piece of code that terminates all CODE words:
|
||||
|
|
4
build
4
build
|
@ -1,3 +1,3 @@
|
|||
fasm $1.asm -s $1.sym
|
||||
fasmlist -a $1.sym $1.lst
|
||||
tools/fasm $1.asm -s $1.sym
|
||||
tools/fasmlist -a $1.sym $1.lst
|
||||
rm $1.sym
|
||||
|
|
149
nforth.asm
149
nforth.asm
|
@ -1,9 +1,10 @@
|
|||
|
||||
|
||||
|
||||
; fasm demonstration of writing simple ELF executable
|
||||
|
||||
MEMSIZE = $2000000 ;32MB
|
||||
LASTHEAD = osexit
|
||||
LASTHEAD = bye ;search terminates at bye (first head)
|
||||
|
||||
include "macros.asm"
|
||||
|
||||
|
@ -17,10 +18,20 @@ hthanx = $07596E46
|
|||
|
||||
inmsg: db "nForth 0.0.1, Copyright (C) 2022 StackSmith"
|
||||
.1:
|
||||
argv: dd 0
|
||||
;argv: dd 0
|
||||
|
||||
start:
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
pop eax ;argc
|
||||
pop edi ;argv
|
||||
dec eax ;one argument?
|
||||
jz noargs ;then, no arguments
|
||||
xor eax,eax
|
||||
lea ecx,[eax-1]
|
||||
repne scasb
|
||||
mov [argv],edi
|
||||
noargs:
|
||||
;-----------------------------------------------------------------------
|
||||
; First brk gets the top of allocated memory; second attempts to allot
|
||||
; more memory.
|
||||
;
|
||||
|
@ -40,9 +51,8 @@ start:
|
|||
DSTACK
|
||||
push 1
|
||||
push 2
|
||||
push 3
|
||||
RSTACK
|
||||
mov ebx,4
|
||||
mov ebx,[argv]
|
||||
|
||||
mov esi,main+4 ;start
|
||||
NEXT
|
||||
|
@ -82,6 +92,7 @@ _oswrite:
|
|||
|
||||
;;; mode,flags,path
|
||||
_osopen:
|
||||
|
||||
mov eax,5 ;sys_open
|
||||
jmp _oswrite.1
|
||||
_osexit:
|
||||
|
@ -235,7 +246,9 @@ _parse:
|
|||
;;; ****************************************************************************
|
||||
;;; ****************************************************************************
|
||||
;;; ----- DO NOT PUT HEADS ABOVE HERE
|
||||
HEAD osexit,$+4
|
||||
HEAD bye,$+4
|
||||
|
||||
|
||||
jmp _osexit
|
||||
HEAD oswrite,$+4
|
||||
call _oswrite
|
||||
|
@ -449,16 +462,16 @@ HEAD spaces,docol
|
|||
dd xdup,nzbranch,.again
|
||||
.done: dd drop,return ;
|
||||
|
||||
HEAD hello,docol,1
|
||||
dd _strlit
|
||||
mstring <"nForth 0.0.1, Copyright (C) 2022 StackSmith",10>
|
||||
.strend:
|
||||
align 4
|
||||
dd type
|
||||
dd return
|
||||
|
||||
;HEAD hello,docol,1
|
||||
; dd _strlit
|
||||
; mstring <"nForth 0.0.1, Copyright (C) 2022 StackSmith",10>
|
||||
;.strend:
|
||||
;align 4
|
||||
; dd type
|
||||
; dd return
|
||||
|
||||
HEAD main,docol
|
||||
dd hello
|
||||
; dd hello
|
||||
.in: dd parsereset
|
||||
dd ERR.CATCH
|
||||
dd xdup,zbranch,.noerr
|
||||
|
@ -473,6 +486,8 @@ HEAD main,docol
|
|||
dd branch, .in
|
||||
|
||||
.noerr: dd drop
|
||||
dd autoexec
|
||||
|
||||
.loop:
|
||||
dd INTERPRET
|
||||
dd branch, .loop
|
||||
|
@ -572,6 +587,18 @@ HEAD hexw,$+4
|
|||
mov ecx,4
|
||||
jmp hexloop
|
||||
|
||||
;; (char--char)
|
||||
HEAD printable,$+4
|
||||
xor eax,eax
|
||||
mov al,$7E
|
||||
cmp bl,20
|
||||
cmovc ebx,eax
|
||||
cmp bl,$7F
|
||||
cmovnc ebx,eax
|
||||
NEXT
|
||||
|
||||
|
||||
|
||||
|
||||
;;; ------------------------------------------------------------------------------
|
||||
;;; ERROR HANDLING
|
||||
|
@ -665,7 +692,12 @@ HEADN colon,":",docol,1
|
|||
;;; & ; , \ compile <return>
|
||||
;;; HERE @ RUNTPR ! \ do not run definition
|
||||
;;; ;
|
||||
|
||||
|
||||
;;; Uncompile: get rid of all the code copiled between RUNPTR and HERE
|
||||
HEAD uncompile,docol
|
||||
dd RUNPTR,fetch,HERE,xstore
|
||||
dd return;
|
||||
|
||||
;;; Execute tokens from address in TOS, and return when done.
|
||||
HEAD CALLSTREAM,$+4
|
||||
push esi
|
||||
|
@ -679,9 +711,9 @@ HEAD CALLSTREAM,$+4
|
|||
HEAD INTERPRET,docol
|
||||
dd HERE,fetch,RUNPTR,xstore ; start of compile
|
||||
dd ws,COMPILE.ONE
|
||||
dd lit,return,comma ; terminate with return
|
||||
dd lit,return,comma ; terminate with return
|
||||
dd RUNPTR,fetch,CALLSTREAM
|
||||
dd RUNPTR,fetch,HERE,xstore ; erase
|
||||
dd uncompile ;get rid of compiled code
|
||||
dd return
|
||||
|
||||
|
||||
|
@ -881,15 +913,28 @@ HEADN xpop,"pop",$+4
|
|||
RSTACK
|
||||
pop ebx
|
||||
NEXT
|
||||
|
||||
|
||||
|
||||
HEAD dumpbyte,docol
|
||||
dd xdup,fetch,hexb,space,plus1,return
|
||||
HEAD dumpascii,docol
|
||||
dd xdup,fetch,printable,emit,plus1,return
|
||||
|
||||
|
||||
HEAD dump16,docol ;addr
|
||||
dd xdup,hexd,space,space
|
||||
dd lit,16,xpush ;16 times
|
||||
@@: dd dumpbyte
|
||||
dd decibranz,@b
|
||||
dd cr,return
|
||||
dd space
|
||||
dd lit,16,minus
|
||||
|
||||
dd lit,16,xpush ;16 times
|
||||
@@: dd dumpascii
|
||||
dd decibranz,@b
|
||||
dd cr,return
|
||||
|
||||
HEAD dump,docol
|
||||
dd dump16,dump16,dump16,dump16,return
|
||||
|
||||
|
@ -968,6 +1013,7 @@ HEADN xtimes,"times",docol,1 ;(n-- n times (...)
|
|||
dd return
|
||||
|
||||
|
||||
|
||||
HEADN xif,"if",docol,1
|
||||
dd FIXUP.IF,fetch,xpush ;reentrant: push old IF
|
||||
dd lit,zbranch,comma ;compile <zbranch>
|
||||
|
@ -987,31 +1033,70 @@ HEADN xelse,"else",docol,1
|
|||
dd return
|
||||
.err: dd lit,$99,ERXIT
|
||||
|
||||
;;;(name,namelen--)
|
||||
HEADN xload,"load",docol
|
||||
dd HANDLE.IN, fetch,xpush ; keep old input handle on stack
|
||||
dd drop,xpush,zero,zero,xpop ; --0,0,fname
|
||||
dd osopen
|
||||
dd HANDLE.IN,xstore
|
||||
;;; Loader
|
||||
;;;
|
||||
;;; Problem: This is an always-compile system, so invoking the loader
|
||||
;;; compiles the invoking code, which will be stuck there below the
|
||||
;;; loaded code. We must distinguish between the two possibilities:
|
||||
;;; 1) loading interactively, or chain-loading multiple files, in which case
|
||||
;;; the invoking code must be wiped, and we must therefore return
|
||||
;;; two levels up (since the calling code is destroyed);
|
||||
;;; 2) loading from compiled code (non-interactively, such as loading a
|
||||
;;; layer during execution), in which case we will return normally;
|
||||
;;;
|
||||
;;;(handle--) Load a forth file from an open file handle
|
||||
HEADN xloadh,"loadh",docol
|
||||
dd HANDLE.IN, fetch, xpush ; keep old input handle on stack
|
||||
dd HANDLE.IN, xstore
|
||||
dd ERR.CATCH,xdup,nzbranch,.err
|
||||
|
||||
|
||||
dd drop
|
||||
dd RUNPTR,fetch,HERE,xstore ;abandon current execution
|
||||
dd parsereset ;will force a line load
|
||||
|
||||
.loop: dd INTERPRET,branch,.loop ; no way out except EOF
|
||||
|
||||
.err: dd drop ;error number
|
||||
.err:
|
||||
dd drop ;error number
|
||||
dd HANDLE.IN,fetch,osclose,drop
|
||||
|
||||
dd xpop,HANDLE.IN,xstore
|
||||
|
||||
dd parsereset
|
||||
;;; We were invoked with a [ " foo.f" load ], and must not return there, as it was
|
||||
;;; erased prior to load! Instead, return to the level above, INTERPRET or another
|
||||
;;; layer of load when nested...
|
||||
dd xpop,drop
|
||||
dd return
|
||||
|
||||
;;HEADN included,"included;",docol
|
||||
;; dd uncompile
|
||||
;; dd xloadh
|
||||
;; dd xpop,drop ;return up
|
||||
;; dd return
|
||||
|
||||
HEADN included,"included",docol
|
||||
|
||||
dd drop
|
||||
dd xpush,zero,zero,xpop ;0,0,path
|
||||
dd osopen
|
||||
dd xloadh
|
||||
dd return
|
||||
|
||||
;;;(name,namelen--)
|
||||
HEADN included_ret,"included;",docol
|
||||
dd drop
|
||||
dd xpush,zero,zero,xpop ; --0,0,path
|
||||
dd osopen
|
||||
dd uncompile
|
||||
dd xloadh
|
||||
dd xpop,drop
|
||||
dd return ; --handle or error..
|
||||
|
||||
;;; autorun "autoexec.f" if it exists.
|
||||
;;; _autofname:db "autoexec.f",0
|
||||
HEAD autoexec,docol
|
||||
dd lit,argv,fetch
|
||||
|
||||
dd xdup,zbranch,@f
|
||||
dd zero,included
|
||||
dd xdup
|
||||
@@: dd drop,return
|
||||
|
||||
FINALHEAD = LASTHEAD
|
||||
align 4
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,8 @@
|
|||
fasm.1.73.29
|
||||
|
||||
The file 'fasm' is originally fasm.x64.
|
||||
fasmlist is an executable that generates a listing from the .sym file:
|
||||
|
||||
fasm test.asm -s test.sym
|
||||
fasmlist -a test.sym test.lst
|
||||
|
Loading…
Reference in New Issue