rename codegen_state to parser_state and move it
later commits will rewrite the parser and separate the codegen bits into their own APImaster
parent
9a2de6ffd3
commit
ccb0c09d59
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "cs_gen.hh"
|
#include "cs_parser.hh"
|
||||||
#include "cs_thread.hh"
|
#include "cs_thread.hh"
|
||||||
|
|
||||||
namespace cubescript {
|
namespace cubescript {
|
||||||
|
@ -49,7 +49,7 @@ LIBCUBESCRIPT_EXPORT char *error::request_buf(
|
||||||
) {
|
) {
|
||||||
auto &ts = state_p{cs}.ts();
|
auto &ts = state_p{cs}.ts();
|
||||||
charbuf &cb = ts.errbuf;
|
charbuf &cb = ts.errbuf;
|
||||||
codegen_state *gs = ts.cstate;
|
parser_state *gs = ts.cstate;
|
||||||
cb.clear();
|
cb.clear();
|
||||||
std::size_t sz = 0;
|
std::size_t sz = 0;
|
||||||
if (gs) {
|
if (gs) {
|
||||||
|
|
1389
src/cs_gen.cc
1389
src/cs_gen.cc
File diff suppressed because it is too large
Load Diff
142
src/cs_gen.hh
142
src/cs_gen.hh
|
@ -3,150 +3,8 @@
|
||||||
|
|
||||||
#include "cubescript/cubescript.hh"
|
#include "cubescript/cubescript.hh"
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <array>
|
|
||||||
#include <vector>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
#include "cs_std.hh"
|
|
||||||
#include "cs_bcode.hh"
|
|
||||||
#include "cs_ident.hh"
|
|
||||||
#include "cs_thread.hh"
|
|
||||||
|
|
||||||
namespace cubescript {
|
namespace cubescript {
|
||||||
|
|
||||||
struct codegen_state {
|
|
||||||
thread_state &ts;
|
|
||||||
codegen_state *prevps;
|
|
||||||
bool parsing = true;
|
|
||||||
valbuf<uint32_t> code;
|
|
||||||
char const *source, *send;
|
|
||||||
std::size_t current_line;
|
|
||||||
std::string_view src_name;
|
|
||||||
|
|
||||||
codegen_state() = delete;
|
|
||||||
codegen_state(thread_state &tsr):
|
|
||||||
ts{tsr}, prevps{tsr.cstate}, code{tsr.istate},
|
|
||||||
source{}, send{}, current_line{1}, src_name{}
|
|
||||||
{
|
|
||||||
tsr.cstate = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
~codegen_state() {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
|
|
||||||
void done() {
|
|
||||||
if (!parsing) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ts.cstate = prevps;
|
|
||||||
parsing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string_view get_str();
|
|
||||||
charbuf get_str_dup();
|
|
||||||
|
|
||||||
std::string_view get_word();
|
|
||||||
|
|
||||||
void gen_str(std::string_view word = std::string_view{}) {
|
|
||||||
if (word.size() <= 3) {
|
|
||||||
std::uint32_t op = BC_INST_VAL_INT | BC_RET_STRING;
|
|
||||||
for (size_t i = 0; i < word.size(); ++i) {
|
|
||||||
op |= std::uint32_t(
|
|
||||||
static_cast<unsigned char>(word[i])
|
|
||||||
) << ((i + 1) * 8);
|
|
||||||
}
|
|
||||||
code.push_back(op);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
code.push_back(
|
|
||||||
BC_INST_VAL | BC_RET_STRING | std::uint32_t(word.size() << 8)
|
|
||||||
);
|
|
||||||
auto it = reinterpret_cast<std::uint32_t const *>(word.data());
|
|
||||||
code.append(it, it + (word.size() / sizeof(std::uint32_t)));
|
|
||||||
std::size_t esz = word.size() % sizeof(std::uint32_t);
|
|
||||||
char c[sizeof(std::uint32_t)] = {0};
|
|
||||||
std::memcpy(c, word.data() + word.size() - esz, esz);
|
|
||||||
std::uint32_t u;
|
|
||||||
std::memcpy(&u, c, sizeof(u));
|
|
||||||
code.push_back(u);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gen_null() {
|
|
||||||
code.push_back(BC_INST_VAL_INT | BC_RET_NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gen_int(integer_type i = 0) {
|
|
||||||
if (i >= -0x800000 && i <= 0x7FFFFF) {
|
|
||||||
code.push_back(BC_INST_VAL_INT | BC_RET_INT | (i << 8));
|
|
||||||
} else {
|
|
||||||
std::uint32_t u[bc_store_size<integer_type>] = {0};
|
|
||||||
std::memcpy(u, &i, sizeof(i));
|
|
||||||
code.push_back(BC_INST_VAL | BC_RET_INT);
|
|
||||||
code.append(u, u + bc_store_size<integer_type>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void gen_int(std::string_view word);
|
|
||||||
|
|
||||||
void gen_float(float_type f = 0.0f) {
|
|
||||||
if (integer_type(f) == f && f >= -0x800000 && f <= 0x7FFFFF) {
|
|
||||||
code.push_back(BC_INST_VAL_INT | BC_RET_FLOAT | (integer_type(f) << 8));
|
|
||||||
} else {
|
|
||||||
std::uint32_t u[bc_store_size<float_type>] = {0};
|
|
||||||
std::memcpy(u, &f, sizeof(f));
|
|
||||||
code.push_back(BC_INST_VAL | BC_RET_FLOAT);
|
|
||||||
code.append(u, u + bc_store_size<float_type>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void gen_float(std::string_view word);
|
|
||||||
|
|
||||||
void gen_ident(ident &id) {
|
|
||||||
code.push_back(BC_INST_IDENT | (id.get_index() << 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
void gen_ident() {
|
|
||||||
gen_ident(*ts.istate->id_dummy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gen_ident(std::string_view word) {
|
|
||||||
gen_ident(ts.istate->new_ident(*ts.pstate, word, IDENT_FLAG_UNKNOWN));
|
|
||||||
}
|
|
||||||
|
|
||||||
void gen_value(
|
|
||||||
int wordtype, std::string_view word = std::string_view(),
|
|
||||||
int line = 0
|
|
||||||
);
|
|
||||||
|
|
||||||
void gen_main(std::string_view s, int ret_type = VAL_ANY);
|
|
||||||
|
|
||||||
void next_char() {
|
|
||||||
if (source == send) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (*source == '\n') {
|
|
||||||
++current_line;
|
|
||||||
}
|
|
||||||
++source;
|
|
||||||
}
|
|
||||||
|
|
||||||
char current(size_t ahead = 0) {
|
|
||||||
if (std::size_t(send - source) <= ahead) {
|
|
||||||
return '\0';
|
|
||||||
}
|
|
||||||
return source[ahead];
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string_view read_macro_name();
|
|
||||||
|
|
||||||
char skip_until(std::string_view chars);
|
|
||||||
char skip_until(char cf);
|
|
||||||
|
|
||||||
void skip_comments();
|
|
||||||
};
|
|
||||||
|
|
||||||
} /* namespace cubescript */
|
} /* namespace cubescript */
|
||||||
|
|
||||||
#endif /* LIBCUBESCRIPT_GEN_HH */
|
#endif /* LIBCUBESCRIPT_GEN_HH */
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "cs_ident.hh"
|
#include "cs_ident.hh"
|
||||||
|
|
||||||
#include "cs_bcode.hh"
|
#include "cs_bcode.hh"
|
||||||
#include "cs_gen.hh"
|
|
||||||
#include "cs_thread.hh"
|
#include "cs_thread.hh"
|
||||||
|
|
||||||
namespace cubescript {
|
namespace cubescript {
|
||||||
|
|
1383
src/cs_parser.cc
1383
src/cs_parser.cc
File diff suppressed because it is too large
Load Diff
141
src/cs_parser.hh
141
src/cs_parser.hh
|
@ -1,9 +1,16 @@
|
||||||
#ifndef LIBCUBESCRIPT_PARSER_HH
|
#ifndef LIBCUBESCRIPT_PARSER_HH
|
||||||
#define LIBCUBESCRIPT_PARSER_HH
|
#define LIBCUBESCRIPT_PARSER_HH
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
#include <cubescript/cubescript.hh>
|
#include <cubescript/cubescript.hh>
|
||||||
|
|
||||||
#include <string_view>
|
#include "cs_std.hh"
|
||||||
|
#include "cs_bcode.hh"
|
||||||
|
#include "cs_ident.hh"
|
||||||
|
#include "cs_thread.hh"
|
||||||
|
|
||||||
namespace cubescript {
|
namespace cubescript {
|
||||||
|
|
||||||
|
@ -12,6 +19,138 @@ float_type parse_float(std::string_view input, std::string_view *end = nullptr);
|
||||||
|
|
||||||
bool is_valid_name(std::string_view input);
|
bool is_valid_name(std::string_view input);
|
||||||
|
|
||||||
|
struct parser_state {
|
||||||
|
thread_state &ts;
|
||||||
|
parser_state *prevps;
|
||||||
|
bool parsing = true;
|
||||||
|
valbuf<uint32_t> code;
|
||||||
|
char const *source, *send;
|
||||||
|
std::size_t current_line;
|
||||||
|
std::string_view src_name;
|
||||||
|
|
||||||
|
parser_state() = delete;
|
||||||
|
parser_state(thread_state &tsr):
|
||||||
|
ts{tsr}, prevps{tsr.cstate}, code{tsr.istate},
|
||||||
|
source{}, send{}, current_line{1}, src_name{}
|
||||||
|
{
|
||||||
|
tsr.cstate = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~parser_state() {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
|
||||||
|
void done() {
|
||||||
|
if (!parsing) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ts.cstate = prevps;
|
||||||
|
parsing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view get_str();
|
||||||
|
charbuf get_str_dup();
|
||||||
|
|
||||||
|
std::string_view get_word();
|
||||||
|
|
||||||
|
void gen_str(std::string_view word = std::string_view{}) {
|
||||||
|
if (word.size() <= 3) {
|
||||||
|
std::uint32_t op = BC_INST_VAL_INT | BC_RET_STRING;
|
||||||
|
for (size_t i = 0; i < word.size(); ++i) {
|
||||||
|
op |= std::uint32_t(
|
||||||
|
static_cast<unsigned char>(word[i])
|
||||||
|
) << ((i + 1) * 8);
|
||||||
|
}
|
||||||
|
code.push_back(op);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
code.push_back(
|
||||||
|
BC_INST_VAL | BC_RET_STRING | std::uint32_t(word.size() << 8)
|
||||||
|
);
|
||||||
|
auto it = reinterpret_cast<std::uint32_t const *>(word.data());
|
||||||
|
code.append(it, it + (word.size() / sizeof(std::uint32_t)));
|
||||||
|
std::size_t esz = word.size() % sizeof(std::uint32_t);
|
||||||
|
char c[sizeof(std::uint32_t)] = {0};
|
||||||
|
std::memcpy(c, word.data() + word.size() - esz, esz);
|
||||||
|
std::uint32_t u;
|
||||||
|
std::memcpy(&u, c, sizeof(u));
|
||||||
|
code.push_back(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_null() {
|
||||||
|
code.push_back(BC_INST_VAL_INT | BC_RET_NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_int(integer_type i = 0) {
|
||||||
|
if (i >= -0x800000 && i <= 0x7FFFFF) {
|
||||||
|
code.push_back(BC_INST_VAL_INT | BC_RET_INT | (i << 8));
|
||||||
|
} else {
|
||||||
|
std::uint32_t u[bc_store_size<integer_type>] = {0};
|
||||||
|
std::memcpy(u, &i, sizeof(i));
|
||||||
|
code.push_back(BC_INST_VAL | BC_RET_INT);
|
||||||
|
code.append(u, u + bc_store_size<integer_type>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_int(std::string_view word);
|
||||||
|
|
||||||
|
void gen_float(float_type f = 0.0f) {
|
||||||
|
if (integer_type(f) == f && f >= -0x800000 && f <= 0x7FFFFF) {
|
||||||
|
code.push_back(BC_INST_VAL_INT | BC_RET_FLOAT | (integer_type(f) << 8));
|
||||||
|
} else {
|
||||||
|
std::uint32_t u[bc_store_size<float_type>] = {0};
|
||||||
|
std::memcpy(u, &f, sizeof(f));
|
||||||
|
code.push_back(BC_INST_VAL | BC_RET_FLOAT);
|
||||||
|
code.append(u, u + bc_store_size<float_type>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_float(std::string_view word);
|
||||||
|
|
||||||
|
void gen_ident(ident &id) {
|
||||||
|
code.push_back(BC_INST_IDENT | (id.get_index() << 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_ident() {
|
||||||
|
gen_ident(*ts.istate->id_dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_ident(std::string_view word) {
|
||||||
|
gen_ident(ts.istate->new_ident(*ts.pstate, word, IDENT_FLAG_UNKNOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_value(
|
||||||
|
int wordtype, std::string_view word = std::string_view(),
|
||||||
|
int line = 0
|
||||||
|
);
|
||||||
|
|
||||||
|
void gen_main(std::string_view s, int ret_type = VAL_ANY);
|
||||||
|
|
||||||
|
void next_char() {
|
||||||
|
if (source == send) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (*source == '\n') {
|
||||||
|
++current_line;
|
||||||
|
}
|
||||||
|
++source;
|
||||||
|
}
|
||||||
|
|
||||||
|
char current(size_t ahead = 0) {
|
||||||
|
if (std::size_t(send - source) <= ahead) {
|
||||||
|
return '\0';
|
||||||
|
}
|
||||||
|
return source[ahead];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view read_macro_name();
|
||||||
|
|
||||||
|
char skip_until(std::string_view chars);
|
||||||
|
char skip_until(char cf);
|
||||||
|
|
||||||
|
void skip_comments();
|
||||||
|
};
|
||||||
|
|
||||||
} /* namespace cubescript */
|
} /* namespace cubescript */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "cs_state.hh"
|
#include "cs_state.hh"
|
||||||
#include "cs_thread.hh"
|
#include "cs_thread.hh"
|
||||||
#include "cs_strman.hh"
|
#include "cs_strman.hh"
|
||||||
#include "cs_gen.hh"
|
|
||||||
#include "cs_vm.hh" // break/continue, call_with_args
|
#include "cs_vm.hh" // break/continue, call_with_args
|
||||||
#include "cs_parser.hh"
|
#include "cs_parser.hh"
|
||||||
|
|
||||||
|
@ -656,7 +655,7 @@ static any_value do_run(
|
||||||
thread_state &ts, std::string_view file, std::string_view code
|
thread_state &ts, std::string_view file, std::string_view code
|
||||||
) {
|
) {
|
||||||
any_value ret{*ts.pstate};
|
any_value ret{*ts.pstate};
|
||||||
codegen_state gs{ts};
|
parser_state gs{ts};
|
||||||
gs.src_name = file;
|
gs.src_name = file;
|
||||||
gs.code.reserve(64);
|
gs.code.reserve(64);
|
||||||
gs.gen_main(code, VAL_ANY);
|
gs.gen_main(code, VAL_ANY);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "cs_thread.hh"
|
#include "cs_thread.hh"
|
||||||
|
|
||||||
#include "cs_gen.hh"
|
|
||||||
|
|
||||||
namespace cubescript {
|
namespace cubescript {
|
||||||
|
|
||||||
thread_state::thread_state(internal_state *cs):
|
thread_state::thread_state(internal_state *cs):
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
namespace cubescript {
|
namespace cubescript {
|
||||||
|
|
||||||
struct codegen_state;
|
struct parser_state;
|
||||||
|
|
||||||
struct thread_state {
|
struct thread_state {
|
||||||
using astack_allocator = std_allocator<std::pair<int const, alias_stack>>;
|
using astack_allocator = std_allocator<std::pair<int const, alias_stack>>;
|
||||||
|
@ -22,7 +22,7 @@ struct thread_state {
|
||||||
/* the public state interface */
|
/* the public state interface */
|
||||||
state *pstate{};
|
state *pstate{};
|
||||||
/* current codegen state for diagnostics */
|
/* current codegen state for diagnostics */
|
||||||
codegen_state *cstate{};
|
parser_state *cstate{};
|
||||||
/* VM stack */
|
/* VM stack */
|
||||||
valbuf<any_value> vmstack;
|
valbuf<any_value> vmstack;
|
||||||
/* ident stack */
|
/* ident stack */
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include <cubescript/cubescript.hh>
|
#include <cubescript/cubescript.hh>
|
||||||
#include "cs_gen.hh"
|
|
||||||
#include "cs_std.hh"
|
#include "cs_std.hh"
|
||||||
#include "cs_parser.hh"
|
#include "cs_parser.hh"
|
||||||
#include "cs_state.hh"
|
#include "cs_state.hh"
|
||||||
|
@ -270,7 +269,7 @@ bcode_ref any_value::force_code(state &cs) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
codegen_state gs{state_p{cs}.ts()};
|
parser_state gs{state_p{cs}.ts()};
|
||||||
gs.code.reserve(64);
|
gs.code.reserve(64);
|
||||||
gs.gen_main(get_string());
|
gs.gen_main(get_string());
|
||||||
gs.done();
|
gs.done();
|
||||||
|
|
|
@ -239,7 +239,7 @@ bool exec_alias(
|
||||||
ident_link aliaslink = {a, ts.callstack, uargs};
|
ident_link aliaslink = {a, ts.callstack, uargs};
|
||||||
ts.callstack = &aliaslink;
|
ts.callstack = &aliaslink;
|
||||||
if (!aast.node->code) {
|
if (!aast.node->code) {
|
||||||
codegen_state gs{ts};
|
parser_state gs{ts};
|
||||||
gs.code.reserve(64);
|
gs.code.reserve(64);
|
||||||
gs.gen_main(aast.node->val_s.get_string());
|
gs.gen_main(aast.node->val_s.get_string());
|
||||||
/* i wish i could steal the memory somehow */
|
/* i wish i could steal the memory somehow */
|
||||||
|
@ -687,7 +687,7 @@ std::uint32_t *vm_exec(
|
||||||
|
|
||||||
case BC_INST_COMPILE: {
|
case BC_INST_COMPILE: {
|
||||||
any_value &arg = args.back();
|
any_value &arg = args.back();
|
||||||
codegen_state gs{ts};
|
parser_state gs{ts};
|
||||||
switch (arg.get_type()) {
|
switch (arg.get_type()) {
|
||||||
case value_type::INTEGER:
|
case value_type::INTEGER:
|
||||||
gs.code.reserve(8);
|
gs.code.reserve(8);
|
||||||
|
@ -733,7 +733,7 @@ std::uint32_t *vm_exec(
|
||||||
case value_type::STRING: {
|
case value_type::STRING: {
|
||||||
std::string_view s = arg.get_string();
|
std::string_view s = arg.get_string();
|
||||||
if (!s.empty()) {
|
if (!s.empty()) {
|
||||||
codegen_state gs{ts};
|
parser_state gs{ts};
|
||||||
gs.code.reserve(64);
|
gs.code.reserve(64);
|
||||||
gs.gen_main(s);
|
gs.gen_main(s);
|
||||||
gs.done();
|
gs.done();
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include "cs_std.hh"
|
#include "cs_std.hh"
|
||||||
#include "cs_ident.hh"
|
#include "cs_ident.hh"
|
||||||
#include "cs_gen.hh"
|
|
||||||
#include "cs_thread.hh"
|
#include "cs_thread.hh"
|
||||||
|
|
||||||
namespace cubescript {
|
namespace cubescript {
|
||||||
|
|
Loading…
Reference in New Issue