forked from OctaForge/libcubescript
begin naming scheme rework
parent
140ccf08c6
commit
41eb8b211f
|
@ -21,176 +21,176 @@
|
|||
|
||||
namespace cscript {
|
||||
|
||||
using CsString = std::string;
|
||||
using cs_string = std::string;
|
||||
|
||||
static_assert(std::is_integral_v<CsInt>, "CsInt must be integral");
|
||||
static_assert(std::is_signed_v<CsInt>, "CsInt must be signed");
|
||||
static_assert(std::is_floating_point_v<CsFloat>, "CsFloat must be floating point");
|
||||
static_assert(std::is_integral_v<cs_int>, "cs_int must be integral");
|
||||
static_assert(std::is_signed_v<cs_int>, "cs_int must be signed");
|
||||
static_assert(std::is_floating_point_v<cs_float>, "cs_float must be floating point");
|
||||
|
||||
struct cs_internal_error: public std::runtime_error {
|
||||
struct cs_internal_error: std::runtime_error {
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
enum {
|
||||
CsIdfPersist = 1 << 0,
|
||||
CsIdfOverride = 1 << 1,
|
||||
CsIdfHex = 1 << 2,
|
||||
CsIdfReadOnly = 1 << 3,
|
||||
CsIdfOverridden = 1 << 4,
|
||||
CsIdfUnknown = 1 << 5,
|
||||
CsIdfArg = 1 << 6
|
||||
CS_IDF_PERSIST = 1 << 0,
|
||||
CS_IDF_OVERRIDE = 1 << 1,
|
||||
CS_IDF_HEX = 1 << 2,
|
||||
CS_IDF_READONLY = 1 << 3,
|
||||
CS_IDF_OVERRIDDEN = 1 << 4,
|
||||
CS_IDF_UNKNOWN = 1 << 5,
|
||||
CS_IDF_ARG = 1 << 6
|
||||
};
|
||||
|
||||
struct CsBytecode;
|
||||
struct cs_bcode;
|
||||
|
||||
struct OSTD_EXPORT CsBytecodeRef {
|
||||
CsBytecodeRef():
|
||||
struct OSTD_EXPORT cs_bcode_ref {
|
||||
cs_bcode_ref():
|
||||
p_code(nullptr)
|
||||
{}
|
||||
CsBytecodeRef(CsBytecode *v);
|
||||
CsBytecodeRef(CsBytecodeRef const &v);
|
||||
CsBytecodeRef(CsBytecodeRef &&v):
|
||||
cs_bcode_ref(cs_bcode *v);
|
||||
cs_bcode_ref(cs_bcode_ref const &v);
|
||||
cs_bcode_ref(cs_bcode_ref &&v):
|
||||
p_code(v.p_code)
|
||||
{
|
||||
v.p_code = nullptr;
|
||||
}
|
||||
|
||||
~CsBytecodeRef();
|
||||
~cs_bcode_ref();
|
||||
|
||||
CsBytecodeRef &operator=(CsBytecodeRef const &v);
|
||||
CsBytecodeRef &operator=(CsBytecodeRef &&v);
|
||||
cs_bcode_ref &operator=(cs_bcode_ref const &v);
|
||||
cs_bcode_ref &operator=(cs_bcode_ref &&v);
|
||||
|
||||
operator bool() const { return p_code != nullptr; }
|
||||
operator CsBytecode *() const { return p_code; }
|
||||
operator cs_bcode *() const { return p_code; }
|
||||
|
||||
private:
|
||||
CsBytecode *p_code;
|
||||
cs_bcode *p_code;
|
||||
};
|
||||
|
||||
OSTD_EXPORT bool cs_code_is_empty(CsBytecode *code);
|
||||
OSTD_EXPORT bool cs_code_is_empty(cs_bcode *code);
|
||||
|
||||
enum class CsValueType {
|
||||
enum class cs_value_type {
|
||||
Null = 0, Int, Float, String, Cstring, Code, Macro, Ident
|
||||
};
|
||||
|
||||
struct OSTD_EXPORT CsValue {
|
||||
CsValue();
|
||||
~CsValue();
|
||||
struct OSTD_EXPORT cs_value {
|
||||
cs_value();
|
||||
~cs_value();
|
||||
|
||||
CsValue(CsValue const &);
|
||||
CsValue(CsValue &&);
|
||||
cs_value(cs_value const &);
|
||||
cs_value(cs_value &&);
|
||||
|
||||
CsValue &operator=(CsValue const &v);
|
||||
CsValue &operator=(CsValue &&v);
|
||||
cs_value &operator=(cs_value const &v);
|
||||
cs_value &operator=(cs_value &&v);
|
||||
|
||||
CsValueType get_type() const;
|
||||
cs_value_type get_type() const;
|
||||
|
||||
void set_int(CsInt val);
|
||||
void set_float(CsFloat val);
|
||||
void set_str(CsString val);
|
||||
void set_int(cs_int val);
|
||||
void set_float(cs_float val);
|
||||
void set_str(cs_string val);
|
||||
void set_null();
|
||||
void set_code(CsBytecode *val);
|
||||
void set_code(cs_bcode *val);
|
||||
void set_cstr(ostd::ConstCharRange val);
|
||||
void set_ident(CsIdent *val);
|
||||
void set_ident(cs_ident *val);
|
||||
void set_macro(ostd::ConstCharRange val);
|
||||
|
||||
CsString get_str() const;
|
||||
cs_string get_str() const;
|
||||
ostd::ConstCharRange get_strr() const;
|
||||
CsInt get_int() const;
|
||||
CsFloat get_float() const;
|
||||
CsBytecode *get_code() const;
|
||||
CsIdent *get_ident() const;
|
||||
void get_val(CsValue &r) const;
|
||||
cs_int get_int() const;
|
||||
cs_float get_float() const;
|
||||
cs_bcode *get_code() const;
|
||||
cs_ident *get_ident() const;
|
||||
void get_val(cs_value &r) const;
|
||||
|
||||
bool get_bool() const;
|
||||
|
||||
void force_null();
|
||||
CsFloat force_float();
|
||||
CsInt force_int();
|
||||
cs_float force_float();
|
||||
cs_int force_int();
|
||||
ostd::ConstCharRange force_str();
|
||||
|
||||
bool code_is_empty() const;
|
||||
|
||||
private:
|
||||
std::aligned_union_t<1, CsInt, CsFloat, void *> p_stor;
|
||||
std::aligned_union_t<1, cs_int, cs_float, void *> p_stor;
|
||||
size_t p_len;
|
||||
CsValueType p_type;
|
||||
cs_value_type p_type;
|
||||
};
|
||||
|
||||
struct CsIdentStack {
|
||||
CsValue val_s;
|
||||
CsIdentStack *next;
|
||||
struct cs_ident_stack {
|
||||
cs_value val_s;
|
||||
cs_ident_stack *next;
|
||||
};
|
||||
|
||||
struct CsSharedState;
|
||||
struct CsErrorException;
|
||||
struct GenState;
|
||||
struct cs_shared_state;
|
||||
struct cs_error;
|
||||
struct cs_gen_state;
|
||||
|
||||
enum class CsIdentType {
|
||||
enum class cs_ident_type {
|
||||
Ivar = 0, Fvar, Svar, Command, Alias, Special
|
||||
};
|
||||
|
||||
struct CsVar;
|
||||
struct CsIvar;
|
||||
struct CsFvar;
|
||||
struct CsSvar;
|
||||
struct CsAlias;
|
||||
struct CsCommand;
|
||||
struct cs_var;
|
||||
struct cs_ivar;
|
||||
struct cs_fvar;
|
||||
struct cs_svar;
|
||||
struct cs_alias;
|
||||
struct cs_command;
|
||||
|
||||
struct OSTD_EXPORT CsIdent {
|
||||
friend struct CsState;
|
||||
friend struct CsSharedState;
|
||||
struct OSTD_EXPORT cs_ident {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
CsIdent() = delete;
|
||||
CsIdent(CsIdent const &) = delete;
|
||||
CsIdent(CsIdent &&) = delete;
|
||||
cs_ident() = delete;
|
||||
cs_ident(cs_ident const &) = delete;
|
||||
cs_ident(cs_ident &&) = delete;
|
||||
|
||||
/* trigger destructors for all inherited members properly */
|
||||
virtual ~CsIdent() {};
|
||||
virtual ~cs_ident() {};
|
||||
|
||||
CsIdent &operator=(CsIdent const &) = delete;
|
||||
CsIdent &operator=(CsIdent &&) = delete;
|
||||
cs_ident &operator=(cs_ident const &) = delete;
|
||||
cs_ident &operator=(cs_ident &&) = delete;
|
||||
|
||||
CsIdentType get_type() const;
|
||||
cs_ident_type get_type() const;
|
||||
ostd::ConstCharRange get_name() const;
|
||||
int get_flags() const;
|
||||
int get_index() const;
|
||||
|
||||
bool is_alias() const;
|
||||
CsAlias *get_alias();
|
||||
CsAlias const *get_alias() const;
|
||||
cs_alias *get_alias();
|
||||
cs_alias const *get_alias() const;
|
||||
|
||||
bool is_command() const;
|
||||
CsCommand *get_command();
|
||||
CsCommand const *get_command() const;
|
||||
cs_command *get_command();
|
||||
cs_command const *get_command() const;
|
||||
|
||||
bool is_special() const;
|
||||
|
||||
bool is_var() const;
|
||||
CsVar *get_var();
|
||||
CsVar const *get_var() const;
|
||||
cs_var *get_var();
|
||||
cs_var const *get_var() const;
|
||||
|
||||
bool is_ivar() const;
|
||||
CsIvar *get_ivar();
|
||||
CsIvar const *get_ivar() const;
|
||||
cs_ivar *get_ivar();
|
||||
cs_ivar const *get_ivar() const;
|
||||
|
||||
bool is_fvar() const;
|
||||
CsFvar *get_fvar();
|
||||
CsFvar const *get_fvar() const;
|
||||
cs_fvar *get_fvar();
|
||||
cs_fvar const *get_fvar() const;
|
||||
|
||||
bool is_svar() const;
|
||||
CsSvar *get_svar();
|
||||
CsSvar const *get_svar() const;
|
||||
cs_svar *get_svar();
|
||||
cs_svar const *get_svar() const;
|
||||
|
||||
int get_type_raw() const {
|
||||
return p_type;
|
||||
}
|
||||
|
||||
protected:
|
||||
CsIdent(CsIdentType tp, ostd::ConstCharRange name, int flags = 0);
|
||||
cs_ident(cs_ident_type tp, ostd::ConstCharRange name, int flags = 0);
|
||||
|
||||
CsString p_name;
|
||||
/* represents the CsIdentType above, but internally it has a wider variety
|
||||
cs_string p_name;
|
||||
/* represents the cs_ident_type above, but internally it has a wider variety
|
||||
* of values, so it's an int here (maps to an internal enum)
|
||||
*/
|
||||
int p_type, p_flags;
|
||||
|
@ -199,128 +199,128 @@ private:
|
|||
int p_index = -1;
|
||||
};
|
||||
|
||||
struct OSTD_EXPORT CsVar: CsIdent {
|
||||
friend struct CsState;
|
||||
friend struct CsSharedState;
|
||||
struct OSTD_EXPORT cs_var: cs_ident {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
protected:
|
||||
CsVar(CsIdentType tp, ostd::ConstCharRange name, CsVarCb func, int flags = 0);
|
||||
cs_var(cs_ident_type tp, ostd::ConstCharRange name, cs_var_cb func, int flags = 0);
|
||||
|
||||
private:
|
||||
CsVarCb cb_var;
|
||||
cs_var_cb cb_var;
|
||||
|
||||
virtual CsString to_printable() const = 0;
|
||||
virtual cs_string to_printable() const = 0;
|
||||
|
||||
void changed(CsState &cs) {
|
||||
void changed(cs_state &cs) {
|
||||
if (cb_var) {
|
||||
cb_var(cs, *this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct OSTD_EXPORT CsIvar: CsVar {
|
||||
friend struct CsState;
|
||||
friend struct CsSharedState;
|
||||
struct OSTD_EXPORT cs_ivar: cs_var {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
CsInt get_val_min() const;
|
||||
CsInt get_val_max() const;
|
||||
cs_int get_val_min() const;
|
||||
cs_int get_val_max() const;
|
||||
|
||||
CsInt get_value() const;
|
||||
void set_value(CsInt val);
|
||||
cs_int get_value() const;
|
||||
void set_value(cs_int val);
|
||||
|
||||
CsString to_printable() const final;
|
||||
cs_string to_printable() const final;
|
||||
|
||||
private:
|
||||
CsIvar(
|
||||
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v, CsVarCb f, int flags
|
||||
cs_ivar(
|
||||
ostd::ConstCharRange n, cs_int m, cs_int x, cs_int v, cs_var_cb f, int flags
|
||||
);
|
||||
|
||||
CsInt p_storage, p_minval, p_maxval, p_overrideval;
|
||||
cs_int p_storage, p_minval, p_maxval, p_overrideval;
|
||||
};
|
||||
|
||||
struct OSTD_EXPORT CsFvar: CsVar {
|
||||
friend struct CsState;
|
||||
friend struct CsSharedState;
|
||||
struct OSTD_EXPORT cs_fvar: cs_var {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
CsFloat get_val_min() const;
|
||||
CsFloat get_val_max() const;
|
||||
cs_float get_val_min() const;
|
||||
cs_float get_val_max() const;
|
||||
|
||||
CsFloat get_value() const;
|
||||
void set_value(CsFloat val);
|
||||
cs_float get_value() const;
|
||||
void set_value(cs_float val);
|
||||
|
||||
CsString to_printable() const final;
|
||||
cs_string to_printable() const final;
|
||||
|
||||
private:
|
||||
CsFvar(
|
||||
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v,
|
||||
CsVarCb f, int flags
|
||||
cs_fvar(
|
||||
ostd::ConstCharRange n, cs_float m, cs_float x, cs_float v,
|
||||
cs_var_cb f, int flags
|
||||
);
|
||||
|
||||
CsFloat p_storage, p_minval, p_maxval, p_overrideval;
|
||||
cs_float p_storage, p_minval, p_maxval, p_overrideval;
|
||||
};
|
||||
|
||||
struct OSTD_EXPORT CsSvar: CsVar {
|
||||
friend struct CsState;
|
||||
friend struct CsSharedState;
|
||||
struct OSTD_EXPORT cs_svar: cs_var {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
|
||||
ostd::ConstCharRange get_value() const;
|
||||
void set_value(CsString val);
|
||||
void set_value(cs_string val);
|
||||
|
||||
CsString to_printable() const final;
|
||||
cs_string to_printable() const final;
|
||||
|
||||
private:
|
||||
CsSvar(ostd::ConstCharRange n, CsString v, CsVarCb f, int flags);
|
||||
cs_svar(ostd::ConstCharRange n, cs_string v, cs_var_cb f, int flags);
|
||||
|
||||
CsString p_storage, p_overrideval;
|
||||
cs_string p_storage, p_overrideval;
|
||||
};
|
||||
|
||||
struct OSTD_EXPORT CsAlias: CsIdent {
|
||||
friend struct CsState;
|
||||
friend struct CsSharedState;
|
||||
friend struct CsAliasInternal;
|
||||
struct OSTD_EXPORT cs_alias: cs_ident {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
friend struct cs_aliasInternal;
|
||||
|
||||
CsValue const &get_value() const {
|
||||
cs_value const &get_value() const {
|
||||
return p_val;
|
||||
}
|
||||
|
||||
CsValue &get_value() {
|
||||
cs_value &get_value() {
|
||||
return p_val;
|
||||
}
|
||||
|
||||
void get_cstr(CsValue &v) const;
|
||||
void get_cval(CsValue &v) const;
|
||||
void get_cstr(cs_value &v) const;
|
||||
void get_cval(cs_value &v) const;
|
||||
private:
|
||||
CsAlias(ostd::ConstCharRange n, CsString a, int flags);
|
||||
CsAlias(ostd::ConstCharRange n, CsInt a, int flags);
|
||||
CsAlias(ostd::ConstCharRange n, CsFloat a, int flags);
|
||||
CsAlias(ostd::ConstCharRange n, int flags);
|
||||
CsAlias(ostd::ConstCharRange n, CsValue v, int flags);
|
||||
cs_alias(ostd::ConstCharRange n, cs_string a, int flags);
|
||||
cs_alias(ostd::ConstCharRange n, cs_int a, int flags);
|
||||
cs_alias(ostd::ConstCharRange n, cs_float a, int flags);
|
||||
cs_alias(ostd::ConstCharRange n, int flags);
|
||||
cs_alias(ostd::ConstCharRange n, cs_value v, int flags);
|
||||
|
||||
CsBytecode *p_acode;
|
||||
CsIdentStack *p_astack;
|
||||
CsValue p_val;
|
||||
cs_bcode *p_acode;
|
||||
cs_ident_stack *p_astack;
|
||||
cs_value p_val;
|
||||
};
|
||||
|
||||
struct CsCommand: CsIdent {
|
||||
friend struct CsState;
|
||||
friend struct CsSharedState;
|
||||
friend struct CsCommandInternal;
|
||||
struct cs_command: cs_ident {
|
||||
friend struct cs_state;
|
||||
friend struct cs_shared_state;
|
||||
friend struct cs_cmd_internal;
|
||||
|
||||
ostd::ConstCharRange get_args() const;
|
||||
int get_num_args() const;
|
||||
|
||||
private:
|
||||
CsCommand(
|
||||
cs_command(
|
||||
ostd::ConstCharRange name, ostd::ConstCharRange args,
|
||||
int numargs, CsCommandCb func
|
||||
int numargs, cs_command_cb func
|
||||
);
|
||||
|
||||
CsString p_cargs;
|
||||
CsCommandCb p_cb_cftv;
|
||||
cs_string p_cargs;
|
||||
cs_command_cb p_cb_cftv;
|
||||
int p_numargs;
|
||||
};
|
||||
|
||||
struct CsIdentLink;
|
||||
struct cs_identLink;
|
||||
|
||||
enum {
|
||||
CsLibMath = 1 << 0,
|
||||
|
@ -341,172 +341,172 @@ static inline void *cs_default_alloc(void *, void *p, size_t, size_t ns) {
|
|||
return new unsigned char[ns];
|
||||
}
|
||||
|
||||
struct OSTD_EXPORT CsState {
|
||||
friend struct CsErrorException;
|
||||
friend struct GenState;
|
||||
struct OSTD_EXPORT cs_state {
|
||||
friend struct cs_error;
|
||||
friend struct cs_gen_state;
|
||||
|
||||
CsSharedState *p_state;
|
||||
CsIdentLink *p_callstack = nullptr;
|
||||
cs_shared_state *p_state;
|
||||
cs_identLink *p_callstack = nullptr;
|
||||
|
||||
int identflags = 0;
|
||||
|
||||
CsState(CsAllocCb func = cs_default_alloc, void *data = nullptr);
|
||||
virtual ~CsState();
|
||||
cs_state(cs_alloc_cb func = cs_default_alloc, void *data = nullptr);
|
||||
virtual ~cs_state();
|
||||
|
||||
CsHookCb set_call_hook(CsHookCb func);
|
||||
CsHookCb const &get_call_hook() const;
|
||||
CsHookCb &get_call_hook();
|
||||
cs_hook_cb set_call_hook(cs_hook_cb func);
|
||||
cs_hook_cb const &get_call_hook() const;
|
||||
cs_hook_cb &get_call_hook();
|
||||
|
||||
void init_libs(int libs = CsLibAll);
|
||||
|
||||
void clear_override(CsIdent &id);
|
||||
void clear_override(cs_ident &id);
|
||||
void clear_overrides();
|
||||
|
||||
CsIdent *new_ident(ostd::ConstCharRange name, int flags = CsIdfUnknown);
|
||||
CsIdent *force_ident(CsValue &v);
|
||||
cs_ident *new_ident(ostd::ConstCharRange name, int flags = CS_IDF_UNKNOWN);
|
||||
cs_ident *force_ident(cs_value &v);
|
||||
|
||||
CsIvar *new_ivar(
|
||||
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v,
|
||||
CsVarCb f = CsVarCb(), int flags = 0
|
||||
cs_ivar *new_ivar(
|
||||
ostd::ConstCharRange n, cs_int m, cs_int x, cs_int v,
|
||||
cs_var_cb f = cs_var_cb(), int flags = 0
|
||||
);
|
||||
CsFvar *new_fvar(
|
||||
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v,
|
||||
CsVarCb f = CsVarCb(), int flags = 0
|
||||
cs_fvar *new_fvar(
|
||||
ostd::ConstCharRange n, cs_float m, cs_float x, cs_float v,
|
||||
cs_var_cb f = cs_var_cb(), int flags = 0
|
||||
);
|
||||
CsSvar *new_svar(
|
||||
ostd::ConstCharRange n, CsString v,
|
||||
CsVarCb f = CsVarCb(), int flags = 0
|
||||
cs_svar *new_svar(
|
||||
ostd::ConstCharRange n, cs_string v,
|
||||
cs_var_cb f = cs_var_cb(), int flags = 0
|
||||
);
|
||||
|
||||
CsCommand *new_command(
|
||||
ostd::ConstCharRange name, ostd::ConstCharRange args, CsCommandCb func
|
||||
cs_command *new_command(
|
||||
ostd::ConstCharRange name, ostd::ConstCharRange args, cs_command_cb func
|
||||
);
|
||||
|
||||
CsIdent *get_ident(ostd::ConstCharRange name);
|
||||
CsAlias *get_alias(ostd::ConstCharRange name);
|
||||
cs_ident *get_ident(ostd::ConstCharRange name);
|
||||
cs_alias *get_alias(ostd::ConstCharRange name);
|
||||
bool have_ident(ostd::ConstCharRange name);
|
||||
|
||||
CsIdentRange get_idents();
|
||||
CsConstIdentRange get_idents() const;
|
||||
cs_ident_r get_idents();
|
||||
cs_const_ident_r get_idents() const;
|
||||
|
||||
void reset_var(ostd::ConstCharRange name);
|
||||
void touch_var(ostd::ConstCharRange name);
|
||||
|
||||
CsString run_str(CsBytecode *code);
|
||||
CsString run_str(ostd::ConstCharRange code);
|
||||
CsString run_str(CsIdent *id, CsValueRange args);
|
||||
cs_string run_str(cs_bcode *code);
|
||||
cs_string run_str(ostd::ConstCharRange code);
|
||||
cs_string run_str(cs_ident *id, cs_value_r args);
|
||||
|
||||
CsInt run_int(CsBytecode *code);
|
||||
CsInt run_int(ostd::ConstCharRange code);
|
||||
CsInt run_int(CsIdent *id, CsValueRange args);
|
||||
cs_int run_int(cs_bcode *code);
|
||||
cs_int run_int(ostd::ConstCharRange code);
|
||||
cs_int run_int(cs_ident *id, cs_value_r args);
|
||||
|
||||
CsFloat run_float(CsBytecode *code);
|
||||
CsFloat run_float(ostd::ConstCharRange code);
|
||||
CsFloat run_float(CsIdent *id, CsValueRange args);
|
||||
cs_float run_float(cs_bcode *code);
|
||||
cs_float run_float(ostd::ConstCharRange code);
|
||||
cs_float run_float(cs_ident *id, cs_value_r args);
|
||||
|
||||
bool run_bool(CsBytecode *code);
|
||||
bool run_bool(cs_bcode *code);
|
||||
bool run_bool(ostd::ConstCharRange code);
|
||||
bool run_bool(CsIdent *id, CsValueRange args);
|
||||
bool run_bool(cs_ident *id, cs_value_r args);
|
||||
|
||||
void run(CsBytecode *code, CsValue &ret);
|
||||
void run(ostd::ConstCharRange code, CsValue &ret);
|
||||
void run(CsIdent *id, CsValueRange args, CsValue &ret);
|
||||
void run(cs_bcode *code, cs_value &ret);
|
||||
void run(ostd::ConstCharRange code, cs_value &ret);
|
||||
void run(cs_ident *id, cs_value_r args, cs_value &ret);
|
||||
|
||||
void run(CsBytecode *code);
|
||||
void run(cs_bcode *code);
|
||||
void run(ostd::ConstCharRange code);
|
||||
void run(CsIdent *id, CsValueRange args);
|
||||
void run(cs_ident *id, cs_value_r args);
|
||||
|
||||
CsLoopState run_loop(CsBytecode *code, CsValue &ret);
|
||||
CsLoopState run_loop(CsBytecode *code);
|
||||
CsLoopState run_loop(cs_bcode *code, cs_value &ret);
|
||||
CsLoopState run_loop(cs_bcode *code);
|
||||
|
||||
bool is_in_loop() const {
|
||||
return p_inloop;
|
||||
}
|
||||
|
||||
std::optional<CsString> run_file_str(ostd::ConstCharRange fname);
|
||||
std::optional<CsInt> run_file_int(ostd::ConstCharRange fname);
|
||||
std::optional<CsFloat> run_file_float(ostd::ConstCharRange fname);
|
||||
std::optional<cs_string> run_file_str(ostd::ConstCharRange fname);
|
||||
std::optional<cs_int> run_file_int(ostd::ConstCharRange fname);
|
||||
std::optional<cs_float> run_file_float(ostd::ConstCharRange fname);
|
||||
std::optional<bool> run_file_bool(ostd::ConstCharRange fname);
|
||||
bool run_file(ostd::ConstCharRange fname, CsValue &ret);
|
||||
bool run_file(ostd::ConstCharRange fname, cs_value &ret);
|
||||
bool run_file(ostd::ConstCharRange fname);
|
||||
|
||||
void set_alias(ostd::ConstCharRange name, CsValue v);
|
||||
void set_alias(ostd::ConstCharRange name, cs_value v);
|
||||
|
||||
void set_var_int(
|
||||
ostd::ConstCharRange name, CsInt v,
|
||||
ostd::ConstCharRange name, cs_int v,
|
||||
bool dofunc = true, bool doclamp = true
|
||||
);
|
||||
void set_var_float(
|
||||
ostd::ConstCharRange name, CsFloat v,
|
||||
ostd::ConstCharRange name, cs_float v,
|
||||
bool dofunc = true, bool doclamp = true
|
||||
);
|
||||
void set_var_str(
|
||||
ostd::ConstCharRange name, ostd::ConstCharRange v, bool dofunc = true
|
||||
);
|
||||
|
||||
void set_var_int_checked(CsIvar *iv, CsInt v);
|
||||
void set_var_int_checked(CsIvar *iv, CsValueRange args);
|
||||
void set_var_float_checked(CsFvar *fv, CsFloat v);
|
||||
void set_var_str_checked(CsSvar *fv, ostd::ConstCharRange v);
|
||||
void set_var_int_checked(cs_ivar *iv, cs_int v);
|
||||
void set_var_int_checked(cs_ivar *iv, cs_value_r args);
|
||||
void set_var_float_checked(cs_fvar *fv, cs_float v);
|
||||
void set_var_str_checked(cs_svar *fv, ostd::ConstCharRange v);
|
||||
|
||||
std::optional<CsInt> get_var_int(ostd::ConstCharRange name);
|
||||
std::optional<CsFloat> get_var_float(ostd::ConstCharRange name);
|
||||
std::optional<CsString> get_var_str(ostd::ConstCharRange name);
|
||||
std::optional<cs_int> get_var_int(ostd::ConstCharRange name);
|
||||
std::optional<cs_float> get_var_float(ostd::ConstCharRange name);
|
||||
std::optional<cs_string> get_var_str(ostd::ConstCharRange name);
|
||||
|
||||
std::optional<CsInt> get_var_min_int(ostd::ConstCharRange name);
|
||||
std::optional<CsInt> get_var_max_int(ostd::ConstCharRange name);
|
||||
std::optional<cs_int> get_var_min_int(ostd::ConstCharRange name);
|
||||
std::optional<cs_int> get_var_max_int(ostd::ConstCharRange name);
|
||||
|
||||
std::optional<CsFloat> get_var_min_float(ostd::ConstCharRange name);
|
||||
std::optional<CsFloat> get_var_max_float(ostd::ConstCharRange name);
|
||||
std::optional<cs_float> get_var_min_float(ostd::ConstCharRange name);
|
||||
std::optional<cs_float> get_var_max_float(ostd::ConstCharRange name);
|
||||
|
||||
std::optional<CsString> get_alias_val(ostd::ConstCharRange name);
|
||||
std::optional<cs_string> get_alias_val(ostd::ConstCharRange name);
|
||||
|
||||
virtual void print_var(CsVar *v);
|
||||
virtual void print_var(cs_var *v);
|
||||
|
||||
private:
|
||||
CsIdent *add_ident(CsIdent *id);
|
||||
cs_ident *add_ident(cs_ident *id);
|
||||
|
||||
void *alloc(void *ptr, size_t olds, size_t news);
|
||||
|
||||
GenState *p_pstate = nullptr;
|
||||
cs_gen_state *p_pstate = nullptr;
|
||||
int p_inloop = 0;
|
||||
|
||||
char p_errbuf[512];
|
||||
|
||||
CsHookCb p_callhook;
|
||||
cs_hook_cb p_callhook;
|
||||
};
|
||||
|
||||
struct CsStackStateNode {
|
||||
CsStackStateNode const *next;
|
||||
CsIdent const *id;
|
||||
struct cs_stack_state_node {
|
||||
cs_stack_state_node const *next;
|
||||
cs_ident const *id;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct CsStackState {
|
||||
CsStackState() = delete;
|
||||
CsStackState(CsState &cs, CsStackStateNode *nd = nullptr, bool gap = false);
|
||||
CsStackState(CsStackState const &) = delete;
|
||||
CsStackState(CsStackState &&st);
|
||||
~CsStackState();
|
||||
struct cs_stack_state {
|
||||
cs_stack_state() = delete;
|
||||
cs_stack_state(cs_state &cs, cs_stack_state_node *nd = nullptr, bool gap = false);
|
||||
cs_stack_state(cs_stack_state const &) = delete;
|
||||
cs_stack_state(cs_stack_state &&st);
|
||||
~cs_stack_state();
|
||||
|
||||
CsStackState &operator=(CsStackState const &) = delete;
|
||||
CsStackState &operator=(CsStackState &&);
|
||||
cs_stack_state &operator=(cs_stack_state const &) = delete;
|
||||
cs_stack_state &operator=(cs_stack_state &&);
|
||||
|
||||
CsStackStateNode const *get() const;
|
||||
cs_stack_state_node const *get() const;
|
||||
bool gap() const;
|
||||
|
||||
private:
|
||||
CsState &p_state;
|
||||
CsStackStateNode *p_node;
|
||||
cs_state &p_state;
|
||||
cs_stack_state_node *p_node;
|
||||
bool p_gap;
|
||||
};
|
||||
|
||||
struct CsErrorException {
|
||||
friend struct CsState;
|
||||
struct cs_error {
|
||||
friend struct cs_state;
|
||||
|
||||
CsErrorException() = delete;
|
||||
CsErrorException(CsErrorException const &) = delete;
|
||||
CsErrorException(CsErrorException &&v):
|
||||
cs_error() = delete;
|
||||
cs_error(cs_error const &) = delete;
|
||||
cs_error(cs_error &&v):
|
||||
p_errmsg(v.p_errmsg), p_stack(std::move(v.p_stack))
|
||||
{}
|
||||
|
||||
|
@ -514,15 +514,15 @@ struct CsErrorException {
|
|||
return p_errmsg;
|
||||
}
|
||||
|
||||
CsStackState &get_stack() {
|
||||
cs_stack_state &get_stack() {
|
||||
return p_stack;
|
||||
}
|
||||
|
||||
CsStackState const &get_stack() const {
|
||||
cs_stack_state const &get_stack() const {
|
||||
return p_stack;
|
||||
}
|
||||
|
||||
CsErrorException(CsState &cs, ostd::ConstCharRange msg):
|
||||
cs_error(cs_state &cs, ostd::ConstCharRange msg):
|
||||
p_errmsg(), p_stack(cs)
|
||||
{
|
||||
p_errmsg = save_msg(cs, msg);
|
||||
|
@ -530,7 +530,7 @@ struct CsErrorException {
|
|||
}
|
||||
|
||||
template<typename ...A>
|
||||
CsErrorException(CsState &cs, ostd::ConstCharRange msg, A &&...args):
|
||||
cs_error(cs_state &cs, ostd::ConstCharRange msg, A &&...args):
|
||||
p_errmsg(), p_stack(cs)
|
||||
{
|
||||
try {
|
||||
|
@ -547,36 +547,36 @@ struct CsErrorException {
|
|||
}
|
||||
|
||||
private:
|
||||
CsStackState save_stack(CsState &cs);
|
||||
ostd::ConstCharRange save_msg(CsState &cs, ostd::ConstCharRange v);
|
||||
cs_stack_state save_stack(cs_state &cs);
|
||||
ostd::ConstCharRange save_msg(cs_state &cs, ostd::ConstCharRange v);
|
||||
|
||||
ostd::ConstCharRange p_errmsg;
|
||||
CsStackState p_stack;
|
||||
cs_stack_state p_stack;
|
||||
};
|
||||
|
||||
struct OSTD_EXPORT CsStackedValue: CsValue {
|
||||
CsStackedValue(CsIdent *id = nullptr);
|
||||
~CsStackedValue();
|
||||
struct OSTD_EXPORT cs_stacked_value: cs_value {
|
||||
cs_stacked_value(cs_ident *id = nullptr);
|
||||
~cs_stacked_value();
|
||||
|
||||
CsStackedValue(CsStackedValue const &) = delete;
|
||||
CsStackedValue(CsStackedValue &&) = delete;
|
||||
cs_stacked_value(cs_stacked_value const &) = delete;
|
||||
cs_stacked_value(cs_stacked_value &&) = delete;
|
||||
|
||||
CsStackedValue &operator=(CsStackedValue const &) = delete;
|
||||
CsStackedValue &operator=(CsStackedValue &&v) = delete;
|
||||
cs_stacked_value &operator=(cs_stacked_value const &) = delete;
|
||||
cs_stacked_value &operator=(cs_stacked_value &&v) = delete;
|
||||
|
||||
CsStackedValue &operator=(CsValue const &v);
|
||||
CsStackedValue &operator=(CsValue &&v);
|
||||
cs_stacked_value &operator=(cs_value const &v);
|
||||
cs_stacked_value &operator=(cs_value &&v);
|
||||
|
||||
bool set_alias(CsIdent *id);
|
||||
CsAlias *get_alias() const;
|
||||
bool set_alias(cs_ident *id);
|
||||
cs_alias *get_alias() const;
|
||||
bool has_alias() const;
|
||||
|
||||
bool push();
|
||||
bool pop();
|
||||
|
||||
private:
|
||||
CsAlias *p_a;
|
||||
CsIdentStack p_stack;
|
||||
cs_alias *p_a;
|
||||
cs_ident_stack p_stack;
|
||||
bool p_pushed;
|
||||
};
|
||||
|
||||
|
@ -661,23 +661,23 @@ namespace util {
|
|||
}
|
||||
|
||||
OSTD_EXPORT ostd::ConstCharRange parse_string(
|
||||
CsState &cs, ostd::ConstCharRange str, size_t &nlines
|
||||
cs_state &cs, ostd::ConstCharRange str, size_t &nlines
|
||||
);
|
||||
|
||||
inline ostd::ConstCharRange parse_string(
|
||||
CsState &cs, ostd::ConstCharRange str
|
||||
cs_state &cs, ostd::ConstCharRange str
|
||||
) {
|
||||
size_t nlines;
|
||||
return parse_string(cs, str, nlines);
|
||||
}
|
||||
|
||||
OSTD_EXPORT ostd::ConstCharRange parse_word(
|
||||
CsState &cs, ostd::ConstCharRange str
|
||||
cs_state &cs, ostd::ConstCharRange str
|
||||
);
|
||||
|
||||
struct OSTD_EXPORT ListParser {
|
||||
ListParser() = delete;
|
||||
ListParser(CsState &cs, ostd::ConstCharRange src):
|
||||
ListParser(cs_state &cs, ostd::ConstCharRange src):
|
||||
p_state(cs), p_input(src)
|
||||
{}
|
||||
|
||||
|
@ -694,8 +694,8 @@ namespace util {
|
|||
}
|
||||
}
|
||||
|
||||
CsString get_item() const {
|
||||
auto app = ostd::appender<CsString>();
|
||||
cs_string get_item() const {
|
||||
auto app = ostd::appender<cs_string>();
|
||||
get_item(app);
|
||||
return std::move(app.get());
|
||||
}
|
||||
|
@ -715,12 +715,12 @@ namespace util {
|
|||
private:
|
||||
ostd::ConstCharRange p_quote = ostd::ConstCharRange();
|
||||
ostd::ConstCharRange p_item = ostd::ConstCharRange();
|
||||
CsState &p_state;
|
||||
cs_state &p_state;
|
||||
ostd::ConstCharRange p_input;
|
||||
};
|
||||
|
||||
template<typename R>
|
||||
inline std::size_t format_int(R &&writer, CsInt val) {
|
||||
inline std::size_t format_int(R &&writer, cs_int val) {
|
||||
try {
|
||||
return ostd::format(std::forward<R>(writer), IntFormat, val);
|
||||
} catch (ostd::format_error const &e) {
|
||||
|
@ -729,11 +729,11 @@ private:
|
|||
}
|
||||
|
||||
template<typename R>
|
||||
inline std::size_t format_float(R &&writer, CsFloat val) {
|
||||
inline std::size_t format_float(R &&writer, cs_float val) {
|
||||
try {
|
||||
return ostd::format(
|
||||
std::forward<R>(writer),
|
||||
(val == CsInt(val)) ? RoundFloatFormat : FloatFormat, val
|
||||
(val == cs_int(val)) ? RoundFloatFormat : FloatFormat, val
|
||||
);
|
||||
} catch (ostd::format_error const &e) {
|
||||
throw cs_internal_error{e.what()};
|
||||
|
@ -742,14 +742,14 @@ private:
|
|||
|
||||
template<typename R>
|
||||
inline size_t tvals_concat(
|
||||
R &&writer, CsValueRange vals,
|
||||
R &&writer, cs_value_r vals,
|
||||
ostd::ConstCharRange sep = ostd::ConstCharRange()
|
||||
) {
|
||||
size_t ret = 0;
|
||||
for (size_t i = 0; i < vals.size(); ++i) {
|
||||
auto s = ostd::appender<CsString>();
|
||||
auto s = ostd::appender<cs_string>();
|
||||
switch (vals[i].get_type()) {
|
||||
case CsValueType::Int: {
|
||||
case cs_value_type::Int: {
|
||||
auto r = format_int(
|
||||
std::forward<R>(writer), vals[i].get_int()
|
||||
);
|
||||
|
@ -758,7 +758,7 @@ private:
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CsValueType::Float: {
|
||||
case cs_value_type::Float: {
|
||||
auto r = format_float(
|
||||
std::forward<R>(writer), vals[i].get_float()
|
||||
);
|
||||
|
@ -767,9 +767,9 @@ private:
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CsValueType::String:
|
||||
case CsValueType::Cstring:
|
||||
case CsValueType::Macro: {
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Cstring:
|
||||
case cs_value_type::Macro: {
|
||||
auto sv = vals[i].get_strr();
|
||||
ret += writer.put_n(sv.data(), sv.size());
|
||||
break;
|
||||
|
@ -786,7 +786,7 @@ private:
|
|||
}
|
||||
|
||||
template<typename R>
|
||||
inline size_t print_stack(R &&writer, CsStackState const &st) {
|
||||
inline size_t print_stack(R &&writer, cs_stack_state const &st) {
|
||||
size_t ret = 0;
|
||||
auto nd = st.get();
|
||||
while (nd) {
|
||||
|
|
|
@ -7,19 +7,19 @@
|
|||
|
||||
/* do not modify */
|
||||
namespace cscript {
|
||||
struct CsState;
|
||||
struct CsIdent;
|
||||
struct CsValue;
|
||||
struct cs_state;
|
||||
struct cs_ident;
|
||||
struct cs_value;
|
||||
|
||||
using CsValueRange = ostd::PointerRange<CsValue>;
|
||||
using CsIdentRange = ostd::PointerRange<CsIdent *>;
|
||||
using CsConstIdentRange = ostd::PointerRange<CsIdent const *>;
|
||||
using cs_value_r = ostd::PointerRange<cs_value>;
|
||||
using cs_ident_r = ostd::PointerRange<cs_ident *>;
|
||||
using cs_const_ident_r = ostd::PointerRange<cs_ident const *>;
|
||||
}
|
||||
|
||||
/* configurable section */
|
||||
namespace cscript {
|
||||
using CsInt = int;
|
||||
using CsFloat = float;
|
||||
using cs_int = int;
|
||||
using cs_float = float;
|
||||
|
||||
/* probably don't want to change these, but if you use a custom allocation
|
||||
* function for your state, keep in mind potential heap allocations in
|
||||
|
@ -30,10 +30,10 @@ namespace cscript {
|
|||
* or move or something similar, you should be fine - but if you really
|
||||
* need to make sure, override this with your own type
|
||||
*/
|
||||
using CsVarCb = std::function<void(CsState &, CsIdent &)>;
|
||||
using CsCommandCb = std::function<void(CsState &, CsValueRange, CsValue &)>;
|
||||
using CsHookCb = std::function<void(CsState &)>;
|
||||
using CsAllocCb = void *(*)(void *, void *, size_t, size_t);
|
||||
using cs_var_cb = std::function<void(cs_state &, cs_ident &)>;
|
||||
using cs_command_cb = std::function<void(cs_state &, cs_value_r, cs_value &)>;
|
||||
using cs_hook_cb = std::function<void(cs_state &)>;
|
||||
using cs_alloc_cb = void *(*)(void *, void *, size_t, size_t);
|
||||
|
||||
constexpr auto const IntFormat = "%d";
|
||||
constexpr auto const FloatFormat = "%.7g";
|
||||
|
|
126
src/cs_gen.cc
126
src/cs_gen.cc
|
@ -8,7 +8,7 @@
|
|||
|
||||
namespace cscript {
|
||||
|
||||
ostd::ConstCharRange GenState::get_str() {
|
||||
ostd::ConstCharRange cs_gen_state::get_str() {
|
||||
size_t nl;
|
||||
ostd::ConstCharRange beg = source;
|
||||
source = util::parse_string(cs, source, nl);
|
||||
|
@ -17,9 +17,9 @@ ostd::ConstCharRange GenState::get_str() {
|
|||
return ret.slice(1, ret.size() - 1);
|
||||
}
|
||||
|
||||
CsString GenState::get_str_dup(bool unescape) {
|
||||
cs_string cs_gen_state::get_str_dup(bool unescape) {
|
||||
auto str = get_str();
|
||||
auto app = ostd::appender<CsString>();
|
||||
auto app = ostd::appender<cs_string>();
|
||||
if (unescape) {
|
||||
util::unescape_string(app, str);
|
||||
} else {
|
||||
|
@ -28,7 +28,7 @@ CsString GenState::get_str_dup(bool unescape) {
|
|||
return std::move(app.get());
|
||||
}
|
||||
|
||||
ostd::ConstCharRange GenState::read_macro_name() {
|
||||
ostd::ConstCharRange cs_gen_state::read_macro_name() {
|
||||
auto op = source;
|
||||
char c = current();
|
||||
if (!isalpha(c) && (c != '_')) {
|
||||
|
@ -40,7 +40,7 @@ ostd::ConstCharRange GenState::read_macro_name() {
|
|||
return ostd::slice_until(op, source);
|
||||
}
|
||||
|
||||
char GenState::skip_until(ostd::ConstCharRange chars) {
|
||||
char cs_gen_state::skip_until(ostd::ConstCharRange chars) {
|
||||
char c = current();
|
||||
while (c && ostd::find(chars, c).empty()) {
|
||||
next_char();
|
||||
|
@ -49,7 +49,7 @@ char GenState::skip_until(ostd::ConstCharRange chars) {
|
|||
return c;
|
||||
}
|
||||
|
||||
char GenState::skip_until(char cf) {
|
||||
char cs_gen_state::skip_until(char cf) {
|
||||
char c = current();
|
||||
while (c && (c != cf)) {
|
||||
next_char();
|
||||
|
@ -62,7 +62,7 @@ static bool cs_is_hspace(char c) {
|
|||
return (c == ' ') || (c == '\t') || (c == '\r');
|
||||
}
|
||||
|
||||
void GenState::skip_comments() {
|
||||
void cs_gen_state::skip_comments() {
|
||||
for (;;) {
|
||||
for (char c = current(); cs_is_hspace(c); c = current()) {
|
||||
next_char();
|
||||
|
@ -70,7 +70,7 @@ void GenState::skip_comments() {
|
|||
if (current() == '\\') {
|
||||
char c = current(1);
|
||||
if ((c != '\r') && (c != '\n')) {
|
||||
throw CsErrorException(cs, "invalid line break");
|
||||
throw cs_error(cs, "invalid line break");
|
||||
}
|
||||
/* skip backslash */
|
||||
next_char();
|
||||
|
@ -92,7 +92,7 @@ void GenState::skip_comments() {
|
|||
}
|
||||
}
|
||||
|
||||
ostd::ConstCharRange GenState::get_word() {
|
||||
ostd::ConstCharRange cs_gen_state::get_word() {
|
||||
auto beg = source;
|
||||
source = util::parse_word(cs, source);
|
||||
return ostd::slice_until(beg, source);
|
||||
|
@ -106,22 +106,22 @@ static inline int cs_ret_code(int type, int def = 0) {
|
|||
}
|
||||
|
||||
static void compilestatements(
|
||||
GenState &gs, int rettype, int brak = '\0', int prevargs = 0
|
||||
cs_gen_state &gs, int rettype, int brak = '\0', int prevargs = 0
|
||||
);
|
||||
static inline std::pair<ostd::ConstCharRange, size_t> compileblock(
|
||||
GenState &gs, ostd::ConstCharRange p, size_t line,
|
||||
cs_gen_state &gs, ostd::ConstCharRange p, size_t line,
|
||||
int rettype = CsRetNull, int brak = '\0'
|
||||
);
|
||||
|
||||
void GenState::gen_int(ostd::ConstCharRange word) {
|
||||
void cs_gen_state::gen_int(ostd::ConstCharRange word) {
|
||||
gen_int(cs_parse_int(word));
|
||||
}
|
||||
|
||||
void GenState::gen_float(ostd::ConstCharRange word) {
|
||||
void cs_gen_state::gen_float(ostd::ConstCharRange word) {
|
||||
gen_float(cs_parse_float(word));
|
||||
}
|
||||
|
||||
void GenState::gen_value(int wordtype, ostd::ConstCharRange word, int line) {
|
||||
void cs_gen_state::gen_value(int wordtype, ostd::ConstCharRange word, int line) {
|
||||
switch (wordtype) {
|
||||
case CsValCany:
|
||||
if (!word.empty()) {
|
||||
|
@ -167,12 +167,12 @@ void GenState::gen_value(int wordtype, ostd::ConstCharRange word, int line) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline void compileblock(GenState &gs) {
|
||||
static inline void compileblock(cs_gen_state &gs) {
|
||||
gs.code.push_back(CsCodeEmpty);
|
||||
}
|
||||
|
||||
static inline std::pair<ostd::ConstCharRange, size_t> compileblock(
|
||||
GenState &gs, ostd::ConstCharRange p, size_t line, int rettype, int brak
|
||||
cs_gen_state &gs, ostd::ConstCharRange p, size_t line, int rettype, int brak
|
||||
) {
|
||||
size_t start = gs.code.size();
|
||||
gs.code.push_back(CsCodeBlock);
|
||||
|
@ -199,7 +199,7 @@ static inline std::pair<ostd::ConstCharRange, size_t> compileblock(
|
|||
return std::make_pair(p, retline);
|
||||
}
|
||||
|
||||
static inline void compileunescapestr(GenState &gs, bool macro = false) {
|
||||
static inline void compileunescapestr(cs_gen_state &gs, bool macro = false) {
|
||||
auto str = gs.get_str();
|
||||
gs.code.push_back(macro ? CsCodeMacro : (CsCodeVal | CsRetString));
|
||||
gs.code.reserve(
|
||||
|
@ -217,12 +217,12 @@ static inline void compileunescapestr(GenState &gs, bool macro = false) {
|
|||
}
|
||||
|
||||
static bool compilearg(
|
||||
GenState &gs, int wordtype, int prevargs = MaxResults,
|
||||
CsString *word = nullptr
|
||||
cs_gen_state &gs, int wordtype, int prevargs = MaxResults,
|
||||
cs_string *word = nullptr
|
||||
);
|
||||
|
||||
static void compilelookup(GenState &gs, int ltype, int prevargs = MaxResults) {
|
||||
CsString lookup;
|
||||
static void compilelookup(cs_gen_state &gs, int ltype, int prevargs = MaxResults) {
|
||||
cs_string lookup;
|
||||
gs.next_char();
|
||||
switch (gs.current()) {
|
||||
case '(':
|
||||
|
@ -241,10 +241,10 @@ static void compilelookup(GenState &gs, int ltype, int prevargs = MaxResults) {
|
|||
lookup = gs.get_word();
|
||||
if (lookup.empty()) goto invalid;
|
||||
lookupid:
|
||||
CsIdent *id = gs.cs.new_ident(lookup);
|
||||
cs_ident *id = gs.cs.new_ident(lookup);
|
||||
if (id) {
|
||||
switch (id->get_type()) {
|
||||
case CsIdentType::Ivar:
|
||||
case cs_ident_type::Ivar:
|
||||
gs.code.push_back(
|
||||
CsCodeIvar | cs_ret_code(ltype, CsRetInt) |
|
||||
(id->get_index() << 8)
|
||||
|
@ -261,7 +261,7 @@ lookupid:
|
|||
break;
|
||||
}
|
||||
return;
|
||||
case CsIdentType::Fvar:
|
||||
case cs_ident_type::Fvar:
|
||||
gs.code.push_back(
|
||||
CsCodeFvar | cs_ret_code(ltype, CsRetFloat) |
|
||||
(id->get_index() << 8)
|
||||
|
@ -278,7 +278,7 @@ lookupid:
|
|||
break;
|
||||
}
|
||||
return;
|
||||
case CsIdentType::Svar:
|
||||
case cs_ident_type::Svar:
|
||||
switch (ltype) {
|
||||
case CsValPop:
|
||||
return;
|
||||
|
@ -299,7 +299,7 @@ lookupid:
|
|||
break;
|
||||
}
|
||||
goto done;
|
||||
case CsIdentType::Alias:
|
||||
case cs_ident_type::Alias:
|
||||
switch (ltype) {
|
||||
case CsValPop:
|
||||
return;
|
||||
|
@ -333,12 +333,12 @@ lookupid:
|
|||
break;
|
||||
}
|
||||
goto done;
|
||||
case CsIdentType::Command: {
|
||||
case cs_ident_type::Command: {
|
||||
int comtype = CsCodeCom, numargs = 0;
|
||||
if (prevargs >= MaxResults) {
|
||||
gs.code.push_back(CsCodeEnter);
|
||||
}
|
||||
auto fmt = static_cast<CsCommand *>(id)->get_args();
|
||||
auto fmt = static_cast<cs_command *>(id)->get_args();
|
||||
for (char c: fmt) {
|
||||
switch (c) {
|
||||
case 'S':
|
||||
|
@ -354,7 +354,7 @@ lookupid:
|
|||
numargs++;
|
||||
break;
|
||||
case 'b':
|
||||
gs.gen_int(std::numeric_limits<CsInt>::min());
|
||||
gs.gen_int(std::numeric_limits<cs_int>::min());
|
||||
numargs++;
|
||||
break;
|
||||
case 'f':
|
||||
|
@ -478,7 +478,7 @@ invalid:
|
|||
}
|
||||
}
|
||||
|
||||
static bool compileblockstr(GenState &gs, ostd::ConstCharRange str, bool macro) {
|
||||
static bool compileblockstr(cs_gen_state &gs, ostd::ConstCharRange str, bool macro) {
|
||||
int startc = gs.code.size();
|
||||
gs.code.push_back(macro ? CsCodeMacro : CsCodeVal | CsRetString);
|
||||
gs.code.reserve(gs.code.size() + str.size() / sizeof(uint32_t) + 1);
|
||||
|
@ -528,8 +528,8 @@ done:
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool compileblocksub(GenState &gs, int prevargs) {
|
||||
CsString lookup;
|
||||
static bool compileblocksub(cs_gen_state &gs, int prevargs) {
|
||||
cs_string lookup;
|
||||
switch (gs.current()) {
|
||||
case '(':
|
||||
if (!compilearg(gs, CsValCany, prevargs)) {
|
||||
|
@ -551,19 +551,19 @@ static bool compileblocksub(GenState &gs, int prevargs) {
|
|||
return false;
|
||||
}
|
||||
lookupid:
|
||||
CsIdent *id = gs.cs.new_ident(lookup);
|
||||
cs_ident *id = gs.cs.new_ident(lookup);
|
||||
if (id) {
|
||||
switch (id->get_type()) {
|
||||
case CsIdentType::Ivar:
|
||||
case cs_ident_type::Ivar:
|
||||
gs.code.push_back(CsCodeIvar | (id->get_index() << 8));
|
||||
goto done;
|
||||
case CsIdentType::Fvar:
|
||||
case cs_ident_type::Fvar:
|
||||
gs.code.push_back(CsCodeFvar | (id->get_index() << 8));
|
||||
goto done;
|
||||
case CsIdentType::Svar:
|
||||
case cs_ident_type::Svar:
|
||||
gs.code.push_back(CsCodeSvarM | (id->get_index() << 8));
|
||||
goto done;
|
||||
case CsIdentType::Alias:
|
||||
case cs_ident_type::Alias:
|
||||
gs.code.push_back(
|
||||
(id->get_index() < MaxArguments
|
||||
? CsCodeLookupMarg
|
||||
|
@ -584,14 +584,14 @@ done:
|
|||
return true;
|
||||
}
|
||||
|
||||
static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
|
||||
static void compileblockmain(cs_gen_state &gs, int wordtype, int prevargs) {
|
||||
char const *start = gs.source.data();
|
||||
size_t curline = gs.current_line;
|
||||
int concs = 0;
|
||||
for (int brak = 1; brak;) {
|
||||
switch (gs.skip_until("@\"/[]")) {
|
||||
case '\0':
|
||||
throw CsErrorException(gs.cs, "missing \"]\"");
|
||||
throw cs_error(gs.cs, "missing \"]\"");
|
||||
return;
|
||||
case '\"':
|
||||
gs.get_str();
|
||||
|
@ -620,7 +620,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
|
|||
if (brak > level) {
|
||||
continue;
|
||||
} else if (brak < level) {
|
||||
throw CsErrorException(gs.cs, "too many @s");
|
||||
throw cs_error(gs.cs, "too many @s");
|
||||
return;
|
||||
}
|
||||
if (!concs && prevargs >= MaxResults) {
|
||||
|
@ -752,7 +752,7 @@ static void compileblockmain(GenState &gs, int wordtype, int prevargs) {
|
|||
}
|
||||
|
||||
static bool compilearg(
|
||||
GenState &gs, int wordtype, int prevargs, CsString *word
|
||||
cs_gen_state &gs, int wordtype, int prevargs, cs_string *word
|
||||
) {
|
||||
gs.skip_comments();
|
||||
switch (gs.current()) {
|
||||
|
@ -883,7 +883,7 @@ static bool compilearg(
|
|||
}
|
||||
|
||||
static void compile_cmd(
|
||||
GenState &gs, CsCommand *id, bool &more, int rettype, int prevargs
|
||||
cs_gen_state &gs, cs_command *id, bool &more, int rettype, int prevargs
|
||||
) {
|
||||
int comtype = CsCodeCom, numargs = 0, fakeargs = 0;
|
||||
bool rep = false;
|
||||
|
@ -942,7 +942,7 @@ static void compile_cmd(
|
|||
if (rep) {
|
||||
break;
|
||||
}
|
||||
gs.gen_int(std::numeric_limits<CsInt>::min());
|
||||
gs.gen_int(std::numeric_limits<cs_int>::min());
|
||||
fakeargs++;
|
||||
}
|
||||
numargs++;
|
||||
|
@ -1086,7 +1086,7 @@ compilecomv:
|
|||
);
|
||||
}
|
||||
|
||||
static void compile_alias(GenState &gs, CsAlias *id, bool &more, int prevargs) {
|
||||
static void compile_alias(cs_gen_state &gs, cs_alias *id, bool &more, int prevargs) {
|
||||
int numargs = 0;
|
||||
while (numargs < MaxArguments) {
|
||||
more = compilearg(gs, CsValAny, prevargs + numargs);
|
||||
|
@ -1101,7 +1101,7 @@ static void compile_alias(GenState &gs, CsAlias *id, bool &more, int prevargs) {
|
|||
);
|
||||
}
|
||||
|
||||
static void compile_local(GenState &gs, bool &more, int prevargs) {
|
||||
static void compile_local(cs_gen_state &gs, bool &more, int prevargs) {
|
||||
int numargs = 0;
|
||||
if (more) {
|
||||
while (numargs < MaxArguments) {
|
||||
|
@ -1119,7 +1119,7 @@ static void compile_local(GenState &gs, bool &more, int prevargs) {
|
|||
}
|
||||
|
||||
static void compile_do(
|
||||
GenState &gs, bool &more, int prevargs, int rettype, int opcode
|
||||
cs_gen_state &gs, bool &more, int prevargs, int rettype, int opcode
|
||||
) {
|
||||
if (more) {
|
||||
more = compilearg(gs, CsValCode, prevargs);
|
||||
|
@ -1128,7 +1128,7 @@ static void compile_do(
|
|||
}
|
||||
|
||||
static void compile_if(
|
||||
GenState &gs, CsIdent *id, bool &more, int prevargs, int rettype
|
||||
cs_gen_state &gs, cs_ident *id, bool &more, int prevargs, int rettype
|
||||
) {
|
||||
if (more) {
|
||||
more = compilearg(gs, CsValCany, prevargs);
|
||||
|
@ -1192,7 +1192,7 @@ static void compile_if(
|
|||
}
|
||||
|
||||
static void compile_and_or(
|
||||
GenState &gs, CsIdent *id, bool &more, int prevargs, int rettype
|
||||
cs_gen_state &gs, cs_ident *id, bool &more, int prevargs, int rettype
|
||||
) {
|
||||
int numargs = 0;
|
||||
if (more) {
|
||||
|
@ -1250,8 +1250,8 @@ static void compile_and_or(
|
|||
}
|
||||
}
|
||||
|
||||
static void compilestatements(GenState &gs, int rettype, int brak, int prevargs) {
|
||||
CsString idname;
|
||||
static void compilestatements(cs_gen_state &gs, int rettype, int brak, int prevargs) {
|
||||
cs_string idname;
|
||||
for (;;) {
|
||||
gs.skip_comments();
|
||||
idname.clear();
|
||||
|
@ -1275,10 +1275,10 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs)
|
|||
case '\0':
|
||||
gs.next_char();
|
||||
if (!idname.empty()) {
|
||||
CsIdent *id = gs.cs.new_ident(idname);
|
||||
cs_ident *id = gs.cs.new_ident(idname);
|
||||
if (id) {
|
||||
switch (id->get_type()) {
|
||||
case CsIdentType::Alias:
|
||||
case cs_ident_type::Alias:
|
||||
more = compilearg(gs, CsValAny, prevargs);
|
||||
if (!more) {
|
||||
gs.gen_str();
|
||||
|
@ -1290,7 +1290,7 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs)
|
|||
) | (id->get_index() << 8)
|
||||
);
|
||||
goto endstatement;
|
||||
case CsIdentType::Ivar:
|
||||
case cs_ident_type::Ivar:
|
||||
more = compilearg(gs, CsValInt, prevargs);
|
||||
if (!more) {
|
||||
gs.gen_int();
|
||||
|
@ -1299,7 +1299,7 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs)
|
|||
CsCodeIvar1 | (id->get_index() << 8)
|
||||
);
|
||||
goto endstatement;
|
||||
case CsIdentType::Fvar:
|
||||
case cs_ident_type::Fvar:
|
||||
more = compilearg(gs, CsValFloat, prevargs);
|
||||
if (!more) {
|
||||
gs.gen_float();
|
||||
|
@ -1308,7 +1308,7 @@ static void compilestatements(GenState &gs, int rettype, int brak, int prevargs)
|
|||
CsCodeFvar1 | (id->get_index() << 8)
|
||||
);
|
||||
goto endstatement;
|
||||
case CsIdentType::Svar:
|
||||
case cs_ident_type::Svar:
|
||||
more = compilearg(gs, CsValCstring, prevargs);
|
||||
if (!more) {
|
||||
gs.gen_str();
|
||||
|
@ -1343,7 +1343,7 @@ noid:
|
|||
}
|
||||
gs.code.push_back(CsCodeCallU | (numargs << 8));
|
||||
} else {
|
||||
CsIdent *id = gs.cs.get_ident(idname);
|
||||
cs_ident *id = gs.cs.get_ident(idname);
|
||||
if (!id) {
|
||||
if (!cs_check_num(idname)) {
|
||||
gs.gen_str(idname, true);
|
||||
|
@ -1353,7 +1353,7 @@ noid:
|
|||
case CsValAny:
|
||||
case CsValCany: {
|
||||
ostd::ConstCharRange end = idname;
|
||||
CsInt val = cs_parse_int(end, &end);
|
||||
cs_int val = cs_parse_int(end, &end);
|
||||
if (!end.empty()) {
|
||||
gs.gen_str(idname, rettype == CsValCany);
|
||||
} else {
|
||||
|
@ -1370,12 +1370,12 @@ noid:
|
|||
switch (id->get_type_raw()) {
|
||||
case CsIdAlias:
|
||||
compile_alias(
|
||||
gs, static_cast<CsAlias *>(id), more, prevargs
|
||||
gs, static_cast<cs_alias *>(id), more, prevargs
|
||||
);
|
||||
break;
|
||||
case CsIdCommand:
|
||||
compile_cmd(
|
||||
gs, static_cast<CsCommand *>(id), more,
|
||||
gs, static_cast<cs_command *>(id), more,
|
||||
rettype, prevargs
|
||||
);
|
||||
break;
|
||||
|
@ -1421,7 +1421,7 @@ noid:
|
|||
case CsIdIvar:
|
||||
if (!(more = compilearg(gs, CsValInt, prevargs))) {
|
||||
gs.code.push_back(CsCodePrint | (id->get_index() << 8));
|
||||
} else if (!(id->get_flags() & CsIdfHex) || !(
|
||||
} else if (!(id->get_flags() & CS_IDF_HEX) || !(
|
||||
more = compilearg(gs, CsValInt, prevargs + 1)
|
||||
)) {
|
||||
gs.code.push_back(CsCodeIvar1 | (id->get_index() << 8));
|
||||
|
@ -1470,7 +1470,7 @@ endstatement:
|
|||
switch (gs.skip_until(")];/\n")) {
|
||||
case '\0':
|
||||
if (gs.current() != brak) {
|
||||
throw CsErrorException(gs.cs, "missing \"%c\"", char(brak));
|
||||
throw cs_error(gs.cs, "missing \"%c\"", char(brak));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
@ -1480,7 +1480,7 @@ endstatement:
|
|||
gs.next_char();
|
||||
return;
|
||||
}
|
||||
throw CsErrorException(gs.cs, "unexpected \"%c\"", gs.current());
|
||||
throw cs_error(gs.cs, "unexpected \"%c\"", gs.current());
|
||||
return;
|
||||
case '/':
|
||||
gs.next_char();
|
||||
|
@ -1495,7 +1495,7 @@ endstatement:
|
|||
}
|
||||
}
|
||||
|
||||
void GenState::gen_main(ostd::ConstCharRange s, int ret_type) {
|
||||
void cs_gen_state::gen_main(ostd::ConstCharRange s, int ret_type) {
|
||||
source = s;
|
||||
code.push_back(CsCodeStart);
|
||||
compilestatements(*this, CsValAny);
|
||||
|
|
|
@ -22,7 +22,7 @@ static inline void p_set_end(
|
|||
}
|
||||
|
||||
/* this function assumes the input is definitely a hex digit */
|
||||
static inline CsInt p_hexd_to_int(char c) {
|
||||
static inline cs_int p_hexd_to_int(char c) {
|
||||
if (c >= 97) { /* a-f */
|
||||
return (c - 'a') + 10;
|
||||
} else if (c >= 65) { /* A-F */
|
||||
|
@ -40,15 +40,15 @@ static inline bool p_check_neg(ostd::ConstCharRange &input) {
|
|||
return neg;
|
||||
}
|
||||
|
||||
CsInt cs_parse_int(ostd::ConstCharRange input, ostd::ConstCharRange *end) {
|
||||
cs_int cs_parse_int(ostd::ConstCharRange input, ostd::ConstCharRange *end) {
|
||||
ostd::ConstCharRange orig = input;
|
||||
p_skip_white(input);
|
||||
if (input.empty()) {
|
||||
p_set_end(orig, end);
|
||||
return CsInt(0);
|
||||
return cs_int(0);
|
||||
}
|
||||
bool neg = p_check_neg(input);
|
||||
CsInt ret = 0;
|
||||
cs_int ret = 0;
|
||||
ostd::ConstCharRange past = input;
|
||||
if (input.size() >= 2) {
|
||||
ostd::ConstCharRange pfx = input.slice(0, 2);
|
||||
|
@ -87,7 +87,7 @@ done:
|
|||
}
|
||||
|
||||
template<bool Hex, char e1 = Hex ? 'p' : 'e', char e2 = Hex ? 'P' : 'E'>
|
||||
static inline bool p_read_exp(ostd::ConstCharRange &input, CsInt &fn) {
|
||||
static inline bool p_read_exp(ostd::ConstCharRange &input, cs_int &fn) {
|
||||
if (input.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ static inline bool p_read_exp(ostd::ConstCharRange &input, CsInt &fn) {
|
|||
if (input.empty() || !isdigit(*input)) {
|
||||
return false;
|
||||
}
|
||||
CsInt exp = 0;
|
||||
cs_int exp = 0;
|
||||
while (!input.empty() && isdigit(*input)) {
|
||||
exp = exp * 10 + (*input - '0');
|
||||
++input;
|
||||
|
@ -116,9 +116,9 @@ static inline bool p_read_exp(ostd::ConstCharRange &input, CsInt &fn) {
|
|||
|
||||
template<bool Hex>
|
||||
static inline bool parse_gen_float(
|
||||
ostd::ConstCharRange input, ostd::ConstCharRange *end, CsFloat &ret
|
||||
ostd::ConstCharRange input, ostd::ConstCharRange *end, cs_float &ret
|
||||
) {
|
||||
auto read_digits = [&input](double r, CsInt &n) {
|
||||
auto read_digits = [&input](double r, cs_int &n) {
|
||||
while (!input.empty() && (Hex ? isxdigit(*input) : isdigit(*input))) {
|
||||
if (Hex) {
|
||||
r = r * 16.0 + double(p_hexd_to_int(*input));
|
||||
|
@ -130,7 +130,7 @@ static inline bool parse_gen_float(
|
|||
}
|
||||
return r;
|
||||
};
|
||||
CsInt wn = 0, fn = 0;
|
||||
cs_int wn = 0, fn = 0;
|
||||
double r = read_digits(0.0, wn);
|
||||
if (!input.empty() && (*input == '.')) {
|
||||
++input;
|
||||
|
@ -145,22 +145,22 @@ static inline bool parse_gen_float(
|
|||
p_set_end(input, end);
|
||||
}
|
||||
if (Hex) {
|
||||
ret = CsFloat(ldexp(r, fn * 4));
|
||||
ret = cs_float(ldexp(r, fn * 4));
|
||||
} else {
|
||||
ret = CsFloat(r * pow(10, fn));
|
||||
ret = cs_float(r * pow(10, fn));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CsFloat cs_parse_float(ostd::ConstCharRange input, ostd::ConstCharRange *end) {
|
||||
cs_float cs_parse_float(ostd::ConstCharRange input, ostd::ConstCharRange *end) {
|
||||
ostd::ConstCharRange orig = input;
|
||||
p_skip_white(input);
|
||||
if (input.empty()) {
|
||||
p_set_end(orig, end);
|
||||
return CsFloat(0);
|
||||
return cs_float(0);
|
||||
}
|
||||
bool neg = p_check_neg(input);
|
||||
CsFloat ret = CsFloat(0);
|
||||
cs_float ret = cs_float(0);
|
||||
if (input.size() >= 2) {
|
||||
ostd::ConstCharRange pfx = input.slice(0, 2);
|
||||
if ((pfx == "0x") || (pfx == "0X")) {
|
||||
|
@ -185,7 +185,7 @@ done:
|
|||
|
||||
namespace util {
|
||||
OSTD_EXPORT ostd::ConstCharRange parse_string(
|
||||
CsState &cs, ostd::ConstCharRange str, size_t &nlines
|
||||
cs_state &cs, ostd::ConstCharRange str, size_t &nlines
|
||||
) {
|
||||
size_t nl = 0;
|
||||
nlines = nl;
|
||||
|
@ -228,7 +228,7 @@ namespace util {
|
|||
end:
|
||||
nlines = nl;
|
||||
if (str.empty() || (*str != '\"')) {
|
||||
throw CsErrorException(
|
||||
throw cs_error(
|
||||
cs, "unfinished string '%s'", ostd::slice_until(orig, str)
|
||||
);
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ end:
|
|||
}
|
||||
|
||||
OSTD_EXPORT ostd::ConstCharRange parse_word(
|
||||
CsState &cs, ostd::ConstCharRange str
|
||||
cs_state &cs, ostd::ConstCharRange str
|
||||
) {
|
||||
for (;;) {
|
||||
str = ostd::find_one_of(str, ostd::ConstCharRange("\"/;()[] \t\r\n"));
|
||||
|
@ -259,13 +259,13 @@ end:
|
|||
case '[':
|
||||
str = parse_word(cs, str + 1);
|
||||
if (str.empty() || (*str != ']')) {
|
||||
throw CsErrorException(cs, "missing \"]\"");
|
||||
throw cs_error(cs, "missing \"]\"");
|
||||
}
|
||||
break;
|
||||
case '(':
|
||||
str = parse_word(cs, str + 1);
|
||||
if (str.empty() || (*str != ')')) {
|
||||
throw CsErrorException(cs, "missing \")\"");
|
||||
throw cs_error(cs, "missing \")\"");
|
||||
}
|
||||
break;
|
||||
case ']':
|
||||
|
|
|
@ -15,11 +15,11 @@ using CsMap = std::unordered_map<K, V>;
|
|||
template<typename T>
|
||||
using CsVector = std::vector<T>;
|
||||
|
||||
CsInt cs_parse_int(
|
||||
cs_int cs_parse_int(
|
||||
ostd::ConstCharRange input, ostd::ConstCharRange *end = nullptr
|
||||
);
|
||||
|
||||
CsFloat cs_parse_float(
|
||||
cs_float cs_parse_float(
|
||||
ostd::ConstCharRange input, ostd::ConstCharRange *end = nullptr
|
||||
);
|
||||
|
||||
|
|
290
src/cs_val.cc
290
src/cs_val.cc
|
@ -11,12 +11,12 @@ static inline T &csv_get(U &stor) {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void csv_cleanup(CsValueType tv, T &stor) {
|
||||
static inline void csv_cleanup(cs_value_type tv, T &stor) {
|
||||
switch (tv) {
|
||||
case CsValueType::String:
|
||||
case cs_value_type::String:
|
||||
delete[] csv_get<char *>(stor);
|
||||
break;
|
||||
case CsValueType::Code: {
|
||||
case cs_value_type::Code: {
|
||||
uint32_t *bcode = csv_get<uint32_t *>(stor);
|
||||
if (bcode[-1] == CsCodeStart) {
|
||||
delete[] &bcode[-1];
|
||||
|
@ -28,39 +28,39 @@ static inline void csv_cleanup(CsValueType tv, T &stor) {
|
|||
}
|
||||
}
|
||||
|
||||
CsValue::CsValue():
|
||||
p_stor(), p_len(0), p_type(CsValueType::Null)
|
||||
cs_value::cs_value():
|
||||
p_stor(), p_len(0), p_type(cs_value_type::Null)
|
||||
{}
|
||||
|
||||
CsValue::~CsValue() {
|
||||
cs_value::~cs_value() {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
}
|
||||
|
||||
CsValue::CsValue(CsValue const &v): CsValue() {
|
||||
cs_value::cs_value(cs_value const &v): cs_value() {
|
||||
*this = v;
|
||||
}
|
||||
|
||||
CsValue::CsValue(CsValue &&v): CsValue() {
|
||||
cs_value::cs_value(cs_value &&v): cs_value() {
|
||||
*this = std::move(v);
|
||||
}
|
||||
|
||||
CsValue &CsValue::operator=(CsValue const &v) {
|
||||
cs_value &cs_value::operator=(cs_value const &v) {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_type = CsValueType::Null;
|
||||
p_type = cs_value_type::Null;
|
||||
switch (v.get_type()) {
|
||||
case CsValueType::Int:
|
||||
case CsValueType::Float:
|
||||
case CsValueType::Ident:
|
||||
case cs_value_type::Int:
|
||||
case cs_value_type::Float:
|
||||
case cs_value_type::Ident:
|
||||
p_len = v.p_len;
|
||||
p_type = v.p_type;
|
||||
p_stor = v.p_stor;
|
||||
break;
|
||||
case CsValueType::String:
|
||||
case CsValueType::Cstring:
|
||||
case CsValueType::Macro:
|
||||
set_str(CsString{csv_get<char const *>(v.p_stor), v.p_len});
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Cstring:
|
||||
case cs_value_type::Macro:
|
||||
set_str(cs_string{csv_get<char const *>(v.p_stor), v.p_len});
|
||||
break;
|
||||
case CsValueType::Code:
|
||||
case cs_value_type::Code:
|
||||
set_code(cs_copy_code(v.get_code()));
|
||||
break;
|
||||
default:
|
||||
|
@ -69,94 +69,94 @@ CsValue &CsValue::operator=(CsValue const &v) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
CsValue &CsValue::operator=(CsValue &&v) {
|
||||
cs_value &cs_value::operator=(cs_value &&v) {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_stor = v.p_stor;
|
||||
p_type = v.p_type;
|
||||
p_len = v.p_len;
|
||||
v.p_type = CsValueType::Null;
|
||||
v.p_type = cs_value_type::Null;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CsValueType CsValue::get_type() const {
|
||||
cs_value_type cs_value::get_type() const {
|
||||
return p_type;
|
||||
}
|
||||
|
||||
void CsValue::set_int(CsInt val) {
|
||||
void cs_value::set_int(cs_int val) {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_type = CsValueType::Int;
|
||||
csv_get<CsInt>(p_stor) = val;
|
||||
p_type = cs_value_type::Int;
|
||||
csv_get<cs_int>(p_stor) = val;
|
||||
}
|
||||
|
||||
void CsValue::set_float(CsFloat val) {
|
||||
void cs_value::set_float(cs_float val) {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_type = CsValueType::Float;
|
||||
csv_get<CsFloat>(p_stor) = val;
|
||||
p_type = cs_value_type::Float;
|
||||
csv_get<cs_float>(p_stor) = val;
|
||||
}
|
||||
|
||||
void CsValue::set_str(CsString val) {
|
||||
void cs_value::set_str(cs_string val) {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_type = CsValueType::String;
|
||||
p_type = cs_value_type::String;
|
||||
p_len = val.size();
|
||||
char *buf = new char[p_len + 1];
|
||||
memcpy(buf, val.data(), p_len + 1);
|
||||
csv_get<char *>(p_stor) = buf;
|
||||
}
|
||||
|
||||
void CsValue::set_null() {
|
||||
void cs_value::set_null() {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_type = CsValueType::Null;
|
||||
p_type = cs_value_type::Null;
|
||||
}
|
||||
|
||||
void CsValue::set_code(CsBytecode *val) {
|
||||
void cs_value::set_code(cs_bcode *val) {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_type = CsValueType::Code;
|
||||
csv_get<CsBytecode *>(p_stor) = val;
|
||||
p_type = cs_value_type::Code;
|
||||
csv_get<cs_bcode *>(p_stor) = val;
|
||||
}
|
||||
|
||||
void CsValue::set_cstr(ostd::ConstCharRange val) {
|
||||
void cs_value::set_cstr(ostd::ConstCharRange val) {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_type = CsValueType::Cstring;
|
||||
p_type = cs_value_type::Cstring;
|
||||
p_len = val.size();
|
||||
csv_get<char const *>(p_stor) = val.data();
|
||||
}
|
||||
|
||||
void CsValue::set_ident(CsIdent *val) {
|
||||
void cs_value::set_ident(cs_ident *val) {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_type = CsValueType::Ident;
|
||||
csv_get<CsIdent *>(p_stor) = val;
|
||||
p_type = cs_value_type::Ident;
|
||||
csv_get<cs_ident *>(p_stor) = val;
|
||||
}
|
||||
|
||||
void CsValue::set_macro(ostd::ConstCharRange val) {
|
||||
void cs_value::set_macro(ostd::ConstCharRange val) {
|
||||
csv_cleanup(p_type, p_stor);
|
||||
p_type = CsValueType::Macro;
|
||||
p_type = cs_value_type::Macro;
|
||||
p_len = val.size();
|
||||
csv_get<char const *>(p_stor) = val.data();
|
||||
}
|
||||
|
||||
void CsValue::force_null() {
|
||||
if (get_type() == CsValueType::Null) {
|
||||
void cs_value::force_null() {
|
||||
if (get_type() == cs_value_type::Null) {
|
||||
return;
|
||||
}
|
||||
set_null();
|
||||
}
|
||||
|
||||
CsFloat CsValue::force_float() {
|
||||
CsFloat rf = 0.0f;
|
||||
cs_float cs_value::force_float() {
|
||||
cs_float rf = 0.0f;
|
||||
switch (get_type()) {
|
||||
case CsValueType::Int:
|
||||
rf = csv_get<CsInt>(p_stor);
|
||||
case cs_value_type::Int:
|
||||
rf = csv_get<cs_int>(p_stor);
|
||||
break;
|
||||
case CsValueType::String:
|
||||
case CsValueType::Macro:
|
||||
case CsValueType::Cstring:
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Macro:
|
||||
case cs_value_type::Cstring:
|
||||
rf = cs_parse_float(ostd::ConstCharRange(
|
||||
csv_get<char const *>(p_stor),
|
||||
csv_get<char const *>(p_stor) + p_len
|
||||
));
|
||||
break;
|
||||
case CsValueType::Float:
|
||||
return csv_get<CsFloat>(p_stor);
|
||||
case cs_value_type::Float:
|
||||
return csv_get<cs_float>(p_stor);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -164,22 +164,22 @@ CsFloat CsValue::force_float() {
|
|||
return rf;
|
||||
}
|
||||
|
||||
CsInt CsValue::force_int() {
|
||||
CsInt ri = 0;
|
||||
cs_int cs_value::force_int() {
|
||||
cs_int ri = 0;
|
||||
switch (get_type()) {
|
||||
case CsValueType::Float:
|
||||
ri = csv_get<CsFloat>(p_stor);
|
||||
case cs_value_type::Float:
|
||||
ri = csv_get<cs_float>(p_stor);
|
||||
break;
|
||||
case CsValueType::String:
|
||||
case CsValueType::Macro:
|
||||
case CsValueType::Cstring:
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Macro:
|
||||
case cs_value_type::Cstring:
|
||||
ri = cs_parse_int(ostd::ConstCharRange(
|
||||
csv_get<char const *>(p_stor),
|
||||
csv_get<char const *>(p_stor) + p_len
|
||||
));
|
||||
break;
|
||||
case CsValueType::Int:
|
||||
return csv_get<CsInt>(p_stor);
|
||||
case cs_value_type::Int:
|
||||
return csv_get<cs_int>(p_stor);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -187,23 +187,23 @@ CsInt CsValue::force_int() {
|
|||
return ri;
|
||||
}
|
||||
|
||||
ostd::ConstCharRange CsValue::force_str() {
|
||||
CsString rs;
|
||||
ostd::ConstCharRange cs_value::force_str() {
|
||||
cs_string rs;
|
||||
switch (get_type()) {
|
||||
case CsValueType::Float:
|
||||
rs = floatstr(csv_get<CsFloat>(p_stor));
|
||||
case cs_value_type::Float:
|
||||
rs = floatstr(csv_get<cs_float>(p_stor));
|
||||
break;
|
||||
case CsValueType::Int:
|
||||
rs = intstr(csv_get<CsInt>(p_stor));
|
||||
case cs_value_type::Int:
|
||||
rs = intstr(csv_get<cs_int>(p_stor));
|
||||
break;
|
||||
case CsValueType::Macro:
|
||||
case CsValueType::Cstring:
|
||||
case cs_value_type::Macro:
|
||||
case cs_value_type::Cstring:
|
||||
rs = ostd::ConstCharRange(
|
||||
csv_get<char const *>(p_stor),
|
||||
csv_get<char const *>(p_stor) + p_len
|
||||
);
|
||||
break;
|
||||
case CsValueType::String:
|
||||
case cs_value_type::String:
|
||||
return ostd::ConstCharRange(
|
||||
csv_get<char const *>(p_stor),
|
||||
csv_get<char const *>(p_stor) + p_len
|
||||
|
@ -218,15 +218,15 @@ ostd::ConstCharRange CsValue::force_str() {
|
|||
);
|
||||
}
|
||||
|
||||
CsInt CsValue::get_int() const {
|
||||
cs_int cs_value::get_int() const {
|
||||
switch (get_type()) {
|
||||
case CsValueType::Float:
|
||||
return CsInt(csv_get<CsFloat>(p_stor));
|
||||
case CsValueType::Int:
|
||||
return csv_get<CsInt>(p_stor);
|
||||
case CsValueType::String:
|
||||
case CsValueType::Macro:
|
||||
case CsValueType::Cstring:
|
||||
case cs_value_type::Float:
|
||||
return cs_int(csv_get<cs_float>(p_stor));
|
||||
case cs_value_type::Int:
|
||||
return csv_get<cs_int>(p_stor);
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Macro:
|
||||
case cs_value_type::Cstring:
|
||||
return cs_parse_int(ostd::ConstCharRange(
|
||||
csv_get<char const *>(p_stor),
|
||||
csv_get<char const *>(p_stor) + p_len
|
||||
|
@ -237,15 +237,15 @@ CsInt CsValue::get_int() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
CsFloat CsValue::get_float() const {
|
||||
cs_float cs_value::get_float() const {
|
||||
switch (get_type()) {
|
||||
case CsValueType::Float:
|
||||
return csv_get<CsFloat>(p_stor);
|
||||
case CsValueType::Int:
|
||||
return CsFloat(csv_get<CsInt>(p_stor));
|
||||
case CsValueType::String:
|
||||
case CsValueType::Macro:
|
||||
case CsValueType::Cstring:
|
||||
case cs_value_type::Float:
|
||||
return csv_get<cs_float>(p_stor);
|
||||
case cs_value_type::Int:
|
||||
return cs_float(csv_get<cs_int>(p_stor));
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Macro:
|
||||
case cs_value_type::Cstring:
|
||||
return cs_parse_float(ostd::ConstCharRange(
|
||||
csv_get<char const *>(p_stor),
|
||||
csv_get<char const *>(p_stor) + p_len
|
||||
|
@ -256,41 +256,41 @@ CsFloat CsValue::get_float() const {
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
CsBytecode *CsValue::get_code() const {
|
||||
if (get_type() != CsValueType::Code) {
|
||||
cs_bcode *cs_value::get_code() const {
|
||||
if (get_type() != cs_value_type::Code) {
|
||||
return nullptr;
|
||||
}
|
||||
return csv_get<CsBytecode *>(p_stor);
|
||||
return csv_get<cs_bcode *>(p_stor);
|
||||
}
|
||||
|
||||
CsIdent *CsValue::get_ident() const {
|
||||
if (get_type() != CsValueType::Ident) {
|
||||
cs_ident *cs_value::get_ident() const {
|
||||
if (get_type() != cs_value_type::Ident) {
|
||||
return nullptr;
|
||||
}
|
||||
return csv_get<CsIdent *>(p_stor);
|
||||
return csv_get<cs_ident *>(p_stor);
|
||||
}
|
||||
|
||||
CsString CsValue::get_str() const {
|
||||
cs_string cs_value::get_str() const {
|
||||
switch (get_type()) {
|
||||
case CsValueType::String:
|
||||
case CsValueType::Macro:
|
||||
case CsValueType::Cstring:
|
||||
return CsString{csv_get<char const *>(p_stor), p_len};
|
||||
case CsValueType::Int:
|
||||
return intstr(csv_get<CsInt>(p_stor));
|
||||
case CsValueType::Float:
|
||||
return floatstr(csv_get<CsFloat>(p_stor));
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Macro:
|
||||
case cs_value_type::Cstring:
|
||||
return cs_string{csv_get<char const *>(p_stor), p_len};
|
||||
case cs_value_type::Int:
|
||||
return intstr(csv_get<cs_int>(p_stor));
|
||||
case cs_value_type::Float:
|
||||
return floatstr(csv_get<cs_float>(p_stor));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return CsString("");
|
||||
return cs_string("");
|
||||
}
|
||||
|
||||
ostd::ConstCharRange CsValue::get_strr() const {
|
||||
ostd::ConstCharRange cs_value::get_strr() const {
|
||||
switch (get_type()) {
|
||||
case CsValueType::String:
|
||||
case CsValueType::Macro:
|
||||
case CsValueType::Cstring:
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Macro:
|
||||
case cs_value_type::Cstring:
|
||||
return ostd::ConstCharRange(
|
||||
csv_get<char const *>(p_stor),
|
||||
csv_get<char const *>(p_stor)+ p_len
|
||||
|
@ -301,20 +301,20 @@ ostd::ConstCharRange CsValue::get_strr() const {
|
|||
return ostd::ConstCharRange();
|
||||
}
|
||||
|
||||
void CsValue::get_val(CsValue &r) const {
|
||||
void cs_value::get_val(cs_value &r) const {
|
||||
switch (get_type()) {
|
||||
case CsValueType::String:
|
||||
case CsValueType::Macro:
|
||||
case CsValueType::Cstring:
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Macro:
|
||||
case cs_value_type::Cstring:
|
||||
r.set_str(
|
||||
CsString{csv_get<char const *>(p_stor), p_len}
|
||||
cs_string{csv_get<char const *>(p_stor), p_len}
|
||||
);
|
||||
break;
|
||||
case CsValueType::Int:
|
||||
r.set_int(csv_get<CsInt>(p_stor));
|
||||
case cs_value_type::Int:
|
||||
r.set_int(csv_get<cs_int>(p_stor));
|
||||
break;
|
||||
case CsValueType::Float:
|
||||
r.set_float(csv_get<CsFloat>(p_stor));
|
||||
case cs_value_type::Float:
|
||||
r.set_float(csv_get<cs_float>(p_stor));
|
||||
break;
|
||||
default:
|
||||
r.set_null();
|
||||
|
@ -322,7 +322,7 @@ void CsValue::get_val(CsValue &r) const {
|
|||
}
|
||||
}
|
||||
|
||||
OSTD_EXPORT bool cs_code_is_empty(CsBytecode *code) {
|
||||
OSTD_EXPORT bool cs_code_is_empty(cs_bcode *code) {
|
||||
if (!code) {
|
||||
return true;
|
||||
}
|
||||
|
@ -331,11 +331,11 @@ OSTD_EXPORT bool cs_code_is_empty(CsBytecode *code) {
|
|||
) == CsCodeExit;
|
||||
}
|
||||
|
||||
bool CsValue::code_is_empty() const {
|
||||
if (get_type() != CsValueType::Code) {
|
||||
bool cs_value::code_is_empty() const {
|
||||
if (get_type() != cs_value_type::Code) {
|
||||
return true;
|
||||
}
|
||||
return cscript::cs_code_is_empty(csv_get<CsBytecode *>(p_stor));
|
||||
return cscript::cs_code_is_empty(csv_get<cs_bcode *>(p_stor));
|
||||
}
|
||||
|
||||
static inline bool cs_get_bool(ostd::ConstCharRange s) {
|
||||
|
@ -343,27 +343,27 @@ static inline bool cs_get_bool(ostd::ConstCharRange s) {
|
|||
return false;
|
||||
}
|
||||
ostd::ConstCharRange end = s;
|
||||
CsInt ival = cs_parse_int(end, &end);
|
||||
cs_int ival = cs_parse_int(end, &end);
|
||||
if (end.empty()) {
|
||||
return !!ival;
|
||||
}
|
||||
end = s;
|
||||
CsFloat fval = cs_parse_float(end, &end);
|
||||
cs_float fval = cs_parse_float(end, &end);
|
||||
if (end.empty()) {
|
||||
return !!fval;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CsValue::get_bool() const {
|
||||
bool cs_value::get_bool() const {
|
||||
switch (get_type()) {
|
||||
case CsValueType::Float:
|
||||
return csv_get<CsFloat>(p_stor) != 0;
|
||||
case CsValueType::Int:
|
||||
return csv_get<CsInt>(p_stor) != 0;
|
||||
case CsValueType::String:
|
||||
case CsValueType::Macro:
|
||||
case CsValueType::Cstring:
|
||||
case cs_value_type::Float:
|
||||
return csv_get<cs_float>(p_stor) != 0;
|
||||
case cs_value_type::Int:
|
||||
return csv_get<cs_int>(p_stor) != 0;
|
||||
case cs_value_type::String:
|
||||
case cs_value_type::Macro:
|
||||
case cs_value_type::Cstring:
|
||||
return cs_get_bool(ostd::ConstCharRange(
|
||||
csv_get<char const *>(p_stor),
|
||||
csv_get<char const *>(p_stor) + p_len
|
||||
|
@ -375,57 +375,57 @@ bool CsValue::get_bool() const {
|
|||
|
||||
/* stacked value for easy stack management */
|
||||
|
||||
CsStackedValue::CsStackedValue(CsIdent *id):
|
||||
CsValue(), p_a(nullptr), p_stack(), p_pushed(false)
|
||||
cs_stacked_value::cs_stacked_value(cs_ident *id):
|
||||
cs_value(), p_a(nullptr), p_stack(), p_pushed(false)
|
||||
{
|
||||
set_alias(id);
|
||||
}
|
||||
|
||||
CsStackedValue::~CsStackedValue() {
|
||||
cs_stacked_value::~cs_stacked_value() {
|
||||
pop();
|
||||
static_cast<CsValue *>(this)->~CsValue();
|
||||
static_cast<cs_value *>(this)->~cs_value();
|
||||
}
|
||||
|
||||
CsStackedValue &CsStackedValue::operator=(CsValue const &v) {
|
||||
*static_cast<CsValue *>(this) = v;
|
||||
cs_stacked_value &cs_stacked_value::operator=(cs_value const &v) {
|
||||
*static_cast<cs_value *>(this) = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CsStackedValue &CsStackedValue::operator=(CsValue &&v) {
|
||||
*static_cast<CsValue *>(this) = std::move(v);
|
||||
cs_stacked_value &cs_stacked_value::operator=(cs_value &&v) {
|
||||
*static_cast<cs_value *>(this) = std::move(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool CsStackedValue::set_alias(CsIdent *id) {
|
||||
bool cs_stacked_value::set_alias(cs_ident *id) {
|
||||
if (!id || !id->is_alias()) {
|
||||
return false;
|
||||
}
|
||||
p_a = static_cast<CsAlias *>(id);
|
||||
p_a = static_cast<cs_alias *>(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
CsAlias *CsStackedValue::get_alias() const {
|
||||
cs_alias *cs_stacked_value::get_alias() const {
|
||||
return p_a;
|
||||
}
|
||||
|
||||
bool CsStackedValue::has_alias() const {
|
||||
bool cs_stacked_value::has_alias() const {
|
||||
return p_a != nullptr;
|
||||
}
|
||||
|
||||
bool CsStackedValue::push() {
|
||||
bool cs_stacked_value::push() {
|
||||
if (!p_a) {
|
||||
return false;
|
||||
}
|
||||
CsAliasInternal::push_arg(p_a, *this, p_stack);
|
||||
cs_aliasInternal::push_arg(p_a, *this, p_stack);
|
||||
p_pushed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CsStackedValue::pop() {
|
||||
bool cs_stacked_value::pop() {
|
||||
if (!p_pushed || !p_a) {
|
||||
return false;
|
||||
}
|
||||
CsAliasInternal::pop_arg(p_a);
|
||||
cs_aliasInternal::pop_arg(p_a);
|
||||
p_pushed = false;
|
||||
return true;
|
||||
}
|
||||
|
|
610
src/cs_vm.cc
610
src/cs_vm.cc
File diff suppressed because it is too large
Load Diff
108
src/cs_vm.hh
108
src/cs_vm.hh
|
@ -25,11 +25,11 @@ enum {
|
|||
CsIdNot, CsIdAnd, CsIdOr
|
||||
};
|
||||
|
||||
struct CsIdentLink {
|
||||
CsIdent *id;
|
||||
CsIdentLink *next;
|
||||
struct cs_identLink {
|
||||
cs_ident *id;
|
||||
cs_identLink *next;
|
||||
int usedargs;
|
||||
CsIdentStack *argstack;
|
||||
cs_ident_stack *argstack;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -43,7 +43,7 @@ static const int cs_valtypet[] = {
|
|||
CsValCstring, CsValCode, CsValMacro, CsValIdent
|
||||
};
|
||||
|
||||
static inline int cs_vtype_to_int(CsValueType v) {
|
||||
static inline int cs_vtype_to_int(cs_value_type v) {
|
||||
return cs_valtypet[int(v)];
|
||||
}
|
||||
|
||||
|
@ -94,10 +94,10 @@ enum {
|
|||
CsCodeFlagFalse = 0 << CsCodeRet
|
||||
};
|
||||
|
||||
struct CsSharedState {
|
||||
CsMap<ostd::ConstCharRange, CsIdent *> idents;
|
||||
CsVector<CsIdent *> identmap;
|
||||
CsAllocCb allocf;
|
||||
struct cs_shared_state {
|
||||
CsMap<ostd::ConstCharRange, cs_ident *> idents;
|
||||
CsVector<cs_ident *> identmap;
|
||||
cs_alloc_cb allocf;
|
||||
void *aptr;
|
||||
|
||||
void *alloc(void *ptr, size_t os, size_t ns) {
|
||||
|
@ -143,24 +143,24 @@ template<typename T>
|
|||
constexpr size_t CsTypeStorageSize =
|
||||
(sizeof(T) - 1) / sizeof(uint32_t) + 1;
|
||||
|
||||
struct GenState {
|
||||
CsState &cs;
|
||||
GenState *prevps;
|
||||
struct cs_gen_state {
|
||||
cs_state &cs;
|
||||
cs_gen_state *prevps;
|
||||
bool parsing = true;
|
||||
CsVector<uint32_t> code;
|
||||
ostd::ConstCharRange source;
|
||||
size_t current_line;
|
||||
ostd::ConstCharRange src_name;
|
||||
|
||||
GenState() = delete;
|
||||
GenState(CsState &csr):
|
||||
cs_gen_state() = delete;
|
||||
cs_gen_state(cs_state &csr):
|
||||
cs(csr), prevps(csr.p_pstate), code(),
|
||||
source(nullptr), current_line(1), src_name()
|
||||
{
|
||||
csr.p_pstate = this;
|
||||
}
|
||||
|
||||
~GenState() {
|
||||
~cs_gen_state() {
|
||||
done();
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ struct GenState {
|
|||
}
|
||||
|
||||
ostd::ConstCharRange get_str();
|
||||
CsString get_str_dup(bool unescape = true);
|
||||
cs_string get_str_dup(bool unescape = true);
|
||||
|
||||
ostd::ConstCharRange get_word();
|
||||
|
||||
|
@ -211,39 +211,39 @@ struct GenState {
|
|||
code.push_back(CsCodeValInt | CsRetNull);
|
||||
}
|
||||
|
||||
void gen_int(CsInt i = 0) {
|
||||
void gen_int(cs_int i = 0) {
|
||||
if (i >= -0x800000 && i <= 0x7FFFFF) {
|
||||
code.push_back(CsCodeValInt | CsRetInt | (i << 8));
|
||||
} else {
|
||||
union {
|
||||
CsInt i;
|
||||
uint32_t u[CsTypeStorageSize<CsInt>];
|
||||
cs_int i;
|
||||
uint32_t u[CsTypeStorageSize<cs_int>];
|
||||
} c;
|
||||
c.i = i;
|
||||
code.push_back(CsCodeVal | CsRetInt);
|
||||
code.insert(code.end(), c.u, c.u + CsTypeStorageSize<CsInt>);
|
||||
code.insert(code.end(), c.u, c.u + CsTypeStorageSize<cs_int>);
|
||||
}
|
||||
}
|
||||
|
||||
void gen_int(ostd::ConstCharRange word);
|
||||
|
||||
void gen_float(CsFloat f = 0.0f) {
|
||||
if (CsInt(f) == f && f >= -0x800000 && f <= 0x7FFFFF) {
|
||||
code.push_back(CsCodeValInt | CsRetFloat | (CsInt(f) << 8));
|
||||
void gen_float(cs_float f = 0.0f) {
|
||||
if (cs_int(f) == f && f >= -0x800000 && f <= 0x7FFFFF) {
|
||||
code.push_back(CsCodeValInt | CsRetFloat | (cs_int(f) << 8));
|
||||
} else {
|
||||
union {
|
||||
CsFloat f;
|
||||
uint32_t u[CsTypeStorageSize<CsFloat>];
|
||||
cs_float f;
|
||||
uint32_t u[CsTypeStorageSize<cs_float>];
|
||||
} c;
|
||||
c.f = f;
|
||||
code.push_back(CsCodeVal | CsRetFloat);
|
||||
code.insert(code.end(), c.u, c.u + CsTypeStorageSize<CsFloat>);
|
||||
code.insert(code.end(), c.u, c.u + CsTypeStorageSize<cs_float>);
|
||||
}
|
||||
}
|
||||
|
||||
void gen_float(ostd::ConstCharRange word);
|
||||
|
||||
void gen_ident(CsIdent *id) {
|
||||
void gen_ident(cs_ident *id) {
|
||||
code.push_back(
|
||||
((id->get_index() < MaxArguments)
|
||||
? CsCodeIdentArg
|
||||
|
@ -292,8 +292,8 @@ struct GenState {
|
|||
void skip_comments();
|
||||
};
|
||||
|
||||
CsString intstr(CsInt v);
|
||||
CsString floatstr(CsFloat v);
|
||||
cs_string intstr(cs_int v);
|
||||
cs_string floatstr(cs_float v);
|
||||
|
||||
bool cs_check_num(ostd::ConstCharRange s);
|
||||
|
||||
|
@ -308,16 +308,16 @@ static inline void bcode_decr(uint32_t *bc) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool cs_is_arg_used(CsState &cs, CsIdent *id) {
|
||||
static inline bool cs_is_arg_used(cs_state &cs, cs_ident *id) {
|
||||
if (!cs.p_callstack) {
|
||||
return true;
|
||||
}
|
||||
return cs.p_callstack->usedargs & (1 << id->get_index());
|
||||
}
|
||||
|
||||
struct CsAliasInternal {
|
||||
struct cs_aliasInternal {
|
||||
static void push_arg(
|
||||
CsAlias *a, CsValue &v, CsIdentStack &st, bool um = true
|
||||
cs_alias *a, cs_value &v, cs_ident_stack &st, bool um = true
|
||||
) {
|
||||
if (a->p_astack == &st) {
|
||||
/* prevent cycles and unnecessary code elsewhere */
|
||||
|
@ -331,22 +331,22 @@ struct CsAliasInternal {
|
|||
a->p_val = std::move(v);
|
||||
clean_code(a);
|
||||
if (um) {
|
||||
a->p_flags &= ~CsIdfUnknown;
|
||||
a->p_flags &= ~CS_IDF_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void pop_arg(CsAlias *a) {
|
||||
static void pop_arg(cs_alias *a) {
|
||||
if (!a->p_astack) {
|
||||
return;
|
||||
}
|
||||
CsIdentStack *st = a->p_astack;
|
||||
cs_ident_stack *st = a->p_astack;
|
||||
a->p_val = std::move(a->p_astack->val_s);
|
||||
clean_code(a);
|
||||
a->p_astack = st->next;
|
||||
}
|
||||
|
||||
static void undo_arg(CsAlias *a, CsIdentStack &st) {
|
||||
CsIdentStack *prev = a->p_astack;
|
||||
static void undo_arg(cs_alias *a, cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = a->p_astack;
|
||||
st.val_s = std::move(a->p_val);
|
||||
st.next = prev;
|
||||
a->p_astack = prev->next;
|
||||
|
@ -354,15 +354,15 @@ struct CsAliasInternal {
|
|||
clean_code(a);
|
||||
}
|
||||
|
||||
static void redo_arg(CsAlias *a, CsIdentStack &st) {
|
||||
CsIdentStack *prev = st.next;
|
||||
static void redo_arg(cs_alias *a, cs_ident_stack &st) {
|
||||
cs_ident_stack *prev = st.next;
|
||||
prev->val_s = std::move(a->p_val);
|
||||
a->p_astack = prev;
|
||||
a->p_val = std::move(st.val_s);
|
||||
clean_code(a);
|
||||
}
|
||||
|
||||
static void set_arg(CsAlias *a, CsState &cs, CsValue &v) {
|
||||
static void set_arg(cs_alias *a, cs_state &cs, cs_value &v) {
|
||||
if (cs_is_arg_used(cs, a)) {
|
||||
a->p_val = std::move(v);
|
||||
clean_code(a);
|
||||
|
@ -372,13 +372,13 @@ struct CsAliasInternal {
|
|||
}
|
||||
}
|
||||
|
||||
static void set_alias(CsAlias *a, CsState &cs, CsValue &v) {
|
||||
static void set_alias(cs_alias *a, cs_state &cs, cs_value &v) {
|
||||
a->p_val = std::move(v);
|
||||
clean_code(a);
|
||||
a->p_flags = (a->p_flags & cs.identflags) | cs.identflags;
|
||||
}
|
||||
|
||||
static void clean_code(CsAlias *a) {
|
||||
static void clean_code(cs_alias *a) {
|
||||
uint32_t *bcode = reinterpret_cast<uint32_t *>(a->p_acode);
|
||||
if (bcode) {
|
||||
bcode_decr(bcode);
|
||||
|
@ -386,38 +386,38 @@ struct CsAliasInternal {
|
|||
}
|
||||
}
|
||||
|
||||
static CsBytecode *compile_code(CsAlias *a, CsState &cs) {
|
||||
static cs_bcode *compile_code(cs_alias *a, cs_state &cs) {
|
||||
if (!a->p_acode) {
|
||||
GenState gs(cs);
|
||||
cs_gen_state gs(cs);
|
||||
gs.code.reserve(64);
|
||||
gs.gen_main(a->get_value().get_str());
|
||||
/* i wish i could steal the memory somehow */
|
||||
uint32_t *code = new uint32_t[gs.code.size()];
|
||||
memcpy(code, gs.code.data(), gs.code.size() * sizeof(uint32_t));
|
||||
bcode_incr(code);
|
||||
a->p_acode = reinterpret_cast<CsBytecode *>(code);
|
||||
a->p_acode = reinterpret_cast<cs_bcode *>(code);
|
||||
}
|
||||
return a->p_acode;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
static void cs_do_args(CsState &cs, F body) {
|
||||
static void cs_do_args(cs_state &cs, F body) {
|
||||
if (!cs.p_callstack) {
|
||||
body();
|
||||
return;
|
||||
}
|
||||
CsIdentStack argstack[MaxArguments];
|
||||
cs_ident_stack argstack[MaxArguments];
|
||||
int argmask1 = cs.p_callstack->usedargs;
|
||||
for (int i = 0; argmask1; argmask1 >>= 1, ++i) {
|
||||
if (argmask1 & 1) {
|
||||
CsAliasInternal::undo_arg(
|
||||
static_cast<CsAlias *>(cs.p_state->identmap[i]), argstack[i]
|
||||
cs_aliasInternal::undo_arg(
|
||||
static_cast<cs_alias *>(cs.p_state->identmap[i]), argstack[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
CsIdentLink *prevstack = cs.p_callstack->next;
|
||||
CsIdentLink aliaslink = {
|
||||
cs_identLink *prevstack = cs.p_callstack->next;
|
||||
cs_identLink aliaslink = {
|
||||
cs.p_callstack->id, cs.p_callstack,
|
||||
prevstack ? prevstack->usedargs : ((1 << MaxArguments) - 1),
|
||||
prevstack ? prevstack->argstack : nullptr
|
||||
|
@ -431,15 +431,15 @@ static void cs_do_args(CsState &cs, F body) {
|
|||
int argmask2 = cs.p_callstack->usedargs;
|
||||
for (int i = 0; argmask2; argmask2 >>= 1, ++i) {
|
||||
if (argmask2 & 1) {
|
||||
CsAliasInternal::redo_arg(
|
||||
static_cast<CsAlias *>(cs.p_state->identmap[i]), argstack[i]
|
||||
cs_aliasInternal::redo_arg(
|
||||
static_cast<cs_alias *>(cs.p_state->identmap[i]), argstack[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CsBytecode *cs_copy_code(CsBytecode *c);
|
||||
cs_bcode *cs_copy_code(cs_bcode *c);
|
||||
|
||||
} /* namespace cscript */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
132
src/lib_list.cc
132
src/lib_list.cc
|
@ -9,31 +9,31 @@ template<typename T>
|
|||
struct CsArgVal;
|
||||
|
||||
template<>
|
||||
struct CsArgVal<CsInt> {
|
||||
static CsInt get(CsValue &tv) {
|
||||
struct CsArgVal<cs_int> {
|
||||
static cs_int get(cs_value &tv) {
|
||||
return tv.get_int();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CsArgVal<CsFloat> {
|
||||
static CsFloat get(CsValue &tv) {
|
||||
struct CsArgVal<cs_float> {
|
||||
static cs_float get(cs_value &tv) {
|
||||
return tv.get_float();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CsArgVal<ostd::ConstCharRange> {
|
||||
static ostd::ConstCharRange get(CsValue &tv) {
|
||||
static ostd::ConstCharRange get(cs_value &tv) {
|
||||
return tv.get_strr();
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename F>
|
||||
static inline void cs_list_find(
|
||||
CsState &cs, CsValueRange args, CsValue &res, F cmp
|
||||
cs_state &cs, cs_value_r args, cs_value &res, F cmp
|
||||
) {
|
||||
CsInt n = 0, skip = args[2].get_int();
|
||||
cs_int n = 0, skip = args[2].get_int();
|
||||
T val = CsArgVal<T>::get(args[1]);
|
||||
for (util::ListParser p(cs, args[0].get_strr()); p.parse(); ++n) {
|
||||
if (cmp(p, val)) {
|
||||
|
@ -53,7 +53,7 @@ notfound:
|
|||
|
||||
template<typename T, typename F>
|
||||
static inline void cs_list_assoc(
|
||||
CsState &cs, CsValueRange args, CsValue &res, F cmp
|
||||
cs_state &cs, cs_value_r args, cs_value &res, F cmp
|
||||
) {
|
||||
T val = CsArgVal<T>::get(args[1]);
|
||||
for (util::ListParser p(cs, args[0].get_strr()); p.parse();) {
|
||||
|
@ -70,14 +70,14 @@ static inline void cs_list_assoc(
|
|||
}
|
||||
|
||||
static void cs_loop_list_conc(
|
||||
CsState &cs, CsValue &res, CsIdent *id, ostd::ConstCharRange list,
|
||||
CsBytecode *body, bool space
|
||||
cs_state &cs, cs_value &res, cs_ident *id, ostd::ConstCharRange list,
|
||||
cs_bcode *body, bool space
|
||||
) {
|
||||
CsStackedValue idv{id};
|
||||
cs_stacked_value idv{id};
|
||||
if (!idv.has_alias()) {
|
||||
return;
|
||||
}
|
||||
CsString r;
|
||||
cs_string r;
|
||||
int n = 0;
|
||||
for (util::ListParser p(cs, list); p.parse(); ++n) {
|
||||
idv.set_str(p.get_item());
|
||||
|
@ -85,7 +85,7 @@ static void cs_loop_list_conc(
|
|||
if (n && space) {
|
||||
r += ' ';
|
||||
}
|
||||
CsValue v;
|
||||
cs_value v;
|
||||
switch (cs.run_loop(body, v)) {
|
||||
case CsLoopState::Break:
|
||||
goto end;
|
||||
|
@ -101,7 +101,7 @@ end:
|
|||
}
|
||||
|
||||
int cs_list_includes(
|
||||
CsState &cs, ostd::ConstCharRange list, ostd::ConstCharRange needle
|
||||
cs_state &cs, ostd::ConstCharRange list, ostd::ConstCharRange needle
|
||||
) {
|
||||
int offset = 0;
|
||||
for (util::ListParser p(cs, list); p.parse();) {
|
||||
|
@ -115,11 +115,11 @@ int cs_list_includes(
|
|||
|
||||
template<bool PushList, bool Swap, typename F>
|
||||
static inline void cs_list_merge(
|
||||
CsState &cs, CsValueRange args, CsValue &res, F cmp
|
||||
cs_state &cs, cs_value_r args, cs_value &res, F cmp
|
||||
) {
|
||||
ostd::ConstCharRange list = args[0].get_strr();
|
||||
ostd::ConstCharRange elems = args[1].get_strr();
|
||||
CsString buf;
|
||||
cs_string buf;
|
||||
if (PushList) {
|
||||
buf += list;
|
||||
}
|
||||
|
@ -137,23 +137,23 @@ static inline void cs_list_merge(
|
|||
res.set_str(std::move(buf));
|
||||
}
|
||||
|
||||
static void cs_init_lib_list_sort(CsState &cs);
|
||||
static void cs_init_lib_list_sort(cs_state &cs);
|
||||
|
||||
void cs_init_lib_list(CsState &gcs) {
|
||||
void cs_init_lib_list(cs_state &gcs) {
|
||||
gcs.new_command("listlen", "s", [](auto &cs, auto args, auto &res) {
|
||||
res.set_int(CsInt(util::ListParser(cs, args[0].get_strr()).count()));
|
||||
res.set_int(cs_int(util::ListParser(cs, args[0].get_strr()).count()));
|
||||
});
|
||||
|
||||
gcs.new_command("at", "si1V", [](auto &cs, auto args, auto &res) {
|
||||
if (args.empty()) {
|
||||
return;
|
||||
}
|
||||
CsString str = std::move(args[0].get_str());
|
||||
cs_string str = std::move(args[0].get_str());
|
||||
util::ListParser p(cs, str);
|
||||
p.get_raw_item() = str;
|
||||
for (size_t i = 1; i < args.size(); ++i) {
|
||||
p.get_input() = str;
|
||||
CsInt pos = args[i].get_int();
|
||||
cs_int pos = args[i].get_int();
|
||||
for (; pos > 0; --pos) {
|
||||
if (!p.parse()) {
|
||||
break;
|
||||
|
@ -167,22 +167,22 @@ void cs_init_lib_list(CsState &gcs) {
|
|||
});
|
||||
|
||||
gcs.new_command("sublist", "siiN", [](auto &cs, auto args, auto &res) {
|
||||
CsInt skip = args[1].get_int(),
|
||||
cs_int skip = args[1].get_int(),
|
||||
count = args[2].get_int(),
|
||||
numargs = args[3].get_int();
|
||||
|
||||
CsInt offset = ostd::max(skip, CsInt(0)),
|
||||
len = (numargs >= 3) ? ostd::max(count, CsInt(0)) : -1;
|
||||
cs_int offset = ostd::max(skip, cs_int(0)),
|
||||
len = (numargs >= 3) ? ostd::max(count, cs_int(0)) : -1;
|
||||
|
||||
util::ListParser p(cs, args[0].get_strr());
|
||||
for (CsInt i = 0; i < offset; ++i) {
|
||||
for (cs_int i = 0; i < offset; ++i) {
|
||||
if (!p.parse()) break;
|
||||
}
|
||||
if (len < 0) {
|
||||
if (offset > 0) {
|
||||
p.skip();
|
||||
}
|
||||
res.set_str(CsString{p.get_input()});
|
||||
res.set_str(cs_string{p.get_input()});
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -193,11 +193,11 @@ void cs_init_lib_list(CsState &gcs) {
|
|||
}
|
||||
ostd::ConstCharRange quote = p.get_raw_item(true);
|
||||
char const *qend = !quote.empty() ? "e[quote.size()] : list;
|
||||
res.set_str(CsString{list, size_t(qend - list)});
|
||||
res.set_str(cs_string{list, size_t(qend - list)});
|
||||
});
|
||||
|
||||
gcs.new_command("listfind", "rse", [](auto &cs, auto args, auto &res) {
|
||||
CsStackedValue idv{args[0].get_ident()};
|
||||
cs_stacked_value idv{args[0].get_ident()};
|
||||
if (!idv.has_alias()) {
|
||||
res.set_int(-1);
|
||||
return;
|
||||
|
@ -206,10 +206,10 @@ void cs_init_lib_list(CsState &gcs) {
|
|||
int n = -1;
|
||||
for (util::ListParser p(cs, args[1].get_strr()); p.parse();) {
|
||||
++n;
|
||||
idv.set_str(CsString{p.get_raw_item()});
|
||||
idv.set_str(cs_string{p.get_raw_item()});
|
||||
idv.push();
|
||||
if (cs.run_bool(body)) {
|
||||
res.set_int(CsInt(n));
|
||||
res.set_int(cs_int(n));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ void cs_init_lib_list(CsState &gcs) {
|
|||
});
|
||||
|
||||
gcs.new_command("listassoc", "rse", [](auto &cs, auto args, auto &res) {
|
||||
CsStackedValue idv{args[0].get_ident()};
|
||||
cs_stacked_value idv{args[0].get_ident()};
|
||||
if (!idv.has_alias()) {
|
||||
return;
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ void cs_init_lib_list(CsState &gcs) {
|
|||
int n = -1;
|
||||
for (util::ListParser p(cs, args[1].get_strr()); p.parse();) {
|
||||
++n;
|
||||
idv.set_str(CsString{p.get_raw_item()});
|
||||
idv.set_str(cs_string{p.get_raw_item()});
|
||||
idv.push();
|
||||
if (cs.run_bool(body)) {
|
||||
if (p.parse()) {
|
||||
|
@ -240,15 +240,15 @@ void cs_init_lib_list(CsState &gcs) {
|
|||
});
|
||||
|
||||
gcs.new_command("listfind=", "i", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_find<CsInt>(
|
||||
cs, args, res, [](const util::ListParser &p, CsInt val) {
|
||||
cs_list_find<cs_int>(
|
||||
cs, args, res, [](const util::ListParser &p, cs_int val) {
|
||||
return cs_parse_int(p.get_raw_item()) == val;
|
||||
}
|
||||
);
|
||||
});
|
||||
gcs.new_command("listfind=f", "f", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_find<CsFloat>(
|
||||
cs, args, res, [](const util::ListParser &p, CsFloat val) {
|
||||
cs_list_find<cs_float>(
|
||||
cs, args, res, [](const util::ListParser &p, cs_float val) {
|
||||
return cs_parse_float(p.get_raw_item()) == val;
|
||||
}
|
||||
);
|
||||
|
@ -262,15 +262,15 @@ void cs_init_lib_list(CsState &gcs) {
|
|||
});
|
||||
|
||||
gcs.new_command("listassoc=", "i", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_assoc<CsInt>(
|
||||
cs, args, res, [](const util::ListParser &p, CsInt val) {
|
||||
cs_list_assoc<cs_int>(
|
||||
cs, args, res, [](const util::ListParser &p, cs_int val) {
|
||||
return cs_parse_int(p.get_raw_item()) == val;
|
||||
}
|
||||
);
|
||||
});
|
||||
gcs.new_command("listassoc=f", "f", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_assoc<CsFloat>(
|
||||
cs, args, res, [](const util::ListParser &p, CsFloat val) {
|
||||
cs_list_assoc<cs_float>(
|
||||
cs, args, res, [](const util::ListParser &p, cs_float val) {
|
||||
return cs_parse_float(p.get_raw_item()) == val;
|
||||
}
|
||||
);
|
||||
|
@ -284,7 +284,7 @@ void cs_init_lib_list(CsState &gcs) {
|
|||
});
|
||||
|
||||
gcs.new_command("looplist", "rse", [](auto &cs, auto args, auto &) {
|
||||
CsStackedValue idv{args[0].get_ident()};
|
||||
cs_stacked_value idv{args[0].get_ident()};
|
||||
if (!idv.has_alias()) {
|
||||
return;
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ end:
|
|||
});
|
||||
|
||||
gcs.new_command("looplist2", "rrse", [](auto &cs, auto args, auto &) {
|
||||
CsStackedValue idv1{args[0].get_ident()}, idv2{args[1].get_ident()};
|
||||
cs_stacked_value idv1{args[0].get_ident()}, idv2{args[1].get_ident()};
|
||||
if (!idv1.has_alias() || !idv2.has_alias()) {
|
||||
return;
|
||||
}
|
||||
|
@ -332,9 +332,9 @@ end:
|
|||
});
|
||||
|
||||
gcs.new_command("looplist3", "rrrse", [](auto &cs, auto args, auto &) {
|
||||
CsStackedValue idv1{args[0].get_ident()};
|
||||
CsStackedValue idv2{args[1].get_ident()};
|
||||
CsStackedValue idv3{args[2].get_ident()};
|
||||
cs_stacked_value idv1{args[0].get_ident()};
|
||||
cs_stacked_value idv2{args[1].get_ident()};
|
||||
cs_stacked_value idv3{args[2].get_ident()};
|
||||
if (!idv1.has_alias() || !idv2.has_alias() || !idv3.has_alias()) {
|
||||
return;
|
||||
}
|
||||
|
@ -383,15 +383,15 @@ end:
|
|||
});
|
||||
|
||||
gcs.new_command("listfilter", "rse", [](auto &cs, auto args, auto &res) {
|
||||
CsStackedValue idv{args[0].get_ident()};
|
||||
cs_stacked_value idv{args[0].get_ident()};
|
||||
if (!idv.has_alias()) {
|
||||
return;
|
||||
}
|
||||
auto body = args[2].get_code();
|
||||
CsString r;
|
||||
cs_string r;
|
||||
int n = 0;
|
||||
for (util::ListParser p(cs, args[1].get_strr()); p.parse(); ++n) {
|
||||
idv.set_str(CsString{p.get_raw_item()});
|
||||
idv.set_str(cs_string{p.get_raw_item()});
|
||||
idv.push();
|
||||
if (cs.run_bool(body)) {
|
||||
if (r.size()) {
|
||||
|
@ -404,14 +404,14 @@ end:
|
|||
});
|
||||
|
||||
gcs.new_command("listcount", "rse", [](auto &cs, auto args, auto &res) {
|
||||
CsStackedValue idv{args[0].get_ident()};
|
||||
cs_stacked_value idv{args[0].get_ident()};
|
||||
if (!idv.has_alias()) {
|
||||
return;
|
||||
}
|
||||
auto body = args[2].get_code();
|
||||
int n = 0, r = 0;
|
||||
for (util::ListParser p(cs, args[1].get_strr()); p.parse(); ++n) {
|
||||
idv.set_str(CsString{p.get_raw_item()});
|
||||
idv.set_str(cs_string{p.get_raw_item()});
|
||||
idv.push();
|
||||
if (cs.run_bool(body)) {
|
||||
r++;
|
||||
|
@ -421,7 +421,7 @@ end:
|
|||
});
|
||||
|
||||
gcs.new_command("prettylist", "ss", [](auto &cs, auto args, auto &res) {
|
||||
auto buf = ostd::appender<CsString>();
|
||||
auto buf = ostd::appender<cs_string>();
|
||||
ostd::ConstCharRange s = args[0].get_strr();
|
||||
ostd::ConstCharRange conj = args[1].get_strr();
|
||||
size_t len = util::ListParser(cs, s).count();
|
||||
|
@ -464,20 +464,20 @@ end:
|
|||
});
|
||||
|
||||
gcs.new_command("listsplice", "ssii", [](auto &cs, auto args, auto &res) {
|
||||
CsInt offset = ostd::max(args[2].get_int(), CsInt(0));
|
||||
CsInt len = ostd::max(args[3].get_int(), CsInt(0));
|
||||
cs_int offset = ostd::max(args[2].get_int(), cs_int(0));
|
||||
cs_int len = ostd::max(args[3].get_int(), cs_int(0));
|
||||
ostd::ConstCharRange s = args[0].get_strr();
|
||||
ostd::ConstCharRange vals = args[1].get_strr();
|
||||
char const *list = s.data();
|
||||
util::ListParser p(cs, s);
|
||||
for (CsInt i = 0; i < offset; ++i) {
|
||||
for (cs_int i = 0; i < offset; ++i) {
|
||||
if (!p.parse()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ostd::ConstCharRange quote = p.get_raw_item(true);
|
||||
char const *qend = !quote.empty() ? "e[quote.size()] : list;
|
||||
CsString buf;
|
||||
cs_string buf;
|
||||
if (qend > list) {
|
||||
buf += ostd::ConstCharRange(list, qend);
|
||||
}
|
||||
|
@ -487,7 +487,7 @@ end:
|
|||
}
|
||||
buf += vals;
|
||||
}
|
||||
for (CsInt i = 0; i < len; ++i) {
|
||||
for (cs_int i = 0; i < len; ++i) {
|
||||
if (!p.parse()) {
|
||||
break;
|
||||
}
|
||||
|
@ -518,9 +518,9 @@ struct ListSortItem {
|
|||
};
|
||||
|
||||
struct ListSortFun {
|
||||
CsState &cs;
|
||||
CsStackedValue &xv, &yv;
|
||||
CsBytecode *body;
|
||||
cs_state &cs;
|
||||
cs_stacked_value &xv, &yv;
|
||||
cs_bcode *body;
|
||||
|
||||
bool operator()(ListSortItem const &xval, ListSortItem const &yval) {
|
||||
xv.set_cstr(xval.str);
|
||||
|
@ -532,14 +532,14 @@ struct ListSortFun {
|
|||
};
|
||||
|
||||
static void cs_list_sort(
|
||||
CsState &cs, CsValue &res, ostd::ConstCharRange list,
|
||||
CsIdent *x, CsIdent *y, CsBytecode *body, CsBytecode *unique
|
||||
cs_state &cs, cs_value &res, ostd::ConstCharRange list,
|
||||
cs_ident *x, cs_ident *y, cs_bcode *body, cs_bcode *unique
|
||||
) {
|
||||
if (x == y || !x->is_alias() || !y->is_alias()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CsAlias *xa = static_cast<CsAlias *>(x), *ya = static_cast<CsAlias *>(y);
|
||||
cs_alias *xa = static_cast<cs_alias *>(x), *ya = static_cast<cs_alias *>(y);
|
||||
|
||||
CsVector<ListSortItem> items;
|
||||
size_t total = 0;
|
||||
|
@ -551,11 +551,11 @@ static void cs_list_sort(
|
|||
}
|
||||
|
||||
if (items.empty()) {
|
||||
res.set_str(CsString{list});
|
||||
res.set_str(cs_string{list});
|
||||
return;
|
||||
}
|
||||
|
||||
CsStackedValue xval{xa}, yval{ya};
|
||||
cs_stacked_value xval{xa}, yval{ya};
|
||||
xval.set_null();
|
||||
yval.set_null();
|
||||
xval.push();
|
||||
|
@ -603,7 +603,7 @@ static void cs_list_sort(
|
|||
xval.pop();
|
||||
yval.pop();
|
||||
|
||||
CsString sorted;
|
||||
cs_string sorted;
|
||||
sorted.reserve(totaluniq + ostd::max(nuniq - 1, size_t(0)));
|
||||
for (size_t i = 0; i < items.size(); ++i) {
|
||||
ListSortItem &item = items[i];
|
||||
|
@ -618,7 +618,7 @@ static void cs_list_sort(
|
|||
res.set_str(std::move(sorted));
|
||||
}
|
||||
|
||||
static void cs_init_lib_list_sort(CsState &gcs) {
|
||||
static void cs_init_lib_list_sort(cs_state &gcs) {
|
||||
gcs.new_command("sortlist", "srree", [](auto &cs, auto args, auto &res) {
|
||||
cs_list_sort(
|
||||
cs, res, args[0].get_strr(), args[1].get_ident(),
|
||||
|
|
164
src/lib_math.cc
164
src/lib_math.cc
|
@ -8,28 +8,28 @@
|
|||
|
||||
namespace cscript {
|
||||
|
||||
static constexpr CsFloat PI = 3.14159265358979f;
|
||||
static constexpr CsFloat RAD = PI / 180.0f;
|
||||
static constexpr cs_float PI = 3.14159265358979f;
|
||||
static constexpr cs_float RAD = PI / 180.0f;
|
||||
|
||||
template<typename T>
|
||||
struct CsMathVal;
|
||||
|
||||
template<>
|
||||
struct CsMathVal<CsInt> {
|
||||
static CsInt get(CsValue &tv) {
|
||||
struct CsMathVal<cs_int> {
|
||||
static cs_int get(cs_value &tv) {
|
||||
return tv.get_int();
|
||||
}
|
||||
static void set(CsValue &res, CsInt val) {
|
||||
static void set(cs_value &res, cs_int val) {
|
||||
res.set_int(val);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct CsMathVal<CsFloat> {
|
||||
static CsFloat get(CsValue &tv) {
|
||||
struct CsMathVal<cs_float> {
|
||||
static cs_float get(cs_value &tv) {
|
||||
return tv.get_float();
|
||||
}
|
||||
static void set(CsValue &res, CsFloat val) {
|
||||
static void set(cs_value &res, cs_float val) {
|
||||
res.set_float(val);
|
||||
}
|
||||
};
|
||||
|
@ -43,7 +43,7 @@ struct CsMathNoop {
|
|||
|
||||
template<typename T, typename F1, typename F2>
|
||||
static inline void cs_mathop(
|
||||
CsValueRange args, CsValue &res, T initval,
|
||||
cs_value_r args, cs_value &res, T initval,
|
||||
F1 binop, F2 unop
|
||||
) {
|
||||
T val;
|
||||
|
@ -59,7 +59,7 @@ static inline void cs_mathop(
|
|||
}
|
||||
|
||||
template<typename T, typename F>
|
||||
static inline void cs_cmpop(CsValueRange args, CsValue &res, F cmp) {
|
||||
static inline void cs_cmpop(cs_value_r args, cs_value &res, F cmp) {
|
||||
bool val;
|
||||
if (args.size() >= 2) {
|
||||
val = cmp(CsMathVal<T>::get(args[0]), CsMathVal<T>::get(args[1]));
|
||||
|
@ -69,10 +69,10 @@ static inline void cs_cmpop(CsValueRange args, CsValue &res, F cmp) {
|
|||
} else {
|
||||
val = cmp(!args.empty() ? CsMathVal<T>::get(args[0]) : T(0), T(0));
|
||||
}
|
||||
res.set_int(CsInt(val));
|
||||
res.set_int(cs_int(val));
|
||||
}
|
||||
|
||||
void cs_init_lib_math(CsState &cs) {
|
||||
void cs_init_lib_math(cs_state &cs) {
|
||||
cs.new_command("sin", "f", [](auto &, auto args, auto &res) {
|
||||
res.set_float(std::sin(args[0].get_float() * RAD));
|
||||
});
|
||||
|
@ -114,28 +114,28 @@ void cs_init_lib_math(CsState &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("min", "i1V", [](auto &, auto args, auto &res) {
|
||||
CsInt v = (!args.empty() ? args[0].get_int() : 0);
|
||||
cs_int v = (!args.empty() ? args[0].get_int() : 0);
|
||||
for (size_t i = 1; i < args.size(); ++i) {
|
||||
v = std::min(v, args[i].get_int());
|
||||
}
|
||||
res.set_int(v);
|
||||
});
|
||||
cs.new_command("max", "i1V", [](auto &, auto args, auto &res) {
|
||||
CsInt v = (!args.empty() ? args[0].get_int() : 0);
|
||||
cs_int v = (!args.empty() ? args[0].get_int() : 0);
|
||||
for (size_t i = 1; i < args.size(); ++i) {
|
||||
v = std::max(v, args[i].get_int());
|
||||
}
|
||||
res.set_int(v);
|
||||
});
|
||||
cs.new_command("minf", "f1V", [](auto &, auto args, auto &res) {
|
||||
CsFloat v = (!args.empty() ? args[0].get_float() : 0);
|
||||
cs_float v = (!args.empty() ? args[0].get_float() : 0);
|
||||
for (size_t i = 1; i < args.size(); ++i) {
|
||||
v = std::min(v, args[i].get_float());
|
||||
}
|
||||
res.set_float(v);
|
||||
});
|
||||
cs.new_command("maxf", "f1V", [](auto &, auto args, auto &res) {
|
||||
CsFloat v = (!args.empty() ? args[0].get_float() : 0);
|
||||
cs_float v = (!args.empty() ? args[0].get_float() : 0);
|
||||
for (size_t i = 1; i < args.size(); ++i) {
|
||||
v = std::max(v, args[i].get_float());
|
||||
}
|
||||
|
@ -157,8 +157,8 @@ void cs_init_lib_math(CsState &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("round", "ff", [](auto &, auto args, auto &res) {
|
||||
CsFloat step = args[1].get_float();
|
||||
CsFloat r = args[0].get_float();
|
||||
cs_float step = args[1].get_float();
|
||||
cs_float r = args[0].get_float();
|
||||
if (step > 0) {
|
||||
r += step * ((r < 0) ? -0.5 : 0.5);
|
||||
r -= std::fmod(r, step);
|
||||
|
@ -169,43 +169,43 @@ void cs_init_lib_math(CsState &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("+", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(args, res, 0, std::plus<CsInt>(), CsMathNoop<CsInt>());
|
||||
cs_mathop<cs_int>(args, res, 0, std::plus<cs_int>(), CsMathNoop<cs_int>());
|
||||
});
|
||||
cs.new_command("*", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 1, std::multiplies<CsInt>(), CsMathNoop<CsInt>()
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 1, std::multiplies<cs_int>(), CsMathNoop<cs_int>()
|
||||
);
|
||||
});
|
||||
cs.new_command("-", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 0, std::minus<CsInt>(), std::negate<CsInt>()
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 0, std::minus<cs_int>(), std::negate<cs_int>()
|
||||
);
|
||||
});
|
||||
|
||||
cs.new_command("^", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 0, std::bit_xor<CsInt>(), [](CsInt val) { return ~val; }
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 0, std::bit_xor<cs_int>(), [](cs_int val) { return ~val; }
|
||||
);
|
||||
});
|
||||
cs.new_command("~", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 0, std::bit_xor<CsInt>(), [](CsInt val) { return ~val; }
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 0, std::bit_xor<cs_int>(), [](cs_int val) { return ~val; }
|
||||
);
|
||||
});
|
||||
cs.new_command("&", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 0, std::bit_and<CsInt>(), CsMathNoop<CsInt>()
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 0, std::bit_and<cs_int>(), CsMathNoop<cs_int>()
|
||||
);
|
||||
});
|
||||
cs.new_command("|", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 0, std::bit_or<CsInt>(), CsMathNoop<CsInt>()
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 0, std::bit_or<cs_int>(), CsMathNoop<cs_int>()
|
||||
);
|
||||
});
|
||||
|
||||
/* special combined cases */
|
||||
cs.new_command("^~", "i1V", [](auto &, auto args, auto &res) {
|
||||
CsInt val;
|
||||
cs_int val;
|
||||
if (args.size() >= 2) {
|
||||
val = args[0].get_int() ^ ~args[1].get_int();
|
||||
for (size_t i = 2; i < args.size(); ++i) {
|
||||
|
@ -217,7 +217,7 @@ void cs_init_lib_math(CsState &cs) {
|
|||
res.set_int(val);
|
||||
});
|
||||
cs.new_command("&~", "i1V", [](auto &, auto args, auto &res) {
|
||||
CsInt val;
|
||||
cs_int val;
|
||||
if (args.size() >= 2) {
|
||||
val = args[0].get_int() & ~args[1].get_int();
|
||||
for (size_t i = 2; i < args.size(); ++i) {
|
||||
|
@ -229,7 +229,7 @@ void cs_init_lib_math(CsState &cs) {
|
|||
res.set_int(val);
|
||||
});
|
||||
cs.new_command("|~", "i1V", [](auto &, auto args, auto &res) {
|
||||
CsInt val;
|
||||
cs_int val;
|
||||
if (args.size() >= 2) {
|
||||
val = args[0].get_int() | ~args[1].get_int();
|
||||
for (size_t i = 2; i < args.size(); ++i) {
|
||||
|
@ -242,125 +242,125 @@ void cs_init_lib_math(CsState &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("<<", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 0, [](CsInt val1, CsInt val2) {
|
||||
return (val2 < CsInt(sizeof(CsInt) * CHAR_BIT))
|
||||
? (val1 << std::max(val2, CsInt(0)))
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 0, [](cs_int val1, cs_int val2) {
|
||||
return (val2 < cs_int(sizeof(cs_int) * CHAR_BIT))
|
||||
? (val1 << std::max(val2, cs_int(0)))
|
||||
: 0;
|
||||
}, CsMathNoop<CsInt>()
|
||||
}, CsMathNoop<cs_int>()
|
||||
);
|
||||
});
|
||||
cs.new_command(">>", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 0, [](CsInt val1, CsInt val2) {
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 0, [](cs_int val1, cs_int val2) {
|
||||
return val1 >> std::clamp(
|
||||
val2, CsInt(0), CsInt(sizeof(CsInt) * CHAR_BIT)
|
||||
val2, cs_int(0), cs_int(sizeof(cs_int) * CHAR_BIT)
|
||||
);
|
||||
}, CsMathNoop<CsInt>()
|
||||
}, CsMathNoop<cs_int>()
|
||||
);
|
||||
});
|
||||
|
||||
cs.new_command("+f", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsFloat>(
|
||||
args, res, 0, std::plus<CsFloat>(), CsMathNoop<CsFloat>()
|
||||
cs_mathop<cs_float>(
|
||||
args, res, 0, std::plus<cs_float>(), CsMathNoop<cs_float>()
|
||||
);
|
||||
});
|
||||
cs.new_command("*f", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsFloat>(
|
||||
args, res, 1, std::multiplies<CsFloat>(), CsMathNoop<CsFloat>()
|
||||
cs_mathop<cs_float>(
|
||||
args, res, 1, std::multiplies<cs_float>(), CsMathNoop<cs_float>()
|
||||
);
|
||||
});
|
||||
cs.new_command("-f", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsFloat>(
|
||||
args, res, 0, std::minus<CsFloat>(), std::negate<CsFloat>()
|
||||
cs_mathop<cs_float>(
|
||||
args, res, 0, std::minus<cs_float>(), std::negate<cs_float>()
|
||||
);
|
||||
});
|
||||
|
||||
cs.new_command("div", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 0, [](CsInt val1, CsInt val2) {
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 0, [](cs_int val1, cs_int val2) {
|
||||
if (val2) {
|
||||
return val1 / val2;
|
||||
}
|
||||
return CsInt(0);
|
||||
}, CsMathNoop<CsInt>()
|
||||
return cs_int(0);
|
||||
}, CsMathNoop<cs_int>()
|
||||
);
|
||||
});
|
||||
cs.new_command("mod", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsInt>(
|
||||
args, res, 0, [](CsInt val1, CsInt val2) {
|
||||
cs_mathop<cs_int>(
|
||||
args, res, 0, [](cs_int val1, cs_int val2) {
|
||||
if (val2) {
|
||||
return val1 % val2;
|
||||
}
|
||||
return CsInt(0);
|
||||
}, CsMathNoop<CsInt>()
|
||||
return cs_int(0);
|
||||
}, CsMathNoop<cs_int>()
|
||||
);
|
||||
});
|
||||
cs.new_command("divf", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsFloat>(
|
||||
args, res, 0, [](CsFloat val1, CsFloat val2) {
|
||||
cs_mathop<cs_float>(
|
||||
args, res, 0, [](cs_float val1, cs_float val2) {
|
||||
if (val2) {
|
||||
return val1 / val2;
|
||||
}
|
||||
return CsFloat(0);
|
||||
}, CsMathNoop<CsFloat>()
|
||||
return cs_float(0);
|
||||
}, CsMathNoop<cs_float>()
|
||||
);
|
||||
});
|
||||
cs.new_command("modf", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsFloat>(
|
||||
args, res, 0, [](CsFloat val1, CsFloat val2) {
|
||||
cs_mathop<cs_float>(
|
||||
args, res, 0, [](cs_float val1, cs_float val2) {
|
||||
if (val2) {
|
||||
return CsFloat(fmod(val1, val2));
|
||||
return cs_float(fmod(val1, val2));
|
||||
}
|
||||
return CsFloat(0);
|
||||
}, CsMathNoop<CsFloat>()
|
||||
return cs_float(0);
|
||||
}, CsMathNoop<cs_float>()
|
||||
);
|
||||
});
|
||||
|
||||
cs.new_command("pow", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_mathop<CsFloat>(
|
||||
args, res, 0, [](CsFloat val1, CsFloat val2) {
|
||||
return CsFloat(pow(val1, val2));
|
||||
}, CsMathNoop<CsFloat>()
|
||||
cs_mathop<cs_float>(
|
||||
args, res, 0, [](cs_float val1, cs_float val2) {
|
||||
return cs_float(pow(val1, val2));
|
||||
}, CsMathNoop<cs_float>()
|
||||
);
|
||||
});
|
||||
|
||||
cs.new_command("=", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsInt>(args, res, std::equal_to<CsInt>());
|
||||
cs_cmpop<cs_int>(args, res, std::equal_to<cs_int>());
|
||||
});
|
||||
cs.new_command("!=", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsInt>(args, res, std::not_equal_to<CsInt>());
|
||||
cs_cmpop<cs_int>(args, res, std::not_equal_to<cs_int>());
|
||||
});
|
||||
cs.new_command("<", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsInt>(args, res, std::less<CsInt>());
|
||||
cs_cmpop<cs_int>(args, res, std::less<cs_int>());
|
||||
});
|
||||
cs.new_command(">", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsInt>(args, res, std::greater<CsInt>());
|
||||
cs_cmpop<cs_int>(args, res, std::greater<cs_int>());
|
||||
});
|
||||
cs.new_command("<=", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsInt>(args, res, std::less_equal<CsInt>());
|
||||
cs_cmpop<cs_int>(args, res, std::less_equal<cs_int>());
|
||||
});
|
||||
cs.new_command(">=", "i1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsInt>(args, res, std::greater_equal<CsInt>());
|
||||
cs_cmpop<cs_int>(args, res, std::greater_equal<cs_int>());
|
||||
});
|
||||
|
||||
cs.new_command("=f", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsFloat>(args, res, std::equal_to<CsFloat>());
|
||||
cs_cmpop<cs_float>(args, res, std::equal_to<cs_float>());
|
||||
});
|
||||
cs.new_command("!=f", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsFloat>(args, res, std::not_equal_to<CsFloat>());
|
||||
cs_cmpop<cs_float>(args, res, std::not_equal_to<cs_float>());
|
||||
});
|
||||
cs.new_command("<f", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsFloat>(args, res, std::less<CsFloat>());
|
||||
cs_cmpop<cs_float>(args, res, std::less<cs_float>());
|
||||
});
|
||||
cs.new_command(">f", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsFloat>(args, res, std::greater<CsFloat>());
|
||||
cs_cmpop<cs_float>(args, res, std::greater<cs_float>());
|
||||
});
|
||||
cs.new_command("<=f", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsFloat>(args, res, std::less_equal<CsFloat>());
|
||||
cs_cmpop<cs_float>(args, res, std::less_equal<cs_float>());
|
||||
});
|
||||
cs.new_command(">=f", "f1V", [](auto &, auto args, auto &res) {
|
||||
cs_cmpop<CsFloat>(args, res, std::greater_equal<CsFloat>());
|
||||
cs_cmpop<cs_float>(args, res, std::greater_equal<cs_float>());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
namespace cscript {
|
||||
|
||||
template<typename F>
|
||||
static inline void cs_strgcmp(CsValueRange args, CsValue &res, F cfunc) {
|
||||
static inline void cs_strgcmp(cs_value_r args, cs_value &res, F cfunc) {
|
||||
bool val;
|
||||
if (args.size() >= 2) {
|
||||
val = cfunc(args[0].get_strr(), args[1].get_strr());
|
||||
|
@ -18,14 +18,14 @@ static inline void cs_strgcmp(CsValueRange args, CsValue &res, F cfunc) {
|
|||
ostd::ConstCharRange()
|
||||
);
|
||||
}
|
||||
res.set_int(CsInt(val));
|
||||
res.set_int(cs_int(val));
|
||||
};
|
||||
|
||||
void cs_init_lib_string(CsState &cs) {
|
||||
void cs_init_lib_string(cs_state &cs) {
|
||||
cs.new_command("strstr", "ss", [](auto &, auto args, auto &res) {
|
||||
ostd::ConstCharRange a = args[0].get_strr(), b = args[1].get_strr();
|
||||
ostd::ConstCharRange s = a;
|
||||
for (CsInt i = 0; b.size() <= s.size(); ++i) {
|
||||
for (cs_int i = 0; b.size() <= s.size(); ++i) {
|
||||
if (b == s.slice(0, b.size())) {
|
||||
res.set_int(i);
|
||||
return;
|
||||
|
@ -36,13 +36,13 @@ void cs_init_lib_string(CsState &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("strlen", "s", [](auto &, auto args, auto &res) {
|
||||
res.set_int(CsInt(args[0].get_strr().size()));
|
||||
res.set_int(cs_int(args[0].get_strr().size()));
|
||||
});
|
||||
|
||||
cs.new_command("strcode", "si", [](auto &, auto args, auto &res) {
|
||||
ostd::ConstCharRange str = args[0].get_strr();
|
||||
CsInt i = args[1].get_int();
|
||||
if (i >= CsInt(str.size())) {
|
||||
cs_int i = args[1].get_int();
|
||||
if (i >= cs_int(str.size())) {
|
||||
res.set_int(0);
|
||||
} else {
|
||||
res.set_int(ostd::byte(str[i]));
|
||||
|
@ -50,11 +50,11 @@ void cs_init_lib_string(CsState &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("codestr", "i", [](auto &, auto args, auto &res) {
|
||||
res.set_str(CsString(1, char(args[0].get_int())));
|
||||
res.set_str(cs_string(1, char(args[0].get_int())));
|
||||
});
|
||||
|
||||
cs.new_command("strlower", "s", [](auto &, auto args, auto &res) {
|
||||
CsString s = args[0].get_str();
|
||||
cs_string s = args[0].get_str();
|
||||
for (auto i: ostd::range(s.size())) {
|
||||
s[i] = tolower(s[i]);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ void cs_init_lib_string(CsState &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("strupper", "s", [](auto &, auto args, auto &res) {
|
||||
CsString s = args[0].get_str();
|
||||
cs_string s = args[0].get_str();
|
||||
for (auto i: ostd::range(s.size())) {
|
||||
s[i] = toupper(s[i]);
|
||||
}
|
||||
|
@ -70,25 +70,25 @@ void cs_init_lib_string(CsState &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("escape", "s", [](auto &, auto args, auto &res) {
|
||||
auto s = ostd::appender<CsString>();
|
||||
auto s = ostd::appender<cs_string>();
|
||||
util::escape_string(s, args[0].get_strr());
|
||||
res.set_str(std::move(s.get()));
|
||||
});
|
||||
|
||||
cs.new_command("unescape", "s", [](auto &, auto args, auto &res) {
|
||||
auto s = ostd::appender<CsString>();
|
||||
auto s = ostd::appender<cs_string>();
|
||||
util::unescape_string(s, args[0].get_strr());
|
||||
res.set_str(std::move(s.get()));
|
||||
});
|
||||
|
||||
cs.new_command("concat", "V", [](auto &, auto args, auto &res) {
|
||||
auto s = ostd::appender<CsString>();
|
||||
auto s = ostd::appender<cs_string>();
|
||||
cscript::util::tvals_concat(s, args, " ");
|
||||
res.set_str(std::move(s.get()));
|
||||
});
|
||||
|
||||
cs.new_command("concatword", "V", [](auto &, auto args, auto &res) {
|
||||
auto s = ostd::appender<CsString>();
|
||||
auto s = ostd::appender<cs_string>();
|
||||
cscript::util::tvals_concat(s, args);
|
||||
res.set_str(std::move(s.get()));
|
||||
});
|
||||
|
@ -97,8 +97,8 @@ void cs_init_lib_string(CsState &cs) {
|
|||
if (args.empty()) {
|
||||
return;
|
||||
}
|
||||
CsString s;
|
||||
CsString fs = args[0].get_str();
|
||||
cs_string s;
|
||||
cs_string fs = args[0].get_str();
|
||||
ostd::ConstCharRange f = ostd::iter(fs);
|
||||
while (!f.empty()) {
|
||||
char c = *f;
|
||||
|
@ -122,10 +122,10 @@ void cs_init_lib_string(CsState &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("tohex", "ii", [](auto &, auto args, auto &res) {
|
||||
auto r = ostd::appender<CsString>();
|
||||
auto r = ostd::appender<cs_string>();
|
||||
try {
|
||||
ostd::format(
|
||||
r, "0x%.*X", ostd::max(args[1].get_int(), CsInt(1)),
|
||||
r, "0x%.*X", ostd::max(args[1].get_int(), cs_int(1)),
|
||||
args[0].get_int()
|
||||
);
|
||||
} catch (ostd::format_error const &e) {
|
||||
|
@ -136,13 +136,13 @@ void cs_init_lib_string(CsState &cs) {
|
|||
|
||||
cs.new_command("substr", "siiN", [](auto &, auto args, auto &res) {
|
||||
ostd::ConstCharRange s = args[0].get_strr();
|
||||
CsInt start = args[1].get_int(), count = args[2].get_int();
|
||||
CsInt numargs = args[3].get_int();
|
||||
CsInt len = CsInt(s.size()), offset = ostd::clamp(start, CsInt(0), len);
|
||||
res.set_str(CsString{
|
||||
cs_int start = args[1].get_int(), count = args[2].get_int();
|
||||
cs_int numargs = args[3].get_int();
|
||||
cs_int len = cs_int(s.size()), offset = ostd::clamp(start, cs_int(0), len);
|
||||
res.set_str(cs_string{
|
||||
&s[offset],
|
||||
(numargs >= 3)
|
||||
? size_t(ostd::clamp(count, CsInt(0), len - offset))
|
||||
? size_t(ostd::clamp(count, cs_int(0), len - offset))
|
||||
: size_t(len - offset)
|
||||
});
|
||||
});
|
||||
|
@ -177,9 +177,9 @@ void cs_init_lib_string(CsState &cs) {
|
|||
if (newval2.empty()) {
|
||||
newval2 = newval;
|
||||
}
|
||||
CsString buf;
|
||||
cs_string buf;
|
||||
if (!oldval.size()) {
|
||||
res.set_str(CsString{s});
|
||||
res.set_str(cs_string{s});
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0;; ++i) {
|
||||
|
@ -206,11 +206,11 @@ void cs_init_lib_string(CsState &cs) {
|
|||
cs.new_command("strsplice", "ssii", [](auto &, auto args, auto &res) {
|
||||
ostd::ConstCharRange s = args[0].get_strr();
|
||||
ostd::ConstCharRange vals = args[1].get_strr();
|
||||
CsInt skip = args[2].get_int(),
|
||||
cs_int skip = args[2].get_int(),
|
||||
count = args[3].get_int();
|
||||
CsInt offset = ostd::clamp(skip, CsInt(0), CsInt(s.size())),
|
||||
len = ostd::clamp(count, CsInt(0), CsInt(s.size()) - offset);
|
||||
CsString p;
|
||||
cs_int offset = ostd::clamp(skip, cs_int(0), cs_int(s.size())),
|
||||
len = ostd::clamp(count, cs_int(0), cs_int(s.size()) - offset);
|
||||
cs_string p;
|
||||
p.reserve(s.size() - len + vals.size());
|
||||
if (offset) {
|
||||
p += s.slice(0, offset);
|
||||
|
@ -218,7 +218,7 @@ void cs_init_lib_string(CsState &cs) {
|
|||
if (!vals.empty()) {
|
||||
p += vals;
|
||||
}
|
||||
if ((offset + len) < CsInt(s.size())) {
|
||||
if ((offset + len) < cs_int(s.size())) {
|
||||
p += s.slice(offset + len, s.size());
|
||||
}
|
||||
res.set_str(std::move(p));
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
#include <ostd/string.hh>
|
||||
|
||||
static void init_lineedit(CsState &, ostd::ConstCharRange) {
|
||||
static void init_lineedit(cs_state &, ostd::ConstCharRange) {
|
||||
}
|
||||
|
||||
static std::optional<std::string> read_line(CsState &, CsSvar *pr) {
|
||||
static std::optional<std::string> read_line(cs_state &, cs_svar *pr) {
|
||||
ostd::write(pr->get_value());
|
||||
std::string ret;
|
||||
/* i really need to implement some sort of get_line for ostd streams */
|
||||
|
@ -18,7 +18,7 @@ static std::optional<std::string> read_line(CsState &, CsSvar *pr) {
|
|||
return std::move(ret);
|
||||
}
|
||||
|
||||
static void add_history(CsState &, ostd::ConstCharRange) {
|
||||
static void add_history(cs_state &, ostd::ConstCharRange) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "linenoise.hh"
|
||||
|
||||
static CsState *ln_cs = nullptr;
|
||||
static cs_state *ln_cs = nullptr;
|
||||
|
||||
static void ln_complete(char const *buf, linenoiseCompletions *lc) {
|
||||
ostd::ConstCharRange cmd = get_complete_cmd(buf);
|
||||
|
@ -33,7 +33,7 @@ static void ln_complete(char const *buf, linenoiseCompletions *lc) {
|
|||
}
|
||||
|
||||
static char *ln_hint(char const *buf, int *color, int *bold) {
|
||||
CsCommand *cmd = get_hint_cmd(*ln_cs, buf);
|
||||
cs_command *cmd = get_hint_cmd(*ln_cs, buf);
|
||||
if (!cmd) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ static void ln_hint_free(void *hint) {
|
|||
delete[] static_cast<char *>(hint);
|
||||
}
|
||||
|
||||
static void init_lineedit(CsState &cs, ostd::ConstCharRange) {
|
||||
static void init_lineedit(cs_state &cs, ostd::ConstCharRange) {
|
||||
/* sensible default history size */
|
||||
linenoiseHistorySetMaxLen(1000);
|
||||
ln_cs = &cs;
|
||||
|
@ -60,7 +60,7 @@ static void init_lineedit(CsState &cs, ostd::ConstCharRange) {
|
|||
linenoiseSetFreeHintsCallback(ln_hint_free);
|
||||
}
|
||||
|
||||
static std::optional<std::string> read_line(CsState &, CsSvar *pr) {
|
||||
static std::optional<std::string> read_line(cs_state &, cs_svar *pr) {
|
||||
auto line = linenoise(pr->get_value().data());
|
||||
if (!line) {
|
||||
/* linenoise traps ctrl-c, detect it and let the user exit */
|
||||
|
@ -75,7 +75,7 @@ static std::optional<std::string> read_line(CsState &, CsSvar *pr) {
|
|||
return std::move(ret);
|
||||
}
|
||||
|
||||
static void add_history(CsState &, ostd::ConstCharRange line) {
|
||||
static void add_history(cs_state &, ostd::ConstCharRange line) {
|
||||
/* backed by std::string so it's terminated */
|
||||
linenoiseHistoryAdd(line.data());
|
||||
}
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
|
||||
static CsState *rd_cs = nullptr;
|
||||
static cs_state *rd_cs = nullptr;
|
||||
|
||||
static char *ln_complete_list(char const *buf, int state) {
|
||||
static ostd::ConstCharRange cmd;
|
||||
static ostd::PointerRange<CsIdent *> itr;
|
||||
static ostd::PointerRange<cs_ident *> itr;
|
||||
|
||||
if (!state) {
|
||||
cmd = get_complete_cmd(buf);
|
||||
|
@ -24,7 +24,7 @@ static char *ln_complete_list(char const *buf, int state) {
|
|||
}
|
||||
|
||||
for (; !itr.empty(); itr.pop_front()) {
|
||||
CsIdent *id = itr.front();
|
||||
cs_ident *id = itr.front();
|
||||
if (!id->is_command()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ static char **ln_complete(char const *buf, int, int) {
|
|||
}
|
||||
|
||||
void ln_hint() {
|
||||
CsCommand *cmd = get_hint_cmd(*rd_cs, rl_line_buffer);
|
||||
cs_command *cmd = get_hint_cmd(*rd_cs, rl_line_buffer);
|
||||
if (!cmd) {
|
||||
rl_redisplay();
|
||||
return;
|
||||
|
@ -63,13 +63,13 @@ void ln_hint() {
|
|||
rl_replace_line(old.data(), 0);
|
||||
}
|
||||
|
||||
static void init_lineedit(CsState &cs, ostd::ConstCharRange) {
|
||||
static void init_lineedit(cs_state &cs, ostd::ConstCharRange) {
|
||||
rd_cs = &cs;
|
||||
rl_attempted_completion_function = ln_complete;
|
||||
rl_redisplay_function = ln_hint;
|
||||
}
|
||||
|
||||
static std::optional<std::string> read_line(CsState &, CsSvar *pr) {
|
||||
static std::optional<std::string> read_line(cs_state &, cs_svar *pr) {
|
||||
auto line = readline(pr->get_value().data());
|
||||
if (!line) {
|
||||
return std::string();
|
||||
|
@ -79,7 +79,7 @@ static std::optional<std::string> read_line(CsState &, CsSvar *pr) {
|
|||
return std::move(ret);
|
||||
}
|
||||
|
||||
static void add_history(CsState &, ostd::ConstCharRange line) {
|
||||
static void add_history(cs_state &, ostd::ConstCharRange line) {
|
||||
/* backed by std::string so it's terminated */
|
||||
add_history(line.data());
|
||||
}
|
||||
|
|
|
@ -128,11 +128,11 @@ static inline void fill_cmd_args(std::string &writer, ostd::ConstCharRange args)
|
|||
}
|
||||
}
|
||||
|
||||
static inline CsCommand *get_hint_cmd(CsState &cs, ostd::ConstCharRange buf) {
|
||||
static inline cs_command *get_hint_cmd(cs_state &cs, ostd::ConstCharRange buf) {
|
||||
ostd::ConstCharRange nextchars = "([;";
|
||||
auto lp = ostd::find_one_of(buf, nextchars);
|
||||
if (!lp.empty()) {
|
||||
CsCommand *cmd = get_hint_cmd(cs, buf + 1);
|
||||
cs_command *cmd = get_hint_cmd(cs, buf + 1);
|
||||
if (cmd) {
|
||||
return cmd;
|
||||
}
|
||||
|
@ -177,18 +177,18 @@ void print_version() {
|
|||
ostd::writeln(version);
|
||||
}
|
||||
|
||||
static CsState *scs = nullptr;
|
||||
static cs_state *scs = nullptr;
|
||||
static void do_sigint(int n) {
|
||||
/* in case another SIGINT happens, terminate normally */
|
||||
signal(n, SIG_DFL);
|
||||
scs->set_call_hook([](CsState &cs) {
|
||||
scs->set_call_hook([](cs_state &cs) {
|
||||
cs.set_call_hook(nullptr);
|
||||
throw cscript::CsErrorException(cs, "<execution interrupted>");
|
||||
throw cscript::cs_error(cs, "<execution interrupted>");
|
||||
});
|
||||
}
|
||||
|
||||
static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
|
||||
CsValue ret;
|
||||
static bool do_call(cs_state &cs, ostd::ConstCharRange line, bool file = false) {
|
||||
cs_value ret;
|
||||
scs = &cs;
|
||||
signal(SIGINT, do_sigint);
|
||||
try {
|
||||
|
@ -199,7 +199,7 @@ static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
|
|||
} else {
|
||||
cs.run(line, ret);
|
||||
}
|
||||
} catch (cscript::CsErrorException const &e) {
|
||||
} catch (cscript::cs_error const &e) {
|
||||
signal(SIGINT, SIG_DFL);
|
||||
scs = nullptr;
|
||||
ostd::ConstCharRange terr = e.what();
|
||||
|
@ -223,13 +223,13 @@ static bool do_call(CsState &cs, ostd::ConstCharRange line, bool file = false) {
|
|||
}
|
||||
signal(SIGINT, SIG_DFL);
|
||||
scs = nullptr;
|
||||
if (ret.get_type() != CsValueType::Null) {
|
||||
if (ret.get_type() != cs_value_type::Null) {
|
||||
ostd::writeln(ret.get_str());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void do_tty(CsState &cs) {
|
||||
static void do_tty(cs_state &cs) {
|
||||
auto prompt = cs.new_svar("PROMPT", "> ");
|
||||
auto prompt2 = cs.new_svar("PROMPT2", ">> ");
|
||||
|
||||
|
@ -270,14 +270,14 @@ static void do_tty(CsState &cs) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
CsState gcs;
|
||||
cs_state gcs;
|
||||
gcs.init_libs();
|
||||
|
||||
gcs.new_command("exec", "s", [](auto &cs, auto args, auto &) {
|
||||
auto file = args[0].get_strr();
|
||||
bool ret = cs.run_file(file);
|
||||
if (!ret) {
|
||||
throw cscript::CsErrorException(
|
||||
throw cscript::cs_error(
|
||||
cs, "could not run file \"%s\"", file
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue