mirascript 0.0.6__tar.gz

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.
Files changed (38) hide show
  1. mirascript-0.0.6/PKG-INFO +17 -0
  2. mirascript-0.0.6/README.md +24 -0
  3. mirascript-0.0.6/mirascript/__init__.py +11 -0
  4. mirascript-0.0.6/mirascript/deep_nonlocal_fix.py +136 -0
  5. mirascript-0.0.6/mirascript/diagnostics.py +82 -0
  6. mirascript-0.0.6/mirascript/emit.py +1182 -0
  7. mirascript-0.0.6/mirascript/main.py +26 -0
  8. mirascript-0.0.6/mirascript/subtle.py +5 -0
  9. mirascript-0.0.6/mirascript/vm/VmWrapper.py +50 -0
  10. mirascript-0.0.6/mirascript/vm/__init__.py +15 -0
  11. mirascript-0.0.6/mirascript/vm/env.py +13 -0
  12. mirascript-0.0.6/mirascript/vm/error.py +19 -0
  13. mirascript-0.0.6/mirascript/vm/helpers.py +124 -0
  14. mirascript-0.0.6/mirascript/vm/operations.py +592 -0
  15. mirascript-0.0.6/mirascript/vm/types/__init__.py +21 -0
  16. mirascript-0.0.6/mirascript/vm/types/checker.py +107 -0
  17. mirascript-0.0.6/mirascript/vm/types/const.py +39 -0
  18. mirascript-0.0.6/mirascript/vm/types/context.py +130 -0
  19. mirascript-0.0.6/mirascript/vm/types/extern.py +123 -0
  20. mirascript-0.0.6/mirascript/vm/types/function.py +28 -0
  21. mirascript-0.0.6/mirascript/vm/types/module.py +33 -0
  22. mirascript-0.0.6/mirascript/vm/types/script.py +17 -0
  23. mirascript-0.0.6/mirascript/vm/types/types.py +143 -0
  24. mirascript-0.0.6/mirascript/vm/types/wrapper.py +56 -0
  25. mirascript-0.0.6/mirascript.egg-info/PKG-INFO +17 -0
  26. mirascript-0.0.6/mirascript.egg-info/SOURCES.txt +36 -0
  27. mirascript-0.0.6/mirascript.egg-info/dependency_links.txt +1 -0
  28. mirascript-0.0.6/mirascript.egg-info/top_level.txt +1 -0
  29. mirascript-0.0.6/pyproject.toml +16 -0
  30. mirascript-0.0.6/setup.cfg +4 -0
  31. mirascript-0.0.6/setup.py +79 -0
  32. mirascript-0.0.6/test/test.py +19 -0
  33. mirascript-0.0.6/test/test2.py +15 -0
  34. mirascript-0.0.6/test/test3.py +22 -0
  35. mirascript-0.0.6/test/test4.py +279 -0
  36. mirascript-0.0.6/test/test5.py +57 -0
  37. mirascript-0.0.6/test/test6.py +0 -0
  38. mirascript-0.0.6/test/test_is_string_number.py +0 -0
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.1
2
+ Name: mirascript
3
+ Version: 0.0.6
4
+ Summary: cloudpss mirascript
5
+ Home-page: https://www.cloudpss.net
6
+ Author: cloudpss
7
+ Author-email: zhangdaming@cloudpss.net
8
+ License: MIT Licence
9
+ Keywords: cloudpss,cloudpss-mirascript,mirascript
10
+ Platform: any
11
+ Classifier: Programming Language :: Rust
12
+ Classifier: Programming Language :: Python :: Implementation :: CPython
13
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
14
+ Requires-Python: >=3.7
15
+ Description-Content-Type: text/markdown
16
+
17
+ MiraScript 的 Python 绑定允许在 Python 中使用 MiraScript 编译器。它提供了一个简单的接口来编译 MiraScript 脚本,并返回编译结果和诊断信息。
@@ -0,0 +1,24 @@
1
+ # MiraScript Python Bindings
2
+
3
+ MiraScript 的 Python 绑定允许在 Python 中使用 MiraScript 编译器。它提供了一个简单的接口来编译 MiraScript 脚本,并返回编译结果和诊断信息。
4
+
5
+ ## 开发
6
+
7
+ 1. 初始化虚拟环境
8
+
9
+ ```bash
10
+ python -m venv .venv
11
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
12
+ ```
13
+
14
+ 2. 安装依赖
15
+
16
+ ```bash
17
+ pip install -r requirements.txt
18
+ ```
19
+
20
+ 3. 编译并安装 bindings
21
+
22
+ ```bash
23
+ maturin develop
24
+ ```
@@ -0,0 +1,11 @@
1
+ """
2
+ MiraScript Python Module
3
+
4
+ This module provides the main entry point for compiling MiraScript code
5
+ """
6
+
7
+ from .mirascript import Config
8
+ from .diagnostics import Diagnostic
9
+ from .main import compile
10
+ __version__ = '0.0.6'
11
+ __all__ = ["Config", "Diagnostic", "compile","__version__"]
@@ -0,0 +1,136 @@
1
+ ## 将所有 nonlocal 声明提升到函数体顶部,有些情况下nonlocal声明可能在条件语句或循环内
2
+ import ast
3
+
4
+
5
+ def deep_nonlocal_fix(node, nonlocal_vars=None):
6
+ """
7
+ 将函数体内部所有非嵌套位置的 `nonlocal` 声明收集并提升到函数体顶部。
8
+ 对 FunctionDef / AsyncFunctionDef 递归处理,保持嵌套函数的 nonlocal 在其自身作用域内。
9
+ """
10
+ class _Hoister(ast.NodeTransformer):
11
+ def visit_FunctionDef(self, fn: ast.FunctionDef):
12
+ # 先处理内部(从底向上)
13
+ self.generic_visit(fn)
14
+
15
+ # 收集当前函数作用域(不进入嵌套函数/类/lambda)的 nonlocal 名称
16
+ names = set()
17
+
18
+ def collect_from_nodes(stmts):
19
+ for s in stmts:
20
+ if isinstance(s, ast.Nonlocal):
21
+ for n in s.names:
22
+ names.add(n)
23
+ # 不进入嵌套作用域
24
+ elif isinstance(s, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)):
25
+ continue
26
+ else:
27
+ if s is None:
28
+ continue
29
+ for field, value in ast.iter_fields(s):
30
+ if isinstance(value, list):
31
+ collect_from_nodes(value)
32
+ elif isinstance(value, ast.AST):
33
+ if isinstance(value, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)):
34
+ continue
35
+ collect_from_nodes([value])
36
+
37
+ collect_from_nodes(fn.body)
38
+
39
+ if names:
40
+ # 从当前函数体及其子节点中移除所有 Nonlocal 节点(不进入嵌套函数/类/lambda)
41
+ def remove_from_nodes(stmts):
42
+ new_stmts = []
43
+ for s in stmts:
44
+ if isinstance(s, ast.Nonlocal):
45
+ # 跳过(已收集)
46
+ continue
47
+ elif isinstance(s, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)):
48
+ new_stmts.append(s)
49
+ else:
50
+ for field, value in list(ast.iter_fields(s)):
51
+ if isinstance(value, list):
52
+ filtered = remove_from_nodes(value)
53
+ setattr(s, field, filtered)
54
+ elif isinstance(value, ast.AST):
55
+ if isinstance(value, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)):
56
+ pass
57
+ else:
58
+ replaced = remove_from_nodes([value])
59
+ if replaced:
60
+ setattr(s, field, replaced[0])
61
+ new_stmts.append(s)
62
+ return new_stmts
63
+
64
+ fn.body = remove_from_nodes(fn.body)
65
+
66
+ # 构造新的 nonlocal 节点并插入到函数体顶部,若首节点为 Try 则插入到 Try.body 顶部
67
+ nl_node = ast.Nonlocal(names=sorted(names))
68
+ if fn.body and isinstance(fn.body[0], ast.Try):
69
+ try_node: ast.Try = fn.body[0]
70
+ try_node.body.insert(0, nl_node)
71
+ else:
72
+ fn.body.insert(0, nl_node)
73
+
74
+ return fn
75
+
76
+ def visit_AsyncFunctionDef(self, fn: ast.AsyncFunctionDef):
77
+ # 同样处理异步函数
78
+ self.generic_visit(fn)
79
+
80
+ names = set()
81
+
82
+ def collect_from_nodes(stmts):
83
+ for s in stmts:
84
+ if isinstance(s, ast.Nonlocal):
85
+ for n in s.names:
86
+ names.add(n)
87
+ elif isinstance(s, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)):
88
+ continue
89
+ else:
90
+ for field, value in ast.iter_fields(s):
91
+ if isinstance(value, list):
92
+ collect_from_nodes(value)
93
+ elif isinstance(value, ast.AST):
94
+ if isinstance(value, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)):
95
+ continue
96
+ collect_from_nodes([value])
97
+
98
+ collect_from_nodes(fn.body)
99
+
100
+ if names:
101
+ def remove_from_nodes(stmts):
102
+ new_stmts = []
103
+ for s in stmts:
104
+ if isinstance(s, ast.Nonlocal):
105
+ continue
106
+ elif isinstance(s, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)):
107
+ new_stmts.append(s)
108
+ else:
109
+ for field, value in list(ast.iter_fields(s)):
110
+ if isinstance(value, list):
111
+ filtered = remove_from_nodes(value)
112
+ setattr(s, field, filtered)
113
+ elif isinstance(value, ast.AST):
114
+ if isinstance(value, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Lambda)):
115
+ pass
116
+ else:
117
+ replaced = remove_from_nodes([value])
118
+ if replaced:
119
+ setattr(s, field, replaced[0])
120
+ new_stmts.append(s)
121
+ return new_stmts
122
+
123
+ fn.body = remove_from_nodes(fn.body)
124
+ nl_node = ast.Nonlocal(names=sorted(names),lineno=0)
125
+ if fn.body and isinstance(fn.body[0], ast.Try):
126
+ fn.body[0].body.insert(0, nl_node)
127
+ else:
128
+ fn.body.insert(0, nl_node)
129
+
130
+ return fn
131
+
132
+ hoister = _Hoister()
133
+ return hoister.visit(node)
134
+
135
+ # ...existing code...
136
+
@@ -0,0 +1,82 @@
1
+
2
+ from .mirascript import get_diagnostic_message
3
+
4
+
5
+ # DiagnosticLevel = Literal["Error", "Warning", "Info", "Hint", "Reference", "Unknown"]
6
+
7
+
8
+ class Diagnostic:
9
+ """
10
+ 诊断信息类
11
+ """
12
+
13
+ __cache = {}
14
+
15
+ start_line: int
16
+ """起始行号"""
17
+ start_column: int
18
+ """起始列号"""
19
+ end_line: int
20
+ """结束行号"""
21
+ end_column: int
22
+ """结束列号"""
23
+ code: int
24
+ """诊断代码"""
25
+ level: str
26
+ """诊断级别"""
27
+ name: str
28
+ """诊断名称"""
29
+ message: str
30
+ """诊断消息"""
31
+
32
+ def __init__(
33
+ self,
34
+ start_line: int,
35
+ start_column: int,
36
+ end_line: int,
37
+ end_column: int,
38
+ code: int,
39
+ ):
40
+ self.start_line = start_line
41
+ self.start_column = start_column
42
+ self.end_line = end_line
43
+ self.end_column = end_column
44
+ self.code = code
45
+ info = Diagnostic.__cache.get(self.code)
46
+ if info is None:
47
+ try:
48
+ info = get_diagnostic_message(self.code)
49
+ Diagnostic.__cache[self.code] = info
50
+ except:
51
+ info = (
52
+ "Unknown",
53
+ f"{self.code}",
54
+ f"Unknown diagnostic code",
55
+ )
56
+ Diagnostic.__cache[self.code] = info
57
+ self.level = info[0]
58
+ self.name = info[1]
59
+ self.message = info[2]
60
+
61
+ def __repr__(self) -> str:
62
+ return f"Diagnostic(code={self.code}, level={self.level}, name={self.name}, start=({self.start_line}, {self.start_column}), end=({self.end_line}, {self.end_column}))"
63
+
64
+ def __str__(self) -> str:
65
+ return (
66
+ f"[{self.level}] {self.message} ({self.name}) at "
67
+ f"{self.start_line}:{self.start_column} - "
68
+ f"{self.end_line}:{self.end_column}"
69
+ )
70
+
71
+
72
+ def decode_diagnostics(diagnostics) :
73
+ """
74
+ 解析诊断信息
75
+
76
+ Args:
77
+ diagnostics (list[int]): 诊断信息列表,包含 [start_line, start_column, end_line, end_column, code]
78
+
79
+ Returns:
80
+ list[Diagnostic]: 解析后的诊断信息列表
81
+ """
82
+ return [Diagnostic(*diagnostics[i : i + 5]) for i in range(0, len(diagnostics), 5)]