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#include <memory>
10
11#include "awkward/common.h"
12#include "awkward/util.h"
15
16namespace awkward {
22 template <typename T, typename I>
24
25 template <typename TYPE> using IndexTypeOf = typename std::vector<TYPE>::size_type;
26
27 public:
28 ForthMachineOf(const std::string& source,
29 int64_t stack_max_depth=1024,
30 int64_t recursion_max_depth=1024,
31 int64_t string_buffer_size=1024,
32 int64_t output_initial_size=1024,
33 double output_resize_factor=1.5);
34
36
38 int64_t
39 abi_version() const noexcept;
40
42 const std::string
43 source() const noexcept;
44
46 const std::vector<I>
47 bytecodes() const;
48
50 const std::vector<int64_t>
52
54 const std::string
55 decompiled() const;
56
58 const std::string
59 decompiled_segment(int64_t segment_position, const std::string& indent="",
60 bool endline = true) const;
61
63 const std::string
64 decompiled_at(int64_t bytecode_position, const std::string& indent="") const;
65
67 const std::vector<std::string>
68 dictionary() const;
69
71 int64_t
72 stack_max_depth() const noexcept;
73
75 int64_t
76 recursion_max_depth() const noexcept;
77
79 int64_t
80 string_buffer_size() const noexcept;
81
83 int64_t
84 output_initial_size() const noexcept;
85
87 double
88 output_resize_factor() const noexcept;
89
91 const std::vector<T>
92 stack() const;
93
95 T
96 stack_at(int64_t from_top) const noexcept;
97
99 int64_t
100 stack_depth() const noexcept;
101
103 inline bool
104 stack_can_push() const noexcept {
105 return stack_depth_ < stack_max_depth_;
106 }
107
109 inline bool
110 stack_can_pop() const noexcept {
111 return stack_depth_ > 0;
112 }
113
115 inline void
116 stack_push(T value) noexcept {
117 stack_buffer_[stack_depth_] = value;
118 stack_depth_++;
119 }
120
122 inline T
123 stack_pop() noexcept {
124 stack_depth_--;
125 return stack_buffer_[stack_depth_];
126 }
127
129 void
130 stack_clear() noexcept;
131
133 const std::map<std::string, T>
134 variables() const;
135
137 const std::vector<std::string>
139
141 T
142 variable_at(const std::string& name) const;
143
145 T
146 variable_at(int64_t index) const noexcept;
147
149 bool
150 input_must_be_writable(const std::string& name) const;
151
153 int64_t
154 input_position_at(const std::string& name) const;
155
157 int64_t
158 input_position_at(int64_t index) const noexcept;
159
161 const std::map<std::string, std::shared_ptr<ForthOutputBuffer>>
162 outputs() const;
163
165 const std::vector<std::string>
166 output_index() const noexcept;
167
169 const std::shared_ptr<ForthOutputBuffer>
170 output_at(const std::string& name) const;
171
173 const std::shared_ptr<ForthOutputBuffer>
174 output_at(int64_t index) const noexcept;
175
178 const std::string
179 string_at(int64_t index) const noexcept;
180
182 void
184
186 void
187 begin(const std::map<std::string, std::shared_ptr<ForthInputBuffer>>& inputs);
188
190 void
192
194 util::ForthError
195 begin_again(const std::map<std::string, std::shared_ptr<ForthInputBuffer>>& inputs, bool reset_instruction);
196
198 util::ForthError
200
202 util::ForthError
203 run(const std::map<std::string, std::shared_ptr<ForthInputBuffer>>& inputs);
204
206 util::ForthError
208
210 util::ForthError
212
214 util::ForthError
215 call(const std::string& name);
216
218 util::ForthError
219 call(int64_t index);
220
222 void
223 maybe_throw(util::ForthError err, const std::set<util::ForthError>& ignore) const;
224
226 int64_t
228
230 int64_t
231 current_recursion_depth() const noexcept;
232
234 const std::string
236
238 void
239 count_reset() noexcept;
240
242 int64_t
243 count_instructions() const noexcept;
244
246 int64_t
247 count_reads() const noexcept;
248
250 int64_t
251 count_writes() const noexcept;
252
254 int64_t
255 count_nanoseconds() const noexcept;
256
258 bool
259 is_integer(const std::string& word, int64_t& value) const;
260
262 bool
263 is_variable(const std::string& word) const;
264
266 bool
267 is_input(const std::string& word) const;
268
270 bool
271 is_output(const std::string& word) const;
272
274 bool
275 is_nbit(const std::string& word, I& value) const;
276
278 bool
279 is_reserved(const std::string& word) const;
280
282 bool
283 is_defined(const std::string& word) const;
284
286 inline bool
287 is_ready() const noexcept {
288 return is_ready_;
289 }
290
292 inline bool
293 is_done() const noexcept {
294 return recursion_target_depth_.empty();
295 }
296
298 inline bool
299 is_segment_done() const noexcept {
300 return !(bytecodes_pointer_where() < (
301 bytecodes_offsets_[(IndexTypeOf<int64_t>)bytecodes_pointer_which() + 1] -
302 bytecodes_offsets_[(IndexTypeOf<int64_t>)bytecodes_pointer_which()]
303 ));
304 }
305
306 private:
308 bool
309 segment_nonempty(int64_t segment_position) const;
310
312 int64_t
313 bytecodes_per_instruction(int64_t bytecode_position) const;
314
316 const std::string
317 err_linecol(const std::vector<std::pair<int64_t, int64_t>>& linecol,
318 int64_t startpos,
319 int64_t stoppos,
320 const std::string& message) const;
321
323 void
324 tokenize(std::vector<std::string>& tokenized,
325 std::vector<std::pair<int64_t, int64_t>>& linecol);
326
328 void
329 compile(const std::vector<std::string>& tokenized,
330 const std::vector<std::pair<int64_t, int64_t>>& linecol);
331
333 void
334 parse(const std::string& defn,
335 const std::vector<std::string>& tokenized,
336 const std::vector<std::pair<int64_t, int64_t>>& linecol,
337 int64_t start,
338 int64_t stop,
339 std::vector<I>& bytecodes,
340 std::vector<std::vector<I>>& dictionary,
341 int64_t exitdepth,
342 int64_t dodepth);
343
345 void
346 internal_run(bool single_step, int64_t recursion_target_depth_top); // noexcept
347
349 void
350 write_from_stack(int64_t num, T* top) noexcept;
351
353 void
354 write_add_from_stack(int64_t num, T* top) noexcept;
355
357 void
358 print_number(T num) noexcept;
359
361 inline bool
362 stack_cannot_push() const noexcept {
363 return stack_depth_ == stack_max_depth_;
364 }
365
367 inline bool
368 stack_cannot_pop() const noexcept {
369 return stack_depth_ == 0;
370 }
371
373 inline bool
374 stack_cannot_pop2() const noexcept {
375 return stack_depth_ < 2;
376 }
377
379 inline bool
380 stack_cannot_pop3() const noexcept {
381 return stack_depth_ < 3;
382 }
383
385 inline T*
386 stack_pop2() noexcept {
387 stack_depth_ -= 2;
388 return &stack_buffer_[stack_depth_];
389 }
390
392 inline T*
393 stack_pop2_before_pushing1() noexcept {
394 stack_depth_--;
395 return &stack_buffer_[stack_depth_ - 1];
396 }
397
399 inline T*
400 stack_peek() const noexcept {
401 return &stack_buffer_[stack_depth_ - 1];
402 }
403
405 inline I
406 bytecode_get() const noexcept {
407 int64_t start = bytecodes_offsets_[(IndexTypeOf<int64_t>)bytecodes_pointer_which()];
408 return bytecodes_[(IndexTypeOf<I>)(start + bytecodes_pointer_where())];
409 }
410
412 inline void
413 bytecodes_pointer_push(int64_t which) noexcept {
414 current_which_[recursion_current_depth_] = which;
415 current_where_[recursion_current_depth_] = 0;
416 recursion_current_depth_++;
417 }
418
420 inline void
421 bytecodes_pointer_pop() noexcept {
422 recursion_current_depth_--;
423 }
424
426 inline int64_t&
427 bytecodes_pointer_which() const noexcept {
428 return current_which_[recursion_current_depth_ - 1];
429 }
430
432 inline int64_t&
433 bytecodes_pointer_where() const noexcept {
434 return current_where_[recursion_current_depth_ - 1];
435 }
436
438 inline void
439 do_loop_push(int64_t start, int64_t stop) noexcept {
440 do_recursion_depth_[do_current_depth_] = recursion_current_depth_;
441 do_stop_[do_current_depth_] = stop;
442 do_i_[do_current_depth_] = start;
443 do_current_depth_++;
444 }
445
447 inline void
448 do_steploop_push(int64_t start, int64_t stop) noexcept {
449 do_recursion_depth_[do_current_depth_] = ~recursion_current_depth_;
450 do_stop_[do_current_depth_] = stop;
451 do_i_[do_current_depth_] = start;
452 do_current_depth_++;
453 }
454
456 inline int64_t&
457 do_recursion_depth() const noexcept {
458 return do_recursion_depth_[do_current_depth_ - 1];
459 }
460
462 inline int64_t
463 do_abs_recursion_depth() const noexcept {
464 int64_t out = do_recursion_depth_[do_current_depth_ - 1];
465 if (out < 0) {
466 return ~out;
467 }
468 else {
469 return out;
470 }
471 }
472
474 inline bool
475 do_loop_is_step() const noexcept {
476 return do_recursion_depth_[do_current_depth_ - 1] < 0;
477 }
478
480 inline int64_t&
481 do_stop() const noexcept {
482 return do_stop_[do_current_depth_ - 1];
483 }
484
486 inline int64_t&
487 do_i() const noexcept {
488 return do_i_[do_current_depth_ - 1];
489 }
490
492 inline int64_t&
493 do_j() const noexcept {
494 return do_i_[do_current_depth_ - 2];
495 }
496
498 inline int64_t&
499 do_k() const noexcept {
500 return do_i_[do_current_depth_ - 3];
501 }
502
503 std::string source_;
504 int64_t output_initial_size_;
505 double output_resize_factor_;
506
507 std::unique_ptr<T[]> stack_buffer_;
508 int64_t stack_depth_;
509 int64_t stack_max_depth_;
510
511 std::vector<std::string> variable_names_;
512 std::vector<T> variables_;
513
514 std::vector<std::string> input_names_;
515 std::vector<bool> input_must_be_writable_;
516 std::vector<std::string> output_names_;
517 std::vector<util::dtype> output_dtypes_;
518
519 std::vector<std::string> strings_;
520 std::vector<std::string> dictionary_names_;
521 std::vector<I> dictionary_bytecodes_;
522 std::vector<int64_t> bytecodes_offsets_;
523 std::vector<I> bytecodes_;
524
525 std::unique_ptr<char[]> string_buffer_;
526 int64_t string_buffer_size_;
527
528 std::vector<std::shared_ptr<ForthInputBuffer>> current_inputs_;
529 std::vector<std::shared_ptr<ForthOutputBuffer>> current_outputs_;
530 bool is_ready_;
531
532 std::unique_ptr<int64_t[]> current_which_;
533 std::unique_ptr<int64_t[]> current_where_;
534 int64_t recursion_current_depth_;
535 std::stack<int64_t> recursion_target_depth_;
536 int64_t recursion_max_depth_;
537
538 std::unique_ptr<int64_t[]> do_recursion_depth_;
539 std::unique_ptr<int64_t[]> do_stop_;
540 std::unique_ptr<int64_t[]> do_i_;
541 int64_t do_current_depth_;
542
543 util::ForthError current_error_;
544
545 int64_t count_instructions_;
546 int64_t count_reads_;
547 int64_t count_writes_;
548 int64_t count_nanoseconds_;
549 };
550
553
554}
555
556#endif // AWKWARD_FORTHMACHINE_H_
HERE.
Definition ForthInputBuffer.h:17
Definition ForthMachine.h:23
util::ForthError run(const std::map< std::string, std::shared_ptr< ForthInputBuffer > > &inputs)
const std::vector< int64_t > bytecodes_offsets() const
bool is_integer(const std::string &word, int64_t &value) const
int64_t count_nanoseconds() const noexcept
const std::string decompiled_segment(int64_t segment_position, const std::string &indent="", bool endline=true) const
const std::vector< std::string > output_index() const noexcept
util::ForthError call(const std::string &name)
void begin(const std::map< std::string, std::shared_ptr< ForthInputBuffer > > &inputs)
int64_t count_instructions() const noexcept
bool is_variable(const std::string &word) const
const std::vector< int32_t > stack() const
void stack_clear() noexcept
HERE.
void stack_push(T value) noexcept
HERE.
Definition ForthMachine.h:116
int32_t variable_at(const std::string &name) const
void maybe_throw(util::ForthError err, const std::set< util::ForthError > &ignore) const
bool is_segment_done() const noexcept
HERE.
Definition ForthMachine.h:299
bool is_defined(const std::string &word) const
const std::string string_at(int64_t index) const noexcept
const std::vector< std::string > variable_index() const
bool is_reserved(const std::string &word) const
bool is_ready() const noexcept
Definition ForthMachine.h:287
double output_resize_factor() const noexcept
bool input_must_be_writable(const std::string &name) const
bool is_input(const std::string &word) const
util::ForthError begin_again(const std::map< std::string, std::shared_ptr< ForthInputBuffer > > &inputs, bool reset_instruction)
bool is_output(const std::string &word) const
T stack_pop() noexcept
HERE.
Definition ForthMachine.h:123
int64_t string_buffer_size() const noexcept
const std::map< std::string, std::shared_ptr< ForthOutputBuffer > > outputs() const
int64_t stack_max_depth() const noexcept
bool stack_can_pop() const noexcept
HERE.
Definition ForthMachine.h:110
bool is_done() const noexcept
HERE.
Definition ForthMachine.h:293
int64_t abi_version() const noexcept
HERE.
bool is_nbit(const std::string &word, int32_t &value) const
const std::vector< int32_t > bytecodes() const
const std::vector< std::string > dictionary() const
const std::string decompiled_at(int64_t bytecode_position, const std::string &indent="") const
int64_t input_position_at(const std::string &name) const
const std::map< std::string, int32_t > variables() const
int64_t output_initial_size() const noexcept
int64_t current_bytecode_position() const noexcept
int64_t recursion_max_depth() const noexcept
int32_t stack_at(int64_t from_top) const noexcept
const std::string source() const noexcept
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)
const std::string current_instruction() const
bool stack_can_push() const noexcept
Definition ForthMachine.h:104
const std::shared_ptr< ForthOutputBuffer > output_at(const std::string &name) const
int64_t current_recursion_depth() const noexcept
HERE.
Definition ForthOutputBuffer.h:34
#define EXPORT_SYMBOL
Definition common.h:15
Definition util.h:18
Definition ArrayBuilder.h:14
ForthMachineOf< int32_t, int32_t > ForthMachine32
Definition ForthMachine.h:551
ForthMachineOf< int64_t, int32_t > ForthMachine64
Definition ForthMachine.h:552