2016-08-14 16:35:38 +00:00
|
|
|
#ifndef LIBCUBESCRIPT_CUBESCRIPT_HH
|
|
|
|
#define LIBCUBESCRIPT_CUBESCRIPT_HH
|
2015-09-10 17:53:43 +00:00
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
#include "cubescript_conf.hh"
|
|
|
|
|
2016-03-17 21:21:45 +00:00
|
|
|
#include <ostd/platform.hh>
|
2015-08-08 16:13:19 +00:00
|
|
|
#include <ostd/types.hh>
|
2015-08-05 21:58:45 +00:00
|
|
|
#include <ostd/string.hh>
|
2015-08-08 16:13:19 +00:00
|
|
|
#include <ostd/vector.hh>
|
2016-08-17 20:21:16 +00:00
|
|
|
#include <ostd/map.hh>
|
2015-08-08 16:13:19 +00:00
|
|
|
#include <ostd/range.hh>
|
|
|
|
#include <ostd/utility.hh>
|
2015-08-07 01:11:53 +00:00
|
|
|
#include <ostd/maybe.hh>
|
2015-08-08 16:13:19 +00:00
|
|
|
#include <ostd/io.hh>
|
|
|
|
#include <ostd/functional.hh>
|
2016-08-14 15:14:10 +00:00
|
|
|
#include <ostd/format.hh>
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2015-08-08 15:13:46 +00:00
|
|
|
namespace cscript {
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
enum {
|
|
|
|
VAL_NULL = 0, VAL_INT, VAL_FLOAT, VAL_STR,
|
|
|
|
VAL_ANY, VAL_CODE, VAL_MACRO, VAL_IDENT, VAL_CSTR,
|
|
|
|
VAL_CANY, VAL_WORD, VAL_POP, VAL_COND
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
IDF_PERSIST = 1 << 0,
|
|
|
|
IDF_OVERRIDE = 1 << 1,
|
|
|
|
IDF_HEX = 1 << 2,
|
|
|
|
IDF_READONLY = 1 << 3,
|
|
|
|
IDF_OVERRIDDEN = 1 << 4,
|
|
|
|
IDF_UNKNOWN = 1 << 5,
|
2016-08-01 18:05:47 +00:00
|
|
|
IDF_ARG = 1 << 6
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
2016-08-06 18:12:38 +00:00
|
|
|
struct Bytecode;
|
|
|
|
|
2016-08-06 17:38:05 +00:00
|
|
|
struct OSTD_EXPORT BytecodeRef {
|
2016-08-07 20:39:27 +00:00
|
|
|
BytecodeRef():
|
|
|
|
p_code(nullptr)
|
|
|
|
{}
|
2016-08-06 18:12:38 +00:00
|
|
|
BytecodeRef(Bytecode *v);
|
2016-08-06 17:38:05 +00:00
|
|
|
BytecodeRef(BytecodeRef const &v);
|
2016-08-07 20:39:27 +00:00
|
|
|
BytecodeRef(BytecodeRef &&v):
|
|
|
|
p_code(v.p_code)
|
|
|
|
{
|
|
|
|
v.p_code = nullptr;
|
|
|
|
}
|
2015-12-19 23:28:12 +00:00
|
|
|
|
2016-08-06 17:38:05 +00:00
|
|
|
~BytecodeRef();
|
2015-12-24 14:57:19 +00:00
|
|
|
|
2016-08-06 17:38:05 +00:00
|
|
|
BytecodeRef &operator=(BytecodeRef const &v);
|
|
|
|
BytecodeRef &operator=(BytecodeRef &&v);
|
2015-12-19 23:28:12 +00:00
|
|
|
|
|
|
|
operator bool() const { return p_code != nullptr; }
|
2016-08-06 18:12:38 +00:00
|
|
|
operator Bytecode *() const { return p_code; }
|
2015-12-19 23:28:12 +00:00
|
|
|
|
|
|
|
private:
|
2016-08-06 18:12:38 +00:00
|
|
|
Bytecode *p_code;
|
2015-12-19 23:28:12 +00:00
|
|
|
};
|
|
|
|
|
2016-08-06 18:12:38 +00:00
|
|
|
OSTD_EXPORT bool code_is_empty(Bytecode const *code);
|
2016-08-06 16:33:01 +00:00
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
struct Ident;
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
struct OSTD_EXPORT CsValue {
|
2015-08-05 21:58:45 +00:00
|
|
|
union {
|
2016-08-14 16:35:38 +00:00
|
|
|
CsInt i; /* ID_IVAR, VAL_INT */
|
|
|
|
CsFloat f; /* ID_FVAR, VAL_FLOAT */
|
2016-08-06 18:12:38 +00:00
|
|
|
Bytecode const *code; /* VAL_CODE */
|
2015-08-05 21:58:45 +00:00
|
|
|
Ident *id; /* VAL_IDENT */
|
2016-08-01 20:46:50 +00:00
|
|
|
char *s; /* ID_SVAR, VAL_STR */
|
2016-07-17 17:50:40 +00:00
|
|
|
char const *cstr; /* VAL_CSTR */
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
2016-08-01 20:46:50 +00:00
|
|
|
ostd::Size len;
|
2015-08-13 21:23:46 +00:00
|
|
|
|
2015-08-13 20:48:03 +00:00
|
|
|
int get_type() const {
|
2016-08-01 20:35:42 +00:00
|
|
|
return p_type;
|
2015-08-13 20:48:03 +00:00
|
|
|
}
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
void set_int(CsInt val) {
|
2015-08-13 20:48:03 +00:00
|
|
|
p_type = VAL_INT;
|
2015-08-05 21:58:45 +00:00
|
|
|
i = val;
|
|
|
|
}
|
2016-08-14 16:35:38 +00:00
|
|
|
void set_float(CsFloat val) {
|
2015-08-13 20:48:03 +00:00
|
|
|
p_type = VAL_FLOAT;
|
2015-08-05 21:58:45 +00:00
|
|
|
f = val;
|
|
|
|
}
|
2016-07-13 17:46:35 +00:00
|
|
|
void set_str(ostd::String val) {
|
2016-08-17 23:53:14 +00:00
|
|
|
if (val.size() == 0) {
|
|
|
|
/* ostd zero length strings cannot be disowned */
|
|
|
|
char *buf = new char[1];
|
|
|
|
buf[0] = '\0';
|
|
|
|
set_mstr(buf);
|
|
|
|
return;
|
|
|
|
}
|
2016-07-13 17:46:35 +00:00
|
|
|
ostd::CharRange cr = val.iter();
|
|
|
|
val.disown();
|
|
|
|
set_mstr(cr);
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
void set_null() {
|
2015-08-13 20:48:03 +00:00
|
|
|
p_type = VAL_NULL;
|
2015-08-05 21:58:45 +00:00
|
|
|
i = 0;
|
|
|
|
}
|
2016-08-06 18:12:38 +00:00
|
|
|
void set_code(Bytecode const *val) {
|
2015-08-13 20:48:03 +00:00
|
|
|
p_type = VAL_CODE;
|
2015-08-05 21:58:45 +00:00
|
|
|
code = val;
|
|
|
|
}
|
2015-08-13 21:46:03 +00:00
|
|
|
void set_cstr(ostd::ConstCharRange val) {
|
2016-08-01 20:35:42 +00:00
|
|
|
p_type = VAL_CSTR;
|
2016-08-01 20:46:50 +00:00
|
|
|
len = val.size();
|
2015-08-13 21:46:03 +00:00
|
|
|
cstr = val.data();
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
2016-07-13 17:46:35 +00:00
|
|
|
void set_mstr(ostd::CharRange val) {
|
2016-08-01 20:35:42 +00:00
|
|
|
p_type = VAL_STR;
|
2016-08-01 20:46:50 +00:00
|
|
|
len = val.size();
|
2016-07-13 17:46:35 +00:00
|
|
|
s = val.data();
|
|
|
|
}
|
2015-08-05 21:58:45 +00:00
|
|
|
void set_ident(Ident *val) {
|
2015-08-13 20:48:03 +00:00
|
|
|
p_type = VAL_IDENT;
|
2015-08-05 21:58:45 +00:00
|
|
|
id = val;
|
|
|
|
}
|
2016-08-12 17:14:07 +00:00
|
|
|
void set_macro(Bytecode const *val, ostd::Size ln) {
|
|
|
|
p_type = VAL_MACRO;
|
|
|
|
len = ln;
|
|
|
|
code = val;
|
|
|
|
}
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void set(CsValue &tv) {
|
2015-08-08 00:40:29 +00:00
|
|
|
*this = tv;
|
2015-08-13 20:48:03 +00:00
|
|
|
tv.p_type = VAL_NULL;
|
2015-08-08 00:40:29 +00:00
|
|
|
}
|
|
|
|
|
2016-07-13 18:24:26 +00:00
|
|
|
ostd::String get_str() const;
|
2016-07-30 23:49:32 +00:00
|
|
|
ostd::ConstCharRange get_strr() const;
|
2016-08-14 16:35:38 +00:00
|
|
|
CsInt get_int() const;
|
|
|
|
CsFloat get_float() const;
|
2016-08-06 18:12:38 +00:00
|
|
|
Bytecode *get_code() const;
|
2016-08-01 20:35:42 +00:00
|
|
|
Ident *get_ident() const;
|
2016-08-18 18:38:30 +00:00
|
|
|
void get_val(CsValue &r) const;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-08-02 00:21:36 +00:00
|
|
|
bool get_bool() const;
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
void force_null();
|
2016-08-14 16:35:38 +00:00
|
|
|
CsFloat force_float();
|
|
|
|
CsInt force_int();
|
2015-08-11 21:47:25 +00:00
|
|
|
ostd::ConstCharRange force_str();
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-08-06 16:33:01 +00:00
|
|
|
bool code_is_empty() const;
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
void cleanup();
|
2016-08-18 18:38:30 +00:00
|
|
|
void copy_arg(CsValue &r) const;
|
2015-08-13 20:48:03 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
int p_type;
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
using CsValueRange = ostd::PointerRange<CsValue>;
|
2015-08-27 08:16:22 +00:00
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
struct IdentStack {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue val_s;
|
2015-08-05 21:58:45 +00:00
|
|
|
IdentStack *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CsState;
|
|
|
|
|
2016-08-10 17:33:43 +00:00
|
|
|
enum class IdentType {
|
2016-08-18 01:53:51 +00:00
|
|
|
ivar = 0, fvar, svar, command, alias, special
|
2016-08-10 17:33:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
struct Var;
|
|
|
|
struct Ivar;
|
|
|
|
struct Fvar;
|
|
|
|
struct Svar;
|
2016-08-18 01:00:32 +00:00
|
|
|
struct Alias;
|
2016-08-17 22:54:57 +00:00
|
|
|
|
2016-03-17 21:21:45 +00:00
|
|
|
struct OSTD_EXPORT Ident {
|
2016-08-18 01:53:51 +00:00
|
|
|
friend struct CsState;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-08-10 17:33:43 +00:00
|
|
|
IdentType get_type() const;
|
2016-08-18 01:53:51 +00:00
|
|
|
ostd::ConstCharRange get_name() const;
|
|
|
|
int get_flags() const;
|
|
|
|
int get_index() const;
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
bool is_alias() const;
|
|
|
|
Alias *get_alias();
|
|
|
|
Alias const *get_alias() const;
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
bool is_command() const;
|
2016-08-18 01:53:51 +00:00
|
|
|
bool is_special() const;
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
bool is_var() const;
|
|
|
|
Var *get_var();
|
|
|
|
Var const *get_var() const;
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
bool is_ivar() const;
|
|
|
|
Ivar *get_ivar();
|
|
|
|
Ivar const *get_ivar() const;
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
bool is_fvar() const;
|
|
|
|
Fvar *get_fvar();
|
|
|
|
Fvar const *get_fvar() const;
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
bool is_svar() const;
|
|
|
|
Svar *get_svar();
|
|
|
|
Svar const *get_svar() const;
|
2016-08-17 21:04:43 +00:00
|
|
|
|
2016-08-18 01:53:51 +00:00
|
|
|
int get_type_raw() const {
|
|
|
|
return p_type;
|
|
|
|
}
|
|
|
|
|
2016-08-17 21:04:43 +00:00
|
|
|
protected:
|
2016-08-18 01:00:32 +00:00
|
|
|
Ident(IdentType tp, ostd::ConstCharRange name, int flags = 0);
|
2016-08-18 01:53:51 +00:00
|
|
|
|
|
|
|
ostd::String p_name;
|
|
|
|
/* represents the IdentType 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;
|
|
|
|
|
|
|
|
private:
|
|
|
|
int p_index = -1;
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-17 22:06:39 +00:00
|
|
|
using VarCb = ostd::Function<void(Ident &)>;
|
|
|
|
|
2016-08-17 21:31:47 +00:00
|
|
|
struct OSTD_EXPORT Var: Ident {
|
2016-08-18 02:14:55 +00:00
|
|
|
friend struct CsState;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Var(IdentType tp, ostd::ConstCharRange name, VarCb func, int flags = 0);
|
|
|
|
|
|
|
|
private:
|
2016-08-17 21:29:31 +00:00
|
|
|
VarCb cb_var;
|
|
|
|
|
|
|
|
void changed() {
|
|
|
|
if (cb_var) {
|
|
|
|
cb_var(*this);
|
|
|
|
}
|
|
|
|
}
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-17 21:31:47 +00:00
|
|
|
struct OSTD_EXPORT Ivar: Var {
|
2016-08-18 02:14:55 +00:00
|
|
|
friend struct CsState;
|
|
|
|
|
|
|
|
CsInt get_val_min() const;
|
|
|
|
CsInt get_val_max() const;
|
|
|
|
|
|
|
|
CsInt get_var_value() const;
|
2016-08-17 22:36:37 +00:00
|
|
|
|
2016-08-17 21:04:43 +00:00
|
|
|
Ivar(
|
|
|
|
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt *s,
|
|
|
|
VarCb f = VarCb(), int flags = 0
|
|
|
|
);
|
2016-08-18 02:14:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
CsInt *p_storage;
|
|
|
|
CsInt p_minval, p_maxval, p_overrideval;
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-17 21:31:47 +00:00
|
|
|
struct OSTD_EXPORT Fvar: Var {
|
2016-08-18 02:14:55 +00:00
|
|
|
friend struct CsState;
|
|
|
|
|
|
|
|
CsFloat get_val_min() const;
|
|
|
|
CsFloat get_val_max() const;
|
|
|
|
|
|
|
|
CsFloat get_var_value() const;
|
2016-08-17 22:36:37 +00:00
|
|
|
|
2016-08-17 21:04:43 +00:00
|
|
|
Fvar(
|
|
|
|
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat *s,
|
|
|
|
VarCb f = VarCb(), int flags = 0
|
|
|
|
);
|
2016-08-18 02:14:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
CsFloat *p_storage;
|
|
|
|
CsFloat p_minval, p_maxval, p_overrideval;
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-17 21:31:47 +00:00
|
|
|
struct OSTD_EXPORT Svar: Var {
|
2016-08-18 02:14:55 +00:00
|
|
|
friend struct CsState;
|
|
|
|
|
|
|
|
ostd::ConstCharRange get_var_value() const;
|
2016-08-17 22:36:37 +00:00
|
|
|
|
2016-08-17 21:04:43 +00:00
|
|
|
Svar(
|
|
|
|
ostd::ConstCharRange n, char **s, VarCb f = VarCb(),
|
|
|
|
int flags = 0
|
|
|
|
);
|
2016-08-18 02:14:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
char **p_storage;
|
|
|
|
char *p_overrideval;
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-17 21:31:47 +00:00
|
|
|
struct OSTD_EXPORT Alias: Ident {
|
2016-08-17 22:06:39 +00:00
|
|
|
Bytecode *code;
|
2016-08-17 22:18:36 +00:00
|
|
|
IdentStack *stack;
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue val_v;
|
2016-08-17 22:06:39 +00:00
|
|
|
|
2016-08-17 21:04:43 +00:00
|
|
|
Alias(ostd::ConstCharRange n, char *a, int flags);
|
|
|
|
Alias(ostd::ConstCharRange n, CsInt a, int flags);
|
|
|
|
Alias(ostd::ConstCharRange n, CsFloat a, int flags);
|
|
|
|
Alias(ostd::ConstCharRange n, int flags);
|
2016-08-18 18:38:30 +00:00
|
|
|
Alias(ostd::ConstCharRange n, CsValue const &v, int flags);
|
2016-08-17 21:04:43 +00:00
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void set_value(CsValue const &v) {
|
2016-08-17 23:53:14 +00:00
|
|
|
val_v = v;
|
2016-08-17 22:18:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void set_value(IdentStack const &v) {
|
2016-08-17 23:53:14 +00:00
|
|
|
val_v = v.val_s;
|
2016-08-17 22:18:36 +00:00
|
|
|
}
|
|
|
|
|
2016-08-20 15:40:00 +00:00
|
|
|
void set_value_cstr(ostd::ConstCharRange val) {
|
|
|
|
val_v.set_cstr(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_value_mstr(ostd::CharRange val) {
|
|
|
|
val_v.set_mstr(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_value_str(ostd::String val) {
|
|
|
|
val_v.set_str(ostd::move(val));
|
|
|
|
}
|
|
|
|
|
|
|
|
void cleanup_value() {
|
|
|
|
val_v.cleanup();
|
|
|
|
}
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void get_cstr(CsValue &v) const;
|
|
|
|
void get_cval(CsValue &v) const;
|
2016-08-17 22:18:36 +00:00
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void push_arg(CsValue const &v, IdentStack &st, bool um = true);
|
2016-08-17 22:06:39 +00:00
|
|
|
void pop_arg();
|
|
|
|
void undo_arg(IdentStack &st);
|
|
|
|
void redo_arg(IdentStack const &st);
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void set_arg(CsState &cs, CsValue &v);
|
|
|
|
void set_alias(CsState &cs, CsValue &v);
|
2016-08-17 22:06:39 +00:00
|
|
|
|
|
|
|
void clean_code();
|
|
|
|
|
2016-08-17 21:04:43 +00:00
|
|
|
void force_null() {
|
2016-08-20 15:40:00 +00:00
|
|
|
cleanup_value();
|
2016-08-17 23:53:14 +00:00
|
|
|
val_v.set_null();
|
2016-08-17 21:04:43 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-08-06 20:43:36 +00:00
|
|
|
struct IdentLink {
|
|
|
|
Ident *id;
|
|
|
|
IdentLink *next;
|
|
|
|
int usedargs;
|
|
|
|
IdentStack *argstack;
|
|
|
|
};
|
|
|
|
|
2016-08-18 18:47:29 +00:00
|
|
|
enum {
|
|
|
|
CS_LIB_IO = 1 << 0,
|
|
|
|
CS_LIB_MATH = 1 << 1,
|
|
|
|
CS_LIB_STRING = 1 << 2,
|
|
|
|
CS_LIB_LIST = 1 << 3,
|
|
|
|
CS_LIB_ALL = 0b1111
|
|
|
|
};
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
using CmdFunc = ostd::Function<void(CsValueRange, CsValue &)>;
|
2016-08-18 01:00:32 +00:00
|
|
|
|
2016-03-17 21:21:45 +00:00
|
|
|
struct OSTD_EXPORT CsState {
|
2016-08-17 20:21:16 +00:00
|
|
|
ostd::Map<ostd::ConstCharRange, Ident *> idents;
|
2015-08-05 21:58:45 +00:00
|
|
|
ostd::Vector<Ident *> identmap;
|
|
|
|
|
|
|
|
Ident *dummy = nullptr;
|
|
|
|
|
2016-07-27 17:52:01 +00:00
|
|
|
IdentLink noalias;
|
2016-08-20 15:40:00 +00:00
|
|
|
IdentLink *p_stack = &noalias;
|
2015-08-06 20:43:36 +00:00
|
|
|
|
|
|
|
ostd::ConstCharRange src_file;
|
|
|
|
ostd::ConstCharRange src_str;
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
int identflags = 0;
|
2015-08-06 20:43:36 +00:00
|
|
|
int nodebug = 0;
|
2016-08-14 16:35:38 +00:00
|
|
|
CsInt numargs = 0;
|
|
|
|
CsInt dbgalias = 4;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
|
|
|
CsState();
|
|
|
|
~CsState();
|
|
|
|
|
2016-08-18 18:47:29 +00:00
|
|
|
void init_libs(int libs = CS_LIB_ALL);
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
void clear_override(Ident &id);
|
|
|
|
void clear_overrides();
|
|
|
|
|
2016-08-18 01:53:51 +00:00
|
|
|
Ident *add_ident(Ident *id);
|
2015-08-13 18:51:15 +00:00
|
|
|
Ident *new_ident(ostd::ConstCharRange name, int flags = IDF_UNKNOWN);
|
2016-08-18 18:38:30 +00:00
|
|
|
Ident *force_ident(CsValue &v);
|
2015-08-05 21:58:45 +00:00
|
|
|
|
|
|
|
Ident *get_ident(ostd::ConstCharRange name) {
|
2016-08-17 20:21:16 +00:00
|
|
|
Ident **id = idents.at(name);
|
|
|
|
if (!id) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return *id;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-17 21:04:43 +00:00
|
|
|
Alias *get_alias(ostd::ConstCharRange name) {
|
|
|
|
Ident *id = get_ident(name);
|
|
|
|
if (!id->is_alias()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return static_cast<Alias *>(id);
|
|
|
|
}
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
bool have_ident(ostd::ConstCharRange name) {
|
|
|
|
return idents.at(name) != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool reset_var(ostd::ConstCharRange name);
|
|
|
|
void touch_var(ostd::ConstCharRange name);
|
|
|
|
|
2016-08-07 20:39:27 +00:00
|
|
|
bool add_command(
|
2016-08-10 17:33:43 +00:00
|
|
|
ostd::ConstCharRange name, ostd::ConstCharRange args, CmdFunc func
|
2016-08-07 20:39:27 +00:00
|
|
|
);
|
2015-10-11 15:59:36 +00:00
|
|
|
|
2016-08-06 18:12:38 +00:00
|
|
|
ostd::String run_str(Bytecode const *code);
|
2015-08-06 00:44:13 +00:00
|
|
|
ostd::String run_str(ostd::ConstCharRange code);
|
2016-08-18 18:38:30 +00:00
|
|
|
ostd::String run_str(Ident *id, CsValueRange args);
|
2015-08-06 01:02:06 +00:00
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
CsInt run_int(Bytecode const *code);
|
|
|
|
CsInt run_int(ostd::ConstCharRange code);
|
2016-08-18 18:38:30 +00:00
|
|
|
CsInt run_int(Ident *id, CsValueRange args);
|
2015-08-06 01:02:06 +00:00
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
CsFloat run_float(Bytecode const *code);
|
|
|
|
CsFloat run_float(ostd::ConstCharRange code);
|
2016-08-18 18:38:30 +00:00
|
|
|
CsFloat run_float(Ident *id, CsValueRange args);
|
2015-08-06 01:02:06 +00:00
|
|
|
|
2016-08-06 18:12:38 +00:00
|
|
|
bool run_bool(Bytecode const *code);
|
2015-08-06 01:02:06 +00:00
|
|
|
bool run_bool(ostd::ConstCharRange code);
|
2016-08-18 18:38:30 +00:00
|
|
|
bool run_bool(Ident *id, CsValueRange args);
|
2015-08-06 01:07:16 +00:00
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void run_ret(Bytecode const *code, CsValue &ret);
|
|
|
|
void run_ret(ostd::ConstCharRange code, CsValue &ret);
|
|
|
|
void run_ret(Ident *id, CsValueRange args, CsValue &ret);
|
2015-08-07 20:04:31 +00:00
|
|
|
|
2016-08-18 18:34:24 +00:00
|
|
|
void run(Bytecode const *code);
|
|
|
|
void run(ostd::ConstCharRange code);
|
2016-08-18 18:38:30 +00:00
|
|
|
void run(Ident *id, CsValueRange args);
|
2016-08-18 18:34:24 +00:00
|
|
|
|
|
|
|
ostd::Maybe<ostd::String> run_file_str(ostd::ConstCharRange fname);
|
|
|
|
ostd::Maybe<CsInt> run_file_int(ostd::ConstCharRange fname);
|
|
|
|
ostd::Maybe<CsFloat> run_file_float(ostd::ConstCharRange fname);
|
|
|
|
ostd::Maybe<bool> run_file_bool(ostd::ConstCharRange fname);
|
2016-08-18 18:38:30 +00:00
|
|
|
bool run_file_ret(ostd::ConstCharRange fname, CsValue &ret);
|
2015-09-12 15:21:40 +00:00
|
|
|
bool run_file(ostd::ConstCharRange fname);
|
2015-08-06 20:43:36 +00:00
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void set_alias(ostd::ConstCharRange name, CsValue &v);
|
2015-08-07 01:11:53 +00:00
|
|
|
|
2016-08-07 20:39:27 +00:00
|
|
|
void set_var_int(
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::ConstCharRange name, CsInt v,
|
2016-08-07 20:39:27 +00:00
|
|
|
bool dofunc = true, bool doclamp = true
|
|
|
|
);
|
|
|
|
void set_var_float(
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::ConstCharRange name, CsFloat v,
|
2016-08-07 20:39:27 +00:00
|
|
|
bool dofunc = true, bool doclamp = true
|
|
|
|
);
|
|
|
|
void set_var_str(
|
|
|
|
ostd::ConstCharRange name, ostd::ConstCharRange v, bool dofunc = true
|
|
|
|
);
|
2015-08-07 01:11:53 +00:00
|
|
|
|
2016-08-17 21:29:31 +00:00
|
|
|
void set_var_int_checked(Ivar *iv, CsInt v);
|
2016-08-18 18:38:30 +00:00
|
|
|
void set_var_int_checked(Ivar *iv, CsValueRange args);
|
2016-08-17 21:29:31 +00:00
|
|
|
void set_var_float_checked(Fvar *fv, CsFloat v);
|
|
|
|
void set_var_str_checked(Svar *fv, ostd::ConstCharRange v);
|
2015-08-07 01:44:51 +00:00
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::Maybe<CsInt> get_var_int(ostd::ConstCharRange name);
|
|
|
|
ostd::Maybe<CsFloat> get_var_float(ostd::ConstCharRange name);
|
2015-08-07 01:11:53 +00:00
|
|
|
ostd::Maybe<ostd::String> get_var_str(ostd::ConstCharRange name);
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::Maybe<CsInt> get_var_min_int(ostd::ConstCharRange name);
|
|
|
|
ostd::Maybe<CsInt> get_var_max_int(ostd::ConstCharRange name);
|
2015-08-07 01:11:53 +00:00
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::Maybe<CsFloat> get_var_min_float(ostd::ConstCharRange name);
|
|
|
|
ostd::Maybe<CsFloat> get_var_max_float(ostd::ConstCharRange name);
|
2015-08-07 01:11:53 +00:00
|
|
|
|
2016-08-17 21:04:43 +00:00
|
|
|
ostd::Maybe<ostd::String> get_alias_val(ostd::ConstCharRange name);
|
2015-08-07 20:38:57 +00:00
|
|
|
|
2016-08-17 21:29:31 +00:00
|
|
|
void print_var(Var *v);
|
|
|
|
void print_var_int(Ivar *iv, CsInt i);
|
|
|
|
void print_var_float(Fvar *fv, CsFloat f);
|
|
|
|
void print_var_str(Svar *sv, ostd::ConstCharRange s);
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
struct OSTD_EXPORT StackedValue: CsValue {
|
2016-08-17 22:18:36 +00:00
|
|
|
StackedValue(Ident *id = nullptr):
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue(), p_a(nullptr), p_stack(), p_pushed(false)
|
2016-08-12 03:16:35 +00:00
|
|
|
{
|
2016-08-17 22:18:36 +00:00
|
|
|
set_alias(id);
|
2016-08-12 03:16:35 +00:00
|
|
|
}
|
2015-08-13 18:48:58 +00:00
|
|
|
|
|
|
|
~StackedValue() {
|
|
|
|
pop();
|
|
|
|
}
|
|
|
|
|
2016-08-17 22:06:39 +00:00
|
|
|
bool set_alias(Ident *id) {
|
2016-08-12 03:16:35 +00:00
|
|
|
if (!id || !id->is_alias()) {
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-17 22:06:39 +00:00
|
|
|
p_a = static_cast<Alias *>(id);
|
2016-08-12 03:16:35 +00:00
|
|
|
return true;
|
2016-08-12 03:01:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-17 22:06:39 +00:00
|
|
|
Alias *get_alias() const {
|
|
|
|
return p_a;
|
2016-08-12 03:02:05 +00:00
|
|
|
}
|
|
|
|
|
2016-08-17 22:06:39 +00:00
|
|
|
bool has_alias() const {
|
|
|
|
return p_a != nullptr;
|
2015-12-16 19:05:28 +00:00
|
|
|
}
|
|
|
|
|
2015-08-13 18:48:58 +00:00
|
|
|
bool push() {
|
2016-08-17 22:06:39 +00:00
|
|
|
if (p_pushed || !p_a) {
|
2016-08-07 20:39:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
2016-08-17 22:06:39 +00:00
|
|
|
p_a->push_arg(*this, p_stack);
|
2015-08-13 22:18:48 +00:00
|
|
|
p_pushed = true;
|
2015-08-13 18:48:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool pop() {
|
2016-08-17 22:06:39 +00:00
|
|
|
if (!p_pushed || !p_a) {
|
2016-08-07 20:39:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
2016-08-17 22:06:39 +00:00
|
|
|
p_a->pop_arg();
|
2015-08-13 22:18:48 +00:00
|
|
|
p_pushed = false;
|
2015-08-13 18:48:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
2015-08-13 22:18:48 +00:00
|
|
|
|
|
|
|
private:
|
2016-08-17 22:06:39 +00:00
|
|
|
Alias *p_a;
|
2015-08-13 22:18:48 +00:00
|
|
|
IdentStack p_stack;
|
|
|
|
bool p_pushed;
|
2015-08-13 18:48:58 +00:00
|
|
|
};
|
|
|
|
|
2015-08-08 15:06:18 +00:00
|
|
|
namespace util {
|
|
|
|
template<typename R>
|
|
|
|
inline ostd::Size escape_string(R &&writer, ostd::ConstCharRange str) {
|
|
|
|
ostd::Size ret = 2;
|
|
|
|
writer.put('"');
|
2016-08-07 20:39:27 +00:00
|
|
|
for (; !str.empty(); str.pop_front()) {
|
|
|
|
switch (str.front()) {
|
|
|
|
case '\n':
|
|
|
|
ret += writer.put_n("^n", 2);
|
|
|
|
break;
|
|
|
|
case '\t':
|
|
|
|
ret += writer.put_n("^t", 2);
|
|
|
|
break;
|
|
|
|
case '\f':
|
|
|
|
ret += writer.put_n("^f", 2);
|
|
|
|
break;
|
|
|
|
case '"':
|
|
|
|
ret += writer.put_n("^\"", 2);
|
|
|
|
break;
|
|
|
|
case '^':
|
|
|
|
ret += writer.put_n("^^", 2);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret += writer.put(str.front());
|
|
|
|
break;
|
|
|
|
}
|
2015-08-08 15:06:18 +00:00
|
|
|
}
|
|
|
|
writer.put('"');
|
|
|
|
return ret;
|
|
|
|
}
|
2015-08-08 16:07:01 +00:00
|
|
|
|
2015-08-11 01:18:53 +00:00
|
|
|
template<typename R>
|
|
|
|
inline ostd::Size unescape_string(R &&writer, ostd::ConstCharRange str) {
|
|
|
|
ostd::Size ret = 0;
|
|
|
|
for (; !str.empty(); str.pop_front()) {
|
|
|
|
if (str.front() == '^') {
|
|
|
|
str.pop_front();
|
2016-08-07 20:39:27 +00:00
|
|
|
if (str.empty()) {
|
2015-08-11 01:18:53 +00:00
|
|
|
break;
|
2016-08-07 20:39:27 +00:00
|
|
|
}
|
2015-08-11 01:18:53 +00:00
|
|
|
switch (str.front()) {
|
2016-08-07 20:39:27 +00:00
|
|
|
case 'n':
|
|
|
|
ret += writer.put('\n');
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
ret += writer.put('\r');
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
ret += writer.put('\f');
|
|
|
|
break;
|
|
|
|
case '"':
|
|
|
|
ret += writer.put('"');
|
|
|
|
break;
|
|
|
|
case '^':
|
|
|
|
ret += writer.put('^');
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret += writer.put(str.front());
|
|
|
|
break;
|
2015-08-11 01:18:53 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret += writer.put(str.front());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-08-15 17:48:06 +00:00
|
|
|
struct ListParser {
|
|
|
|
ostd::ConstCharRange input;
|
|
|
|
ostd::ConstCharRange quote = ostd::ConstCharRange();
|
|
|
|
ostd::ConstCharRange item = ostd::ConstCharRange();
|
|
|
|
|
|
|
|
ListParser() = delete;
|
|
|
|
ListParser(ostd::ConstCharRange src): input(src) {}
|
|
|
|
|
|
|
|
void skip();
|
|
|
|
bool parse();
|
|
|
|
|
|
|
|
ostd::String element();
|
|
|
|
};
|
|
|
|
|
2015-08-12 23:16:52 +00:00
|
|
|
ostd::Size list_length(ostd::ConstCharRange s);
|
2016-08-07 20:39:27 +00:00
|
|
|
ostd::Maybe<ostd::String> list_index(
|
|
|
|
ostd::ConstCharRange s, ostd::Size idx
|
|
|
|
);
|
|
|
|
ostd::Vector<ostd::String> list_explode(
|
|
|
|
ostd::ConstCharRange s, ostd::Size limit = -1
|
|
|
|
);
|
2016-08-09 23:10:09 +00:00
|
|
|
|
|
|
|
template<typename R>
|
2016-08-14 16:35:38 +00:00
|
|
|
inline ostd::Ptrdiff format_int(R &&writer, CsInt val) {
|
|
|
|
return ostd::format(ostd::forward<R>(writer), IntFormat, val);
|
2016-08-09 23:10:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename R>
|
2016-08-14 16:35:38 +00:00
|
|
|
inline ostd::Ptrdiff format_float(R &&writer, CsFloat val) {
|
2016-08-09 23:10:09 +00:00
|
|
|
return ostd::format(
|
2016-08-14 16:35:38 +00:00
|
|
|
ostd::forward<R>(writer),
|
|
|
|
(val == CsInt(val)) ? RoundFloatFormat : FloatFormat, val
|
2016-08-09 23:10:09 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename R>
|
|
|
|
inline ostd::Size tvals_concat(
|
2016-08-18 18:38:30 +00:00
|
|
|
R &&writer, CsValueRange vals,
|
2016-08-09 23:10:09 +00:00
|
|
|
ostd::ConstCharRange sep = ostd::ConstCharRange()
|
|
|
|
) {
|
|
|
|
ostd::Size ret = 0;
|
|
|
|
for (ostd::Size i = 0; i < vals.size(); ++i) {
|
|
|
|
auto s = ostd::appender<ostd::String>();
|
|
|
|
switch (vals[i].get_type()) {
|
|
|
|
case VAL_INT: {
|
|
|
|
auto r = format_int(ostd::forward<R>(writer), vals[i].i);
|
|
|
|
if (r > 0) {
|
|
|
|
ret += ostd::Size(r);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case VAL_FLOAT: {
|
2016-08-14 16:35:38 +00:00
|
|
|
auto r = format_float(ostd::forward<R>(writer), vals[i].f);
|
2016-08-09 23:10:09 +00:00
|
|
|
if (r > 0) {
|
|
|
|
ret += ostd::Size(r);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case VAL_STR:
|
|
|
|
case VAL_CSTR:
|
|
|
|
case VAL_MACRO:
|
|
|
|
ret += writer.put_n(vals[i].s, vals[i].len);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i == (vals.size() - 1)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ret += writer.put_n(sep.data(), sep.size());
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
2016-03-06 21:51:11 +00:00
|
|
|
} /* namespace util */
|
2015-08-08 15:13:46 +00:00
|
|
|
|
2015-09-10 17:53:43 +00:00
|
|
|
} /* namespace cscript */
|
|
|
|
|
2016-08-14 16:35:38 +00:00
|
|
|
#endif /* LIBCUBESCRIPT_CUBESCRIPT_HH */
|