1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
|
//
/// @file corewords.hpp
/// @brief Manages the fundamental word-set and its execution.
//
// Alee Forth: A portable and concise Forth implementation in modern C++.
// Copyright (C) 2023 Clyne Sullivan <clyne@bitgloo.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#ifndef ALEEFORTH_COREWORDS_HPP
#define ALEEFORTH_COREWORDS_HPP
#include "config.hpp"
#include "dictionary.hpp"
#include "types.hpp"
#include <algorithm>
class State;
/**
* To be implemented by the user, this function is called when the `sys` word
* is executed.
* @param state Current execution state object.
*/
void user_sys(State& state);
/**
* @class CoreWords
* @brief Provides the fundamental word-set and manages its execution.
*/
class CoreWords
{
public:
/**
* Searches for the token/index of the given word if it is part of the
* fundamental word-set.
* @param state Current execution state object.
* @param word Word (stored in state's dictionary memory) to look up.
* @return The token/index of the word or -1 if not found.
*/
static Cell findi(State& state, Word word);
/**
* Looks up the token/index of the given fundamental word.
* Primarily used for compile-time lookup.
* @param word The word to look up.
* @return The token/index of the word or -1 if not found.
*/
consteval static Cell token(const char *word) {
return findi(word, strlen(word));
}
/**
* Executes the given execution token using the given state.
* @param token Any valid execution token (word, fundamental, constant...).
* @param state The state object to execute with.
*/
static void run(Cell token, State& state);
/**
* String lookup table for the fundamental word-set.
* This also determines the opcode (index) of these words.
*/
constexpr static char wordsarr[] =
"_lit\0drop\0dup\0swap\0pick\0sys\0"
"+\0-\0m*\0_/\0_%\0"
"_@\0_!\0>r\0r>\0=\0"
"<\0&\0|\0^\0"
"<<\0>>\0:\0_'\0execute\0"
"exit\0;\0_jmp0\0_jmp\0"
"depth\0_rdepth\0_in\0_ev\0find\0"
"_uma\0u<\0um/mod\0_nx\0";
/**
* Count of total fundamental words.
*/
constexpr static Cell WordCount = [] {
return std::count(wordsarr, wordsarr + sizeof(wordsarr), '\0'); }();
private:
/**
* Generic implementation of findi(). Private; use public implementations.
* @param it Beginning iterator of the word to search for.
* @param size Size of the searched-for word i.e. end == it + size.
* @return The token/index of the word or -1 if not found.
*/
template<typename Iter>
LIBALEE_SECTION
constexpr static Cell findi(Iter it, std::size_t size)
{
const char *ptr = CoreWords::wordsarr;
for (Cell wordsi = 0; wordsi < WordCount; ++wordsi) {
std::size_t wordsize = strlen(ptr);
if (wordsize == size && Dictionary::equal(ptr, ptr + wordsize, it))
return wordsi;
ptr += wordsize + 1;
}
return -1;
}
public:
static void word_lit(State&);
static void word_drop(State&);
static void word_dup(State&);
static void word_swap(State&);
static void word_pick(State&);
static void word_sys(State&);
static void word_add(State&);
static void word_sub(State&);
static void word_mul(State&);
static void word_div(State&);
static void word_mod(State&);
static void word_peek(State&);
static void word_poke(State&);
static void word_rpush(State&);
static void word_rpop(State&);
static void word_eq(State&);
static void word_lt(State&);
static void word_and(State&);
static void word_or(State&);
static void word_xor(State&);
static void word_shl(State&);
static void word_shr(State&);
static void word_colon(State&);
static void word_tick(State&);
static void word_execute(State&);
static void word_exit(State&);
static void word_semic(State&);
static void word_jmp0(State&);
static void word_jmp(State&);
static void word_depth(State&);
static void word_rdepth(State&);
static void word_in(State&);
static void word_ev(State&);
static void word_find(State&);
static void word_uma(State&);
static void word_ult(State&);
static void word_ummod(State&);
constexpr static void (*wordstbl[])(State&) = {
word_lit,
word_drop,
word_dup,
word_swap,
word_pick,
word_sys,
word_add,
word_sub,
word_mul,
word_div,
word_mod,
word_peek,
word_poke,
word_rpush,
word_rpop,
word_eq,
word_lt,
word_and,
word_or,
word_xor,
word_shl,
word_shr,
word_colon,
word_tick,
word_execute,
word_exit,
word_semic,
word_jmp0,
word_jmp,
word_depth,
word_rdepth,
word_in,
word_ev,
word_find,
word_uma,
word_ult,
word_ummod
};
};
#endif // ALEEFORTH_COREWORDS_HPP
|