implement if and then

llvm
Clyne 2 years ago
parent 501ca28d50
commit 78507c65c4
Signed by: clyne
GPG Key ID: 4C835D6F5F30690A

@ -23,6 +23,8 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
static bool okay = false;
static void parseLine(Parser&, State&, std::string_view); static void parseLine(Parser&, State&, std::string_view);
static void parseFile(Parser&, State&, std::istream&); static void parseFile(Parser&, State&, std::istream&);
@ -38,6 +40,7 @@ int main(int argc, char *argv[])
parseFile(parser, state, file); parseFile(parser, state, file);
} }
okay = true;
//std::cout << state.size() << ' ' << state.compiling << "> "; //std::cout << state.size() << ' ' << state.compiling << "> ";
parseFile(parser, state, std::cin); parseFile(parser, state, std::cin);
@ -65,8 +68,12 @@ void parseLine(Parser& parser, State& state, std::string_view line)
r = parser.parse(state, line); r = parser.parse(state, line);
} while (r == ParseStatus::Continue); } while (r == ParseStatus::Continue);
if (r != ParseStatus::Finished) if (r == ParseStatus::Finished) {
if (okay)
std::cout << " ok" << std::endl;
} else {
std::cout << to_string(r) << ": " << line << std::endl; std::cout << to_string(r) << ": " << line << std::endl;
}
} }
void parseFile(Parser& parser, State& state, std::istream& file) void parseFile(Parser& parser, State& state, std::istream& file)

@ -48,11 +48,12 @@ Func CoreWords::get(int index)
case 24: return op_colon; case 24: return op_colon;
case 25: return op_semic; case 25: return op_semic;
case 26: return op_here; case 26: return op_here;
case 27: return op_exit; case 27: return op_imm;
case 28: return op_imm; case 28: return op_const;
case 29: return op_const; case 29: return op_if;
case 30: return op_literal; case 30: return op_then;
case 31: return op_jump; case 31: return op_literal;
case 32: return op_jump;
default: return nullptr; default: return nullptr;
} }
} }
@ -225,12 +226,6 @@ int CoreWords::op_here(State& state) {
return 0; return 0;
} }
int CoreWords::op_exit(State& state)
{
state.ip = state.popr();
return 0;
}
int CoreWords::op_imm(State& state) int CoreWords::op_imm(State& state)
{ {
state.dict.write(state.dict.latest, state.dict.write(state.dict.latest,
@ -259,6 +254,31 @@ int CoreWords::op_jump(State& state)
return 0; return 0;
} }
int CoreWords::op_if(State& state)
{
if (state.compiling) {
state.push(state.dict.here);
state.dict.add(0);
} else {
if (state.pop())
++state.ip;
else
state.ip = state.beyondip() - 1;
}
return 0;
}
int CoreWords::op_then(State& state)
{
if (state.compiling) {
const auto ifaddr = state.pop();
state.dict.write(ifaddr, state.dict.here);
}
return 0;
}
int CoreWords::findi(std::string_view str) int CoreWords::findi(std::string_view str)
{ {
std::size_t i; std::size_t i;
@ -267,26 +287,28 @@ int CoreWords::findi(std::string_view str)
std::string_view words (wordsarr, sizeof(wordsarr)); std::string_view words (wordsarr, sizeof(wordsarr));
for (i = 0; i < words.size();) { for (i = 0; i < words.size();) {
const auto end = words.find('\0', i); const auto end = words.find_first_of({"\0\1", 2}, i);
if (words.compare(i, end - i, str) == 0) if (words.compare(i, end - i, str) == 0)
break; return words[end] == '\0' ? wordsi : (wordsi | CoreImmediate);
++wordsi; ++wordsi;
i = end + 1; i = end + 1;
} }
return wordsi < VisibleWordCount ? wordsi : -1; return -1;
} }
Func CoreWords::find(std::string_view str) Func CoreWords::find(std::string_view str)
{ {
const auto i = findi(str); const auto i = findi(str);
return i >= 0 ? get(i) : nullptr; return i >= 0 ? get(i & ~CoreWords::CoreImmediate) : nullptr;
} }
void CoreWords::run(int i, State& state) void CoreWords::run(int i, State& state)
{ {
i &= ~CoreWords::CoreImmediate;
if (i >= 0 && i < WordCount) if (i >= 0 && i < WordCount)
get(i)(state); get(i)(state);
} }

@ -27,12 +27,13 @@ int user_sys(State&);
class CoreWords class CoreWords
{ {
public: public:
constexpr static std::size_t VisibleWordCount = 30; // size constexpr static std::size_t VisibleWordCount = 31; // size
constexpr static std::size_t HiddenWordLiteral = 30; // index constexpr static auto HiddenWordLiteral = VisibleWordCount; // index
constexpr static std::size_t HiddenWordJump = 31; // index constexpr static auto HiddenWordJump = VisibleWordCount + 1; // index
constexpr static std::size_t WordCount = 32; // size constexpr static auto WordCount = HiddenWordJump + 1; // size
constexpr static Cell Immediate = (1 << 5); constexpr static Cell Immediate = (1 << 5);
constexpr static Cell CoreImmediate = (1 << 6);
static int findi(std::string_view); static int findi(std::string_view);
static Func find(std::string_view); static Func find(std::string_view);
@ -45,8 +46,8 @@ private:
"@\0!\0rot\0>r\0r>\0" "@\0!\0rot\0>r\0r>\0"
"=\0<\0allot\0&\0|\0" "=\0<\0allot\0&\0|\0"
"^\0<<\0>>\0(\0:\0" "^\0<<\0>>\0(\0:\0"
";\0here\0exit\0imm\0const\0"; ";\1here\0imm\0const\0"
// lit, jmp, jmp0, ', lits "if\1then\1";
static Func get(int); static Func get(int);
@ -77,11 +78,12 @@ private:
static int op_colon(State&); static int op_colon(State&);
static int op_semic(State&); static int op_semic(State&);
static int op_here(State&); static int op_here(State&);
static int op_exit(State&);
static int op_imm(State&); static int op_imm(State&);
static int op_const(State&); static int op_const(State&);
static int op_literal(State&); static int op_literal(State&);
static int op_jump(State&); static int op_jump(State&);
static int op_if(State&);
static int op_then(State&);
}; };
#endif // ALEEFORTH_COREWORDS_HPP #endif // ALEEFORTH_COREWORDS_HPP

@ -35,9 +35,6 @@ void Dictionary::addDefinition(std::string_view str)
add(str.size()); add(str.size());
for (char c : str) for (char c : str)
add(c); add(c);
if (here & 1)
allot(1);
} }
bool Dictionary::issame(Addr addr, std::string_view str, std::size_t n) bool Dictionary::issame(Addr addr, std::string_view str, std::size_t n)
@ -75,6 +72,6 @@ Addr Dictionary::find(std::string_view str)
Addr Dictionary::getexec(Addr addr) Addr Dictionary::getexec(Addr addr)
{ {
const auto len = read(addr) & 0x1F; const auto len = read(addr) & 0x1F;
return ((addr + 1 + len) + 1) & ~1; return addr + 1 + len;
} }

@ -39,7 +39,7 @@ ParseStatus Parser::parse(State& state, std::string_view& str)
break; break;
case Pass::Colon: case Pass::Colon:
state.pass = Pass::None; state.pass = Pass::None;
state.compiling = true; state.compiling = true;
state.dict.addDefinition(sub); state.dict.addDefinition(sub);
break; break;
case Pass::Constant: case Pass::Constant:
@ -57,9 +57,9 @@ ParseStatus Parser::parse(State& state, std::string_view& str)
} else { } else {
if (auto i = CoreWords::findi(sub); i >= 0) { if (auto i = CoreWords::findi(sub); i >= 0) {
if (state.compiling) if (state.compiling)
state.dict.add(i); state.dict.add(i & ~CoreWords::CoreImmediate);
if (!state.compiling || sub.front() == ';') if (!state.compiling || (i & CoreWords::CoreImmediate))
CoreWords::run(i, state); CoreWords::run(i & ~CoreWords::CoreImmediate, state);
} else if (auto j = state.dict.find(sub); j > 0) { } else if (auto j = state.dict.find(sub); j > 0) {
auto e = state.dict.getexec(j); auto e = state.dict.getexec(j);

Loading…
Cancel
Save