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 {
|
|
|
|
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-28 17:40:18 +00:00
|
|
|
struct CsBytecode;
|
2016-08-06 18:12:38 +00:00
|
|
|
|
2016-08-28 17:40:18 +00:00
|
|
|
struct OSTD_EXPORT CsBytecodeRef {
|
|
|
|
CsBytecodeRef():
|
2016-08-07 20:39:27 +00:00
|
|
|
p_code(nullptr)
|
|
|
|
{}
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecodeRef(CsBytecode *v);
|
|
|
|
CsBytecodeRef(CsBytecodeRef const &v);
|
|
|
|
CsBytecodeRef(CsBytecodeRef &&v):
|
2016-08-07 20:39:27 +00:00
|
|
|
p_code(v.p_code)
|
|
|
|
{
|
|
|
|
v.p_code = nullptr;
|
|
|
|
}
|
2015-12-19 23:28:12 +00:00
|
|
|
|
2016-08-28 17:40:18 +00:00
|
|
|
~CsBytecodeRef();
|
2015-12-24 14:57:19 +00:00
|
|
|
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecodeRef &operator=(CsBytecodeRef const &v);
|
|
|
|
CsBytecodeRef &operator=(CsBytecodeRef &&v);
|
2015-12-19 23:28:12 +00:00
|
|
|
|
|
|
|
operator bool() const { return p_code != nullptr; }
|
2016-08-28 17:40:18 +00:00
|
|
|
operator CsBytecode *() const { return p_code; }
|
2015-12-19 23:28:12 +00:00
|
|
|
|
|
|
|
private:
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecode *p_code;
|
2015-12-19 23:28:12 +00:00
|
|
|
};
|
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
OSTD_EXPORT bool cs_code_is_empty(CsBytecode *code);
|
2016-08-06 16:33:01 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
struct CsIdent;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-08-30 21:30:40 +00:00
|
|
|
enum class CsValueType {
|
|
|
|
null = 0, integer, number, string, cstring, code, macro, ident
|
|
|
|
};
|
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
struct OSTD_EXPORT CsValue {
|
2016-08-30 21:30:40 +00:00
|
|
|
CsValueType get_type() const;
|
2016-08-25 20:24:23 +00:00
|
|
|
|
|
|
|
void set_int(CsInt val);
|
|
|
|
void set_float(CsFloat val);
|
|
|
|
void set_str(CsString val);
|
|
|
|
void set_null();
|
2016-08-30 20:29:09 +00:00
|
|
|
void set_code(CsBytecode *val);
|
2016-08-25 20:24:23 +00:00
|
|
|
void set_cstr(ostd::ConstCharRange val);
|
|
|
|
void set_mstr(ostd::CharRange val);
|
2016-08-29 17:17:11 +00:00
|
|
|
void set_ident(CsIdent *val);
|
2016-08-30 20:29:09 +00:00
|
|
|
void set_macro(ostd::ConstCharRange val);
|
2016-08-25 20:24:23 +00:00
|
|
|
|
|
|
|
void set(CsValue &tv);
|
2015-08-08 00:40:29 +00:00
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString 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-28 17:40:18 +00:00
|
|
|
CsBytecode *get_code() const;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *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:
|
2016-09-06 18:06:49 +00:00
|
|
|
ostd::AlignedUnion<1, CsInt, CsFloat, void *> p_stor;
|
2016-08-30 20:55:35 +00:00
|
|
|
ostd::Size p_len;
|
2016-08-30 21:30:40 +00:00
|
|
|
CsValueType 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
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
struct CsIdentStack {
|
2016-08-18 18:38:30 +00:00
|
|
|
CsValue val_s;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentStack *next;
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct CsState;
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
enum class CsIdentType {
|
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-29 17:17:11 +00:00
|
|
|
struct CsVar;
|
|
|
|
struct CsIvar;
|
|
|
|
struct CsFvar;
|
|
|
|
struct CsSvar;
|
|
|
|
struct CsAlias;
|
2016-09-02 16:20:53 +00:00
|
|
|
struct CsCommand;
|
2016-08-17 22:54:57 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
struct OSTD_EXPORT CsIdent {
|
2016-08-18 01:53:51 +00:00
|
|
|
friend struct CsState;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-08-29 17:26:35 +00:00
|
|
|
CsIdent() = delete;
|
|
|
|
CsIdent(CsIdent const &) = delete;
|
|
|
|
CsIdent(CsIdent &&) = delete;
|
|
|
|
|
2016-09-06 18:06:49 +00:00
|
|
|
/* trigger destructors for all inherited members properly */
|
|
|
|
virtual ~CsIdent() {};
|
|
|
|
|
2016-08-29 17:26:35 +00:00
|
|
|
CsIdent &operator=(CsIdent const &) = delete;
|
|
|
|
CsIdent &operator=(CsIdent &&) = delete;
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentType 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;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *get_alias();
|
|
|
|
CsAlias 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-09-02 16:20:53 +00:00
|
|
|
CsCommand *get_command();
|
|
|
|
CsCommand const *get_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;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsVar *get_var();
|
|
|
|
CsVar const *get_var() const;
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
bool is_ivar() const;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIvar *get_ivar();
|
|
|
|
CsIvar const *get_ivar() const;
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
bool is_fvar() const;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFvar *get_fvar();
|
|
|
|
CsFvar const *get_fvar() const;
|
2016-08-10 17:33:43 +00:00
|
|
|
|
2016-08-17 22:54:57 +00:00
|
|
|
bool is_svar() const;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsSvar *get_svar();
|
|
|
|
CsSvar 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-29 17:17:11 +00:00
|
|
|
CsIdent(CsIdentType tp, ostd::ConstCharRange name, int flags = 0);
|
2016-08-18 01:53:51 +00:00
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString p_name;
|
2016-08-29 17:17:11 +00:00
|
|
|
/* represents the CsIdentType above, but internally it has a wider variety
|
2016-08-18 01:53:51 +00:00
|
|
|
* 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-29 17:17:11 +00:00
|
|
|
using CsVarCb = ostd::Function<void(CsIdent &)>;
|
2016-08-17 22:06:39 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
struct OSTD_EXPORT CsVar: CsIdent {
|
2016-08-18 02:14:55 +00:00
|
|
|
friend struct CsState;
|
|
|
|
|
|
|
|
protected:
|
2016-08-29 17:17:11 +00:00
|
|
|
CsVar(CsIdentType tp, ostd::ConstCharRange name, CsVarCb func, int flags = 0);
|
2016-08-18 02:14:55 +00:00
|
|
|
|
|
|
|
private:
|
2016-08-29 17:17:11 +00:00
|
|
|
CsVarCb cb_var;
|
2016-08-17 21:29:31 +00:00
|
|
|
|
|
|
|
void changed() {
|
|
|
|
if (cb_var) {
|
|
|
|
cb_var(*this);
|
|
|
|
}
|
|
|
|
}
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
struct OSTD_EXPORT CsIvar: CsVar {
|
2016-08-18 02:14:55 +00:00
|
|
|
friend struct CsState;
|
|
|
|
|
|
|
|
CsInt get_val_min() const;
|
|
|
|
CsInt get_val_max() const;
|
|
|
|
|
2016-08-22 17:18:22 +00:00
|
|
|
CsInt get_value() const;
|
2016-08-22 17:43:58 +00:00
|
|
|
void set_value(CsInt val);
|
2016-08-17 22:36:37 +00:00
|
|
|
|
2016-08-29 17:23:51 +00:00
|
|
|
private:
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIvar(
|
2016-09-02 17:01:25 +00:00
|
|
|
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v, CsVarCb f, int flags
|
2016-08-17 21:04:43 +00:00
|
|
|
);
|
2016-08-18 02:14:55 +00:00
|
|
|
|
2016-08-22 17:43:58 +00:00
|
|
|
CsInt p_storage, p_minval, p_maxval, p_overrideval;
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
struct OSTD_EXPORT CsFvar: CsVar {
|
2016-08-18 02:14:55 +00:00
|
|
|
friend struct CsState;
|
|
|
|
|
|
|
|
CsFloat get_val_min() const;
|
|
|
|
CsFloat get_val_max() const;
|
|
|
|
|
2016-08-22 17:18:22 +00:00
|
|
|
CsFloat get_value() const;
|
2016-08-22 17:43:58 +00:00
|
|
|
void set_value(CsFloat val);
|
2016-08-17 22:36:37 +00:00
|
|
|
|
2016-08-29 17:23:51 +00:00
|
|
|
private:
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFvar(
|
2016-08-22 17:43:58 +00:00
|
|
|
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v,
|
2016-09-02 17:01:25 +00:00
|
|
|
CsVarCb f, int flags
|
2016-08-17 21:04:43 +00:00
|
|
|
);
|
2016-08-18 02:14:55 +00:00
|
|
|
|
2016-08-22 17:43:58 +00:00
|
|
|
CsFloat p_storage, p_minval, p_maxval, p_overrideval;
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
struct OSTD_EXPORT CsSvar: CsVar {
|
2016-08-18 02:14:55 +00:00
|
|
|
friend struct CsState;
|
|
|
|
|
2016-08-22 17:18:22 +00:00
|
|
|
ostd::ConstCharRange get_value() const;
|
2016-08-31 20:46:25 +00:00
|
|
|
void set_value(CsString val);
|
2016-08-17 22:36:37 +00:00
|
|
|
|
2016-08-29 17:23:51 +00:00
|
|
|
private:
|
2016-09-02 17:01:25 +00:00
|
|
|
CsSvar(ostd::ConstCharRange n, CsString v, CsVarCb f, int flags);
|
2016-08-18 02:14:55 +00:00
|
|
|
|
2016-08-22 17:43:58 +00:00
|
|
|
CsString p_storage, p_overrideval;
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
struct OSTD_EXPORT CsAlias: CsIdent {
|
2016-08-29 17:23:51 +00:00
|
|
|
friend struct CsState;
|
2016-09-02 20:42:10 +00:00
|
|
|
friend struct CsAliasInternal;
|
2016-08-31 18:18:53 +00:00
|
|
|
|
|
|
|
CsValue const &get_value() const {
|
|
|
|
return p_val;
|
|
|
|
}
|
|
|
|
|
|
|
|
CsValue &get_value() {
|
|
|
|
return p_val;
|
|
|
|
}
|
2016-08-17 21:04:43 +00:00
|
|
|
|
2016-08-18 18:38:30 +00:00
|
|
|
void get_cstr(CsValue &v) const;
|
|
|
|
void get_cval(CsValue &v) const;
|
2016-08-20 23:37:34 +00:00
|
|
|
private:
|
2016-08-29 17:23:51 +00:00
|
|
|
CsAlias(ostd::ConstCharRange n, char *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 const &v, int flags);
|
|
|
|
|
2016-08-28 17:40:18 +00:00
|
|
|
CsBytecode *p_acode;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentStack *p_astack;
|
2016-08-31 18:18:53 +00:00
|
|
|
CsValue p_val;
|
2016-08-17 21:04:43 +00:00
|
|
|
};
|
|
|
|
|
2016-09-02 17:01:25 +00:00
|
|
|
using CsCommandCb = ostd::Function<void(CsValueRange, CsValue &)>;
|
2016-09-02 16:20:53 +00:00
|
|
|
|
|
|
|
struct CsCommand: CsIdent {
|
|
|
|
friend struct CsState;
|
2016-09-02 20:49:05 +00:00
|
|
|
friend struct CsCommandInternal;
|
2016-09-02 16:20:53 +00:00
|
|
|
|
2016-09-02 20:49:05 +00:00
|
|
|
ostd::ConstCharRange get_args() const;
|
|
|
|
int get_num_args() const;
|
2016-09-02 16:20:53 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
CsCommand(
|
2016-09-02 17:01:25 +00:00
|
|
|
ostd::ConstCharRange name, ostd::ConstCharRange args,
|
|
|
|
int numargs, CsCommandCb func
|
2016-09-02 16:20:53 +00:00
|
|
|
);
|
2016-09-02 19:27:37 +00:00
|
|
|
|
2016-09-02 19:30:00 +00:00
|
|
|
CsString p_cargs;
|
2016-09-02 19:27:37 +00:00
|
|
|
CsCommandCb p_cb_cftv;
|
2016-09-02 19:30:00 +00:00
|
|
|
int p_numargs;
|
2016-09-02 16:20:53 +00:00
|
|
|
};
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
struct CsIdentLink {
|
|
|
|
CsIdent *id;
|
|
|
|
CsIdentLink *next;
|
2015-08-06 20:43:36 +00:00
|
|
|
int usedargs;
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentStack *argstack;
|
2015-08-06 20:43:36 +00:00
|
|
|
};
|
|
|
|
|
2016-08-18 18:47:29 +00:00
|
|
|
enum {
|
2016-09-02 17:59:04 +00:00
|
|
|
CS_LIB_MATH = 1 << 0,
|
|
|
|
CS_LIB_STRING = 1 << 1,
|
|
|
|
CS_LIB_LIST = 1 << 2,
|
|
|
|
CS_LIB_ALL = 0b111
|
2016-08-18 18:47:29 +00:00
|
|
|
};
|
|
|
|
|
2016-09-05 19:34:48 +00:00
|
|
|
using CsHookCb = ostd::Function<void()>;
|
|
|
|
|
2016-03-17 21:21:45 +00:00
|
|
|
struct OSTD_EXPORT CsState {
|
2016-08-29 17:17:11 +00:00
|
|
|
CsMap<ostd::ConstCharRange, CsIdent *> idents;
|
|
|
|
CsVector<CsIdent *> identmap;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdentLink noalias;
|
|
|
|
CsIdentLink *p_stack = &noalias;
|
2015-08-06 20:43:36 +00:00
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
int identflags = 0;
|
2015-08-06 20:43:36 +00:00
|
|
|
int nodebug = 0;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
|
|
|
CsState();
|
|
|
|
~CsState();
|
|
|
|
|
2016-09-02 18:22:19 +00:00
|
|
|
CsStream const &get_out() const;
|
|
|
|
CsStream &get_out();
|
|
|
|
void set_out(CsStream &s);
|
|
|
|
|
|
|
|
CsStream const &get_err() const;
|
|
|
|
CsStream &get_err();
|
|
|
|
void set_err(CsStream &s);
|
|
|
|
|
2016-09-05 19:34:48 +00:00
|
|
|
CsHookCb set_call_hook(CsHookCb func);
|
|
|
|
CsHookCb const &get_call_hook() const;
|
|
|
|
CsHookCb &get_call_hook();
|
|
|
|
|
2016-08-18 18:47:29 +00:00
|
|
|
void init_libs(int libs = CS_LIB_ALL);
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void clear_override(CsIdent &id);
|
2015-08-05 21:58:45 +00:00
|
|
|
void clear_overrides();
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *new_ident(ostd::ConstCharRange name, int flags = IDF_UNKNOWN);
|
|
|
|
CsIdent *force_ident(CsValue &v);
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-09-02 17:01:25 +00:00
|
|
|
CsIvar *new_ivar(
|
|
|
|
ostd::ConstCharRange n, CsInt m, CsInt x, CsInt v,
|
|
|
|
CsVarCb f = CsVarCb(), int flags = 0
|
|
|
|
);
|
|
|
|
CsFvar *new_fvar(
|
|
|
|
ostd::ConstCharRange n, CsFloat m, CsFloat x, CsFloat v,
|
|
|
|
CsVarCb f = CsVarCb(), int flags = 0
|
|
|
|
);
|
|
|
|
CsSvar *new_svar(
|
|
|
|
ostd::ConstCharRange n, CsString v,
|
|
|
|
CsVarCb f = CsVarCb(), int flags = 0
|
|
|
|
);
|
2016-08-20 15:52:54 +00:00
|
|
|
|
2016-09-02 17:03:01 +00:00
|
|
|
CsCommand *new_command(
|
|
|
|
ostd::ConstCharRange name, ostd::ConstCharRange args, CsCommandCb func
|
|
|
|
);
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *get_ident(ostd::ConstCharRange name) {
|
|
|
|
CsIdent **id = idents.at(name);
|
2016-08-17 20:21:16 +00:00
|
|
|
if (!id) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return *id;
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *get_alias(ostd::ConstCharRange name) {
|
|
|
|
CsIdent *id = get_ident(name);
|
2016-08-17 21:04:43 +00:00
|
|
|
if (!id->is_alias()) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2016-08-29 17:17:11 +00:00
|
|
|
return static_cast<CsAlias *>(id);
|
2016-08-17 21:04:43 +00:00
|
|
|
}
|
|
|
|
|
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-30 20:29:09 +00:00
|
|
|
CsString run_str(CsBytecode *code);
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString run_str(ostd::ConstCharRange code);
|
2016-08-29 17:17:11 +00:00
|
|
|
CsString run_str(CsIdent *id, CsValueRange args);
|
2015-08-06 01:02:06 +00:00
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
CsInt run_int(CsBytecode *code);
|
2016-08-14 16:35:38 +00:00
|
|
|
CsInt run_int(ostd::ConstCharRange code);
|
2016-08-29 17:17:11 +00:00
|
|
|
CsInt run_int(CsIdent *id, CsValueRange args);
|
2015-08-06 01:02:06 +00:00
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
CsFloat run_float(CsBytecode *code);
|
2016-08-14 16:35:38 +00:00
|
|
|
CsFloat run_float(ostd::ConstCharRange code);
|
2016-08-29 17:17:11 +00:00
|
|
|
CsFloat run_float(CsIdent *id, CsValueRange args);
|
2015-08-06 01:02:06 +00:00
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
bool run_bool(CsBytecode *code);
|
2015-08-06 01:02:06 +00:00
|
|
|
bool run_bool(ostd::ConstCharRange code);
|
2016-08-29 17:17:11 +00:00
|
|
|
bool run_bool(CsIdent *id, CsValueRange args);
|
2015-08-06 01:07:16 +00:00
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
void run_ret(CsBytecode *code, CsValue &ret);
|
2016-08-18 18:38:30 +00:00
|
|
|
void run_ret(ostd::ConstCharRange code, CsValue &ret);
|
2016-08-29 17:17:11 +00:00
|
|
|
void run_ret(CsIdent *id, CsValueRange args, CsValue &ret);
|
2015-08-07 20:04:31 +00:00
|
|
|
|
2016-08-30 20:29:09 +00:00
|
|
|
void run(CsBytecode *code);
|
2016-08-18 18:34:24 +00:00
|
|
|
void run(ostd::ConstCharRange code);
|
2016-08-29 17:17:11 +00:00
|
|
|
void run(CsIdent *id, CsValueRange args);
|
2016-08-18 18:34:24 +00:00
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
ostd::Maybe<CsString> run_file_str(ostd::ConstCharRange fname);
|
2016-08-18 18:34:24 +00:00
|
|
|
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-29 17:17:11 +00:00
|
|
|
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);
|
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);
|
2016-08-21 00:34:03 +00:00
|
|
|
ostd::Maybe<CsString> get_var_str(ostd::ConstCharRange name);
|
2015-08-07 01:11:53 +00:00
|
|
|
|
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-21 00:34:03 +00:00
|
|
|
ostd::Maybe<CsString> get_alias_val(ostd::ConstCharRange name);
|
2015-08-07 20:38:57 +00:00
|
|
|
|
2016-08-29 17:17:11 +00:00
|
|
|
void print_var(CsVar *v);
|
2016-09-02 18:22:19 +00:00
|
|
|
virtual void print_var(CsIvar *iv);
|
|
|
|
virtual void print_var(CsFvar *fv);
|
|
|
|
virtual void print_var(CsSvar *sv);
|
2016-08-21 00:34:03 +00:00
|
|
|
|
|
|
|
private:
|
2016-08-29 17:17:11 +00:00
|
|
|
CsIdent *add_ident(CsIdent *id);
|
2016-09-02 18:22:19 +00:00
|
|
|
|
2016-09-05 19:34:48 +00:00
|
|
|
CsHookCb p_callhook;
|
2016-09-02 18:22:19 +00:00
|
|
|
CsStream *p_out, *p_err;
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
2016-08-30 22:19:28 +00:00
|
|
|
struct OSTD_EXPORT CsStackedValue: CsValue {
|
2016-09-02 20:42:10 +00:00
|
|
|
CsStackedValue(CsIdent *id = nullptr);
|
|
|
|
~CsStackedValue();
|
2015-08-13 18:48:58 +00:00
|
|
|
|
2016-09-02 20:42:10 +00:00
|
|
|
bool set_alias(CsIdent *id);
|
|
|
|
CsAlias *get_alias() const;
|
|
|
|
bool has_alias() const;
|
2015-08-13 18:48:58 +00:00
|
|
|
|
2016-09-02 20:42:10 +00:00
|
|
|
bool push();
|
|
|
|
bool pop();
|
2015-08-13 22:18:48 +00:00
|
|
|
|
|
|
|
private:
|
2016-08-29 17:17:11 +00:00
|
|
|
CsAlias *p_a;
|
|
|
|
CsIdentStack p_stack;
|
2015-08-13 22:18:48 +00:00
|
|
|
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();
|
|
|
|
|
2016-08-21 00:34:03 +00:00
|
|
|
CsString element();
|
2016-08-15 17:48:06 +00:00
|
|
|
};
|
|
|
|
|
2015-08-12 23:16:52 +00:00
|
|
|
ostd::Size list_length(ostd::ConstCharRange s);
|
2016-08-21 00:34:03 +00:00
|
|
|
ostd::Maybe<CsString> list_index(
|
2016-08-07 20:39:27 +00:00
|
|
|
ostd::ConstCharRange s, ostd::Size idx
|
|
|
|
);
|
2016-08-21 00:34:03 +00:00
|
|
|
CsVector<CsString> list_explode(
|
2016-08-07 20:39:27 +00:00
|
|
|
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) {
|
2016-08-21 00:34:03 +00:00
|
|
|
auto s = ostd::appender<CsString>();
|
2016-08-09 23:10:09 +00:00
|
|
|
switch (vals[i].get_type()) {
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::integer: {
|
2016-08-30 20:55:35 +00:00
|
|
|
auto r = format_int(
|
|
|
|
ostd::forward<R>(writer), vals[i].get_int()
|
|
|
|
);
|
2016-08-09 23:10:09 +00:00
|
|
|
if (r > 0) {
|
|
|
|
ret += ostd::Size(r);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::number: {
|
2016-08-30 20:55:35 +00:00
|
|
|
auto r = format_float(
|
|
|
|
ostd::forward<R>(writer), vals[i].get_float()
|
|
|
|
);
|
2016-08-09 23:10:09 +00:00
|
|
|
if (r > 0) {
|
|
|
|
ret += ostd::Size(r);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2016-08-30 21:30:40 +00:00
|
|
|
case CsValueType::string:
|
|
|
|
case CsValueType::cstring:
|
|
|
|
case CsValueType::macro: {
|
2016-08-30 20:55:35 +00:00
|
|
|
auto sv = vals[i].get_strr();
|
|
|
|
ret += writer.put_n(sv.data(), sv.size());
|
2016-08-09 23:10:09 +00:00
|
|
|
break;
|
2016-08-30 20:55:35 +00:00
|
|
|
}
|
2016-08-09 23:10:09 +00:00
|
|
|
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 */
|