If the stack head of the stack is true (#t) then execute next function
otherwise execute function after that one. I chose to only execute one
function because i thought it would make the implementation much
simpler.
I needed a nice little function for incrementing as well.
,----
| (inc 1 +)
`----
And those will be all the control flow constructs that we need, more
can be created by using user functions.
fix complex number bug
======================
So it turns out that that bug doesn't appear when I use gerbil
scheme's interpreter with R7RS language option, so it might be a bug
in chibi-scheme, I will try with the HEAD of chibi-scheme's git repo,
not the 0.8 release.
Just tried the latest HEAD of the chibi-scheme git repo, yeah it still
happens.
However after trying the same function in chicken scheme's
interpreter, it yielded the correct result. Very strange. But it
behaves strangely, the chicken interpreter (v4.12) also does the same
thing where it only reads one function invocation per line and only
prints one thing at a time, unlike chibi-scheme which I have been
testing on. It seems to mostly happen with the $ operator.
Tried chicken-scheme v5 with the r7rs egg and it performs the
quadratic calculation correctly, but still doesn't like the $ or D
operator.
I think chibi-schemes handling of /read/ and handling of complex
numbers differs from both gerbil and chicken scheme.
The second $ only prints after I do another operation on the stack, in
this case push a 1. I've tried adding /flush-output-port/ to various
spots, to the definition of $ and D, and the start of the main loop,
but to no avail.
More experimentation has led me to the fact that gerbil doesn't
execute the last function when it reads, until you enter more stuff in
next time. I can write a a hacky workaround so that every time you
manually type into the command line just type the END operator and
it'll be a dummy operator that does nothing but return the stack.
It works but I would rather not keep it permanantly. It seems like
gerbil has this off-by-one sort of error when I /read/ in the main
loop.
R7RS compatability
==================
I just want to take a moment to mention some scheme implementations
and their differences when running this program.
I've mostly been using chibi-scheme to test this code, which works
perfectly except for the complex number bug. Where as both gerbil and
chicken scheme (with their respective r7rs libraries) fail in the same
ways.
1. The if function we defined doesn't work if the result of = is true
2. And still the weird output when displaying.
Here's an example of number one.
,----
| 1 1 1 0 = if + - D END
| (1 1)
| D END
| (2)
| ;; WTF??? why does it print (1 1) when the satck should be (2)??
| ;; AND THEN WHY IS IT NOT (0)???
| $ END
| 2
| ;; now stack is empty
| 1 1 1 1 = if + - D END
|
| Error: (car) bad argument type: ()
`----
Maybe I'm getting tripped up by the r7rs spec just leaving the order
of evaluation for arguments up to the implementation? Because
chibi-scheme strictly does right-to-left evaluation, maybe chicken and
gerbil left-to-right? or unspecified?
What I'm going to try is moving the input in the main loop to be that
last arg for /loop/.
HOLY FUCK THAT ACTUALLY FIXED IT. Now when I run it in chicken scheme
or gerbil it works PERFECTLY. And now chibi-scheme bugs out the same
as chicken and gerbil did. Fuckin' hell.
So that means that both gerbil and chicken evaluate
left-to-right. Confirmed.
So to have it work the same in all the schemes, I could use the
/delay/ and /force/ lazy evaluation primitives, to delay the /read/
call until we are in the loop. And after testing that works, fuck
yeah.
Conclusion
==========
So this time it turned into a whole bunch of bug hunting, and getting
royally bit by the scheme spec. But its not so bad, the fix was
pretty trivial. Next time we will FINALLY get around to some macros
and more RPN programming. If you have any features you would like to
see feel free to email me.