split VM into its own source file

master
Daniel Kolesa 2016-08-12 17:38:43 +01:00
parent 6f603a0b5c
commit edd32bf56b
4 changed files with 1378 additions and 1327 deletions

View File

@ -8,6 +8,7 @@ LIBCS_LDFLAGS = -shared
LIBCS_OBJ = \
cubescript.o \
cs_vm.o \
lib_str.o \
lib_math.o \
lib_list.o
@ -27,7 +28,8 @@ $(LIBCS_LIB): $(LIBCS_OBJ)
clean:
rm -f $(LIBCS_LIB) $(LIBCS_OBJ)
cubescript.o: cubescript.hh
cubescript.o: cubescript.hh cs_vm.hh
cs_vm.o: cubescript.hh cs_vm.hh
lib_str.o: cubescript.hh
lib_math.o: cubescript.hh
lib_list.o: cubescript.hh

1104
cs_vm.cc 100644

File diff suppressed because it is too large Load Diff

220
cs_vm.hh 100644
View File

@ -0,0 +1,220 @@
#ifndef LIBCUBESCRIPT_CS_VM_HH
#define LIBCUBESCRIPT_CS_VM_HH
#include "cubescript.hh"
#include <stdlib.h>
#include <ostd/array.hh>
#include <ostd/vector.hh>
namespace cscript {
static constexpr int MaxArguments = 25;
static constexpr int MaxResults = 7;
enum {
ID_UNKNOWN = -1, ID_VAR, ID_FVAR, ID_SVAR, ID_COMMAND, ID_ALIAS,
ID_LOCAL, ID_DO, ID_DOARGS, ID_IF, ID_RESULT, ID_NOT, ID_AND, ID_OR
};
enum {
CODE_START = 0,
CODE_OFFSET,
CODE_NULL, CODE_TRUE, CODE_FALSE, CODE_NOT,
CODE_POP,
CODE_ENTER, CODE_ENTER_RESULT,
CODE_EXIT, CODE_RESULT_ARG,
CODE_VAL, CODE_VALI,
CODE_DUP,
CODE_MACRO,
CODE_BOOL,
CODE_BLOCK, CODE_EMPTY,
CODE_COMPILE, CODE_COND,
CODE_FORCE,
CODE_RESULT,
CODE_IDENT, CODE_IDENTU, CODE_IDENTARG,
CODE_COM, CODE_COMC, CODE_COMV,
CODE_CONC, CODE_CONCW, CODE_CONCM, CODE_DOWN,
CODE_SVAR, CODE_SVARM, CODE_SVAR1,
CODE_IVAR, CODE_IVAR1, CODE_IVAR2, CODE_IVAR3,
CODE_FVAR, CODE_FVAR1,
CODE_LOOKUP, CODE_LOOKUPU, CODE_LOOKUPARG,
CODE_LOOKUPM, CODE_LOOKUPMU, CODE_LOOKUPMARG,
CODE_ALIAS, CODE_ALIASU, CODE_ALIASARG,
CODE_CALL, CODE_CALLU, CODE_CALLARG,
CODE_PRINT,
CODE_LOCAL,
CODE_DO, CODE_DOARGS,
CODE_JUMP, CODE_JUMP_TRUE, CODE_JUMP_FALSE,
CODE_JUMP_RESULT_TRUE, CODE_JUMP_RESULT_FALSE,
CODE_OP_MASK = 0x3F,
CODE_RET = 6,
CODE_RET_MASK = 0xC0,
/* return type flags */
RET_NULL = VAL_NULL << CODE_RET,
RET_STR = VAL_STR << CODE_RET,
RET_INT = VAL_INT << CODE_RET,
RET_FLOAT = VAL_FLOAT << CODE_RET,
};
struct NullValue: TaggedValue {
NullValue() { set_null(); }
} const null_value;
template<typename F>
static void cs_do_args(CsState &cs, F body) {
IdentStack argstack[MaxArguments];
int argmask1 = cs.stack->usedargs;
for (int i = 0; argmask1; argmask1 >>= 1, ++i) if(argmask1 & 1)
cs.identmap[i]->undo_arg(argstack[i]);
IdentLink *prevstack = cs.stack->next;
IdentLink aliaslink = {
cs.stack->id, cs.stack, prevstack->usedargs, prevstack->argstack
};
cs.stack = &aliaslink;
body();
prevstack->usedargs = aliaslink.usedargs;
cs.stack = aliaslink.next;
int argmask2 = cs.stack->usedargs;
for(int i = 0; argmask2; argmask2 >>= 1, ++i) if(argmask2 & 1)
cs.identmap[i]->redo_arg(argstack[i]);
}
ostd::ConstCharRange cs_debug_line(CsState &cs,
ostd::ConstCharRange p,
ostd::ConstCharRange fmt,
ostd::CharRange buf);
void cs_debug_alias(CsState &cs);
template<typename ...A>
void cs_debug_code(CsState &cs, ostd::ConstCharRange fmt, A &&...args) {
if (cs.nodebug) return;
ostd::err.writefln(fmt, ostd::forward<A>(args)...);
cs_debug_alias(cs);
}
template<typename ...A>
void cs_debug_code_line(CsState &cs, ostd::ConstCharRange p,
ostd::ConstCharRange fmt, A &&...args) {
if (cs.nodebug) return;
ostd::Array<char, 256> buf;
ostd::err.writefln(cs_debug_line(cs, p, fmt, ostd::CharRange(buf.data(),
buf.size())),
ostd::forward<A>(args)...);
cs_debug_alias(cs);
}
ostd::Uint32 *compilecode(CsState &cs, ostd::ConstCharRange str);
struct GenState {
CsState &cs;
ostd::Vector<ostd::Uint32> code;
char const *source;
GenState() = delete;
GenState(CsState &csr): cs(csr), code(), source(nullptr) {}
void gen_str(ostd::ConstCharRange word, bool macro = false) {
if (word.size() <= 3 && !macro) {
ostd::Uint32 op = CODE_VALI | RET_STR;
for (ostd::Size i = 0; i < word.size(); ++i)
op |= ostd::Uint32(ostd::byte(word[i])) << ((i + 1) * 8);
code.push(op);
return;
}
code.push((macro ? CODE_MACRO : (CODE_VAL | RET_STR)) |
(word.size() << 8));
code.push_n(reinterpret_cast<ostd::Uint32 const *>(word.data()),
word.size() / sizeof(ostd::Uint32));
ostd::Size esz = word.size() % sizeof(ostd::Uint32);
union {
char c[sizeof(ostd::Uint32)];
ostd::Uint32 u;
} end;
end.u = 0;
memcpy(end.c, word.data() + word.size() - esz, esz);
code.push(end.u);
}
void gen_str() {
code.push(CODE_VALI | RET_STR);
}
void gen_null() {
code.push(CODE_VALI | RET_NULL);
}
void gen_int(int i = 0) {
if (i >= -0x800000 && i <= 0x7FFFFF)
code.push(CODE_VALI | RET_INT | (i << 8));
else {
code.push(CODE_VAL | RET_INT);
code.push(i);
}
}
void gen_int(ostd::ConstCharRange word);
void gen_float(float f = 0.0f) {
if (int(f) == f && f >= -0x800000 && f <= 0x7FFFFF)
code.push(CODE_VALI | RET_FLOAT | (int(f) << 8));
else {
union {
float f;
ostd::Uint32 u;
} c;
c.f = f;
code.push(CODE_VAL | RET_FLOAT);
code.push(c.u);
}
}
void gen_float(ostd::ConstCharRange word);
void gen_ident(Ident *id) {
code.push(((id->index < MaxArguments) ? CODE_IDENTARG
: CODE_IDENT) |
(id->index << 8));
}
void gen_ident() {
gen_ident(cs.dummy);
}
void gen_ident(ostd::ConstCharRange word) {
gen_ident(cs.new_ident(word));
}
void gen_value(int wordtype, ostd::ConstCharRange word
= ostd::ConstCharRange());
void gen_main(ostd::ConstCharRange s, int ret_type = VAL_ANY);
char next_char() {
return *source++;
}
char current() {
return *source;
}
};
void cs_set_macro(
TaggedValue &tv, Bytecode const *val, ostd::Size len
);
int parseint(char const *s);
float parsefloat(char const *s);
ostd::String intstr(int v);
ostd::String floatstr(float v);
bool cs_check_num(ostd::ConstCharRange s);
} /* namespace cscript */
#endif /* LIBCUBESCRIPT_CS_VM_HH */

File diff suppressed because it is too large Load Diff