dl
dl_script.h
浏览该文件的文档.
1
12#pragma once
13
14#include <vector>
15#include <list>
16#include <unordered_map>
17#include <functional>
18#include <string>
19#include <cassert>
20#include <stack>
21#include <variant>
22#include <array>
23
24namespace dl
25{
26 using ScriptIndex = uint32_t;
27 using ScriptInt = int64_t;
28 using ScriptFloat = double;
29 using ScriptString = std::string;
30 using ScriptIndexVS = uint8_t; // 变量空间下标
31
32 struct ScriptVar;
33 class ScriptVM;
34
35 using ScriptVector = std::vector<ScriptVar>;
36 using ScriptTable = std::unordered_map<std::string, ScriptVar>;
38 using ScriptFunction = std::function<int(ScriptVM&, const ScriptParam&)>;
39
40 constexpr ScriptIndex SCRIPT_INDEX_RETURN = (ScriptIndex)-1; // 返回值
41 constexpr ScriptIndexVS SCRIPT_INDEX_VS_0 = 0; // 全局空间
43 constexpr ScriptIndexVS SCRIPT_INDEX_VS_TEMP = (ScriptIndexVS)-2; // 临时变量
44 constexpr ScriptIndexVS SCRIPT_INDEX_VS_ERROR = (ScriptIndexVS)-1; // 初始变量
45
48 {
49 E_null, // 空
50 E_int, // 整数
51 E_float, // 浮点
52 E_string, // 字符串
53 E_class, // 类
54 E_vector, // 数组
55 E_table, // 表
56 E_function, // 函数
57 E_userdata, // 指针
58 E_operator, // 操作符
60 };
61
62 inline bool IsBaseType(ScriptVarType type)
63 {
64 return type == ScriptVarType::E_null
65 || type == ScriptVarType::E_int
66 || type == ScriptVarType::E_float
69 }
70
73 {
74 E_assign, // 赋值
75 E_add, //
79 E_comma, // 逗号,视为 push_back
80 E_equal, // ==
82 };
83 std::string_view to_string(ScriptOperator op);
84
86 struct ScriptVar
87 {
88 friend class ScriptVarSpace;
89 friend bool operator==(const ScriptVar& a, const ScriptVar& b);
90 public:
92 {
94 _indexVarSpace = SCRIPT_INDEX_VS_ERROR;
95 _value = 0;
96 }
98 {
99 assert(_indexVarSpace != SCRIPT_INDEX_VS_ITERAL);
100 _type = ScriptVarType::E_int;
101 *(ScriptInt*)&_value = *(ScriptInt*)&v;
102 }
104 {
105 assert(_indexVarSpace != SCRIPT_INDEX_VS_ITERAL);
107 *(ScriptFloat*)&_value = *(ScriptFloat*)&v;
108 }
110 {
111 assert(_indexVarSpace != SCRIPT_INDEX_VS_ITERAL);
113 *(ScriptOperator*)&_value = *(ScriptOperator*)&v;
114 }
115
116
118 {
119 assert(_type == ScriptVarType::E_int);
120 return (ScriptInt)_value;
121 }
123 {
124 assert(_type == ScriptVarType::E_float);
125 return (ScriptFloat)_value;
126 }
128 {
129 assert(_type == ScriptVarType::E_operator);
130 return (ScriptOperator)_value;
131 }
132
133 ScriptVarType GetType() const { return _type; }
134 std::string_view GetTypeString() const;
135
136 uint64_t GetValue() const
137 {
138 assert(IsBaseType(_type));
139 return _value;
140 }
141 uint64_t GetIndex() const
142 {
143 assert(!IsBaseType(_type));
144 return _value;
145 }
147 {
148 return _indexVarSpace;
149 }
150 void SetValue(uint64_t v)
151 {
152 assert(IsBaseType(_type));
153 assert(_indexVarSpace != SCRIPT_INDEX_VS_ITERAL);
154 _value = v;
155 }
157 {
158 assert(_type == ScriptVarType::E_null);
159 _type = type;
160 }
161
163 {
164 _indexVarSpace = index;
165 }
166
167 private:
168 ScriptVarType _type;
169 ScriptIndexVS _indexVarSpace; // 所在变量空间(基础类型需要释放,也需要标记)
170 uint64_t _value; // 基础类型直接存储(或变量下标)
171 };
172
173
174 inline bool operator==(const ScriptVar& a, const ScriptVar& b)
175 {
176 return a._type == b._type
177 && a._indexVarSpace == b._indexVarSpace
178 && a._value == b._value;
179 }
180
181 // 初步token(文本解析)
183 {
184 enum Type
185 {
188 OPERATOR,// 操作符
189 };
191 _type{ Type::NORMAL }
192 {}
193 ScriptToken(Type type, std::string_view str) :
194 _type{ type },
195 _str{ std::string{str} }
196 {}
197
199 std::string _str;
200 };
201
202 std::string_view to_string(ScriptToken::Type type);
203
206 {
207 ESET_variable, // 变量
208 ESET_literal, // 字面量
210 };
211
214 {
216 std::string _name; // 字符串内容(变量使用)
217 ScriptVar _value; // 值(表达式用、字面量)
218
219 std::string GetTypeString() const
220 {
221 return "expr_token";
222 }
223 };
224
227 {
228 std::vector<ScriptExprToken> _allToken;
229 size_t _lineNumber; // 行号(0开始)
230 std::string _strRaw;// 源代码,调试用
231 };
232
233 inline std::string to_string(const ScriptExpr& expr)
234 {
235 if (expr._allToken.empty())
236 return {};
237 std::string ret;
238 for (size_t i = 0; i < expr._allToken.size() - 1; ++i)
239 {
240 ret += expr._allToken[i]._name;
241 ret += ' ';
242 }
243 ret += expr._allToken[expr._allToken.size() - 1]._name;
244 return ret;
245 }
246
249 {
250 public:
251 ScriptVarSpace(ScriptIndexVS index, size_t level) :
252 _index{ index },
253 _level{ level }
254 {}
255 ScriptIndexVS GetIndex() const { return _index; }
256 size_t GetLevel() const { return _level; }
257
258 ScriptVar AddString(std::string_view v)
259 {
260 ScriptVar ret;
261 ret._type = ScriptVarType::E_string;
262 ret._indexVarSpace = _index;
263 ret._value = _vecString.size();
264 _vecString.push_back(std::string{ v });
265 return ret;
266 }
268 {
269 ScriptVar ret;
270 ret._type = ScriptVarType::E_function;
271 ret._indexVarSpace = _index;
272 ret._value = _vecFunction.size();
273 _vecFunction.push_back(v);
274 return ret;
275 }
277 {
278 ScriptVar ret;
279 ret._type = ScriptVarType::E_vector;
280 ret._indexVarSpace = _index;
281 ret._value = _vecVector.size();
282 _vecVector.push_back({});
283 return ret;
284 }
285 void SetString(size_t i, const ScriptString& str)
286 {
287 _vecString[i] = str;
288 }
289 void SetVector(size_t i, const ScriptVector& vec)
290 {
291 _vecVector[i] = vec;
292 }
293
294 const ScriptString& GetString(size_t i) const
295 {
296 return _vecString[i];
297 }
298 const ScriptFunction& GetFunction(size_t i) const
299 {
300 return _vecFunction[i];
301 }
303 {
304 return _vecVector[i];
305 }
306 private:
307 ScriptIndexVS _index; // 自己下标 0全局变量
308 size_t _level;
309 std::vector<ScriptString> _vecString;
310 std::vector<ScriptTable> _vecClass;
311 std::vector<ScriptVector> _vecVector;
312 std::vector<ScriptTable> _vecTable;
313 std::vector<ScriptFunction> _vecFunction;
314 std::vector<ScriptExpr> _vecExpr;
315 };
316
317
329
332 {
334 size_t _level; // 层级(作用域)
335 std::vector<ScriptExpr> _allExpr;
336 };
337
339 {
343
344 std::vector<ScriptSegment> _allSeg;
345 // 字面量是编译器固定的,不可修改,全局可见,所以单独处理
347 std::vector<std::string> _vecSource;// 不包含换行
348
349 std::string GetSource(bool line_number = true, bool header = true, bool footer = true) const;
350 };
351
352
370 {
371 std::array<ScriptExpr, 3> _cond;
373 };
379
382 {
383 //std::
384 };
385
388 {
389 friend class ScriptSystem;
390 public:
391 void Execute(const ScriptBlock& block);
392
393 // 变量转字符串
394 std::string Variable2String(const ScriptVar& var);
395 // 变量转bool
396 bool Variable2Bool(const ScriptVar& var);
397
398 // 中断执行(内部调用)
399 void Throw() { _bThrow = true; }
400
402 private:
403 // 当前执行代码块
404 const ScriptBlock* _block;
405 // 名字 -> 变量(变量)
406 std::unordered_map<std::string, ScriptVar> _allVar;
407 // 全局变量空间
408 ScriptVarSpace _varSpaceGlobal;
409 // 变量空间
410 std::vector<ScriptVarSpace*> _allVarSpace;
411 // 函数参数
412 ScriptParam _param;
413
414 //-------------------------------expr------------------------------
415 // 返回值(可变)
416 ScriptExprToken _return;
417 // 操作堆栈
418 std::vector<ScriptIndex> _stackVar;
419 // 当前表达式
420 const ScriptExpr* _expr;
421 // 临时变量空间
422 ScriptVarSpace _varSpaceTemp; //todo清理
423 // 出现异常
424 bool _bThrow;
425
426 void _exec_expr(const ScriptExpr& expr);
427 void _clear_expr();
428
429 // 从 操作堆栈 访问
430 const ScriptExprToken& _get_stack_expr_token(size_t i);
431 const ScriptExprToken& _get_stack_expr_token_top(size_t i);
432 ScriptVar& _get_stack_var(size_t i);
433 ScriptVar& _get_stack_var_top(size_t i);
434
435 void _stack_pop(size_t i);
436
437 void _op_arithmetic(ScriptOperator op);
438 void _op_assign();
439 void _op_comma();
440 void _op_equal();
441
442 // 获取(新建)变量,新建则在当前变量空间初始化
443 ScriptVar& _get_variable(const ScriptExprToken& var0);
444 // 移除变量空间后,从变量表中移除
445 void _delete_var_space(ScriptVarSpace* vs);
446
447 // 返回变量所在空间
448 ScriptVarSpace* GetVariableSpaceRef(ScriptIndexVS index);
449 const ScriptVarSpace* GetVariableSpace(ScriptIndexVS index);
450 ScriptVarSpace* GetVariableSpaceRef(ScriptVar var)
451 {
452 return GetVariableSpaceRef(var.GetSpaceIndex());
453 }
454 const ScriptVarSpace* GetVariableSpace(ScriptVar var)
455 {
456 return GetVariableSpace(var.GetSpaceIndex());
457 }
458 //------------------------------------变量创建(默认值)--------------
459 ScriptVar AddVariable(ScriptIndexVS index, ScriptVarType type);
460 //------------------------------------变量获取(必须已存在)--------------
461 ScriptFunction GetVariableFunction(ScriptVar var);
462 ScriptString GetVariableString(ScriptVar var);
463 ScriptVector& GetVariableVector(ScriptVar var);
464 //------------------------------------变量设置(必须已存在)--------------
465 void SetVariableString(ScriptVar var, ScriptString str);
466 void SetVariableVector(ScriptVar var, const ScriptVector& vec);
467
468 };
469
472 {
473 public:
474 ScriptBlock Compile(std::string_view src);
475
476 // 中缀 -> 后缀(逆波兰表达式)
477 std::vector<ScriptExprToken> ConvertMid(const std::vector<ScriptExprToken>& vec);
478
480 std::string Preprocess(std::string_view src);
481 void PreprocessLineNumber(ScriptBlock& block, std::string_view src);
482
484 bool IsOperator(std::string_view str);
486 bool IsMaybeOperator(char ch);
487
489 int GetOperatorPriority(std::string_view str);
490
492 bool IsKeyword(std::string_view str);
494 bool IsVariable(std::string_view str);
496 bool IsGlobalVariable(std::string_view str);
497
499 ScriptExprTokenType GetTokenType(std::string_view str);
500
503
506
508 void RegisterFunction(std::string_view name, ScriptFunction func)
509 {
510 ScriptVar var = _varSpaceGlobal.AddFunction(func);
511 _allVar[std::string{ name }] = var;
512 }
514 {
515 vm._allVar = _allVar;
516 vm._varSpaceGlobal = _varSpaceGlobal;
517 }
518
520
522 ScriptOperator String2Operator(std::string_view str);
523
524 //------------------------------------基础运算(不考虑变量)-----------------------
526 void OpAssign(ScriptVM& vm, ScriptVar& v0, const ScriptVar& v1);
527
529 private:
530 // 关键字
531 std::unordered_map<std::string_view, int> _allKeyword;
532 // 操作符、优先级(越大越优先)
533 std::unordered_map<std::string_view, int> _allOperator;
534 // 变量空间池
535 std::list<ScriptVarSpace*> _listVarSpaceFree;
536 // 内置变量(例print)
537 std::unordered_map<std::string, ScriptVar> _allVar;
538 // 内置变量空间(全局)
539 ScriptVarSpace _varSpaceGlobal;
540 };
541
542 extern ScriptSystem* g_script;
543}
bool IsVariable(std::string_view str)
是否变量名
std::string Preprocess(std::string_view src)
预处理代码(行号不变)
ScriptBlock Compile(std::string_view src)
int GetOperatorPriority(std::string_view str)
返回操作符优先级,越大越优先
bool IsOperator(std::string_view str)
是否操作符
bool IsKeyword(std::string_view str)
是否关键字
bool CheckToken(ScriptExprTokenType type)
bool IsGlobalVariable(std::string_view str)
是否全局变量名
void PreprocessLineNumber(ScriptBlock &block, std::string_view src)
void RegisterFunction(std::string_view name, ScriptFunction func)
注册函数
void CopyVariableToVm(ScriptVM &vm)
ScriptVar OpArithmetic(ScriptVM &vm, ScriptOperator op, const ScriptVar &v0, const ScriptVar &v1)
ScriptVar MakeLiteral(ScriptBlock &block, const ScriptToken &token)
生成字面量
void OpAssign(ScriptVM &vm, ScriptVar &v0, const ScriptVar &v1)
ScriptExprToken MakeExprToken(ScriptBlock &block, const ScriptToken &token)
生成表达式token(字面量是编译器信息,需要生成到block)
std::vector< ScriptExprToken > ConvertMid(const std::vector< ScriptExprToken > &vec)
bool IsMaybeOperator(char ch)
是否可能为操作符内容(变量名不可能出现)
ScriptExprTokenType GetTokenType(std::string_view str)
返回token类型
ScriptOperator String2Operator(std::string_view str)
字符串转操作符变量
std::string Variable2String(const ScriptVar &var)
bool Variable2Bool(const ScriptVar &var)
void Execute(const ScriptBlock &block)
friend class ScriptSystem
ScriptVector & GetVetorRef(size_t i)
void SetString(size_t i, const ScriptString &str)
const ScriptString & GetString(size_t i) const
void SetVector(size_t i, const ScriptVector &vec)
ScriptVar AddFunction(ScriptFunction v)
const ScriptFunction & GetFunction(size_t i) const
ScriptVar AddString(std::string_view v)
ScriptIndexVS GetIndex() const
ScriptVarSpace(ScriptIndexVS index, size_t level)
size_t GetLevel() const
ScriptSystem * g_script
std::unordered_map< std::string, ScriptVar > ScriptTable
constexpr ScriptIndexVS SCRIPT_INDEX_VS_0
std::function< int(ScriptVM &, const ScriptParam &)> ScriptFunction
constexpr ScriptIndexVS SCRIPT_INDEX_VS_ITERAL
ScriptExprTokenType
表达式token类型
constexpr ScriptIndexVS SCRIPT_INDEX_VS_ERROR
ScriptSegmentType
uint32_t ScriptIndex
std::string to_string(T v)
to_string包装
std::vector< ScriptVar > ScriptVector
ScriptVarType
变量类型(用户层面)
bool IsBaseType(ScriptVarType type)
是基础类型
std::string ScriptString
ScriptVector ScriptParam
ScriptOperator
操作类型
int64_t ScriptInt
constexpr ScriptIndex SCRIPT_INDEX_RETURN
double ScriptFloat
constexpr ScriptIndexVS SCRIPT_INDEX_VS_TEMP
uint8_t ScriptIndexVS
constexpr bool operator==(const Array< T, N > &a, const Array< T, N > &b)
std::vector< std::string > _vecSource
ScriptVarSpace _varSpaceIteral
std::vector< ScriptSegment > _allSeg
std::string GetSource(bool line_number=true, bool header=true, bool footer=true) const
std::array< ScriptExpr, 3 > _cond
后缀表达式
std::vector< ScriptExprToken > _allToken
std::string _strRaw
表达式token(指向真实变量)
ScriptExprTokenType _type
std::string GetTypeString() const
代码段(包含单独作用域)
std::vector< ScriptExpr > _allExpr
ScriptSegmentType _type
代码段运行时
ScriptToken(Type type, std::string_view str)
变量(大小严格控制)
void _set_space_index(ScriptIndexVS index)
void SetType(ScriptVarType type)
std::string_view GetTypeString() const
ScriptVarType GetType() const
ScriptFloat ToFloat() const
void FromInt(ScriptInt v)
void FromFloat(ScriptFloat v)
ScriptOperator ToOperator() const
ScriptIndexVS GetSpaceIndex() const
uint64_t GetValue() const
friend bool operator==(const ScriptVar &a, const ScriptVar &b)
uint64_t GetIndex() const
ScriptInt ToInt() const
void FromOperator(ScriptOperator v)
void SetValue(uint64_t v)
friend class ScriptVarSpace