diff --git a/ext/php/public/eval.php b/ext/php/public/eval.php
new file mode 100644
index 0000000..c19ad73
--- /dev/null
+++ b/ext/php/public/eval.php
@@ -0,0 +1,53 @@
+getMessage();
+}
diff --git a/ext/php/public/index.php b/ext/php/public/index.php
new file mode 100644
index 0000000..7a05cd2
--- /dev/null
+++ b/ext/php/public/index.php
@@ -0,0 +1,30 @@
+
+
+
+
+
+ Arboricx Web
+
+
+
+ Arboricx Bundle Runner
+
+
+
+
diff --git a/ext/php/run.php b/ext/php/run.php
index 1275fa2..30ce434 100644
--- a/ext/php/run.php
+++ b/ext/php/run.php
@@ -11,89 +11,16 @@ declare(strict_types=1);
* php run.php inspect
*/
-require __DIR__ . '/src/ffi.php';
+require __DIR__ . '/src/common.php';
-use function Arboricx\{ctx_init, ctx_free, loadBundleDefault, ofNumber, ofString, app, reduce, toString, toBool, toNumber};
-
-// ── Locate libarboricx.so ──────────────────────────────────────────────────
-
-function findLib(): string
-{
- $env = getenv('ARBORICX_LIB');
- if ($env !== false && file_exists($env)) {
- return $env;
- }
-
- $paths = [
- __DIR__ . '/../../zig/zig-out/lib/libarboricx.so',
- '/usr/local/lib/libarboricx.so',
- '/usr/lib/libarboricx.so',
- './libarboricx.so',
- ];
- foreach ($paths as $p) {
- if (file_exists($p)) {
- return $p;
- }
- }
-
- fwrite(STDERR, "Error: libarboricx.so not found.\nSet ARBORICX_LIB to its full path.\n");
- exit(1);
-}
-
-// ── Decode helpers ─────────────────────────────────────────────────────────
-
-function decode(\FFI\CData $ctx, int $root): string
-{
- // Bool first: false is Leaf, which is also a valid empty string/list.
- try {
- return toBool($ctx, $root) ? 'true' : 'false';
- } catch (\Throwable $e) {
- try {
- return toString($ctx, $root);
- } catch (\Throwable $e2) {
- try {
- return (string) toNumber($ctx, $root);
- } catch (\Throwable $e3) {
- throw new \RuntimeException('could not decode result');
- }
- }
- }
-}
-
-function decodeType(\FFI\CData $ctx, int $root): string
-{
- try {
- toBool($ctx, $root);
- return 'bool';
- } catch (\Throwable $e) {
- try {
- toString($ctx, $root);
- return 'string';
- } catch (\Throwable $e2) {
- try {
- toNumber($ctx, $root);
- return 'number';
- } catch (\Throwable $e3) {
- return 'unknown (raw tree)';
- }
- }
- }
-}
+use function Arboricx\{ctx_init, ctx_free, loadBundleDefault, ofNumber, ofString, app, reduce, toString, toBool, toNumber, findLib, decode, decodeType, readBundle};
// ── Commands ─────────────────────────────────────────────────────────────────
-function readBundle(string $path): string
+function bail(string $msg): void
{
- if (!file_exists($path)) {
- fwrite(STDERR, "Error: bundle not found: $path\n");
- exit(1);
- }
- $bytes = file_get_contents($path);
- if ($bytes === false) {
- fwrite(STDERR, "Error: could not read bundle: $path\n");
- exit(1);
- }
- return $bytes;
+ fwrite(STDERR, "Error: $msg\n");
+ exit(1);
}
function cmdRun(string $libPath, string $bundlePath, array $args): void
@@ -109,6 +36,8 @@ function cmdRun(string $libPath, string $bundlePath, array $args): void
$result = reduce($ctx, $term, 1_000_000_000);
echo decode($ctx, $result) . "\n";
+ } catch (\Throwable $e) {
+ bail($e->getMessage());
} finally {
ctx_free($ctx);
}
@@ -131,6 +60,8 @@ function cmdInspect(string $libPath, string $bundlePath): void
$value = '(raw tree)';
}
echo " Type: $type\n Value: $value\n";
+ } catch (\Throwable $e) {
+ bail($e->getMessage());
} finally {
ctx_free($ctx);
}
diff --git a/ext/php/src/common.php b/ext/php/src/common.php
new file mode 100644
index 0000000..b1b33f3
--- /dev/null
+++ b/ext/php/src/common.php
@@ -0,0 +1,81 @@
+