Commit Graph

370 Commits

Author SHA1 Message Date
Virgil Dupras c3838714d5 forth: improve execution model
My approach with RS was slightly wrong: RS' TOP was always containing current
IP. It worked, but it was problematic when came the time to introduce
RS-modifying words: it's impossible to modify RS in a word without immediately
messing your flow.

Therefore, what used to be RS' TOS has to be a variable that isn't changed
midway by RS-modifying words. I guess that's why RS is called *return* stack...
2020-03-13 16:01:09 -04:00
Virgil Dupras d0d92a4559 forth: Forth-ify IF and ELSE
Now, I really need comments...
2020-03-12 21:49:10 -04:00
Virgil Dupras d5a7d5faf8 forth: add words "(fbr)", "(fbr?)", "'", "[']" 2020-03-12 21:16:20 -04:00
Virgil Dupras fb54fd51af forth: implement THEN in Forth
Also, add "," and "C,"
2020-03-12 13:52:27 -04:00
Virgil Dupras 3819dbc083 forth: remove CMPDST
We now always do ","-style writes in (HERE), even in IMMEDIATE mode. Simplifies
things and paves the way for compiling words in Forth.
2020-03-12 13:08:11 -04:00
Virgil Dupras ff281f69a8 forth: add "UNWORD" flag
Also, reorder word fields so that the flag field is more easily accessible.
2020-03-12 11:39:27 -04:00
Virgil Dupras a8e573c84a forth: add bin dict compilation stage!
Big one.

This allows us to write higher order words directly in Forth, which is much
more convenient than writing post-immediate (see "NOT" structure in diff if
you want to see what I mean) structures in ASM.

These structures can then be written to ROM (rather than loaded in RAM for
definitions loaded at run-time).

That's quite a bit of tooling that was added, 2 compilations stages, but I
think it's well worth it.
2020-03-12 00:14:44 -04:00
Virgil Dupras f89e7bd503 forth: add words "C@" and "C!" 2020-03-11 22:11:54 -04:00
Virgil Dupras 80f63cd185 forth: add words "2DUP", "2SWAP", "2OVER" 2020-03-11 21:58:16 -04:00
Virgil Dupras d8542f7cf7 forth: fix "NOT"
Ouh, I need a solution here...
2020-03-11 19:59:10 -04:00
Virgil Dupras ea5f33558a forth: make branching offsets 1 byte
Those bytes, those precious bytes!
2020-03-11 19:52:49 -04:00
Virgil Dupras 3996f0c825 forth: fix IF/THEN/ELSE in colon defs 2020-03-11 17:53:27 -04:00
Virgil Dupras 02b56c547a forth: make branching cells store relative offsets
This should help with fixing IF/THEN/ELSE in colon defs.
2020-03-11 16:46:25 -04:00
Virgil Dupras 6757c097ea forth: change the whole execution model again
Things are better now, but immediates inside colons are broken. However,
IF/THEN/ELSE are now immediates and it's much cleaner this way. Still, this
commit has too much stuff in it, I need to commit, I don't want to lose this
step.
2020-03-10 21:37:06 -04:00
Virgil Dupras 2ddca57f3f forth: add string and logic routines, as well as "RECURSE"
The goal was to be able to implement "(" in forth, but I realised that my
INTERPRET approach was wrong. Compiling the line beforehand is, after all,
not good. I'll have to change it again.
2020-03-10 16:02:40 -04:00
Virgil Dupras aac0a57a68 forth: add words "PC!" and "PC@" 2020-03-10 13:00:57 -04:00
Virgil Dupras 0b3f6253e4 forth: add support for IMMEDIATE words 2020-03-09 22:13:11 -04:00
Virgil Dupras 03bd9ee39b forth: make readCompWord read from RS' BOS instead of TOS
Previous approach was broken with regards to defined word using CREATE.

Also, reduce name length by one to make space for a new flags field for
"immediate" (which isn't used yet).
2020-03-09 19:50:51 -04:00
Virgil Dupras 0e8af3cea4 forth: clarify the meaning of "wordref"
Also, make entry labels in dict.asm be wordref instead of entry ref.
2020-03-09 15:12:44 -04:00
Virgil Dupras e8a4768304 forth: add words "IF", "ELSE", "THEN" 2020-03-09 14:19:51 -04:00
Virgil Dupras 03e529b762 forth: simplify execution model and handle literals better
This scheme of "when we handle line-by-line, compile one word at a time then
execute" so that we could allow words like "CREATE" to call "readword" before
continuing was a bad scheme. It made things like branching outside of a colon
definition impossible.

This commit implement a new "litWord". When an undefined word is encountered at
compile time, it is included as-is in a string literal word. It is at run time
that we decide what to do with it.
2020-03-09 14:14:26 -04:00
Virgil Dupras 5cadde557c forth: add "VARIABLE" 2020-03-07 22:23:08 -05:00
Virgil Dupras 989d8bbabf forth: add "DOES>" and "CONSTANT" 2020-03-07 22:18:14 -05:00
Virgil Dupras 53024d88f5 forth: add "DUP", "OVER", "SWAP", "?", "+!", "ALLOT" 2020-03-07 21:12:30 -05:00
Virgil Dupras f0cf10ab7c forth: Check for PS underflow 2020-03-07 20:20:11 -05:00
Virgil Dupras 580214426a forth: add +-*/ 2020-03-07 19:42:07 -05:00
Virgil Dupras ad2aca4620 forth: add number literals support 2020-03-07 19:25:55 -05:00
Virgil Dupras 30f188b984 forth: add word ":" 2020-03-07 18:54:16 -05:00
Virgil Dupras e7cd3182d0 forth: add words "CREATE", "@", "!", "HERE", "QUIT" 2020-03-07 17:09:45 -05:00
Virgil Dupras 6f9d28b325 forth: add word "bye"
And make interpret action looping until BYE.
2020-03-07 13:15:19 -05:00
Virgil Dupras 391ddb9984 forth: add word "." 2020-03-07 12:50:54 -05:00
Virgil Dupras 49228e418c apps/forth: new (WIP) application 2020-03-07 12:13:15 -05:00
Virgil Dupras 97dcad9b15 recipes/sms/kbd: use Collapse OS' AVR assembler 2020-02-26 23:10:43 -05:00
Virgil Dupras 6224ea2fe9 zasm: use printcrlf instead of hardcoded CRLF 2020-02-23 18:52:25 -05:00
Virgil Dupras 69f0c6dafd trs80/floppy: implement write 2020-02-22 12:09:43 -05:00
Virgil Dupras 0f2b3aca24 zasm: allow zasm to omit its 3rd argument
A bug in rdWS made zasm error out when omiting its 3rd argument.

fixes #90
2020-02-18 15:46:55 -05:00
Clanmaster21 9cddaf1b59 String functions optimised (#86)
* String functions optimised

A few functions have been tweaked, but the biggest changes are in strlen, strskip and toWS, which take around two third of the cycles they used to (although strskip has more overhead). 10 bytes saved total.
toWS had two bytes added inlining the isWS call, and a jump to unsetZ was inlined too, saving a byte. This saved 29 cycles, with the original function being 90 cycles. I looked at other uses of isWS and it's difficult to inline it effectively in every situation, so I haven't inlined it elsewhere.
rdWS had a byte and two cycles saved by inlining a jump to unsetZ.
strskip is the same size, with the loop cut down from 35 cycles to 21 cycles, but 18 cycles are added outside the loop. I expect one character strings are in the minority, so this should save cycles overall.
strlen had 8 bytes saved, with the loop cut down from 38 cycles to 21 cycles, and 18 cycles removed outside the loop.

* Fixed strskip

Strskip wasn't preserving a properly. The new code uses the shadow af register, so whilst a byte and 4 cycles have been added outside the loop, it's safer and cleaner. The flags register isn't affected, but since the search goes for up to 64Kb I think it's safe to say the end of the string will always be reached.

* Remove inlining of isWS
2020-01-09 20:10:27 -05:00
Clanmaster21 927d5f2392 Reworked parseHexadecimal and parseDecimal, other minor tweaks (#85)
I've tweaked nearly every function in this file, so I'll go through them one by one.
parseDecimal has been reworked a little so that `a` can be used instead of `b` for checking for overflow. I had originally intended to redo it to work like the old parseDecimal, but I think the current method (once reworked a little) is cleaner and smaller, and should be just as fast. 7 bytes and 27 cycles saved.
parseHexadecimal has been changed to load hex digits into `b` `d` `c` `e` from the right (so all the digits move along to the left so the new digit can be inserted on the right), and then only at the end is any shifting done, using the faster `add a, a` to do left shifts. 9 bytes saved and 78 cycles saved inside the loop, and then 49 cycles added after the loop. 
parseBinaryLiteral had a few instructions moved around, saving two bytes and 5 cycles inside the loop, and a further 15 cycles saved on error.
parseLiteral has been reworked slightly, the isDigit call has been replaced with an inline parseDecimalDigit, saving a byte and around 20-30 cycles, with around 16 more cycles saved if the number is a decimal. The .char routine has been reduced by a byte, and 6 cycles saved on success, but 5 cycles added on error.
isDigit has been reduced by 4 bytes and 10 cycles on success, with a few more cycles saved on fail (hard to estimate due to branching).
2020-01-08 16:12:40 -05:00
Virgil Dupras 7ca54d179d lib/expr: make EXPR_PARSE "tail" HL
Things are now much simpler.
2019-12-30 19:24:53 -05:00
Virgil Dupras 73a5275b1e lib/parse: make parseBinaryLiteral "tail" HL 2019-12-30 13:05:21 -05:00
Virgil Dupras 289037a3dd lib/parse: make parseDecimal "tail" HL
HL, instead of being preserved, is set to the character following
the last read character.
2019-12-30 10:13:55 -05:00
Virgil Dupras dcb96aefe9 lib/parse: remove parseHexPair
Also, make parseHexadecimal "tail" (HL). Soon, all routines in lib/parse
will do that, making the life of lib/expr easier.
2019-12-29 21:56:56 -05:00
Virgil Dupras 2503bdfced lib/args: remove 2019-12-29 21:05:09 -05:00
Virgil Dupras 5f2615a134 at28w: don't use lib/args 2019-12-29 21:02:04 -05:00
Virgil Dupras 346bcc3d3d zasm: don't use lib/args
This unit is being removed.
2019-12-29 20:56:13 -05:00
Virgil Dupras d0f031939f lib/parse: make parseLiteral a little tighter
Sub-parsers are seldom used by themselves, except for parseDecimal.
I'm tightening the code of this unit for two reasons:

1. Optimization
2. Upcoming API change where HL won't be preserved anymore, but will
   point to char following the last parse char. This will allow us
   to simplify lib/expr.
2019-12-29 19:47:19 -05:00
Virgil Dupras 15628da7de lib/expr: make EXPR_PARSE put result in DE instead of IX
Finally getting rid of this bad mistake of using IX for this.
2019-12-29 17:37:04 -05:00
Virgil Dupras 981c93bfd4 lib/expr: fix stack imbalance on failure 2019-12-29 16:15:48 -05:00
Virgil Dupras 213614af33 lib/expr: make recursion process a bit more orderly
Instead of going left and right, finding operators chars and replacing them
with nulls, we parse expressions in a more orderly manner, one chunk at a
time. I think it qualifies as "recursive descent", but I'm not sure.

This allows us to preserve the string we parse and should also make the
implementation of parens much easier.
2019-12-29 11:42:18 -05:00
Virgil Dupras 7410891ad1 lib/expr: fix unary minus
For some reason, I've mistakenly disabled tests in test_expr without noticing
and I also broke "-123" parsing. Fixed.
2019-12-23 20:53:31 -05:00