2015-09-10 17:53:43 +00:00
|
|
|
#ifndef CUBESCRIPT_HH
|
|
|
|
#define CUBESCRIPT_HH
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
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>
|
2015-08-05 21:58:45 +00:00
|
|
|
#include <ostd/keyset.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>
|
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 {
|
2015-08-11 21:16:20 +00:00
|
|
|
ID_UNKNOWN = -1, ID_VAR, ID_FVAR, ID_SVAR, ID_COMMAND, ID_ALIAS,
|
|
|
|
ID_LOCAL, ID_DO, ID_DOARGS, ID_IF, ID_RESULT, ID_NOT, ID_AND, ID_OR
|
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-06 18:12:38 +00:00
|
|
|
struct Bytecode;
|
|
|
|
|
2016-08-06 17:38:05 +00:00
|
|
|
struct OSTD_EXPORT BytecodeRef {
|
|
|
|
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);
|
|
|
|
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;
|
|
|
|
|
|
|
|
struct IdentValue {
|
|
|
|
union {
|
|
|
|
int i; /* ID_VAR, VAL_INT */
|
|
|
|
float 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-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
2016-03-17 21:21:45 +00:00
|
|
|
struct OSTD_EXPORT TaggedValue: IdentValue {
|
2015-08-13 21:23:46 +00:00
|
|
|
friend struct Ident;
|
|
|
|
|
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-07-13 18:24:26 +00:00
|
|
|
ostd::Size get_str_len() const {
|
2016-08-01 20:46:50 +00:00
|
|
|
return len;
|
2016-07-13 18:24:26 +00:00
|
|
|
}
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
void set_int(int val) {
|
2015-08-13 20:48:03 +00:00
|
|
|
p_type = VAL_INT;
|
2015-08-05 21:58:45 +00:00
|
|
|
i = val;
|
|
|
|
}
|
|
|
|
void set_float(float 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) {
|
|
|
|
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;
|
|
|
|
}
|
2016-08-06 18:12:38 +00:00
|
|
|
void set_macro(Bytecode const *val) {
|
2016-08-01 20:35:42 +00:00
|
|
|
p_type = VAL_MACRO;
|
2016-08-01 20:46:50 +00:00
|
|
|
len = strlen(reinterpret_cast<char const *>(val));
|
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;
|
|
|
|
}
|
|
|
|
|
2015-08-08 00:40:29 +00:00
|
|
|
void set(TaggedValue &tv) {
|
|
|
|
*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;
|
2015-08-05 21:58:45 +00:00
|
|
|
int get_int() const;
|
|
|
|
float 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;
|
2015-08-05 21:58:45 +00:00
|
|
|
void get_val(TaggedValue &r) const;
|
|
|
|
|
2016-08-02 00:21:36 +00:00
|
|
|
bool get_bool() const;
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
void force_null();
|
|
|
|
float force_float();
|
|
|
|
int 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-03 22:03:44 +00:00
|
|
|
void copy_arg(TaggedValue &r) const;
|
2015-08-13 20:48:03 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
int p_type;
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
2015-08-27 08:16:22 +00:00
|
|
|
using TvalRange = ostd::PointerRange<TaggedValue>;
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
struct IdentStack {
|
|
|
|
IdentValue val;
|
|
|
|
int valtype;
|
|
|
|
IdentStack *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
union IdentValuePtr {
|
2015-08-13 20:08:57 +00:00
|
|
|
int *ip; /* ID_VAR */
|
|
|
|
float *fp; /* ID_FVAR */
|
|
|
|
char **sp; /* ID_SVAR */
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct CsState;
|
|
|
|
|
2016-08-01 18:33:40 +00:00
|
|
|
using VarCb = ostd::Function<void(Ident &)>;
|
|
|
|
using CmdFunc = ostd::Function<void(TvalRange)>;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-03-17 21:21:45 +00:00
|
|
|
struct OSTD_EXPORT Ident {
|
2015-08-05 21:58:45 +00:00
|
|
|
ostd::byte type; /* ID_something */
|
|
|
|
union {
|
2016-07-13 18:24:26 +00:00
|
|
|
int valtype; /* ID_ALIAS */
|
|
|
|
int numargs; /* ID_COMMAND */
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
ostd::ushort flags;
|
|
|
|
int index;
|
|
|
|
ostd::String name;
|
|
|
|
union {
|
|
|
|
struct { /* ID_VAR, ID_FVAR, ID_SVAR */
|
|
|
|
union {
|
|
|
|
struct { /* ID_VAR */
|
|
|
|
int minval, maxval;
|
|
|
|
};
|
|
|
|
struct { /* ID_FVAR */
|
|
|
|
float minvalf, maxvalf;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
IdentValuePtr storage;
|
|
|
|
IdentValue overrideval;
|
|
|
|
};
|
|
|
|
struct { /* ID_ALIAS */
|
2016-08-06 18:12:38 +00:00
|
|
|
Bytecode *code;
|
2015-08-05 21:58:45 +00:00
|
|
|
IdentValue val;
|
|
|
|
IdentStack *stack;
|
|
|
|
};
|
|
|
|
struct { /* ID_COMMAND */
|
|
|
|
char *args;
|
2015-08-07 22:37:54 +00:00
|
|
|
ostd::Uint32 argmask;
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
};
|
2016-08-01 00:10:21 +00:00
|
|
|
VarCb cb_var;
|
2016-08-01 18:17:13 +00:00
|
|
|
CmdFunc cb_cftv;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2015-08-11 21:16:20 +00:00
|
|
|
Ident(): type(ID_UNKNOWN) {}
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
/* ID_VAR */
|
2015-08-11 21:16:20 +00:00
|
|
|
Ident(int t, ostd::ConstCharRange n, int m, int x, int *s,
|
2016-08-01 00:10:21 +00:00
|
|
|
VarCb f = VarCb(), int flags = 0);
|
2015-08-11 21:16:20 +00:00
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
/* ID_FVAR */
|
2015-08-11 21:16:20 +00:00
|
|
|
Ident(int t, ostd::ConstCharRange n, float m, float x, float *s,
|
2016-08-01 00:10:21 +00:00
|
|
|
VarCb f = VarCb(), int flags = 0);
|
2015-08-11 21:16:20 +00:00
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
/* ID_SVAR */
|
2016-08-01 00:10:21 +00:00
|
|
|
Ident(int t, ostd::ConstCharRange n, char **s, VarCb f = VarCb(),
|
2015-08-11 21:16:20 +00:00
|
|
|
int flags = 0);
|
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
/* ID_ALIAS */
|
2015-08-11 21:16:20 +00:00
|
|
|
Ident(int t, ostd::ConstCharRange n, char *a, int flags);
|
|
|
|
Ident(int t, ostd::ConstCharRange n, int a, int flags);
|
|
|
|
Ident(int t, ostd::ConstCharRange n, float a, int flags);
|
|
|
|
Ident(int t, ostd::ConstCharRange n, int flags);
|
2016-07-17 17:50:40 +00:00
|
|
|
Ident(int t, ostd::ConstCharRange n, TaggedValue const &v, int flags);
|
2015-08-11 21:16:20 +00:00
|
|
|
|
2015-08-05 21:58:45 +00:00
|
|
|
/* ID_COMMAND */
|
2015-08-11 21:16:20 +00:00
|
|
|
Ident(int t, ostd::ConstCharRange n, ostd::ConstCharRange args,
|
2016-08-01 18:17:13 +00:00
|
|
|
ostd::Uint32 argmask, int numargs, CmdFunc f = CmdFunc(),
|
2015-08-11 21:16:20 +00:00
|
|
|
int flags = 0);
|
2015-08-05 21:58:45 +00:00
|
|
|
|
2016-08-01 18:33:40 +00:00
|
|
|
void changed() {
|
|
|
|
if (cb_var) cb_var(*this);
|
2015-08-05 21:58:45 +00:00
|
|
|
}
|
|
|
|
|
2016-07-17 17:50:40 +00:00
|
|
|
void set_value(TaggedValue const &v) {
|
2016-08-01 20:35:42 +00:00
|
|
|
valtype = v.get_type();
|
2015-08-05 21:58:45 +00:00
|
|
|
val = v;
|
|
|
|
}
|
|
|
|
|
2016-07-17 17:50:40 +00:00
|
|
|
void set_value(IdentStack const &v) {
|
2015-08-05 21:58:45 +00:00
|
|
|
valtype = v.valtype;
|
|
|
|
val = v.val;
|
|
|
|
}
|
|
|
|
|
2015-08-11 20:41:12 +00:00
|
|
|
void force_null() {
|
2016-08-01 20:46:50 +00:00
|
|
|
if (valtype == VAL_STR) {
|
2015-08-11 20:41:12 +00:00
|
|
|
delete[] val.s;
|
2016-08-01 20:46:50 +00:00
|
|
|
val.s = nullptr;
|
|
|
|
val.len = 0;
|
|
|
|
}
|
2015-08-05 21:58:45 +00:00
|
|
|
valtype = VAL_NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
float get_float() const;
|
|
|
|
int get_int() const;
|
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;
|
2015-08-05 21:58:45 +00:00
|
|
|
void get_val(TaggedValue &r) const;
|
2015-08-11 20:41:12 +00:00
|
|
|
void get_cstr(TaggedValue &v) const;
|
|
|
|
void get_cval(TaggedValue &v) const;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
|
|
|
ostd::ConstCharRange get_key() const {
|
|
|
|
return name.iter();
|
|
|
|
}
|
|
|
|
|
|
|
|
void clean_code();
|
2015-08-06 22:02:56 +00:00
|
|
|
|
2016-07-17 17:50:40 +00:00
|
|
|
void push_arg(TaggedValue const &v, IdentStack &st, bool um = true);
|
2015-08-06 22:02:56 +00:00
|
|
|
void pop_arg();
|
|
|
|
void undo_arg(IdentStack &st);
|
2016-07-17 17:50:40 +00:00
|
|
|
void redo_arg(IdentStack const &st);
|
2015-08-06 22:16:02 +00:00
|
|
|
|
|
|
|
void push_alias(IdentStack &st);
|
|
|
|
void pop_alias();
|
2015-08-06 22:38:22 +00:00
|
|
|
|
|
|
|
void set_arg(CsState &cs, TaggedValue &v);
|
|
|
|
void set_alias(CsState &cs, TaggedValue &v);
|
2015-08-13 21:23:46 +00:00
|
|
|
|
|
|
|
int get_valtype() const {
|
2016-08-01 20:35:42 +00:00
|
|
|
return valtype;
|
|
|
|
}
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
2015-08-06 20:43:36 +00:00
|
|
|
struct IdentLink {
|
|
|
|
Ident *id;
|
|
|
|
IdentLink *next;
|
|
|
|
int usedargs;
|
|
|
|
IdentStack *argstack;
|
|
|
|
};
|
|
|
|
|
2016-03-17 21:21:45 +00:00
|
|
|
struct OSTD_EXPORT CsState {
|
2015-08-05 21:58:45 +00:00
|
|
|
ostd::Keyset<Ident> idents;
|
|
|
|
ostd::Vector<Ident *> identmap;
|
|
|
|
|
|
|
|
Ident *dummy = nullptr;
|
|
|
|
TaggedValue *result = nullptr;
|
|
|
|
|
2016-07-27 17:52:01 +00:00
|
|
|
IdentLink noalias;
|
2015-08-06 20:43:36 +00:00
|
|
|
IdentLink *stack = &noalias;
|
|
|
|
|
|
|
|
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;
|
2015-08-06 22:54:49 +00:00
|
|
|
int numargs = 0;
|
|
|
|
int dbgalias = 4;
|
2015-08-05 21:58:45 +00:00
|
|
|
|
|
|
|
CsState();
|
|
|
|
~CsState();
|
|
|
|
|
|
|
|
void clear_override(Ident &id);
|
|
|
|
void clear_overrides();
|
|
|
|
|
|
|
|
template<typename ...A>
|
|
|
|
Ident *add_ident(A &&...args) {
|
|
|
|
Ident &def = idents.emplace(ostd::forward<A>(args)...).first.front();
|
|
|
|
def.index = identmap.size();
|
|
|
|
return identmap.push(&def);
|
|
|
|
}
|
|
|
|
|
2015-08-13 18:51:15 +00:00
|
|
|
Ident *new_ident(ostd::ConstCharRange name, int flags = IDF_UNKNOWN);
|
2015-08-05 21:58:45 +00:00
|
|
|
Ident *force_ident(TaggedValue &v);
|
|
|
|
|
|
|
|
Ident *get_ident(ostd::ConstCharRange name) {
|
|
|
|
return idents.at(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool have_ident(ostd::ConstCharRange name) {
|
|
|
|
return idents.at(name) != nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool reset_var(ostd::ConstCharRange name);
|
|
|
|
void touch_var(ostd::ConstCharRange name);
|
|
|
|
|
2016-07-31 23:38:11 +00:00
|
|
|
bool add_command(ostd::ConstCharRange name, ostd::ConstCharRange args,
|
2016-08-01 18:17:13 +00:00
|
|
|
CmdFunc func, int type = ID_COMMAND, int flags = 0);
|
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);
|
2015-08-27 08:16:22 +00:00
|
|
|
ostd::String run_str(Ident *id, TvalRange args);
|
2015-08-06 01:02:06 +00:00
|
|
|
|
2016-08-06 18:12:38 +00:00
|
|
|
int run_int(Bytecode const *code);
|
2015-08-06 01:02:06 +00:00
|
|
|
int run_int(ostd::ConstCharRange code);
|
2015-08-27 08:16:22 +00:00
|
|
|
int run_int(Ident *id, TvalRange args);
|
2015-08-06 01:02:06 +00:00
|
|
|
|
2016-08-06 18:12:38 +00:00
|
|
|
float run_float(Bytecode const *code);
|
2015-08-06 01:02:06 +00:00
|
|
|
float run_float(ostd::ConstCharRange code);
|
2015-08-27 08:16:22 +00:00
|
|
|
float run_float(Ident *id, TvalRange 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);
|
2015-08-27 08:16:22 +00:00
|
|
|
bool run_bool(Ident *id, TvalRange args);
|
2015-08-06 01:07:16 +00:00
|
|
|
|
2016-08-06 18:12:38 +00:00
|
|
|
void run_ret(Bytecode const *code, TaggedValue &ret);
|
2016-02-29 00:56:53 +00:00
|
|
|
void run_ret(ostd::ConstCharRange code, TaggedValue &ret);
|
|
|
|
void run_ret(Ident *id, TvalRange args, TaggedValue &ret);
|
2015-08-07 20:04:31 +00:00
|
|
|
|
2016-08-06 18:12:38 +00:00
|
|
|
void run_ret(Bytecode const *code) {
|
2015-08-07 20:04:31 +00:00
|
|
|
run_ret(code, *result);
|
|
|
|
}
|
|
|
|
|
|
|
|
void run_ret(ostd::ConstCharRange code) {
|
|
|
|
run_ret(code, *result);
|
|
|
|
}
|
|
|
|
|
2015-08-27 08:16:22 +00:00
|
|
|
void run_ret(Ident *id, TvalRange args) {
|
2015-08-07 20:04:31 +00:00
|
|
|
run_ret(id, args, *result);
|
|
|
|
}
|
|
|
|
|
2015-09-12 15:21:40 +00:00
|
|
|
bool run_file(ostd::ConstCharRange fname);
|
2015-08-06 20:43:36 +00:00
|
|
|
|
2015-08-06 22:38:22 +00:00
|
|
|
void set_alias(ostd::ConstCharRange name, TaggedValue &v);
|
2015-08-07 01:11:53 +00:00
|
|
|
|
|
|
|
void set_var_int(ostd::ConstCharRange name, int v,
|
|
|
|
bool dofunc = true, bool doclamp = true);
|
|
|
|
void set_var_float(ostd::ConstCharRange name, float v,
|
2015-08-08 16:07:01 +00:00
|
|
|
bool dofunc = true, bool doclamp = true);
|
2015-08-07 01:11:53 +00:00
|
|
|
void set_var_str(ostd::ConstCharRange name, ostd::ConstCharRange v,
|
|
|
|
bool dofunc = true);
|
|
|
|
|
2015-08-07 01:44:51 +00:00
|
|
|
void set_var_int_checked(Ident *id, int v);
|
2015-08-27 08:16:22 +00:00
|
|
|
void set_var_int_checked(Ident *id, TvalRange args);
|
2015-08-07 01:44:51 +00:00
|
|
|
void set_var_float_checked(Ident *id, float v);
|
|
|
|
void set_var_str_checked(Ident *id, ostd::ConstCharRange v);
|
|
|
|
|
2015-08-07 01:11:53 +00:00
|
|
|
ostd::Maybe<int> get_var_int(ostd::ConstCharRange name);
|
|
|
|
ostd::Maybe<float> get_var_float(ostd::ConstCharRange name);
|
|
|
|
ostd::Maybe<ostd::String> get_var_str(ostd::ConstCharRange name);
|
|
|
|
|
|
|
|
ostd::Maybe<int> get_var_min_int(ostd::ConstCharRange name);
|
|
|
|
ostd::Maybe<int> get_var_max_int(ostd::ConstCharRange name);
|
|
|
|
|
|
|
|
ostd::Maybe<float> get_var_min_float(ostd::ConstCharRange name);
|
|
|
|
ostd::Maybe<float> get_var_max_float(ostd::ConstCharRange name);
|
|
|
|
|
2016-07-13 18:24:26 +00:00
|
|
|
ostd::Maybe<ostd::String> get_alias(ostd::ConstCharRange name);
|
2015-08-07 20:38:57 +00:00
|
|
|
|
|
|
|
void print_var(Ident *id);
|
|
|
|
void print_var_int(Ident *id, int i);
|
|
|
|
void print_var_float(Ident *id, float f);
|
|
|
|
void print_var_str(Ident *id, ostd::ConstCharRange s);
|
2015-08-05 21:58:45 +00:00
|
|
|
};
|
|
|
|
|
2016-02-28 22:21:28 +00:00
|
|
|
enum {
|
2016-08-06 15:34:10 +00:00
|
|
|
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-02-28 22:21:28 +00:00
|
|
|
};
|
|
|
|
|
2016-03-17 21:21:45 +00:00
|
|
|
OSTD_EXPORT void init_libs(CsState &cs, int libs = CS_LIB_ALL);
|
2015-08-08 15:06:18 +00:00
|
|
|
|
2015-08-13 18:48:58 +00:00
|
|
|
inline bool check_alias(Ident *id) {
|
|
|
|
return id && (id->type == ID_ALIAS);
|
|
|
|
}
|
|
|
|
|
2016-03-17 21:21:45 +00:00
|
|
|
struct OSTD_EXPORT StackedValue: TaggedValue {
|
2015-08-13 18:48:58 +00:00
|
|
|
Ident *id;
|
|
|
|
|
2016-03-04 21:28:41 +00:00
|
|
|
StackedValue(Ident *idv = nullptr):
|
|
|
|
TaggedValue(), id(idv), p_stack(), p_pushed(false) {}
|
2015-08-13 18:48:58 +00:00
|
|
|
|
|
|
|
~StackedValue() {
|
|
|
|
pop();
|
|
|
|
}
|
|
|
|
|
2015-12-16 19:05:28 +00:00
|
|
|
bool alias(CsState &cs, ostd::ConstCharRange name) {
|
|
|
|
id = cs.new_ident(name);
|
|
|
|
return check_alias(id);
|
|
|
|
}
|
|
|
|
|
2015-08-13 18:48:58 +00:00
|
|
|
bool push() {
|
2015-08-13 22:18:48 +00:00
|
|
|
if (p_pushed || !id) return false;
|
|
|
|
id->push_arg(*this, p_stack);
|
|
|
|
p_pushed = true;
|
2015-08-13 18:48:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool pop() {
|
2015-08-13 22:18:48 +00:00
|
|
|
if (!p_pushed || !id) return false;
|
2015-08-13 18:48:58 +00:00
|
|
|
id->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:
|
|
|
|
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('"');
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
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();
|
|
|
|
if (str.empty())
|
|
|
|
break;
|
|
|
|
switch (str.front()) {
|
|
|
|
case 'n':
|
|
|
|
ret += writer.put('\n');
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
ret += writer.put('\r');
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
ret += writer.put('\f');
|
|
|
|
break;
|
2016-02-11 23:06:28 +00:00
|
|
|
case '"':
|
|
|
|
ret += writer.put('"');
|
|
|
|
break;
|
|
|
|
case '^':
|
|
|
|
ret += writer.put('^');
|
|
|
|
break;
|
2015-08-11 01:18:53 +00:00
|
|
|
default:
|
|
|
|
ret += writer.put(str.front());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret += writer.put(str.front());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-08-12 23:16:52 +00:00
|
|
|
ostd::Size list_length(ostd::ConstCharRange s);
|
|
|
|
ostd::Maybe<ostd::String> list_index(ostd::ConstCharRange s,
|
|
|
|
ostd::Size idx);
|
|
|
|
ostd::Vector<ostd::String> list_explode(ostd::ConstCharRange s,
|
2015-08-08 16:07:01 +00:00
|
|
|
ostd::Size limit = -1);
|
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-02-07 21:22:39 +00:00
|
|
|
#endif /* CUBESCRIPT_HH */
|