🐍 Python統合をAOTレベルまで完成(eval方式でunsupported=0達成)
- PyRuntimeBox.eval() で完全AOT対応(FloatBox返却) - NYASH_PY_AUTODECODE=1 によるプリミティブ型自動変換 - ConsoleBox経由の出力もAOT対応 - 多数のPythonテストサンプル追加 - 論文「1ヶ月でインタープリターからネイティブまで」執筆開始 課題: - import/getattr/callはプラグイン側の実装待ち - importとevalの文脈共有は未対応 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
18
examples/aot_py_eval_code.nyash
Normal file
18
examples/aot_py_eval_code.nyash
Normal file
@ -0,0 +1,18 @@
|
||||
// AOT Python eval with code string - simplest possible
|
||||
static box Main {
|
||||
init { py, code, result }
|
||||
|
||||
main() {
|
||||
// Create Python runtime
|
||||
me.py = new PyRuntimeBox()
|
||||
|
||||
// Create code string
|
||||
me.code = new StringBox("1 + 2 + 3")
|
||||
|
||||
// Eval the code
|
||||
me.result = me.py.eval(me.code)
|
||||
|
||||
// Return the result (should be 6)
|
||||
return me.result
|
||||
}
|
||||
}
|
||||
27
examples/aot_py_eval_console.nyash
Normal file
27
examples/aot_py_eval_console.nyash
Normal file
@ -0,0 +1,27 @@
|
||||
// AOT Python eval with ConsoleBox output
|
||||
static box Main {
|
||||
main() {
|
||||
local py, code, result, console, msg1, msg2
|
||||
|
||||
// Create console for output
|
||||
console = new ConsoleBox()
|
||||
|
||||
// Create Python runtime
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Print start message
|
||||
msg1 = new StringBox("Starting calculation...")
|
||||
console.log(msg1)
|
||||
|
||||
// Eval-only approach for sqrt(16)
|
||||
code = new StringBox("(__import__('math').sqrt)(16)")
|
||||
result = py.eval(code)
|
||||
|
||||
// Print done message
|
||||
msg2 = new StringBox("Calculation complete!")
|
||||
console.log(msg2)
|
||||
|
||||
// Return result (should be 4.0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
19
examples/aot_py_eval_env_min.nyash
Normal file
19
examples/aot_py_eval_env_min.nyash
Normal file
@ -0,0 +1,19 @@
|
||||
// Minimal AOT Python demo: uses env to avoid string args
|
||||
// @env NYASH_PLUGIN_ONLY=1
|
||||
// Notes:
|
||||
// - PyRuntimeBox.eval() with zero args reads NYASH_PY_EVAL_CODE on the host side.
|
||||
// - Avoids StringBox and println to minimize unsupported JIT lowerings.
|
||||
// - Build AOT:
|
||||
// bash tools/build_python_aot.sh examples/aot_py_eval_env_min.nyash -o app
|
||||
// - Run:
|
||||
// NYASH_PY_EVAL_CODE="(__import__('math').sqrt)(9)" ./app
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, _
|
||||
py = new PyRuntimeBox()
|
||||
_ = py.eval() // no args; plugin reads NYASH_PY_EVAL_CODE
|
||||
return 0 // keep return simple for AOT strict
|
||||
}
|
||||
}
|
||||
|
||||
18
examples/aot_py_eval_sqrt.nyash
Normal file
18
examples/aot_py_eval_sqrt.nyash
Normal file
@ -0,0 +1,18 @@
|
||||
// AOT Python eval sqrt - direct eval approach
|
||||
static box Main {
|
||||
main() {
|
||||
local py, code, result
|
||||
|
||||
// Create Python runtime
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Create code string for sqrt
|
||||
code = new StringBox("(__import__('math').sqrt)(16)")
|
||||
|
||||
// Eval the code
|
||||
result = py.eval(code)
|
||||
|
||||
// Return result directly (should be 4.0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
19
examples/aot_py_import_eval.nyash
Normal file
19
examples/aot_py_import_eval.nyash
Normal file
@ -0,0 +1,19 @@
|
||||
// Import then eval
|
||||
static box Main {
|
||||
main() {
|
||||
local py, math_name, math, code, result
|
||||
|
||||
// Create Python runtime
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Import math module
|
||||
math_name = new StringBox("math")
|
||||
math = py.import(math_name)
|
||||
|
||||
// Then use eval to call sqrt
|
||||
code = new StringBox("math.sqrt(16)")
|
||||
result = py.eval(code)
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
15
examples/aot_py_import_only.nyash
Normal file
15
examples/aot_py_import_only.nyash
Normal file
@ -0,0 +1,15 @@
|
||||
// Test just import
|
||||
static box Main {
|
||||
main() {
|
||||
local py, math_name, math
|
||||
|
||||
// Create Python runtime
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Import math module
|
||||
math_name = new StringBox("math")
|
||||
math = py.import(math_name)
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
||||
24
examples/aot_py_math_sqrt.nyash
Normal file
24
examples/aot_py_math_sqrt.nyash
Normal file
@ -0,0 +1,24 @@
|
||||
// AOT Python math.sqrt(16) demo
|
||||
// Demonstrates import/getattr/call chain
|
||||
static box Main {
|
||||
init { py, math, sqrt_func, result }
|
||||
|
||||
main() {
|
||||
// Create Python runtime
|
||||
me.py = new PyRuntimeBox()
|
||||
|
||||
// Import math module
|
||||
me.math = me.py.import("math")
|
||||
|
||||
// Get sqrt function from math module
|
||||
me.sqrt_func = me.py.getattr(me.math, "sqrt")
|
||||
|
||||
// Call sqrt(16)
|
||||
local sixteen
|
||||
sixteen = new IntegerBox(16)
|
||||
me.result = me.py.call(me.sqrt_func, sixteen)
|
||||
|
||||
// Return the result (should be 4.0)
|
||||
return me.result
|
||||
}
|
||||
}
|
||||
33
examples/aot_py_math_sqrt_console.nyash
Normal file
33
examples/aot_py_math_sqrt_console.nyash
Normal file
@ -0,0 +1,33 @@
|
||||
// AOT Python math.sqrt with ConsoleBox output
|
||||
static box Main {
|
||||
main() {
|
||||
local py, math, sqrt_func, sixteen, result, console
|
||||
|
||||
// Create console for output
|
||||
console = new ConsoleBox()
|
||||
|
||||
// Create Python runtime
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Print start message
|
||||
console.log("Starting sqrt calculation...")
|
||||
|
||||
// Import math module
|
||||
math = py.import("math")
|
||||
|
||||
// Get sqrt function
|
||||
sqrt_func = py.getattr(math, "sqrt")
|
||||
|
||||
// Create number
|
||||
sixteen = new IntegerBox(16)
|
||||
|
||||
// Call sqrt(16)
|
||||
result = py.call(sqrt_func, sixteen)
|
||||
|
||||
// Print result message
|
||||
console.log("Result calculated")
|
||||
|
||||
// Return result (should be 4.0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
24
examples/aot_py_math_sqrt_min.nyash
Normal file
24
examples/aot_py_math_sqrt_min.nyash
Normal file
@ -0,0 +1,24 @@
|
||||
// AOT Python math.sqrt minimal - no println
|
||||
static box Main {
|
||||
main() {
|
||||
local py, math, sqrt_func, sixteen, result
|
||||
|
||||
// Create Python runtime
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Import math module
|
||||
math = py.import("math")
|
||||
|
||||
// Get sqrt function
|
||||
sqrt_func = py.getattr(math, "sqrt")
|
||||
|
||||
// Create number
|
||||
sixteen = new IntegerBox(16)
|
||||
|
||||
// Call sqrt(16)
|
||||
result = py.call(sqrt_func, sixteen)
|
||||
|
||||
// Return result directly (should be 4.0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
22
examples/aot_py_math_sqrt_minimal.nyash
Normal file
22
examples/aot_py_math_sqrt_minimal.nyash
Normal file
@ -0,0 +1,22 @@
|
||||
// Minimal math.sqrt example with console output
|
||||
static box Main {
|
||||
main() {
|
||||
local py, code, result, console, msg
|
||||
|
||||
// Create console
|
||||
console = new ConsoleBox()
|
||||
|
||||
// Create Python runtime
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Since import/getattr not available, use eval approach
|
||||
code = new StringBox("__import__('math').sqrt(16)")
|
||||
result = py.eval(code)
|
||||
|
||||
// Log result
|
||||
msg = new StringBox("sqrt(16) = ")
|
||||
console.log(msg)
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
37
examples/aot_py_math_sqrt_separate.nyash
Normal file
37
examples/aot_py_math_sqrt_separate.nyash
Normal file
@ -0,0 +1,37 @@
|
||||
// AOT Python math.sqrt with separate print calls
|
||||
static box Main {
|
||||
main() {
|
||||
local py, math, sqrt_func, sixteen, result, console
|
||||
|
||||
// Create console for output
|
||||
console = new ConsoleBox()
|
||||
|
||||
// Create Python runtime
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Print just text first
|
||||
local msg1
|
||||
msg1 = new StringBox("Starting calculation")
|
||||
console.log(msg1)
|
||||
|
||||
// Import math module
|
||||
math = py.import("math")
|
||||
|
||||
// Get sqrt function
|
||||
sqrt_func = py.getattr(math, "sqrt")
|
||||
|
||||
// Create number
|
||||
sixteen = new IntegerBox(16)
|
||||
|
||||
// Call sqrt(16)
|
||||
result = py.call(sqrt_func, sixteen)
|
||||
|
||||
// Print just text again
|
||||
local msg2
|
||||
msg2 = new StringBox("Calculation done")
|
||||
console.log(msg2)
|
||||
|
||||
// Return result (should be 4.0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
24
examples/aot_py_minimal_print.nyash
Normal file
24
examples/aot_py_minimal_print.nyash
Normal file
@ -0,0 +1,24 @@
|
||||
// AOT minimal example with split println
|
||||
static box Main {
|
||||
main() {
|
||||
local py, code, result, console, msg
|
||||
|
||||
// Create console
|
||||
console = new ConsoleBox()
|
||||
|
||||
// Create Python runtime
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Eval math.sqrt
|
||||
code = new StringBox("__import__('math').sqrt(16)")
|
||||
result = py.eval(code)
|
||||
|
||||
// Print text first
|
||||
msg = new StringBox("Result is:")
|
||||
console.log(msg)
|
||||
|
||||
// Print value separately (would need toString method)
|
||||
// For now just return the result
|
||||
return result
|
||||
}
|
||||
}
|
||||
20
examples/aot_py_simple_call.nyash
Normal file
20
examples/aot_py_simple_call.nyash
Normal file
@ -0,0 +1,20 @@
|
||||
// AOT Python simple call demo - single print to avoid doubling
|
||||
static box Main {
|
||||
init { py, abs_func, result }
|
||||
|
||||
main() {
|
||||
// Create Python runtime
|
||||
me.py = new PyRuntimeBox()
|
||||
|
||||
// Get built-in abs function
|
||||
me.abs_func = me.py.eval("abs")
|
||||
|
||||
// Call abs(-42)
|
||||
local neg42
|
||||
neg42 = new IntegerBox(-42)
|
||||
me.result = me.py.call(me.abs_func, neg42)
|
||||
|
||||
// Return the result (should be 42)
|
||||
return me.result
|
||||
}
|
||||
}
|
||||
22
examples/py_callKwR_ok_demo.nyash
Normal file
22
examples/py_callKwR_ok_demo.nyash
Normal file
@ -0,0 +1,22 @@
|
||||
// Python callKwR OK demo (returns Result.Ok(value))
|
||||
// @env NYASH_PLUGIN_ONLY=1
|
||||
// @env NYASH_PY_AUTODECODE=1
|
||||
// Run:
|
||||
// ./target/release/nyash --backend vm examples/py_callKwR_ok_demo.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, bi, dictf, r
|
||||
py = new PyRuntimeBox()
|
||||
bi = py.import("builtins")
|
||||
dictf = bi.getattr("dict")
|
||||
// dict(a=1, b=2) => {'a': 1, 'b': 2}
|
||||
r = dictf.callKwR("a", 1, "b", 2)
|
||||
me.console.println(r) // expect Ok(PyObjectBox(...))
|
||||
// For readability, also show string form via .str()
|
||||
local s
|
||||
s = dictf.callKw("a", 1, "b", 2).str()
|
||||
me.console.println(s)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
17
examples/py_callR_error_demo.nyash
Normal file
17
examples/py_callR_error_demo.nyash
Normal file
@ -0,0 +1,17 @@
|
||||
// Python callR error demo (returns Result.Err)
|
||||
// Run:
|
||||
// NYASH_PLUGIN_ONLY=1 ./target/release/nyash --backend vm examples/py_callR_error_demo.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, mod, sqrt, r
|
||||
py = new PyRuntimeBox()
|
||||
mod = py.import("math")
|
||||
sqrt = mod.getattr("sqrt")
|
||||
// wrong type to trigger TypeError
|
||||
r = sqrt.callR("oops")
|
||||
me.console.println(r)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
17
examples/py_callR_int_base16_ok_demo.nyash
Normal file
17
examples/py_callR_int_base16_ok_demo.nyash
Normal file
@ -0,0 +1,17 @@
|
||||
// Python callR positional args demo: int('FF', 16) => Ok(255)
|
||||
// @env NYASH_PLUGIN_ONLY=1
|
||||
// @env NYASH_PY_AUTODECODE=1
|
||||
// Run:
|
||||
// ./target/release/nyash --backend vm examples/py_callR_int_base16_ok_demo.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, bi, intf, r
|
||||
py = new PyRuntimeBox()
|
||||
bi = py.import("builtins")
|
||||
intf = bi.getattr("int")
|
||||
r = intf.callR("FF", 16)
|
||||
me.console.println(r) // expect Ok(255)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
17
examples/py_callR_ok_demo.nyash
Normal file
17
examples/py_callR_ok_demo.nyash
Normal file
@ -0,0 +1,17 @@
|
||||
// Python callR OK demo (returns Result.Ok(value))
|
||||
// @env NYASH_PLUGIN_ONLY=1
|
||||
// @env NYASH_PY_AUTODECODE=1
|
||||
// Run:
|
||||
// ./target/release/nyash --backend vm examples/py_callR_ok_demo.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, mod, sqrt, r
|
||||
py = new PyRuntimeBox()
|
||||
mod = py.import("math")
|
||||
sqrt = mod.getattr("sqrt")
|
||||
r = sqrt.callR(16)
|
||||
me.console.println(r) // expect Ok(4.0)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
22
examples/py_eval_demo_simple.nyash
Normal file
22
examples/py_eval_demo_simple.nyash
Normal file
@ -0,0 +1,22 @@
|
||||
// Python plugin demo (Phase 10.5 scaffold) - Simplified version
|
||||
// Requires: plugins/nyash-python-plugin built (release) and nyash.toml updated
|
||||
// Run:
|
||||
// NYASH_PLUGIN_ONLY=1 ./target/release/nyash --backend vm examples/py_eval_demo_simple.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, obj, result
|
||||
py = new PyRuntimeBox()
|
||||
|
||||
// Evaluate simple Python expression
|
||||
obj = py.eval("'hello' * 3")
|
||||
|
||||
// Get string representation
|
||||
result = obj.str()
|
||||
|
||||
// Print result
|
||||
print("Python eval result: " + result)
|
||||
|
||||
return 0
|
||||
}
|
||||
}
|
||||
17
examples/py_eval_env_demo.nyash
Normal file
17
examples/py_eval_env_demo.nyash
Normal file
@ -0,0 +1,17 @@
|
||||
// Python plugin demo via env-provided code (avoids StringBox arg path)
|
||||
// Build:
|
||||
// cargo build --release && (cd plugins/nyash-python-plugin && cargo build --release)
|
||||
// Run:
|
||||
// NYASH_PY_EVAL_CODE="'hello' * 3" ./target/release/nyash --backend vm examples/py_eval_env_demo.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, obj
|
||||
py = new PyRuntimeBox()
|
||||
// Evaluate code from env var (NYASH_PY_EVAL_CODE)
|
||||
obj = py.eval()
|
||||
me.console.println(obj.str())
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
15
examples/py_getattrR_ok_demo.nyash
Normal file
15
examples/py_getattrR_ok_demo.nyash
Normal file
@ -0,0 +1,15 @@
|
||||
// Python getattrR OK demo (returns Result.Ok(handle))
|
||||
// Run:
|
||||
// NYASH_PLUGIN_ONLY=1 ./target/release/nyash --backend vm examples/py_getattrR_ok_demo.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, mod, r
|
||||
py = new PyRuntimeBox()
|
||||
mod = py.import("math")
|
||||
r = mod.getattrR("sqrt")
|
||||
me.console.println(r)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,22 +1,20 @@
|
||||
// Python plugin demo: import math, getattr sqrt, call(9), str()
|
||||
// Build plugin:
|
||||
// (cd plugins/nyash-python-plugin && cargo build --release)
|
||||
// Python math.sqrt demo via plugin (autodecode on)
|
||||
// @env NYASH_PLUGIN_ONLY=1
|
||||
// @env NYASH_PY_AUTODECODE=1
|
||||
// @env NYASH_DEBUG_PLUGIN=1
|
||||
// Build:
|
||||
// cargo build --release && (cd plugins/nyash-python-plugin && cargo build --release)
|
||||
// Run:
|
||||
// NYASH_CLI_VERBOSE=1 ./target/release/nyash --backend vm examples/py_math_sqrt_demo.nyash
|
||||
// ./target/release/nyash --backend vm examples/py_math_sqrt_demo.nyash
|
||||
|
||||
static box Main {
|
||||
init { console }
|
||||
|
||||
main() {
|
||||
me.console = new ConsoleBox()
|
||||
|
||||
local py, m, f, r
|
||||
local py, math, sqrt, r
|
||||
py = new PyRuntimeBox()
|
||||
m = py.import("math")
|
||||
f = m.getattr("sqrt")
|
||||
r = f.call(9)
|
||||
print("sqrt(9) = " + r.str())
|
||||
math = py.import("math")
|
||||
sqrt = math.getattr("sqrt")
|
||||
r = sqrt.call(9)
|
||||
me.console.println(r) // expects 3.0
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
35
examples/py_native_sqrt_app.nyash
Normal file
35
examples/py_native_sqrt_app.nyash
Normal file
@ -0,0 +1,35 @@
|
||||
// Python native build demo (AOT/EXE) via plugin
|
||||
//
|
||||
// Build prerequisites:
|
||||
// 1) System has CPython shared library available (e.g. libpython3.11.so)
|
||||
// - Linux: export LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH
|
||||
// - macOS: export DYLD_LIBRARY_PATH=/usr/local/lib:$DYLD_LIBRARY_PATH
|
||||
// - Windows: python3xx.dll resolvable via PATH or set PYTHONHOME
|
||||
// 2) Build nyash and python plugin in release mode
|
||||
// cargo build --release --features cranelift-jit
|
||||
// (cd plugins/nyash-python-plugin && cargo build --release)
|
||||
//
|
||||
// Build native EXE:
|
||||
// bash tools/build_aot.sh examples/py_native_sqrt_app.nyash -o app
|
||||
//
|
||||
// Run (autodecode on makes float results come back as primitives):
|
||||
// NYASH_PY_AUTODECODE=1 ./app
|
||||
//
|
||||
// Expected output line (among others):
|
||||
// Result: 0
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local c, py, mod, fun, r
|
||||
c = new ConsoleBox()
|
||||
py = new PyRuntimeBox()
|
||||
mod = py.import("math")
|
||||
fun = mod.getattr("sqrt")
|
||||
// With NYASH_PY_AUTODECODE=1, this returns a primitive float 3.0
|
||||
r = fun.call(9)
|
||||
// Avoid string concatenation for AOT strict; print in two calls
|
||||
c.println("sqrt(9) = ")
|
||||
c.println(r)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
15
examples/py_result_error_demo.nyash
Normal file
15
examples/py_result_error_demo.nyash
Normal file
@ -0,0 +1,15 @@
|
||||
// Python evalR error demo (returns Result.Err)
|
||||
// @env NYASH_PLUGIN_ONLY=1
|
||||
// Run:
|
||||
// ./target/release/nyash --backend vm examples/py_result_error_demo.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, r
|
||||
py = new PyRuntimeBox()
|
||||
// Division by zero triggers a Python exception
|
||||
r = py.evalR("1/0")
|
||||
me.console.println(r)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
15
examples/py_result_ok_demo.nyash
Normal file
15
examples/py_result_ok_demo.nyash
Normal file
@ -0,0 +1,15 @@
|
||||
// Python evalR OK demo (returns Result.Ok)
|
||||
// @env NYASH_PLUGIN_ONLY=1
|
||||
// @env NYASH_PY_AUTODECODE=1
|
||||
// Run:
|
||||
// ./target/release/nyash --backend vm examples/py_result_ok_demo.nyash
|
||||
|
||||
static box Main {
|
||||
main() {
|
||||
local py, r
|
||||
py = new PyRuntimeBox()
|
||||
r = py.evalR("1 + 2")
|
||||
me.console.println(r)
|
||||
return 0
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user