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#include <cstdint>
24
25namespace dl
26{
27 using ScriptIndex = uint32_t;
28 using ScriptInt = int64_t;
29 using ScriptFloat = double;
30 using ScriptString = std::string;
31 using ScriptIndexVS = uint8_t; // 变量空间下标
32
33 struct ScriptVar;
34 class ScriptVM;
35
36 using ScriptVector = std::vector<ScriptVar>;
37 using ScriptTable = std::unordered_map<std::string, ScriptVar>;
39 using ScriptFunction = std::function<int(ScriptVM&, const ScriptParam&)>;
40
41 constexpr ScriptIndex SCRIPT_INDEX_RETURN = (ScriptIndex)-1; // 返回值
42 constexpr ScriptIndexVS SCRIPT_INDEX_VS_0 = 0; // 全局空间
44 constexpr ScriptIndexVS SCRIPT_INDEX_VS_TEMP = (ScriptIndexVS)-2; // 临时变量
45 constexpr ScriptIndexVS SCRIPT_INDEX_VS_ERROR = (ScriptIndexVS)-1; // 初始变量
46
49 {
50 E_null, // 空
51 E_int, // 整数
52 E_float, // 浮点
53 E_string, // 字符串
54 E_class, // 类
55 E_vector, // 数组
56 E_table, // 表
57 E_function, // 函数
58 E_userdata, // 指针
59 E_operator, // 操作符
61 };
62
63 inline bool IsBaseType(ScriptVarType type)
64 {
65 return type == ScriptVarType::E_null
66 || type == ScriptVarType::E_int
67 || type == ScriptVarType::E_float
70 }
71
74 {
75 E_assign, // 赋值
76 E_add, //
80 E_comma, // 逗号,视为 push_back
81 E_equal, // ==
83 };
84 std::string_view to_string(ScriptOperator op);
85
87 struct ScriptVar
88 {
89 friend class ScriptVarSpace;
90 friend bool operator==(const ScriptVar& a, const ScriptVar& b);
91 public:
93 {
95 _indexVarSpace = SCRIPT_INDEX_VS_ERROR;
96 _value = 0;
97 }
99 {
100 assert(_indexVarSpace != SCRIPT_INDEX_VS_ITERAL);
101 _type = ScriptVarType::E_int;
102 *(ScriptInt*)&_value = *(ScriptInt*)&v;
103 }
105 {
106 assert(_indexVarSpace != SCRIPT_INDEX_VS_ITERAL);
108 *(ScriptFloat*)&_value = *(ScriptFloat*)&v;
109 }
111 {
112 assert(_indexVarSpace != SCRIPT_INDEX_VS_ITERAL);
114 *(ScriptOperator*)&_value = *(ScriptOperator*)&v;
115 }
116
117
119 {
120 assert(_type == ScriptVarType::E_int);
121 return (ScriptInt)_value;
122 }
124 {
125 assert(_type == ScriptVarType::E_float);
126 return (ScriptFloat)_value;
127 }
129 {
130 assert(_type == ScriptVarType::E_operator);
131 return (ScriptOperator)_value;
132 }
133
134 ScriptVarType GetType() const { return _type; }
135 std::string_view GetTypeString() const;
136
137 uint64_t GetValue() const
138 {
139 assert(IsBaseType(_type));
140 return _value;
141 }
142 uint64_t GetIndex() const
143 {
144 assert(!IsBaseType(_type));
145 return _value;
146 }
148 {
149 return _indexVarSpace;
150 }
151 void SetValue(uint64_t v)
152 {
153 assert(IsBaseType(_type));
154 assert(_indexVarSpace != SCRIPT_INDEX_VS_ITERAL);
155 _value = v;
156 }
158 {
159 assert(_type == ScriptVarType::E_null);
160 _type = type;
161 }
162
164 {
165 _indexVarSpace = index;
166 }
167
168 private:
169 ScriptVarType _type;
170 ScriptIndexVS _indexVarSpace; // 所在变量空间(基础类型需要释放,也需要标记)
171 uint64_t _value; // 基础类型直接存储(或变量下标)
172 };
173
174
175 inline bool operator==(const ScriptVar& a, const ScriptVar& b)
176 {
177 return a._type == b._type
178 && a._indexVarSpace == b._indexVarSpace
179 && a._value == b._value;
180 }
181
182 // 初步token(文本解析)
184 {
185 enum Type
186 {
189 OPERATOR,// 操作符
190 };
192 _type{ Type::NORMAL }
193 {}
194 ScriptToken(Type type, std::string_view str) :
195 _type{ type },
196 _str{ std::string{str} }
197 {}
198
200 std::string _str;
201 };
202
203 std::string_view to_string(ScriptToken::Type type);
204
207 {
208 ESET_variable, // 变量
209 ESET_literal, // 字面量
211 };
212
215 {
217 std::string _name; // 字符串内容(变量使用)
218 ScriptVar _value; // 值(表达式用、字面量)
219
220 std::string GetTypeString() const
221 {
222 return "expr_token";
223 }
224 };
225
228 {
229 std::vector<ScriptExprToken> _allToken;
230 size_t _lineNumber; // 行号(0开始)
231 std::string _strRaw;// 源代码,调试用
232 };
233
234 inline std::string to_string(const ScriptExpr& expr)
235 {
236 if (expr._allToken.empty())
237 return {};
238 std::string ret;
239 for (size_t i = 0; i < expr._allToken.size() - 1; ++i)
240 {
241 ret += expr._allToken[i]._name;
242 ret += ' ';
243 }
244 ret += expr._allToken[expr._allToken.size() - 1]._name;
245 return ret;
246 }
247
250 {
251 public:
252 ScriptVarSpace(ScriptIndexVS index, size_t level) :
253 _index{ index },
254 _level{ level }
255 {}
256 ScriptIndexVS GetIndex() const { return _index; }
257 size_t GetLevel() const { return _level; }
258
259 ScriptVar AddString(std::string_view v)
260 {
261 ScriptVar ret;
262 ret._type = ScriptVarType::E_string;
263 ret._indexVarSpace = _index;
264 ret._value = _vecString.size();
265 _vecString.push_back(std::string{ v });
266 return ret;
267 }
269 {
270 ScriptVar ret;
271 ret._type = ScriptVarType::E_function;
272 ret._indexVarSpace = _index;
273 ret._value = _vecFunction.size();
274 _vecFunction.push_back(v);
275 return ret;
276 }
278 {
279 ScriptVar ret;
280 ret._type = ScriptVarType::E_vector;
281 ret._indexVarSpace = _index;
282 ret._value = _vecVector.size();
283 _vecVector.push_back({});
284 return ret;
285 }
286 void SetString(size_t i, const ScriptString& str)
287 {
288 _vecString[i] = str;
289 }
290 void SetVector(size_t i, const ScriptVector& vec)
291 {
292 _vecVector[i] = vec;
293 }
294
295 const ScriptString& GetString(size_t i) const
296 {
297 return _vecString[i];
298 }
299 const ScriptFunction& GetFunction(size_t i) const
300 {
301 return _vecFunction[i];
302 }
304 {
305 return _vecVector[i];
306 }
307 private:
308 ScriptIndexVS _index; // 自己下标 0全局变量
309 size_t _level;
310 std::vector<ScriptString> _vecString;
311 std::vector<ScriptTable> _vecClass;
312 std::vector<ScriptVector> _vecVector;
313 std::vector<ScriptTable> _vecTable;
314 std::vector<ScriptFunction> _vecFunction;
315 std::vector<ScriptExpr> _vecExpr;
316 };
317
318
330
333 {
335 size_t _level; // 层级(作用域)
336 std::vector<ScriptExpr> _allExpr;
337 };
338
340 {
344
345 std::vector<ScriptSegment> _allSeg;
346 // 字面量是编译器固定的,不可修改,全局可见,所以单独处理
348 std::vector<std::string> _vecSource;// 不包含换行
349
350 std::string GetSource(bool line_number = true, bool header = true, bool footer = true) const;
351 };
352
353
371 {
372 std::array<ScriptExpr, 3> _cond;
374 };
380
383 {
384 //std::
385 };
386
389 {
390 friend class ScriptSystem;
391 public:
392 void Execute(const ScriptBlock& block);
393
394 // 变量转字符串
395 std::string Variable2String(const ScriptVar& var);
396 // 变量转bool
397 bool Variable2Bool(const ScriptVar& var);
398
399 // 中断执行(内部调用)
400 void Throw() { _bThrow = true; }
401
403 private:
404 // 当前执行代码块
405 const ScriptBlock* _block;
406 // 名字 -> 变量(变量)
407 std::unordered_map<std::string, ScriptVar> _allVar;
408 // 全局变量空间
409 ScriptVarSpace _varSpaceGlobal;
410 // 变量空间
411 std::vector<ScriptVarSpace*> _allVarSpace;
412 // 函数参数
413 ScriptParam _param;
414
415 //-------------------------------expr------------------------------
416 // 返回值(可变)
417 ScriptExprToken _return;
418 // 操作堆栈
419 std::vector<ScriptIndex> _stackVar;
420 // 当前表达式
421 const ScriptExpr* _expr;
422 // 临时变量空间
423 ScriptVarSpace _varSpaceTemp; //todo清理
424 // 出现异常
425 bool _bThrow;
426
427 void _exec_expr(const ScriptExpr& expr);
428 void _clear_expr();
429
430 // 从 操作堆栈 访问
431 const ScriptExprToken& _get_stack_expr_token(size_t i);
432 const ScriptExprToken& _get_stack_expr_token_top(size_t i);
433 ScriptVar& _get_stack_var(size_t i);
434 ScriptVar& _get_stack_var_top(size_t i);
435
436 void _stack_pop(size_t i);
437
438 void _op_arithmetic(ScriptOperator op);
439 void _op_assign();
440 void _op_comma();
441 void _op_equal();
442
443 // 获取(新建)变量,新建则在当前变量空间初始化
444 ScriptVar& _get_variable(const ScriptExprToken& var0);
445 // 移除变量空间后,从变量表中移除
446 void _delete_var_space(ScriptVarSpace* vs);
447
448 // 返回变量所在空间
449 ScriptVarSpace* GetVariableSpaceRef(ScriptIndexVS index);
450 const ScriptVarSpace* GetVariableSpace(ScriptIndexVS index);
451 ScriptVarSpace* GetVariableSpaceRef(ScriptVar var)
452 {
453 return GetVariableSpaceRef(var.GetSpaceIndex());
454 }
455 const ScriptVarSpace* GetVariableSpace(ScriptVar var)
456 {
457 return GetVariableSpace(var.GetSpaceIndex());
458 }
459 //------------------------------------变量创建(默认值)--------------
460 ScriptVar AddVariable(ScriptIndexVS index, ScriptVarType type);
461 //------------------------------------变量获取(必须已存在)--------------
462 ScriptFunction GetVariableFunction(ScriptVar var);
463 ScriptString GetVariableString(ScriptVar var);
464 ScriptVector& GetVariableVector(ScriptVar var);
465 //------------------------------------变量设置(必须已存在)--------------
466 void SetVariableString(ScriptVar var, ScriptString str);
467 void SetVariableVector(ScriptVar var, const ScriptVector& vec);
468
469 };
470
473 {
474 public:
475 ScriptBlock Compile(std::string_view src);
476
477 // 中缀 -> 后缀(逆波兰表达式)
478 std::vector<ScriptExprToken> ConvertMid(const std::vector<ScriptExprToken>& vec);
479
481 std::string Preprocess(std::string_view src);
482 void PreprocessLineNumber(ScriptBlock& block, std::string_view src);
483
485 bool IsOperator(std::string_view str);
487 bool IsMaybeOperator(char ch);
488
490 int GetOperatorPriority(std::string_view str);
491
493 bool IsKeyword(std::string_view str);
495 bool IsVariable(std::string_view str);
497 bool IsGlobalVariable(std::string_view str);
498
500 ScriptExprTokenType GetTokenType(std::string_view str);
501
504
507
509 void RegisterFunction(std::string_view name, ScriptFunction func)
510 {
511 ScriptVar var = _varSpaceGlobal.AddFunction(func);
512 _allVar[std::string{ name }] = var;
513 }
515 {
516 vm._allVar = _allVar;
517 vm._varSpaceGlobal = _varSpaceGlobal;
518 }
519
521
523 ScriptOperator String2Operator(std::string_view str);
524
525 //------------------------------------基础运算(不考虑变量)-----------------------
527 void OpAssign(ScriptVM& vm, ScriptVar& v0, const ScriptVar& v1);
528
530 private:
531 // 关键字
532 std::unordered_map<std::string_view, int> _allKeyword;
533 // 操作符、优先级(越大越优先)
534 std::unordered_map<std::string_view, int> _allOperator;
535 // 变量空间池
536 std::list<ScriptVarSpace*> _listVarSpaceFree;
537 // 内置变量(例print)
538 std::unordered_map<std::string, ScriptVar> _allVar;
539 // 内置变量空间(全局)
540 ScriptVarSpace _varSpaceGlobal;
541 };
542
543 extern ScriptSystem* g_script;
544}
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