📚 Phase 12: Nyashスクリプトプラグインシステム設計と埋め込みVM構想
## 主な成果 - Nyashスクリプトでプラグイン作成可能という革命的発見 - C ABI制約の分析と埋め込みVMによる解決策 - MIR/VM/JIT層での箱引数サポートの詳細分析 ## ドキュメント作成 - Phase 12基本構想(README.md) - Gemini/Codex先生の技術分析 - C ABIとの整合性問題と解決策 - 埋め込みVM実装ロードマップ - 箱引数サポートの技術詳細 ## 重要な洞察 - 制約は「リンク時にC ABI必要」のみ - 埋め込みVMでMIRバイトコード実行により解決可能 - Nyashスクリプト→C ABIプラグイン変換が実現可能 Everything is Box → Everything is Plugin → Everything is Possible!
This commit is contained in:
51
tools/pyc/PyCompiler.nyash
Normal file
51
tools/pyc/PyCompiler.nyash
Normal file
@ -0,0 +1,51 @@
|
||||
// Nyash-side Python compiler (Phase 10.7 C2 - minimal)
|
||||
// Orchestrates: Parser(JSON) -> IR(JSON) -> Nyash source (string)
|
||||
|
||||
static box PyCompiler {
|
||||
parseToJson() {
|
||||
// Use Nyash-only parser via PyRuntimeBox (no Rust build)
|
||||
local p
|
||||
p = new PythonParserNy()
|
||||
return p.parse("")
|
||||
}
|
||||
|
||||
buildIRFromParse(json) {
|
||||
// Minimal: analyze Python source from env and build IR with a constant return when possible
|
||||
// Python snippet: parse code from os.getenv("NYASH_PY_CODE"), find first Return(Constant)
|
||||
local os, getenv, src, ast, parsef, walkf, first_ret
|
||||
local py = new PyRuntimeBox()
|
||||
os = py.import("os")
|
||||
getenv = os.getattr("getenv")
|
||||
src = getenv.call("NYASH_PY_CODE").toString()
|
||||
if (src == null || src == "") {
|
||||
return new StringBox("{\"module\":{\"functions\":[{\"name\":\"main\",\"return_value\":0}]}}")
|
||||
}
|
||||
|
||||
ast = py.import("ast")
|
||||
parsef = ast.getattr("parse")
|
||||
local tree
|
||||
tree = parsef.call(src)
|
||||
|
||||
// Walk via Python: extract first constant return value if present
|
||||
local res
|
||||
res = py.eval("next((n.value.value for n in __import__('ast').walk(__import__('ast').parse(__import__('os').getenv('NYASH_PY_CODE') or '')) if isinstance(n, __import__('ast').Return) and isinstance(n.value, __import__('ast').Constant)), None)")
|
||||
// If number -> return that number; if string -> quoted
|
||||
local val
|
||||
val = res.str()
|
||||
if (val.matches("^[0-9]+$")) {
|
||||
return new StringBox("{\"module\":{\"functions\":[{\"name\":\"main\",\"return_value\":" + val + "]}}")
|
||||
} else if (val.length() > 0) {
|
||||
return new StringBox("{\"module\":{\"functions\":[{\"name\":\"main\",\"return_value\":\"" + val + "\"}]}}")
|
||||
} else {
|
||||
return new StringBox("{\"module\":{\"functions\":[{\"name\":\"main\",\"return_value\":0}]}}")
|
||||
}
|
||||
}
|
||||
|
||||
irToNyashSource(irJson) {
|
||||
// Build Nyash source from IR (minimal: assume IR has return_value embedded by PyIR.buildReturn)
|
||||
local src
|
||||
src = "static box Generated {\n main() {\n return 0\n }\n}"
|
||||
// Future: parse irJson and extract return_value
|
||||
return new StringBox(src)
|
||||
}
|
||||
}
|
||||
11
tools/pyc/PyIR.nyash
Normal file
11
tools/pyc/PyIR.nyash
Normal file
@ -0,0 +1,11 @@
|
||||
// Minimal IR helper (Phase 10.7 C2)
|
||||
// Builds small JSON snippets for the compiler pipeline
|
||||
|
||||
static box PyIR {
|
||||
buildReturn(value) {
|
||||
local s
|
||||
// value can be integer or string literal already
|
||||
s = "{\"module\":{\"functions\":[{\"name\":\"main\",\"return_value\":" + value + "}]}}"
|
||||
return new StringBox(s)
|
||||
}
|
||||
}
|
||||
32
tools/pyc/PythonParserNy.nyash
Normal file
32
tools/pyc/PythonParserNy.nyash
Normal file
@ -0,0 +1,32 @@
|
||||
// Nyash-only Python parser using PyRuntimeBox (no Rust build)
|
||||
static box PythonParserNy {
|
||||
parse(code) {
|
||||
local src
|
||||
if (code == null || code.toString() == "") {
|
||||
// Fallback: read from env via Python os.getenv
|
||||
local os, getenv
|
||||
local py = new PyRuntimeBox()
|
||||
os = py.import("os")
|
||||
getenv = os.getattr("getenv")
|
||||
src = getenv.call("NYASH_PY_CODE").toString()
|
||||
} else {
|
||||
src = code.toString()
|
||||
}
|
||||
|
||||
// ast.dump(ast.parse(src))
|
||||
local ast, parsef, dumpf, tree, dump, dump_str
|
||||
local py2 = new PyRuntimeBox()
|
||||
ast = py2.import("ast")
|
||||
parsef = ast.getattr("parse")
|
||||
tree = parsef.call(src)
|
||||
dumpf = ast.getattr("dump")
|
||||
dump = dumpf.call(tree)
|
||||
dump_str = dump.str()
|
||||
|
||||
// Minimal JSON (escape quotes minimally by replacing \" -> \\\" )
|
||||
// Note: for robust escaping, prefer Python json.dumps in a later pass
|
||||
local esc
|
||||
esc = dump_str.replace("\"", "\\\"")
|
||||
return new StringBox("{\"ast\":\"Module\",\"dump\":\"" + esc + "\"}")
|
||||
}
|
||||
}
|
||||
24
tools/pyc/README.md
Normal file
24
tools/pyc/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Nyash Python Compiler (Phase 10.7 Workbench)
|
||||
|
||||
目的: Parser(プラグイン) → Nyash側コンパイラ → Nyashソース → 既存AOT までの最短ルートを、Nyashだけで段階実装する作業場。
|
||||
|
||||
## 構成
|
||||
- `pyc.nyash` — エントリ(最小パイプライン実行)
|
||||
- `PyCompiler.nyash` — Nyash側コンパイラ本体(C2で拡張)
|
||||
- `PyIR.nyash` — IR生成/整形のヘルパ(最小)
|
||||
|
||||
## 使い方(最小)
|
||||
```bash
|
||||
# 1) NYASH_PY_CODE に Python コードを入れる(Parserプラグインが拾う)
|
||||
NYASH_PY_CODE=$'def main():\n return 0' \
|
||||
./target/release/nyash --backend vm tools/pyc/pyc.nyash
|
||||
```
|
||||
|
||||
出力
|
||||
- Parser JSON(dump/counts/unsupported)
|
||||
- 生成された Nyash ソース(現状は最小: return 0)
|
||||
|
||||
## 次の拡張
|
||||
- Parser JSON → IR(JSON) への変換(def/return最小)
|
||||
- IR → Nyash 生成(If/Return/Assign へ拡張)
|
||||
- All-or-Nothing 運用(unsupported_nodes を見て Strict に弾くスイッチ)
|
||||
24
tools/pyc/pyc.nyash
Normal file
24
tools/pyc/pyc.nyash
Normal file
@ -0,0 +1,24 @@
|
||||
// Nyash Python Compiler entry (Phase 10.7 workbench)
|
||||
// Nyash-only pipeline: Parser/Compiler are implemented in Nyash using PyRuntimeBox
|
||||
// Usage:
|
||||
// NYASH_PY_CODE=$'def main():\n return 0' ./target/release/nyash --backend vm tools/pyc/pyc.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
// Load modules via include (returns module boxes)
|
||||
local PyIR = include "tools/pyc/PyIR.nyash"
|
||||
local Parser = include "tools/pyc/PythonParserNy.nyash"
|
||||
local Compiler = include "tools/pyc/PyCompiler.nyash"
|
||||
|
||||
local json, ir, src
|
||||
|
||||
// Skip echo of source to avoid plugin toString issues
|
||||
|
||||
json = Compiler.parseToJson()
|
||||
|
||||
ir = Compiler.buildIRFromParse(json)
|
||||
|
||||
src = Compiler.irToNyashSource(ir)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user