From bc118ad31f2d74b5d5e9e3742e52fc441722c679 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Mon, 20 Feb 2023 19:00:30 -0500 Subject: [PATCH] concise parser; >body, >in, source --- compat.txt | 6 +-- core.fth | 11 ++++-- corewords.cpp | 48 ++++++++++-------------- corewords.hpp | 5 +-- parser.cpp | 101 ++++++++++++++++++++++---------------------------- parser.hpp | 1 + 6 files changed, 78 insertions(+), 94 deletions(-) diff --git a/compat.txt b/compat.txt index bab23a7..ae1b2db 100644 --- a/compat.txt +++ b/compat.txt @@ -36,8 +36,8 @@ yes 6.1.0480 < 6.1.0490 <# yes 6.1.0530 = yes 6.1.0540 > - 6.1.0550 >BODY - 6.1.0560 >IN +yes 6.1.0550 >BODY +yes 6.1.0560 >IN 6.1.0570 >NUMBER yes 6.1.0580 >R yes 6.1.0630 ?DUP @@ -112,7 +112,7 @@ yes 6.1.2162 RSHIFT 6.1.2170 S>D 6.1.2210 SIGN 6.1.2214 SM/REM - 6.1.2216 SOURCE +yes 6.1.2216 SOURCE yes 6.1.2220 SPACE yes 6.1.2230 SPACES yes 6.1.2250 STATE diff --git a/core.fth b/core.fth index 8c57e6d..7164597 100644 --- a/core.fth +++ b/core.fth @@ -31,12 +31,13 @@ : base 0 ; : _latest 1 cells ; +: imm _latest @ dup @ 1 5 << | swap ! ; : state 2 cells ; -: decimal 1 1+ base ! 1010 base ! ; +: postpone 1 3 cells ! ; imm +: _input 4 cells ; -: imm _latest @ dup @ 1 5 << | swap ! ; +: decimal 1 1+ base ! 1010 base ! ; -: postpone 1 3 cells ! ; imm : ['] ' postpone literal ; imm : [ 0 state ! ; imm : ] 1 state ! ; @@ -113,7 +114,11 @@ 2 cells + ['] _jmp over ! cell+ here swap ! ] ; +: >body cell+ @ ; : variable create 1 cells allot ; : constant create , does> ['] @ , postpone ; ; ( TODO fix compile-time does>... above should simply be "does> @ ;" ) + +: >in _input 80 chars + cell+ _input @ - 4 chars - ; +: source _input @ 6 chars + >in 3 chars - swap ; diff --git a/corewords.cpp b/corewords.cpp index fff6d9f..de71f3e 100644 --- a/corewords.cpp +++ b/corewords.cpp @@ -21,15 +21,14 @@ Func CoreWords::get(int index) { static const Func ops[WordCount] = { - op_drop, op_dup, op_swap, op_pick, op_sys, - op_add, op_sub, op_mul, op_div, op_mod, - /*10*/ op_peek, op_poke, op_rot, op_pushr, op_popr, - op_eq, op_lt, op_allot, op_and, op_or, - /*20*/ op_xor, op_shl, op_shr, op_comment, op_colon, - op_semic, op_here, op_const, op_depth, op_key, - /*30*/ op_exit, op_tick, op_execute, op_jmp, op_jmp0, - op_lit, op_literal, - op_jump + op_drop, op_dup, op_swap, op_pick, op_sys, + op_add, op_sub, op_mul, op_div, op_mod, + /*10*/ op_peek, op_poke, op_rot, op_pushr, op_popr, + op_eq, op_lt, op_allot, op_and, op_or, + /*20*/ op_xor, op_shl, op_shr, op_comment, op_colon, + op_semic, op_here, op_const, op_depth, op_key, + /*30*/ op_exit, op_tick, op_execute, op_jmp, op_jmp0, + op_lit, op_literal }; return index >= 0 && index < WordCount ? ops[index] : nullptr; @@ -162,20 +161,19 @@ void CoreWords::op_comment(State& state) { } void CoreWords::op_colon(State& state) { - if (state.compiling()) { - Word word = state.dict.input(); - while (word.size() == 0) { - state.input(state); - word = state.dict.input(); - } - - const auto start = state.dict.alignhere(); - state.dict.addDefinition(word); - state.dict.write(start, - (state.dict.read(start) & 0x1F) | - ((start - state.dict.latest()) << 6)); - state.dict.latest(start); + Word word = state.dict.input(); + while (word.size() == 0) { + state.input(state); + word = state.dict.input(); } + + const auto start = state.dict.alignhere(); + state.dict.addDefinition(word); + state.dict.write(start, + (state.dict.read(start) & 0x1F) | + ((start - state.dict.latest()) << 6)); + state.dict.latest(start); + state.compiling(true); } void CoreWords::op_tick(State& state) { @@ -243,12 +241,6 @@ void CoreWords::op_literal(State& state) } } -void CoreWords::op_jump(State& state) -{ - state.pushr(state.ip + sizeof(Cell)); - op_jmp(state); -} - void CoreWords::op_jmp(State& state) { state.ip = state.beyondip() - sizeof(Cell); diff --git a/corewords.hpp b/corewords.hpp index af719b7..0c00100 100644 --- a/corewords.hpp +++ b/corewords.hpp @@ -29,9 +29,7 @@ void user_sys(State&); class CoreWords { public: - constexpr static std::size_t VisibleWordCount = 37; // size - constexpr static auto HiddenWordJump = VisibleWordCount; // index - constexpr static auto WordCount = VisibleWordCount + 1; // size + constexpr static std::size_t WordCount = 37; constexpr static Cell Immediate = (1 << 5); constexpr static Cell Compiletime = (1 << 6); @@ -85,7 +83,6 @@ private: static void op_here(State&); static void op_const(State&); static void op_lit(State&); - static void op_jump(State&); static void op_depth(State&); static void op_key(State&); static void op_exit(State&); diff --git a/parser.cpp b/parser.cpp index b78390c..3c54adc 100644 --- a/parser.cpp +++ b/parser.cpp @@ -52,69 +52,58 @@ ParseStatus Parser::parseSource(State& state) ParseStatus Parser::parseWord(State& state, Word word) { - // TODO unify core-word and defined-word parsing/execution. + int ins, imm; - if (auto i = CoreWords::findi(state, word); i >= 0) { - auto p = state.dict.read(Dictionary::Postpone); - auto imm = (i & CoreWords::Compiletime); + ins = CoreWords::findi(state, word); + if (ins < 0) { + ins = state.dict.find(word); - if (state.compiling() || p) { - if (p || !imm) { - state.dict.add(i & ~CoreWords::Compiletime); - - if (p) - state.dict.write(Dictionary::Postpone, 0); - } else if (imm) { - CoreWords::run(i & ~CoreWords::Compiletime, state); - } + if (ins <= 0) { + return parseNumber(state, word); } else { - if (state.dict.equal(word, ":")) - state.compiling(true); - - CoreWords::run(i & ~CoreWords::Compiletime, state); - } - } else if (auto j = state.dict.find(word); j > 0) { - auto e = state.dict.getexec(j); - auto p = state.dict.read(Dictionary::Postpone); - - if (state.compiling() || p) { - auto imm = state.dict.read(j) & CoreWords::Immediate; - - if (p || !imm) { - state.dict.add(CoreWords::HiddenWordJump); - state.dict.add(e); - - if (p) - state.dict.write(Dictionary::Postpone, 0); - } else if (imm) { - state.execute(e); - } - } else { - state.execute(e); + imm = state.dict.read(ins) & CoreWords::Immediate; + ins = state.dict.getexec(ins); } } else { - char buf[word.size() + 1]; - for (unsigned i = 0; i < word.size(); ++i) - buf[i] = state.dict.readbyte(word.start + i); - buf[word.size()] = '\0'; - - char *p; - const auto base = state.dict.read(0); - const Cell l = std::strtol(buf, &p, base); - - if (std::distance(buf, p) == word.size()) { - if (state.compiling()) { - state.dict.add(CoreWords::findi("_lit")); - state.dict.add(l); - } else { - state.push(l); - } - } else { - std::cout << "word not found: " << buf << std::endl; - return ParseStatus::NotAWord; - } + imm = ins & CoreWords::Compiletime; + ins &= ~CoreWords::Compiletime; + } + + if (state.dict.read(Dictionary::Postpone)) { + state.dict.add(ins); + state.dict.write(Dictionary::Postpone, 0); + } else if (state.compiling() && !imm) { + state.dict.add(ins); + } else { + state.execute(ins); } return ParseStatus::Finished; } +ParseStatus Parser::parseNumber(State& state, Word word) +{ + char buf[word.size() + 1]; + for (unsigned i = 0; i < word.size(); ++i) + buf[i] = state.dict.readbyte(word.start + i); + buf[word.size()] = '\0'; + + char *p; + const auto base = state.dict.read(0); + const Cell l = std::strtol(buf, &p, base); + + if (std::distance(buf, p) == word.size()) { + if (state.compiling()) { + state.dict.add(CoreWords::findi("_lit")); + state.dict.add(l); + } else { + state.push(l); + } + + return ParseStatus::Finished; + } else { + std::cout << "word not found: " << buf << std::endl; + return ParseStatus::NotAWord; + } +} + diff --git a/parser.hpp b/parser.hpp index 49223f0..ccd5647 100644 --- a/parser.hpp +++ b/parser.hpp @@ -31,6 +31,7 @@ public: private: ParseStatus parseSource(State&); ParseStatus parseWord(State&, Word); + ParseStatus parseNumber(State&, Word); }; #endif // ALEEFORTH_PARSER_HPP