Saturday, 3 November 2007

duped by forth

Forth being a stack language a common exercise is writing a definition of 2DUP that copies the top two items on the stack.

It is cheating to look into the guts of your favourite forth compiler.

I figured quickly that -

: 2DUP dup rot dup rot swap ;

Would work - but it is not exactly going to be fast to execute five steps.

It is a bad sign that dup rot is in there twice so is there some word that does dup rot already?
Well there doesn’t seem to be.

However the word over is also a kind of dup but it duplicates the 2nd value on the stack and brings it the top.

So my second attempt is : 2DUP (n1 n2 - - n1 n2 n1 n2 ) over over ;

This decompiles as:-
8 # EBP SUB EBX 4 [EBP] MOV 8 [EBP] EAX MOV EAX 0 [EBP] MOV
so has to be quite good..

This decompiles the same as the built in definition on the system that I am using (which uses EBP as the data stack and ESP as the return stack.)
There other bad ways of writing 2DUP one way is to use tuck instead of the first over

: 2DUP tuck over ;

This also works but is worse code as tuck does more work than over does.

One annoying thing about forth is that forth kernels tend to be written in assembly language – there is a long tradition of doing that for performance.

It is a shame that more use is not made of optimizing meta-compilers so that more of Forth can be written in Forth and then we could see how the experts would write these standard words.

No comments: