|
|
|
@ -94,7 +94,7 @@ struct ctstring {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<ctstring Name, ctstring Body, auto& Prev>
|
|
|
|
|
template<ctstring Name, ctstring Body, auto *Prev = (const word_base *)nullptr>
|
|
|
|
|
struct comp_word : public word_base
|
|
|
|
|
{
|
|
|
|
|
constexpr static auto N = (sizeof(Name) + sizeof(cell) - 1) & ~(sizeof(cell) - 1);
|
|
|
|
@ -107,7 +107,7 @@ struct comp_word : public word_base
|
|
|
|
|
const auto word = parse(Body.data, sourcei);
|
|
|
|
|
|
|
|
|
|
b++;
|
|
|
|
|
if (!Prev.get_ct(word))
|
|
|
|
|
if (!Prev->get_ct(word))
|
|
|
|
|
b++;
|
|
|
|
|
}
|
|
|
|
|
return b;
|
|
|
|
@ -125,12 +125,14 @@ struct comp_word : public word_base
|
|
|
|
|
consteval const func *get_ct(std::string_view name) const {
|
|
|
|
|
if (name == std::string_view{Name.data})
|
|
|
|
|
return &prologue;
|
|
|
|
|
else if (Prev)
|
|
|
|
|
return Prev->get_ct(name);
|
|
|
|
|
else
|
|
|
|
|
return Prev.get_ct(name);
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
consteval comp_word(const func prol, addr flags = 0):
|
|
|
|
|
word_base{&Prev, N | flags}, namebuf{}, prologue{prol}, bodybuf{}
|
|
|
|
|
word_base{Prev, N | flags}, namebuf{}, prologue{prol}, bodybuf{}
|
|
|
|
|
{
|
|
|
|
|
std::copy(Name.data, Name.data + sizeof(Name), namebuf.data());
|
|
|
|
|
|
|
|
|
@ -157,7 +159,7 @@ struct comp_word : public word_base
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<ctstring Name, auto *Prev = (const word_base *)nullptr>
|
|
|
|
|
template<ctstring Name, func Body, auto *Prev = (const word_base *)nullptr>
|
|
|
|
|
struct native_word : public word_base
|
|
|
|
|
{
|
|
|
|
|
constexpr static auto N = (sizeof(Name) + sizeof(cell) - 1) & ~(sizeof(cell) - 1);
|
|
|
|
@ -173,13 +175,37 @@ struct native_word : public word_base
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
consteval native_word(func bod, addr flags = 0):
|
|
|
|
|
word_base{Prev, N | flags}, namebuf{}, body{bod}
|
|
|
|
|
consteval native_word(addr flags = 0):
|
|
|
|
|
word_base{Prev, N | flags}, namebuf{}, body{Body}
|
|
|
|
|
{
|
|
|
|
|
std::copy(Name.data, Name.data + sizeof(Name), namebuf.data());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<ctstring Name, func Body, addr Flags, auto... Next>
|
|
|
|
|
struct native_dict
|
|
|
|
|
{
|
|
|
|
|
constexpr static native_word<Name, Body,
|
|
|
|
|
[] {
|
|
|
|
|
if constexpr (sizeof...(Next))
|
|
|
|
|
return &native_dict<Next...>::word;
|
|
|
|
|
else
|
|
|
|
|
return (const word_base *)nullptr;
|
|
|
|
|
}()> word {Flags};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<ctstring Name, ctstring Body, addr Flags, auto... Next>
|
|
|
|
|
struct comp_dict
|
|
|
|
|
{
|
|
|
|
|
constexpr static comp_word<Name, Body,
|
|
|
|
|
[] {
|
|
|
|
|
if constexpr (sizeof...(Next))
|
|
|
|
|
return &native_dict<Next...>::word;
|
|
|
|
|
else
|
|
|
|
|
return (const word_base *)nullptr;
|
|
|
|
|
}()> word {Flags};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct forth : public word_list
|
|
|
|
|
{
|
|
|
|
|
static constexpr bool enable_exceptions = true;
|
|
|
|
@ -398,54 +424,51 @@ struct forth : public word_list
|
|
|
|
|
*fth.here++ = std::bit_cast<cell>((*g)->body());
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
constexpr static native_word<"_d"> w_dict {f_dict};
|
|
|
|
|
constexpr static native_word<"_lit", &w_dict> w_liti {lit_impl};
|
|
|
|
|
constexpr static native_word<"swap", &w_liti> w_swap {f_swap};
|
|
|
|
|
constexpr static native_word<"drop", &w_swap> w_drop {f_drop};
|
|
|
|
|
constexpr static native_word<"dup", &w_drop> w_dup {f_dup};
|
|
|
|
|
constexpr static native_word<"rot", &w_dup> w_rot {f_rot};
|
|
|
|
|
constexpr static native_word<"+", &w_rot> w_add {f_add};
|
|
|
|
|
constexpr static native_word<"-", &w_add> w_minus {f_minus};
|
|
|
|
|
constexpr static native_word<"*", &w_minus> w_times {f_times};
|
|
|
|
|
constexpr static native_word<"/", &w_times> w_divid {f_divide};
|
|
|
|
|
constexpr static native_word<"mod", &w_divid> w_mod {f_mod};
|
|
|
|
|
constexpr static native_word<"and", &w_mod> w_and {f_bitand};
|
|
|
|
|
constexpr static native_word<"or", &w_and> w_or {f_bitor};
|
|
|
|
|
constexpr static native_word<"xor", &w_or> w_xor {f_bitxor};
|
|
|
|
|
constexpr static native_word<"lshift", &w_xor> w_lsh {f_lshift};
|
|
|
|
|
constexpr static native_word<"rshift", &w_lsh> w_rsh {f_rshift};
|
|
|
|
|
constexpr static native_word<"[", &w_rsh> w_lbrac {f_lbrac,
|
|
|
|
|
word_base::immediate};
|
|
|
|
|
constexpr static native_word<"]", &w_lbrac> w_rbrac {f_rbrac};
|
|
|
|
|
constexpr static native_word<"immediate", &w_rbrac> w_imm {f_imm};
|
|
|
|
|
constexpr static native_word<"literal", &w_imm> w_lit {f_lit,
|
|
|
|
|
word_base::immediate};
|
|
|
|
|
constexpr static native_word<"@", &w_lit> w_peek {f_peek};
|
|
|
|
|
constexpr static native_word<"!", &w_peek> w_poke {f_poke};
|
|
|
|
|
constexpr static native_word<"c@", &w_poke> w_cpeek {f_cpeek};
|
|
|
|
|
constexpr static native_word<"c!", &w_cpeek> w_cpoke {f_cpoke};
|
|
|
|
|
constexpr static native_word<"=", &w_cpoke> w_eq {f_eq};
|
|
|
|
|
constexpr static native_word<"<", &w_eq> w_lt {f_lt};
|
|
|
|
|
constexpr static native_word<"\'", &w_lt> w_tick {f_tick};
|
|
|
|
|
constexpr static native_word<":", &w_tick> w_colon {f_colon};
|
|
|
|
|
constexpr static native_word<";", &w_colon> w_semic {f_semic,
|
|
|
|
|
word_base::immediate};
|
|
|
|
|
constexpr static native_word<"\\", &w_semic> w_comm {f_comm,
|
|
|
|
|
word_base::immediate};
|
|
|
|
|
constexpr static native_word<"cell", &w_comm> w_cell {f_cell};
|
|
|
|
|
constexpr static native_word<"_jmp", &w_cell> w_jmp {f_jmp};
|
|
|
|
|
constexpr static native_word<"_jmp0", &w_jmp> w_jmp0 {f_jmp0};
|
|
|
|
|
constexpr static native_word<"postpone", &w_jmp0> w_postp {f_postpone,
|
|
|
|
|
word_base::immediate};
|
|
|
|
|
constexpr static comp_word<"cell+", "cell +", w_postp> w_cellp
|
|
|
|
|
constexpr static auto& asdf = native_dict<
|
|
|
|
|
ctstring{"_d"}, f_dict, 0,
|
|
|
|
|
ctstring{"_lit"}, lit_impl, 0,
|
|
|
|
|
ctstring{"swap"}, f_swap, 0,
|
|
|
|
|
ctstring{"drop"}, f_drop, 0,
|
|
|
|
|
ctstring{"dup"}, f_dup, 0,
|
|
|
|
|
ctstring{"rot"}, f_rot, 0,
|
|
|
|
|
ctstring{"+"}, f_add, 0,
|
|
|
|
|
ctstring{"-"}, f_minus, 0,
|
|
|
|
|
ctstring{"*"}, f_times, 0,
|
|
|
|
|
ctstring{"/"}, f_divide, 0,
|
|
|
|
|
ctstring{"mod"}, f_mod, 0,
|
|
|
|
|
ctstring{"and"}, f_bitand, 0,
|
|
|
|
|
ctstring{"or"}, f_bitor, 0,
|
|
|
|
|
ctstring{"xor"}, f_bitxor, 0,
|
|
|
|
|
ctstring{"lshift"}, f_lshift, 0,
|
|
|
|
|
ctstring{"rshift"}, f_rshift, 0,
|
|
|
|
|
ctstring{"["}, f_lbrac, word_base::immediate,
|
|
|
|
|
ctstring{"]"}, f_rbrac, 0,
|
|
|
|
|
ctstring{"immediate"}, f_imm, 0,
|
|
|
|
|
ctstring{"literal"}, f_lit, word_base::immediate,
|
|
|
|
|
ctstring{"@"}, f_peek, 0,
|
|
|
|
|
ctstring{"!"}, f_poke, 0,
|
|
|
|
|
ctstring{"c@"}, f_cpeek, 0,
|
|
|
|
|
ctstring{"c!"}, f_cpoke, 0,
|
|
|
|
|
ctstring{"="}, f_eq, 0,
|
|
|
|
|
ctstring{"<"}, f_lt, 0,
|
|
|
|
|
ctstring{"\'"}, f_tick, 0,
|
|
|
|
|
ctstring{":"}, f_colon, 0,
|
|
|
|
|
ctstring{";"}, f_semic, word_base::immediate,
|
|
|
|
|
ctstring{"\\"}, f_comm, word_base::immediate,
|
|
|
|
|
ctstring{"cell"}, f_cell, 0,
|
|
|
|
|
ctstring{"_jmp"}, f_jmp, 0,
|
|
|
|
|
ctstring{"_jmp0"}, f_jmp0, 0,
|
|
|
|
|
ctstring{"postpone"}, f_postpone, word_base::immediate
|
|
|
|
|
>::word;
|
|
|
|
|
constexpr static comp_word<"cell+", "cell +", &asdf> w_cellp
|
|
|
|
|
{forth::prologue<fthp>};
|
|
|
|
|
constexpr static comp_word<"cells", "cell *", w_cellp> w_cells
|
|
|
|
|
constexpr static comp_word<"cells", "cell *", &w_cellp> w_cells
|
|
|
|
|
{forth::prologue<fthp>};
|
|
|
|
|
constexpr static comp_word<"char+", "1 +", w_cells> w_charp
|
|
|
|
|
constexpr static comp_word<"char+", "1 +", &w_cells> w_charp
|
|
|
|
|
{forth::prologue<fthp>};
|
|
|
|
|
constexpr static comp_word<"1+", "1 +", w_charp> w_inc
|
|
|
|
|
constexpr static comp_word<"1+", "1 +", &w_charp> w_inc
|
|
|
|
|
{forth::prologue<fthp>};
|
|
|
|
|
constexpr static comp_word<"1-", "1 -", w_inc> w_dec
|
|
|
|
|
constexpr static comp_word<"1-", "1 -", &w_inc> w_dec
|
|
|
|
|
{forth::prologue<fthp>};
|
|
|
|
|
|
|
|
|
|
fth.next = &w_dec;
|
|
|
|
|