2021-03-23 23:29:32 +01:00
|
|
|
#ifndef LIBCUBESCRIPT_VM_HH
|
|
|
|
#define LIBCUBESCRIPT_VM_HH
|
2016-08-12 18:38:43 +02:00
|
|
|
|
2021-03-24 20:33:20 +01:00
|
|
|
#include <cubescript/cubescript.hh>
|
2016-08-12 18:38:43 +02:00
|
|
|
|
2021-03-23 01:11:21 +01:00
|
|
|
#include "cs_std.hh"
|
2021-03-22 22:33:01 +01:00
|
|
|
#include "cs_ident.hh"
|
2021-03-24 02:21:27 +01:00
|
|
|
#include "cs_gen.hh"
|
2021-03-24 20:33:20 +01:00
|
|
|
#include "cs_thread.hh"
|
2016-09-08 23:42:14 +02:00
|
|
|
|
2021-03-23 23:32:25 +01:00
|
|
|
namespace cubescript {
|
2016-08-12 18:38:43 +02:00
|
|
|
|
2021-03-24 02:21:27 +01:00
|
|
|
struct break_exception {
|
2016-09-14 23:24:13 +02:00
|
|
|
};
|
|
|
|
|
2021-03-24 02:21:27 +01:00
|
|
|
struct continue_exception {
|
2016-08-12 18:38:43 +02:00
|
|
|
};
|
|
|
|
|
2016-09-02 22:42:10 +02:00
|
|
|
template<typename F>
|
2021-03-25 01:37:13 +01:00
|
|
|
static void call_with_args(thread_state &ts, F body) {
|
|
|
|
if (!ts.callstack) {
|
2016-09-10 19:54:55 +02:00
|
|
|
body();
|
|
|
|
return;
|
|
|
|
}
|
2021-03-25 01:37:13 +01:00
|
|
|
valarray<ident_stack, MAX_ARGUMENTS> argstack{*ts.pstate};
|
|
|
|
int argmask1 = ts.callstack->usedargs;
|
2016-09-02 22:42:10 +02:00
|
|
|
for (int i = 0; argmask1; argmask1 >>= 1, ++i) {
|
|
|
|
if (argmask1 & 1) {
|
2021-03-25 01:37:13 +01:00
|
|
|
static_cast<alias_impl *>(ts.istate->identmap[i])->undo_arg(
|
2021-03-21 02:59:37 +01:00
|
|
|
argstack[i]
|
2016-09-02 22:42:10 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2021-03-25 01:37:13 +01:00
|
|
|
ident_link *prevstack = ts.callstack->next;
|
2021-03-23 23:29:32 +01:00
|
|
|
ident_link aliaslink = {
|
2021-03-25 01:37:13 +01:00
|
|
|
ts.callstack->id, ts.callstack,
|
2021-03-24 02:21:27 +01:00
|
|
|
prevstack ? prevstack->usedargs : ((1 << MAX_ARGUMENTS) - 1),
|
2016-09-15 04:30:37 +02:00
|
|
|
prevstack ? prevstack->argstack : nullptr
|
2016-09-02 22:42:10 +02:00
|
|
|
};
|
2021-03-25 01:37:13 +01:00
|
|
|
ts.callstack = &aliaslink;
|
2021-03-23 01:11:21 +01:00
|
|
|
call_with_cleanup(std::move(body), [&]() {
|
2016-09-15 04:30:37 +02:00
|
|
|
if (prevstack) {
|
|
|
|
prevstack->usedargs = aliaslink.usedargs;
|
|
|
|
}
|
2021-03-25 01:37:13 +01:00
|
|
|
ts.callstack = aliaslink.next;
|
|
|
|
int argmask2 = ts.callstack->usedargs;
|
2016-09-08 23:42:14 +02:00
|
|
|
for (int i = 0; argmask2; argmask2 >>= 1, ++i) {
|
|
|
|
if (argmask2 & 1) {
|
2021-03-25 01:37:13 +01:00
|
|
|
static_cast<alias_impl *>(ts.istate->identmap[i])->redo_arg(
|
2021-03-21 02:59:37 +01:00
|
|
|
argstack[i]
|
2016-09-08 23:42:14 +02:00
|
|
|
);
|
|
|
|
}
|
2016-09-02 22:42:10 +02:00
|
|
|
}
|
2016-09-08 23:42:14 +02:00
|
|
|
});
|
2016-09-02 22:42:10 +02:00
|
|
|
}
|
|
|
|
|
2021-03-23 23:32:25 +01:00
|
|
|
} /* namespace cubescript */
|
2016-08-12 18:38:43 +02:00
|
|
|
|
2021-03-23 23:29:32 +01:00
|
|
|
#endif /* LIBCUBESCRIPT_VM_HH */
|