mirascript 0.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mirascript/__init__.py +11 -0
- mirascript/deep_nonlocal_fix.py +136 -0
- mirascript/diagnostics.py +82 -0
- mirascript/emit.py +1182 -0
- mirascript/main.py +26 -0
- mirascript/subtle.py +5 -0
- mirascript/vm/VmWrapper.py +50 -0
- mirascript/vm/__init__.py +15 -0
- mirascript/vm/env.py +13 -0
- mirascript/vm/error.py +19 -0
- mirascript/vm/helpers.py +124 -0
- mirascript/vm/operations.py +592 -0
- mirascript/vm/types/__init__.py +21 -0
- mirascript/vm/types/checker.py +107 -0
- mirascript/vm/types/const.py +39 -0
- mirascript/vm/types/context.py +130 -0
- mirascript/vm/types/extern.py +123 -0
- mirascript/vm/types/function.py +28 -0
- mirascript/vm/types/module.py +33 -0
- mirascript/vm/types/script.py +17 -0
- mirascript/vm/types/types.py +143 -0
- mirascript/vm/types/wrapper.py +56 -0
- mirascript-0.0.6.dist-info/METADATA +17 -0
- mirascript-0.0.6.dist-info/RECORD +26 -0
- mirascript-0.0.6.dist-info/WHEEL +5 -0
- mirascript-0.0.6.dist-info/top_level.txt +1 -0
mirascript/main.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from .mirascript import Config, compile as _compile
|
|
2
|
+
from .emit import emit
|
|
3
|
+
from .diagnostics import decode_diagnostics, Diagnostic
|
|
4
|
+
|
|
5
|
+
DefaultConfig = Config(input_mode="script")
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def compile(
|
|
9
|
+
script: str, config: Config = DefaultConfig
|
|
10
|
+
) :
|
|
11
|
+
"""
|
|
12
|
+
编译 MiraScript 代码,生成 Python 函数
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
script (str): 要编译的 MiraScript 代码
|
|
16
|
+
config (Config): 编译配置
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
(Script | None): 编译后的 Python 函数
|
|
20
|
+
list[Diagnostic]: 编译过程中产生的诊断信息
|
|
21
|
+
"""
|
|
22
|
+
bytecode, diagnostics = _compile(script, config)
|
|
23
|
+
decoded_diagnostics = decode_diagnostics(diagnostics)
|
|
24
|
+
func = emit(bytecode) if bytecode else None
|
|
25
|
+
return func, decoded_diagnostics
|
|
26
|
+
|
mirascript/subtle.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class VmWrapper(ABC):
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
_VM_WRAPPER_SYMBOL='mirascript.vm.wrapper'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def __init__(self):
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
@abstractmethod
|
|
15
|
+
def has(self,key):
|
|
16
|
+
pass
|
|
17
|
+
@abstractmethod
|
|
18
|
+
def get(self,key):
|
|
19
|
+
pass
|
|
20
|
+
@abstractmethod
|
|
21
|
+
def keys(self):
|
|
22
|
+
pass
|
|
23
|
+
@abstractmethod
|
|
24
|
+
def same(self,other):
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
@abstractmethod
|
|
29
|
+
def type(self):
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
@abstractmethod
|
|
34
|
+
def describe(self):
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## Convert the object to JSON
|
|
39
|
+
def toJSON(self):
|
|
40
|
+
return None
|
|
41
|
+
|
|
42
|
+
## 转为字符串
|
|
43
|
+
def toString(self):
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
def isVmWrapper(v):
|
|
47
|
+
if v is None or not isinstance(v,object):
|
|
48
|
+
return False
|
|
49
|
+
|
|
50
|
+
return hasattr(v,VmWrapper._VM_WRAPPER_SYMBOL)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# from .lib._loader import *
|
|
2
|
+
|
|
3
|
+
from .error import *
|
|
4
|
+
from .types import *
|
|
5
|
+
from .helpers import config_checkpoint
|
|
6
|
+
from .lib._loader import lib
|
|
7
|
+
_all__ = [
|
|
8
|
+
'VmError', 'VmExtern', 'VmFunction', 'VmModule',
|
|
9
|
+
'VmValue', 'VmConst', 'VmArray', 'VmRecord',
|
|
10
|
+
'is_vm_primitive', 'is_vm_const', 'is_vm_array', 'is_vm_record',
|
|
11
|
+
'is_vm_extern', 'is_vm_module',
|
|
12
|
+
'Type_', 'ToNumber_',
|
|
13
|
+
'config_checkpoint',
|
|
14
|
+
'VM_ARRAY_MAX_LENGTH',
|
|
15
|
+
]
|
mirascript/vm/env.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from . import operations,helpers
|
|
2
|
+
|
|
3
|
+
# print(dir(operations))
|
|
4
|
+
|
|
5
|
+
vm_globals={k:getattr(operations,k) for k in dir(operations) if not k.startswith("_")}
|
|
6
|
+
|
|
7
|
+
for k in dir(helpers):
|
|
8
|
+
if not k.startswith("_"):
|
|
9
|
+
vm_globals[k]=getattr(helpers,k)
|
|
10
|
+
|
|
11
|
+
for k in dir(helpers):
|
|
12
|
+
if not k.startswith("_"):
|
|
13
|
+
vm_globals[k]=getattr(helpers,k)
|
mirascript/vm/error.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
## VM 预期的错误
|
|
4
|
+
|
|
5
|
+
class VmError(Exception):
|
|
6
|
+
|
|
7
|
+
def __init__(self, message,recovered):
|
|
8
|
+
super().__init__(message)
|
|
9
|
+
self.message = message
|
|
10
|
+
self.recovered = recovered
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@staticmethod
|
|
14
|
+
def from_(prefix,error,recovered):
|
|
15
|
+
if prefix and not prefix.endswith(":"):
|
|
16
|
+
prefix += ":"
|
|
17
|
+
vmError = VmError(f"{prefix}{str(error)}",recovered)
|
|
18
|
+
|
|
19
|
+
return vmError
|
mirascript/vm/helpers.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import math
|
|
3
|
+
|
|
4
|
+
from mirascript.vm.types.const import VM_ARRAY_MAX_LENGTH
|
|
5
|
+
from .operations import ToNumber_,AssertInit_
|
|
6
|
+
from .types.checker import is_vm_const
|
|
7
|
+
from .types.context import DefaultVmContext
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def Vargs(varags):
|
|
11
|
+
"""将非常量元素置为 None,返回新列表"""
|
|
12
|
+
# 这里假设 is_vm_const 已在其他地方实现
|
|
13
|
+
args = list(varags)
|
|
14
|
+
for i in range(len(args)):
|
|
15
|
+
el = args[i]
|
|
16
|
+
if not is_vm_const(el):
|
|
17
|
+
args[i] = None
|
|
18
|
+
return args
|
|
19
|
+
|
|
20
|
+
def Element(value):
|
|
21
|
+
# 假设 $AssertInit 已在其他地方实现
|
|
22
|
+
AssertInit_(value)
|
|
23
|
+
if not is_vm_const(value):
|
|
24
|
+
return None
|
|
25
|
+
return value
|
|
26
|
+
|
|
27
|
+
def ElementOpt(key, value):
|
|
28
|
+
AssertInit_(value)
|
|
29
|
+
if value is None or not is_vm_const(value):
|
|
30
|
+
return {}
|
|
31
|
+
return {key: value}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def Upvalue(value):
|
|
36
|
+
AssertInit_(value)
|
|
37
|
+
return value
|
|
38
|
+
|
|
39
|
+
def assert_array_length(start, end):
|
|
40
|
+
if end - start > VM_ARRAY_MAX_LENGTH:
|
|
41
|
+
raise RuntimeError(f"Array length exceeds maximum limit of {VM_ARRAY_MAX_LENGTH}")
|
|
42
|
+
|
|
43
|
+
def is_empty_range(start, end):
|
|
44
|
+
return not math.isfinite(start) or not math.isfinite(end) or start > end
|
|
45
|
+
|
|
46
|
+
def ArrayRange(start, end):
|
|
47
|
+
s = ToNumber_(start)
|
|
48
|
+
e = ToNumber_(end)
|
|
49
|
+
if is_empty_range(s, e):
|
|
50
|
+
return []
|
|
51
|
+
assert_array_length(s, e)
|
|
52
|
+
arr = []
|
|
53
|
+
i =s
|
|
54
|
+
while i <= e:
|
|
55
|
+
arr.append(i)
|
|
56
|
+
i += 1
|
|
57
|
+
return arr
|
|
58
|
+
|
|
59
|
+
def ArrayRangeExclusive(start, end):
|
|
60
|
+
s = ToNumber_(start)
|
|
61
|
+
e = ToNumber_(end)
|
|
62
|
+
if is_empty_range(s, e):
|
|
63
|
+
return []
|
|
64
|
+
assert_array_length(s, e)
|
|
65
|
+
arr = []
|
|
66
|
+
i = s
|
|
67
|
+
while i < e:
|
|
68
|
+
arr.append(i)
|
|
69
|
+
i += 1
|
|
70
|
+
return arr
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
MAX_DEPTH = 128
|
|
77
|
+
cp_depth = 0
|
|
78
|
+
cp = float('nan')
|
|
79
|
+
cp_timeout = 100 # 默认超时时间,单位毫秒
|
|
80
|
+
|
|
81
|
+
def Cp():
|
|
82
|
+
"""检查点"""
|
|
83
|
+
pass
|
|
84
|
+
global cp
|
|
85
|
+
current_time = int(time.time() * 1000)
|
|
86
|
+
if not cp or (isinstance(cp, float) and cp != cp): # NaN 检查
|
|
87
|
+
cp = current_time
|
|
88
|
+
elif current_time - cp > cp_timeout:
|
|
89
|
+
raise RuntimeError(f'Execution timeout, exceeded {cp_timeout} ms , last checkpoint at {cp} ms , current time {current_time} ms')
|
|
90
|
+
|
|
91
|
+
def CpEnter():
|
|
92
|
+
"""进入检查点"""
|
|
93
|
+
global cp_depth, cp
|
|
94
|
+
cp_depth += 1
|
|
95
|
+
if cp_depth <= 1:
|
|
96
|
+
cp = int(time.time() * 1000)
|
|
97
|
+
cp_depth = 1
|
|
98
|
+
elif cp_depth > MAX_DEPTH:
|
|
99
|
+
raise RuntimeError('Maximum call depth exceeded')
|
|
100
|
+
else:
|
|
101
|
+
Cp()
|
|
102
|
+
|
|
103
|
+
def CpExit():
|
|
104
|
+
"""退出检查点"""
|
|
105
|
+
global cp_depth, cp
|
|
106
|
+
cp_depth -= 1
|
|
107
|
+
if cp_depth < 1:
|
|
108
|
+
cp = float('nan')
|
|
109
|
+
cp_depth = 0
|
|
110
|
+
else:
|
|
111
|
+
Cp()
|
|
112
|
+
|
|
113
|
+
def config_checkpoint(timeout=100):
|
|
114
|
+
"""设置检查点超时时间"""
|
|
115
|
+
global cp_timeout
|
|
116
|
+
if not isinstance(timeout, (int, float)) or timeout is None or timeout <= 0 or (isinstance(timeout, float) and timeout != timeout):
|
|
117
|
+
raise ValueError('Invalid timeout value')
|
|
118
|
+
cp_timeout = timeout
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def GlobalFallback():
|
|
124
|
+
return DefaultVmContext
|