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 <vector>
static bool okay = false;
static void parseLine(Parser&, State&, std::string_view);
static void parseFile(Parser&, State&, std::istream&);
@ -38,6 +40,7 @@ int main(int argc, char *argv[])
parseFile(parser, state, file);
}
okay = true;
//std::cout << state.size() << ' ' << state.compiling << "> ";
parseFile(parser, state, std::cin);
@ -65,9 +68,13 @@ void parseLine(Parser& parser, State& state, std::string_view line)
r = parser.parse(state, line);
} 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;
}
}
void parseFile(Parser& parser, State& state, std::istream& file)
{

@ -48,11 +48,12 @@ Func CoreWords::get(int index)
case 24: return op_colon;
case 25: return op_semic;
case 26: return op_here;
case 27: return op_exit;
case 28: return op_imm;
case 29: return op_const;
case 30: return op_literal;
case 31: return op_jump;
case 27: return op_imm;
case 28: return op_const;
case 29: return op_if;
case 30: return op_then;
case 31: return op_literal;
case 32: return op_jump;
default: return nullptr;
}
}
@ -225,12 +226,6 @@ int CoreWords::op_here(State& state) {
return 0;
}
int CoreWords::op_exit(State& state)
{
state.ip = state.popr();
return 0;
}
int CoreWords::op_imm(State& state)
{
state.dict.write(state.dict.latest,
@ -259,6 +254,31 @@ int CoreWords::op_jump(State& state)
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)
{
std::size_t i;
@ -267,26 +287,28 @@ int CoreWords::findi(std::string_view str)
std::string_view words (wordsarr, sizeof(wordsarr));
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)
break;
return words[end] == '\0' ? wordsi : (wordsi | CoreImmediate);
++wordsi;
i = end + 1;
}
return wordsi < VisibleWordCount ? wordsi : -1;
return -1;
}
Func CoreWords::find(std::string_view 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)
{
i &= ~CoreWords::CoreImmediate;
if (i >= 0 && i < WordCount)
get(i)(state);
}

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

@ -35,9 +35,6 @@ void Dictionary::addDefinition(std::string_view str)
add(str.size());
for (char c : str)
add(c);
if (here & 1)
allot(1);
}
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)
{
const auto len = read(addr) & 0x1F;
return ((addr + 1 + len) + 1) & ~1;
return addr + 1 + len;
}

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

Loading…
Cancel
Save