Loading...
Searching...
No Matches
ForthMachine.h
Go to the documentation of this file.
1// BSD 3-Clause License; see https://github.com/scikit-hep/awkward/blob/main/LICENSE
2
3#ifndef AWKWARD_FORTHMACHINE_H_
4#define AWKWARD_FORTHMACHINE_H_
5
6#include <set>
7#include <map>
8#include <stack>
9
10#include "awkward/common.h"
11#include "awkward/util.h"
14
15namespace awkward {
21 template <typename T, typename I>
23
24 template <typename TYPE> using IndexTypeOf = typename std::vector<TYPE>::size_type;
25
26 public:
27 ForthMachineOf(const std::string& source,
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);
33
35
37 int64_t
38 abi_version() const noexcept;
39
41 const std::string
42 source() const noexcept;
43
45 const std::vector<I>
46 bytecodes() const;
47
49 const std::vector<int64_t>
50 bytecodes_offsets() const;
51
53 const std::string
54 decompiled() const;
55
57 const std::string
58 decompiled_segment(int64_t segment_position, const std::string& indent="",
59 bool endline = true) const;
60
62 const std::string
63 decompiled_at(int64_t bytecode_position, const std::string& indent="") const;
64
66 const std::vector<std::string>
67 dictionary() const;
68
70 int64_t
71 stack_max_depth() const noexcept;
72
74 int64_t
75 recursion_max_depth() const noexcept;
76
78 int64_t
79 string_buffer_size() const noexcept;
80
82 int64_t
83 output_initial_size() const noexcept;
84
86 double
87 output_resize_factor() const noexcept;
88
90 const std::vector<T>
91 stack() const;
92
94 T
95 stack_at(int64_t from_top) const noexcept;
96
98 int64_t
99 stack_depth() const noexcept;
100
102 inline bool
103 stack_can_push() const noexcept {
104 return stack_depth_ < stack_max_depth_;
105 }
106
108 inline bool
109 stack_can_pop() const noexcept {
110 return stack_depth_ > 0;
111 }
112
114 inline void
115 stack_push(T value) noexcept {
116 stack_buffer_[stack_depth_] = value;
117 stack_depth_++;
118 }
119
121 inline T
122 stack_pop() noexcept {
123 stack_depth_--;
124 return stack_buffer_[stack_depth_];
125 }
126
128 void
129 stack_clear() noexcept;
130
132 const std::map<std::string, T>
133 variables() const;
134
136 const std::vector<std::string>
137 variable_index() const;
138
140 T
141 variable_at(const std::string& name) const;
142
144 T
145 variable_at(int64_t index) const noexcept;
146
148 bool
149 input_must_be_writable(const std::string& name) const;
150
152 int64_t
153 input_position_at(const std::string& name) const;
154
156 int64_t
157 input_position_at(int64_t index) const noexcept;
158
160 const std::map<std::string, std::shared_ptr<ForthOutputBuffer>>
161 outputs() const;
162
164 const std::vector<std::string>
165 output_index() const noexcept;
166
168 const std::shared_ptr<ForthOutputBuffer>
169 output_at(const std::string& name) const;
170
172 const std::shared_ptr<ForthOutputBuffer>
173 output_at(int64_t index) const noexcept;
174
177 const std::string
178 string_at(int64_t index) const noexcept;
179
181 void
182 reset();
183
185 void
186 begin(const std::map<std::string, std::shared_ptr<ForthInputBuffer>>& inputs);
187
189 void
190 begin();
191
193 util::ForthError
194 begin_again(const std::map<std::string, std::shared_ptr<ForthInputBuffer>>& inputs, bool reset_instruction);
195
197 util::ForthError
198 step();
199
201 util::ForthError
202 run(const std::map<std::string, std::shared_ptr<ForthInputBuffer>>& inputs);
203
205 util::ForthError
206 run();
207
209 util::ForthError
210 resume();
211
213 util::ForthError
214 call(const std::string& name);
215
217 util::ForthError
218 call(int64_t index);
219
221 void
222 maybe_throw(util::ForthError err, const std::set<util::ForthError>& ignore) const;
223
225 int64_t
226 current_bytecode_position() const noexcept;
227
229 int64_t
230 current_recursion_depth() const noexcept;
231
233 const std::string
234 current_instruction() const;
235
237 void
238 count_reset() noexcept;
239
241 int64_t
242 count_instructions() const noexcept;
243
245 int64_t
246 count_reads() const noexcept;
247
249 int64_t
250 count_writes() const noexcept;
251
253 int64_t
254 count_nanoseconds() const noexcept;
255
257 bool
258 is_integer(const std::string& word, int64_t& value) const;
259
261 bool
262 is_variable(const std::string& word) const;
263
265 bool
266 is_input(const std::string& word) const;
267
269 bool
270 is_output(const std::string& word) const;
271
273 bool
274 is_nbit(const std::string& word, I& value) const;
275
277 bool
278 is_reserved(const std::string& word) const;
279
281 bool
282 is_defined(const std::string& word) const;
283
285 inline bool
286 is_ready() const noexcept {
287 return is_ready_;
288 }
289
291 inline bool
292 is_done() const noexcept {
293 return recursion_target_depth_.empty();
294 }
295
297 inline bool
298 is_segment_done() const noexcept {
299 return !(bytecodes_pointer_where() < (
300 bytecodes_offsets_[(IndexTypeOf<int64_t>)bytecodes_pointer_which() + 1] -
301 bytecodes_offsets_[(IndexTypeOf<int64_t>)bytecodes_pointer_which()]
302 ));
303 }
304
305 private:
307 bool
308 segment_nonempty(int64_t segment_position) const;
309
311 int64_t
312 bytecodes_per_instruction(int64_t bytecode_position) const;
313
315 const std::string
316 err_linecol(const std::vector<std::pair<int64_t, int64_t>>& linecol,
317 int64_t startpos,
318 int64_t stoppos,
319 const std::string& message) const;
320
322 void
323 tokenize(std::vector<std::string>& tokenized,
324 std::vector<std::pair<int64_t, int64_t>>& linecol);
325
327 void
328 compile(const std::vector<std::string>& tokenized,
329 const std::vector<std::pair<int64_t, int64_t>>& linecol);
330
332 void
333 parse(const std::string& defn,
334 const std::vector<std::string>& tokenized,
335 const std::vector<std::pair<int64_t, int64_t>>& linecol,
336 int64_t start,
337 int64_t stop,
338 std::vector<I>& bytecodes,
339 std::vector<std::vector<I>>& dictionary,
340 int64_t exitdepth,
341 int64_t dodepth);
342
344 void
345 internal_run(bool single_step, int64_t recursion_target_depth_top); // noexcept
346
348 void
349 write_from_stack(int64_t num, T* top) noexcept;
350
352 void
353 write_add_from_stack(int64_t num, T* top) noexcept;
354
356 void
357 print_number(T num) noexcept;
358
360 inline bool
361 stack_cannot_push() const noexcept {
362 return stack_depth_ == stack_max_depth_;
363 }
364
366 inline bool
367 stack_cannot_pop() const noexcept {
368 return stack_depth_ == 0;
369 }
370
372 inline bool
373 stack_cannot_pop2() const noexcept {
374 return stack_depth_ < 2;
375 }
376
378 inline bool
379 stack_cannot_pop3() const noexcept {
380 return stack_depth_ < 3;
381 }
382
384 inline T*
385 stack_pop2() noexcept {
386 stack_depth_ -= 2;
387 return &stack_buffer_[stack_depth_];
388 }
389
391 inline T*
392 stack_pop2_before_pushing1() noexcept {
393 stack_depth_--;
394 return &stack_buffer_[stack_depth_ - 1];
395 }
396
398 inline T*
399 stack_peek() const noexcept {
400 return &stack_buffer_[stack_depth_ - 1];
401 }
402
404 inline I
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())];
408 }
409
411 inline void
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_++;
416 }
417
419 inline void
420 bytecodes_pointer_pop() noexcept {
421 recursion_current_depth_--;
422 }
423
425 inline int64_t&
426 bytecodes_pointer_which() const noexcept {
427 return current_which_[recursion_current_depth_ - 1];
428 }
429
431 inline int64_t&
432 bytecodes_pointer_where() const noexcept {
433 return current_where_[recursion_current_depth_ - 1];
434 }
435
437 inline void
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;
442 do_current_depth_++;
443 }
444
446 inline void
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;
451 do_current_depth_++;
452 }
453
455 inline int64_t&
456 do_recursion_depth() const noexcept {
457 return do_recursion_depth_[do_current_depth_ - 1];
458 }
459
461 inline int64_t
462 do_abs_recursion_depth() const noexcept {
463 int64_t out = do_recursion_depth_[do_current_depth_ - 1];
464 if (out < 0) {
465 return ~out;
466 }
467 else {
468 return out;
469 }
470 }
471
473 inline bool
474 do_loop_is_step() const noexcept {
475 return do_recursion_depth_[do_current_depth_ - 1] < 0;
476 }
477
479 inline int64_t&
480 do_stop() const noexcept {
481 return do_stop_[do_current_depth_ - 1];
482 }
483
485 inline int64_t&
486 do_i() const noexcept {
487 return do_i_[do_current_depth_ - 1];
488 }
489
491 inline int64_t&
492 do_j() const noexcept {
493 return do_i_[do_current_depth_ - 2];
494 }
495
497 inline int64_t&
498 do_k() const noexcept {
499 return do_i_[do_current_depth_ - 3];
500 }
501
502 std::string source_;
503 int64_t output_initial_size_;
504 double output_resize_factor_;
505
506 T* stack_buffer_;
507 int64_t stack_depth_;
508 int64_t stack_max_depth_;
509
510 std::vector<std::string> variable_names_;
511 std::vector<T> variables_;
512
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_;
517
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_;
523
524 char* string_buffer_;
525 int64_t string_buffer_size_;
526
527 std::vector<std::shared_ptr<ForthInputBuffer>> current_inputs_;
528 std::vector<std::shared_ptr<ForthOutputBuffer>> current_outputs_;
529 bool is_ready_;
530
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_;
536
537 int64_t* do_recursion_depth_;
538 int64_t* do_stop_;
539 int64_t* do_i_;
540 int64_t do_current_depth_;
541
542 util::ForthError current_error_;
543
544 int64_t count_instructions_;
545 int64_t count_reads_;
546 int64_t count_writes_;
547 int64_t count_nanoseconds_;
548 };
549
552
553}
554
555#endif // AWKWARD_FORTHMACHINE_H_
HERE.
Definition ForthInputBuffer.h:17
Definition ForthMachine.h:22
void stack_clear() noexcept
HERE.
void stack_push(T value) noexcept
HERE.
Definition ForthMachine.h:115
bool is_segment_done() const noexcept
HERE.
Definition ForthMachine.h:298
T stack_pop() noexcept
HERE.
Definition ForthMachine.h:122
bool stack_can_pop() const noexcept
HERE.
Definition ForthMachine.h:109
bool is_done() const noexcept
HERE.
Definition ForthMachine.h:292
int64_t abi_version() const noexcept
HERE.
ForthMachineOf(const std::string &source, int64_t stack_max_depth=1024, int64_t recursion_max_depth=1024, int64_t string_buffer_size=1024, int64_t output_initial_size=1024, double output_resize_factor=1.5)
HERE.
Definition ForthOutputBuffer.h:34
#define EXPORT_SYMBOL
Definition common.h:25
Definition ArrayBuilder.h:14