From 599e15e9e4cab7f2f7d4e13120ff02ed6cdf5bd7 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Mon, 2 Dec 2024 20:56:48 -0500 Subject: [PATCH] fix case insensitivity --- Makefile | 2 +- core.fth | 22 +++--- main.cpp | 14 ++-- sforth/comp_word.hpp | 2 +- sforth/forth.hpp | 151 ++++++++++++++++++++++------------------- sforth/native_word.hpp | 2 +- 6 files changed, 103 insertions(+), 90 deletions(-) diff --git a/Makefile b/Makefile index f61f58d..e9e7430 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ #CXX := clang++-19 -CXXFLAGS += -m32 -Os -std=c++23 -Wall -Wextra -Wpedantic -ggdb -g3 +CXXFLAGS += -m32 -O0 -std=c++23 -Wall -Wextra -Wpedantic -ggdb -g3 all: main diff --git a/core.fth b/core.fth index 24f6820..82763e9 100644 --- a/core.fth +++ b/core.fth @@ -1,4 +1,4 @@ -: ['] ' [ ' literal , ] ; immediate +: ['] ' postpone literal ; immediate : if ['] _jmp0 , here 0 , ; immediate : then here swap ! ; immediate @@ -59,14 +59,16 @@ dup here c! \ bl key u here + c! \ bl repeat 2drop here ; -: count dup char+ swap c@ ; -: char 0 here char+ c! bl word char+ c@ ; -: [char] char postpone literal ; immediate +: count dup char+ swap c@ ; +: char 0 here char+ c! bl word char+ c@ ; +: [char] char postpone literal ; immediate -: s" state @ if ['] _jmp , here 0 , then - [char] " word count - state @ 0= if exit then - dup cell+ allot - rot here swap ! - swap postpone literal postpone literal ; immediate +: s" state @ if ['] _jmp , here 0 , then + [char] " word count + state @ 0<> if + dup cell+ allot + rot here swap ! + swap postpone literal postpone literal then ; immediate + +: ( begin [char] ) key = until ; immediate diff --git a/main.cpp b/main.cpp index d30b815..06dad34 100644 --- a/main.cpp +++ b/main.cpp @@ -37,10 +37,10 @@ constinit static sforth::native_word<".", [](auto) { if (neg) *--ptr = '-'; std::cout << ptr << ' '; }> dot; -constinit static sforth::native_word<"emit", [](auto) { +constinit static sforth::native_word<"EMIT", [](auto) { std::cout << static_cast(forth.pop()); }, &dot> emit; -constinit static sforth::native_word<"type", [](auto) { +constinit static sforth::native_word<"TYPE", [](auto) { const unsigned u = forth.pop(); const auto caddr = reinterpret_cast(forth.pop()); std::cout << std::string_view{caddr, u}; @@ -69,14 +69,14 @@ bool parse_stream(auto &fth, std::istream& str, bool say_okay) while (str.good()) { std::getline(str, line); if (!line.empty()) { - if (line == "bye") - return true; - for (auto& ch : line) { - if (ch >= 'A' && ch <= 'Z') - ch = ch - 'A' + 'a'; + if (ch >= 'a' && ch <= 'z') + ch = ch - 'a' + 'A'; } + if (line == "BYE") + return true; + try { fth.parse_line(line); } catch (sforth::error e) { diff --git a/sforth/comp_word.hpp b/sforth/comp_word.hpp index 2b5978d..6e3ac49 100644 --- a/sforth/comp_word.hpp +++ b/sforth/comp_word.hpp @@ -66,7 +66,7 @@ struct comp_word : public native_word if (!n.has_value()) std::unreachable(); - bptr->f = Prev->get_ct("_lit"); + bptr->f = Prev->get_ct("_LIT"); bptr++; bptr->c = *n; bptr++; diff --git a/sforth/forth.hpp b/sforth/forth.hpp index be184c6..de87154 100644 --- a/sforth/forth.hpp +++ b/sforth/forth.hpp @@ -144,7 +144,7 @@ struct forth : public word_list push(*n); if (compiling) - execute((*get("literal"))->body()); + execute((*get("LITERAL"))->body()); } else { auto body = (*ent)->body(); @@ -203,44 +203,55 @@ constexpr auto initialize() }; constexpr static auto& dict1 = native_dict< - S{"_d" }, [](auto) { fthp->push(std::bit_cast(fthp)); }, 0 - , S{"sp" }, [](auto) { fthp->push(std::bit_cast(fthp) + sizeof(cell)); }, 0 - , S{"rp" }, [](auto) { fthp->push(std::bit_cast(fthp) + 2 * sizeof(cell)); }, 0 - , S{"ip" }, [](auto) { fthp->push(std::bit_cast(fthp) + 3 * sizeof(cell)); }, 0 - , S{"dp" }, [](auto) { fthp->push(std::bit_cast(fthp) + 4 * sizeof(cell)); }, 0 - , S{"state"}, [](auto) { fthp->push(std::bit_cast(fthp) + 7 * sizeof(cell)); }, 0 - , S{"base" }, [](auto) { fthp->push(std::bit_cast(fthp) + 8 * sizeof(cell)); }, 0 - , S{"depth"}, [](auto) { fthp->push(std::distance(fthp->sp, fthp->dstack.end())); }, 0 - , S{"unused"}, [](auto) { fthp->push(sizeof(cell) * std::distance(fthp->here, fthp->dict.end())); }, 0 - , S{"_lit" }, lit_impl, 0 - , S{"swap" }, [](auto) { auto a = fthp->pop(); auto b = fthp->pop(); fthp->push(a, b); }, 0 - , S{"drop" }, [](auto) { fthp->pop(); }, 0 - , S{"dup" }, [](auto) { fthp->push(fthp->top()); }, 0 - , S{"rot" }, [](auto) { auto a = fthp->pop(); auto b = fthp->pop(); auto c = fthp->pop(); + S{"_D" }, [](auto) { fthp->push(std::bit_cast(fthp)); }, 0 + , S{"SP" }, [](auto) { fthp->push(std::bit_cast(fthp) + sizeof(cell)); }, 0 + , S{"RP" }, [](auto) { fthp->push(std::bit_cast(fthp) + 2 * sizeof(cell)); }, 0 + , S{"IP" }, [](auto) { fthp->push(std::bit_cast(fthp) + 3 * sizeof(cell)); }, 0 + , S{"DP" }, [](auto) { fthp->push(std::bit_cast(fthp) + 4 * sizeof(cell)); }, 0 + , S{"STATE"}, [](auto) { fthp->push(std::bit_cast(fthp) + 7 * sizeof(cell)); }, 0 + , S{"BASE" }, [](auto) { fthp->push(std::bit_cast(fthp) + 8 * sizeof(cell)); }, 0 + , S{"DEPTH"}, [](auto) { fthp->push(std::distance(fthp->sp, fthp->dstack.end())); }, 0 + , S{"UNUSED"}, [](auto) { fthp->push(sizeof(cell) * std::distance(fthp->here, fthp->dict.end())); }, 0 + , S{"_LIT" }, lit_impl, 0 + , S{"SWAP" }, [](auto) { auto a = fthp->pop(); auto b = fthp->pop(); fthp->push(a, b); }, 0 + , S{"DROP" }, [](auto) { fthp->pop(); }, 0 + , S{"DUP" }, [](auto) { fthp->push(fthp->top()); }, 0 + , S{"ROT" }, [](auto) { auto a = fthp->pop(); auto b = fthp->pop(); auto c = fthp->pop(); fthp->push(b, a, c); }, 0 , S{"+" }, [](auto) { fthp->top() += fthp->pop(); }, 0 , S{"-" }, [](auto) { fthp->top() -= fthp->pop(); }, 0 , S{"*" }, [](auto) { fthp->top() *= fthp->pop(); }, 0 , S{"/" }, [](auto) { fthp->top() /= fthp->pop(); }, 0 - , S{"mod" }, [](auto) { fthp->top() %= fthp->pop(); }, 0 - , S{"and" }, [](auto) { fthp->top() &= fthp->pop(); }, 0 - , S{"or" }, [](auto) { fthp->top() |= fthp->pop(); }, 0 - , S{"xor" }, [](auto) { fthp->top() ^= fthp->pop(); }, 0 - , S{"lshift"}, [](auto) { fthp->top() <<= fthp->pop(); }, 0 - , S{"rshift"}, [](auto) { fthp->top() >>= fthp->pop(); }, 0 + , S{"MOD" }, [](auto) { fthp->top() %= fthp->pop(); }, 0 + , S{"AND" }, [](auto) { fthp->top() &= fthp->pop(); }, 0 + , S{"OR" }, [](auto) { fthp->top() |= fthp->pop(); }, 0 + , S{"XOR" }, [](auto) { fthp->top() ^= fthp->pop(); }, 0 + , S{"LSHIFT"}, [](auto) { fthp->top() <<= fthp->pop(); }, 0 + , S{"RSHIFT"}, [](auto) { + const auto shift = fthp->pop(); + addr val = fthp->pop(); + val >>= shift; + fthp->push(val); }, 0 , S{"[" }, [](auto) { fthp->compiling = false; }, word_base::immediate , S{"]" }, [](auto) { fthp->compiling = true; }, 0 - , S{"immediate"}, [](auto) { const_cast(fthp->next)->make_immediate(); }, 0 - , S{"literal"}, [](auto) { - //assert(fthp->compiling); - *fthp->here++ = std::bit_cast(&lit_impl); - *fthp->here++ = fthp->pop(); }, word_base::immediate + , S{"IMMEDIATE"}, [](auto) { const_cast(fthp->next)->make_immediate(); }, 0 + , S{"LITERAL"}, [](auto x) { + if (fthp->compiling) { + *fthp->here++ = std::bit_cast(&lit_impl); + *fthp->here++ = fthp->pop(); + } else { + lit_impl(x); + } }, word_base::immediate , S{"@" }, [](auto) { fthp->push(*std::bit_cast(fthp->pop())); }, 0 , S{"!" }, [](auto) { auto p = fthp->pop(); *std::bit_cast(p) = fthp->pop(); }, 0 - , S{"c@" }, [](auto) { fthp->push(*std::bit_cast(fthp->pop())); }, 0 - , S{"c!" }, [](auto) { auto p = fthp->pop(); *std::bit_cast(p) = fthp->pop(); }, 0 + , S{"C@" }, [](auto) { fthp->push(*std::bit_cast(fthp->pop())); }, 0 + , S{"C!" }, [](auto) { auto p = fthp->pop(); *std::bit_cast(p) = fthp->pop(); }, 0 , S{"=" }, [](auto) { auto v = fthp->pop(); fthp->top() = -(fthp->top() == v); }, 0 , S{"<" }, [](auto) { auto v = fthp->pop(); fthp->top() = -(fthp->top() < v); }, 0 + , S{"U<" }, [](auto) { + addr v = fthp->pop(); + addr w = fthp->pop(); + fthp->push(-(w < v)); }, 0 , S{"\'" }, [](auto) { auto w = fthp->parse(); auto g = fthp->get(w); @@ -252,76 +263,76 @@ constexpr auto initialize() fthp->compiling = true; }, 0 , S{";" }, [](auto) { *fthp->here++ = 0; fthp->compiling = false; }, word_base::immediate , S{"\\" }, [](auto) { fthp->sourcei = std::string_view::npos; }, word_base::immediate - , S{"cell" }, [](auto) { fthp->push(sizeof(cell)); }, 0 - , S{"_jmp" }, [](auto) { + , S{"CELL" }, [](auto) { fthp->push(sizeof(cell)); }, 0 + , S{"_JMP" }, [](auto) { auto ptr = ++fthp->ip; fthp->ip = *std::bit_cast(ptr) - 1; }, 0 - , S{"_jmp0"}, [](auto) { + , S{"_JMP0"}, [](auto) { auto ptr = ++fthp->ip; if (fthp->pop() == 0) fthp->ip = *std::bit_cast(ptr) - 1; }, 0 - , S{"chars"}, [](auto) {}, 0 - , S{"postpone"}, [](auto) { + , S{"CHARS"}, [](auto) {}, 0 + , S{"POSTPONE"}, [](auto) { assert(fthp->compiling); auto w = fthp->parse(); auto g = fthp->get(w); assert(g.has_value()); *fthp->here++ = std::bit_cast((*g)->body()); }, word_base::immediate - , S{"source"}, [](auto) { + , S{"SOURCE"}, [](auto) { auto len = 0u; while (fthp->source[len]) len++; fthp->push(std::bit_cast(fthp->source)); fthp->push(len); }, 0 - , S{">in"}, [](auto) { fthp->push(std::bit_cast(&fthp->sourcei)); }, 0 - , S{"key"}, [](auto) { + , S{">IN"}, [](auto) { fthp->push(std::bit_cast(&fthp->sourcei)); }, 0 + , S{"KEY"}, [](auto) { if (fthp->sourcei != std::string_view::npos) fthp->push(fthp->source[fthp->sourcei++]); else fthp->push(0); }, 0 >::word; constexpr static auto& dict2 = comp_dictr = r> or"}, 0 - , S{"2!" }, S{"swap over ! cell+ !"}, 0 - , S{"2@" }, S{"dup cell+ @ swap @"}, 0 - , S{"c," }, S{"here c! 1 allot"}, 0 - , S{"exit" }, S{"0 ,"}, word_base::immediate - , S{"," }, S{"here ! cell allot"}, 0 - , S{"allot" }, S{"dp +!"}, 0 - , S{"+!" }, S{"dup >r swap r> @ + swap !"}, 0 - , S{"2swap" }, S{"rot >r rot r>"}, 0 - , S{"2dup" }, S{"over over"}, 0 - , S{"2over" }, S{"3 pick 3 pick"}, 0 - , S{">r" }, S{"rp@ cell - rp ! rp@ cell+ @ rp@ ! rp@ cell+ !"}, 0 - , S{"r>" }, S{"rp@ @ rp@ cell+ rp ! rp@ @ swap rp@ !"}, 0 - , S{"over" }, S{"1 pick"}, 0 - , S{"pick" }, S{"cells cell+ sp@ + @"}, 0 - , S{"sp@" }, S{"sp @"}, 0 - , S{"rp@" }, S{"rp @ cell+"}, 0 - , S{"here" }, S{"dp @"}, 0 - , S{"latest"}, S{"_d @"}, 0 + , S{"ALIGN" }, S{"HERE DUP ALIGNED SWAP - ALLOT"}, 0 + , S{"ALIGNED"}, S{"CELL 1- + CELL 1- INVERT AND"}, 0 + , S{"DECIMAL"}, S{"10 BASE !"}, 0 + , S{"HEX" }, S{"16 BASE !"}, 0 + , S{"<=" }, S{"2DUP < >R = R> OR"}, 0 + , S{"2!" }, S{"SWAP OVER ! CELL+ !"}, 0 + , S{"2@" }, S{"DUP CELL+ @ SWAP @"}, 0 + , S{"C," }, S{"HERE C! 1 ALLOT"}, 0 + , S{"EXIT" }, S{"0 ,"}, word_base::immediate + , S{"," }, S{"HERE ! CELL ALLOT"}, 0 + , S{"ALLOT" }, S{"DP +!"}, 0 + , S{"+!" }, S{"DUP >R SWAP R> @ + SWAP !"}, 0 + , S{"2SWAP" }, S{"ROT >R ROT R>"}, 0 + , S{"2DUP" }, S{"OVER OVER"}, 0 + , S{"2OVER" }, S{"3 PICK 3 PICK"}, 0 + , S{">R" }, S{"RP@ CELL - RP ! RP@ CELL+ @ RP@ ! RP@ CELL+ !"}, 0 + , S{"R>" }, S{"RP@ @ RP@ CELL+ RP ! RP@ @ SWAP RP@ !"}, 0 + , S{"OVER" }, S{"1 PICK"}, 0 + , S{"PICK" }, S{"CELLS CELL+ SP@ + @"}, 0 + , S{"SP@" }, S{"SP @"}, 0 + , S{"RP@" }, S{"RP @ CELL+"}, 0 + , S{"HERE" }, S{"DP @"}, 0 + , S{"LATEST"}, S{"_D @"}, 0 , S{"1-" }, S{"1 -" }, 0 , S{"1+" }, S{"1 +" }, 0 - , S{"cell+" }, S{"cell +"}, 0 - , S{"cells" }, S{"cell *"}, 0 - , S{"char+" }, S{"1 +" }, 0 - , S{"-rot" }, S{"rot rot"}, 0 - , S{"2drop" }, S{"drop drop"}, 0 + , S{"CELL+" }, S{"CELL +"}, 0 + , S{"CELLS" }, S{"CELL *"}, 0 + , S{"CHAR+" }, S{"1 +" }, 0 + , S{"-ROT" }, S{"ROT ROT"}, 0 + , S{"2DROP" }, S{"DROP DROP"}, 0 , S{"0<" }, S{"0 <"}, 0 , S{"0<>" }, S{"0 <>"}, 0 , S{"<>" }, S{"= 0="}, 0 , S{"0=" }, S{"0 ="}, 0 - , S{">" }, S{"swap <"}, 0 - , S{"invert"}, S{"-1 xor"}, 0 - , S{"negate"}, S{"-1 *"}, 0 + , S{">" }, S{"SWAP <"}, 0 + , S{"INVERT"}, S{"-1 XOR"}, 0 + , S{"NEGATE"}, S{"-1 *"}, 0 , S{"2*" }, S{"2 *"}, 0 - , S{"bl" }, S{"32"}, 0 - , S{"false" }, S{"0"}, 0 - , S{"true" }, S{"-1"}, 0 + , S{"BL" }, S{"32"}, 0 + , S{"FALSE" }, S{"0"}, 0 + , S{"TRUE" }, S{"-1"}, 0 >::word; return &dict2; diff --git a/sforth/native_word.hpp b/sforth/native_word.hpp index e3cb867..5a98614 100644 --- a/sforth/native_word.hpp +++ b/sforth/native_word.hpp @@ -31,7 +31,7 @@ struct native_word : public word_base func body; constexpr const func *get_ct(std::string_view name) const { - if (name == std::string_view{Name.data}) + if (name == std::string_view{namebuf.data()}) return &body; else if constexpr (Prev != nullptr) return Prev->get_ct(name);