24 template <
typename TYPE>
using IndexTypeOf =
typename std::vector<TYPE>::size_type;
28 int64_t stack_max_depth=1024,
29 int64_t recursion_max_depth=1024,
30 int64_t string_buffer_size=1024,
31 int64_t output_initial_size=1024,
32 double output_resize_factor=1.5);
42 source() const noexcept;
49 const std::vector<int64_t>
50 bytecodes_offsets() const;
58 decompiled_segment(int64_t segment_position, const std::
string& indent="",
59 bool endline = true) const;
63 decompiled_at(int64_t bytecode_position, const std::
string& indent="") const;
66 const std::vector<std::
string>
71 stack_max_depth() const noexcept;
75 recursion_max_depth() const noexcept;
79 string_buffer_size() const noexcept;
83 output_initial_size() const noexcept;
87 output_resize_factor() const noexcept;
95 stack_at(int64_t from_top) const noexcept;
99 stack_depth() const noexcept;
103 stack_can_push() const noexcept {
104 return stack_depth_ < stack_max_depth_;
110 return stack_depth_ > 0;
116 stack_buffer_[stack_depth_] = value;
124 return stack_buffer_[stack_depth_];
132 const std::map<std::
string, T>
136 const std::vector<std::
string>
137 variable_index() const;
141 variable_at(const std::
string& name) const;
145 variable_at(int64_t index) const noexcept;
149 input_must_be_writable(const std::
string& name) const;
153 input_position_at(const std::
string& name) const;
157 input_position_at(int64_t index) const noexcept;
164 const std::vector<std::
string>
165 output_index() const noexcept;
169 output_at(const std::
string& name) const;
173 output_at(int64_t index) const noexcept;
178 string_at(int64_t index) const noexcept;
194 begin_again(const std::map<std::
string, std::shared_ptr<
ForthInputBuffer>>& inputs,
bool reset_instruction);
214 call(const std::
string& name);
222 maybe_throw(util::ForthError err, const std::set<util::ForthError>& ignore) const;
226 current_bytecode_position() const noexcept;
230 current_recursion_depth() const noexcept;
234 current_instruction() const;
238 count_reset() noexcept;
242 count_instructions() const noexcept;
246 count_reads() const noexcept;
250 count_writes() const noexcept;
254 count_nanoseconds() const noexcept;
258 is_integer(const std::
string& word, int64_t& value) const;
262 is_variable(const std::
string& word) const;
266 is_input(const std::
string& word) const;
270 is_output(const std::
string& word) const;
274 is_nbit(const std::
string& word, I& value) const;
278 is_reserved(const std::
string& word) const;
282 is_defined(const std::
string& word) const;
286 is_ready() const noexcept {
293 return recursion_target_depth_.empty();
299 return !(bytecodes_pointer_where() < (
300 bytecodes_offsets_[(IndexTypeOf<int64_t>)bytecodes_pointer_which() + 1] -
301 bytecodes_offsets_[(IndexTypeOf<int64_t>)bytecodes_pointer_which()]
308 segment_nonempty(int64_t segment_position)
const;
312 bytecodes_per_instruction(int64_t bytecode_position)
const;
316 err_linecol(
const std::vector<std::pair<int64_t, int64_t>>& linecol,
319 const std::string& message)
const;
323 tokenize(std::vector<std::string>& tokenized,
324 std::vector<std::pair<int64_t, int64_t>>& linecol);
328 compile(
const std::vector<std::string>& tokenized,
329 const std::vector<std::pair<int64_t, int64_t>>& linecol);
333 parse(
const std::string& defn,
334 const std::vector<std::string>& tokenized,
335 const std::vector<std::pair<int64_t, int64_t>>& linecol,
338 std::vector<I>& bytecodes,
339 std::vector<std::vector<I>>& dictionary,
345 internal_run(
bool single_step, int64_t recursion_target_depth_top);
349 write_from_stack(int64_t num, T* top)
noexcept;
353 write_add_from_stack(int64_t num, T* top)
noexcept;
357 print_number(T num)
noexcept;
361 stack_cannot_push() const noexcept {
362 return stack_depth_ == stack_max_depth_;
367 stack_cannot_pop() const noexcept {
368 return stack_depth_ == 0;
373 stack_cannot_pop2() const noexcept {
374 return stack_depth_ < 2;
379 stack_cannot_pop3() const noexcept {
380 return stack_depth_ < 3;
385 stack_pop2() noexcept {
387 return &stack_buffer_[stack_depth_];
392 stack_pop2_before_pushing1() noexcept {
394 return &stack_buffer_[stack_depth_ - 1];
399 stack_peek() const noexcept {
400 return &stack_buffer_[stack_depth_ - 1];
405 bytecode_get() const noexcept {
406 int64_t start = bytecodes_offsets_[(IndexTypeOf<int64_t>)bytecodes_pointer_which()];
407 return bytecodes_[(IndexTypeOf<I>)(start + bytecodes_pointer_where())];
412 bytecodes_pointer_push(int64_t which)
noexcept {
413 current_which_[recursion_current_depth_] = which;
414 current_where_[recursion_current_depth_] = 0;
415 recursion_current_depth_++;
420 bytecodes_pointer_pop() noexcept {
421 recursion_current_depth_--;
426 bytecodes_pointer_which() const noexcept {
427 return current_which_[recursion_current_depth_ - 1];
432 bytecodes_pointer_where() const noexcept {
433 return current_where_[recursion_current_depth_ - 1];
438 do_loop_push(int64_t start, int64_t stop)
noexcept {
439 do_recursion_depth_[do_current_depth_] = recursion_current_depth_;
440 do_stop_[do_current_depth_] = stop;
441 do_i_[do_current_depth_] = start;
447 do_steploop_push(int64_t start, int64_t stop)
noexcept {
448 do_recursion_depth_[do_current_depth_] = ~recursion_current_depth_;
449 do_stop_[do_current_depth_] = stop;
450 do_i_[do_current_depth_] = start;
456 do_recursion_depth() const noexcept {
457 return do_recursion_depth_[do_current_depth_ - 1];
462 do_abs_recursion_depth() const noexcept {
463 int64_t out = do_recursion_depth_[do_current_depth_ - 1];
474 do_loop_is_step() const noexcept {
475 return do_recursion_depth_[do_current_depth_ - 1] < 0;
480 do_stop() const noexcept {
481 return do_stop_[do_current_depth_ - 1];
486 do_i() const noexcept {
487 return do_i_[do_current_depth_ - 1];
492 do_j() const noexcept {
493 return do_i_[do_current_depth_ - 2];
498 do_k() const noexcept {
499 return do_i_[do_current_depth_ - 3];
503 int64_t output_initial_size_;
504 double output_resize_factor_;
507 int64_t stack_depth_;
508 int64_t stack_max_depth_;
510 std::vector<std::string> variable_names_;
511 std::vector<T> variables_;
513 std::vector<std::string> input_names_;
514 std::vector<bool> input_must_be_writable_;
515 std::vector<std::string> output_names_;
516 std::vector<util::dtype> output_dtypes_;
518 std::vector<std::string> strings_;
519 std::vector<std::string> dictionary_names_;
520 std::vector<I> dictionary_bytecodes_;
521 std::vector<int64_t> bytecodes_offsets_;
522 std::vector<I> bytecodes_;
524 char* string_buffer_;
525 int64_t string_buffer_size_;
527 std::vector<std::shared_ptr<ForthInputBuffer>> current_inputs_;
528 std::vector<std::shared_ptr<ForthOutputBuffer>> current_outputs_;
531 int64_t* current_which_;
532 int64_t* current_where_;
533 int64_t recursion_current_depth_;
534 std::stack<int64_t> recursion_target_depth_;
535 int64_t recursion_max_depth_;
537 int64_t* do_recursion_depth_;
540 int64_t do_current_depth_;
542 util::ForthError current_error_;
544 int64_t count_instructions_;
545 int64_t count_reads_;
546 int64_t count_writes_;
547 int64_t count_nanoseconds_;