Frank Buss <··@frank-buss.de> writes:
> I'm designing a CPU with an instruction set like Forth:
> [...]
> (defun test ()
> (assemble
> "
> .org 0
> .db 1 2 3 4 5
> .db 100 101 102 103 104 105
>
> .org #x100
> push byte 5 ; i=5
> :loop dup popa ; i
> @A byte ; (i) i
> over ; i (i) i
> push byte 6 ; 6 i (i) i
> add popa ; (i) i
> @A byte ; (6+i) (i) i
> over ; (i) (6+i) i
> !A byte ; (6+i) i
> over popa ; (6+i) i
> !A byte ; i
> dec ; i-1
> bcc byte :loop +PC
> drop ; empty stack
> stop
> ")
> (execute #x100))
BAD! BAD! BAD!
If you do it like this, we cannot use lisp macros to generate the
assembler code!
(defmacro while (condition &body body)
(let ((cond-label (gensym))
(end-label (gensym)))
`(forth-asm
,cond-label
(forth-asm ,condition)
--
__Pascal Bourguignon__ http://www.informatimago.com/
In a World without Walls and Fences,
who needs Windows and Gates?
Frank Buss <··@frank-buss.de> writes:
> I'm designing a CPU with an instruction set like Forth:
> [...]
> (defun test ()
> (assemble
> "
> .org 0
> .db 1 2 3 4 5
> .db 100 101 102 103 104 105
>
> .org #x100
> push byte 5 ; i=5
> :loop dup popa ; i
> @A byte ; (i) i
> over ; i (i) i
> push byte 6 ; 6 i (i) i
> add popa ; (i) i
> @A byte ; (6+i) (i) i
> over ; (i) (6+i) i
> !A byte ; (6+i) i
> over popa ; (6+i) i
> !A byte ; i
> dec ; i-1
> bcc byte :loop +PC
> drop ; empty stack
> stop
> ")
> (execute #x100))
BAD! BAD! BAD!
If you do it like this, we cannot use lisp macros to generate the
assembler code!
;; just an example, I've not learned the opcodes to generate correct code.
(defmacro while (condition &body body)
(let ((cond-label (gensym))
(end-label (gensym)))
`(forth-asm
,cond-label
,@condition
(bne byte ,end-label +pc)
,@body
(bt ,cond-label)
,end-label)))
(macroexpand-1 '(while ((dup popa) (push byte 0) (cmp byte))
(push byte -1)
--> (FORTH-ASM #1=#:G6869 (DUP POPA) (PUSH BYTE 0) (CMP BYTE)
(BNE BYTE #2=#:G6870 +PC) (PUSH BYTE -1) (ADD POPA) (BT #1#) #2#)
Moreover, if you take sexps instead of strings, you don't have to
parse anything, and you can use full lisp as a preprocessor to the
assembler:
(forth-asm
(push #.(+ some-label +cdr-offset+))
...)
--
__Pascal Bourguignon__ http://www.informatimago.com/
In a World without Walls and Fences,
who needs Windows and Gates?
Frank Buss wrote:
> Maybe someone wants to write the "execute" function to simulate the CPU?
> After executing the test program, the bytes from 0 to 5 should be swapped
> with the bytes from 6 to 11.
I've changed it to s-expressions and implemented a first version of the
execute function. There was a minor bug in the Forth test program. I wonder
how a Forth programmer writes programs, without confusing which and how
many values are on stack.
http://www.frank-buss.de/tmp/forth-cpu.lisp.txt
--
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Frank Buss <··@frank-buss.de> writes:
> Frank Buss wrote:
>
>> Maybe someone wants to write the "execute" function to simulate the CPU?
>> After executing the test program, the bytes from 0 to 5 should be swapped
>> with the bytes from 6 to 11.
>
> I've changed it to s-expressions and implemented a first version of the
> execute function. There was a minor bug in the Forth test program. I wonder
> how a Forth programmer writes programs, without confusing which and how
> many values are on stack.
I suspect that they keep whiteboards near their workstations.
In article <······························@40tude.net>, Frank Buss
<··@frank-buss.de> wrote:
> ... I wonder
> how a Forth programmer writes programs, without confusing which and how
> many values are on stack.
With a text editor, of course. Writing small functions helps. Back in
the day the old 16x64 (most forths) or 24x40 (apple II forths) screen
editors enforced this the hard way; this was relaxed considerably in
more modern forths with filesystem support. After awhile your brain
just handles it all without effort.
I still think forth style took an irreparable hit in the move from
screen editors to file editors, but then I think it's been all downhill
since FIG-forth.
Frank Buss wrote:
> Frank Buss wrote:
>
>
>>Maybe someone wants to write the "execute" function to simulate the CPU?
>>After executing the test program, the bytes from 0 to 5 should be swapped
>>with the bytes from 6 to 11.
>
>
> I've changed it to s-expressions and implemented a first version of the
> execute function. There was a minor bug in the Forth test program. I wonder
> how a Forth programmer writes programs, without confusing which and how
> many values are on stack.
>
> http://www.frank-buss.de/tmp/forth-cpu.lisp.txt
If you'd crossposted this to c.l.forth, you'd have way more
answers to that than you ever wanted. The most popular
one would be the Method Advocated by Primal Authority: Chuck
Moore says that in his code, the stack rarely gets deeper
than seven items. Obviously, if you can't keep track of
that much data in your head, you're not a Real Programmer.
(Now, what the heck was I doing before I got distracted by
this thread....?)
-- JK