checked in the toolchain

This commit is contained in:
StackSmith 2023-08-31 19:56:26 -04:00
parent e003b50fa2
commit 96a148f58f
7 changed files with 132 additions and 39 deletions

View File

@ -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

View File

@ -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
View File

@ -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

View File

@ -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

BIN
tools/fasm Executable file

Binary file not shown.

BIN
tools/fasmlist Executable file

Binary file not shown.

8
tools/readme.txt Normal file
View File

@ -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