Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ephapax-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ serde_json.workspace = true
[dev-dependencies]
wasmtime.workspace = true
proptest = { workspace = true }
wasmparser = "0.221"
tempfile = "3"
9 changes: 8 additions & 1 deletion src/ephapax-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ enum Commands {
mode: String,
},

/// Compile to WebAssembly
/// Compile to WebAssembly.
///
/// Aliased as `compile-eph` and `compile-affine` for downstream
/// consumers (notably hypatia's `build-gossamer-gui` workflow, which
/// probes for these names in order). All three names route to the same
/// surface-parse → desugar → typecheck → wasm pipeline.
/// Closes hyperpolymath/ephapax#36.
#[command(alias = "compile-eph", alias = "compile-affine")]
Compile {
/// Input file
file: PathBuf,
Expand Down
61 changes: 61 additions & 0 deletions src/ephapax-cli/tests/v2_grammar_phase_d_aliases.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
//
// Phase D: clap aliases for the `compile` subcommand. Closes #36.
// Asserts that invoking the CLI as `compile-eph` and `compile-affine`
// both route to the same `Compile` subcommand. Probed by hypatia's
// `build-gossamer-gui.yml` workflow (see #36 for the probe order).

use std::process::Command;

fn ephapax_bin() -> String {
// CARGO_BIN_EXE_ephapax is set by cargo for integration tests.
env!("CARGO_BIN_EXE_ephapax").to_string()
}

fn fixture(name: &str) -> String {
format!(
"{}/../../tests/v2-grammar/fixtures/{}",
env!("CARGO_MANIFEST_DIR"),
name
)
}

#[test]
fn compile_eph_alias_routes_to_compile() {
let out = tempfile::NamedTempFile::new().expect("temp file");
let status = Command::new(ephapax_bin())
.arg("compile-eph")
.arg(fixture("extern-callsite.eph"))
.arg("-o")
.arg(out.path())
.output()
.expect("ephapax compile-eph must run");
assert!(
status.status.success(),
"compile-eph alias failed: stdout={} stderr={}",
String::from_utf8_lossy(&status.stdout),
String::from_utf8_lossy(&status.stderr)
);
let bytes = std::fs::read(out.path()).expect("output wasm exists");
assert!(bytes.starts_with(b"\0asm"), "wasm magic bytes present");
}

#[test]
fn compile_affine_alias_routes_to_compile() {
let out = tempfile::NamedTempFile::new().expect("temp file");
let status = Command::new(ephapax_bin())
.arg("compile-affine")
.arg(fixture("extern-callsite.eph"))
.arg("-o")
.arg(out.path())
.output()
.expect("ephapax compile-affine must run");
assert!(
status.status.success(),
"compile-affine alias failed: stdout={} stderr={}",
String::from_utf8_lossy(&status.stdout),
String::from_utf8_lossy(&status.stderr)
);
let bytes = std::fs::read(out.path()).expect("output wasm exists");
assert!(bytes.starts_with(b"\0asm"), "wasm magic bytes present");
}
17 changes: 17 additions & 0 deletions tests/v2-grammar/fixtures/extern-callsite.eph
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: PMPL-1.0-or-later
// Extern fn callsite — proves Phase B of #43: the extern signature is
// in scope from the function body. `entry()` returns the result of an
// `extern "wasm"`-declared identity function on a literal.
//
// The `type` extern item is currently dropped by desugar (Phase B+ will
// register it as an abstract type). The `fn` extern item desugars to
// `Decl::Extern`, gets registered in the typechecker env by the
// pre-pass, and the call resolves cleanly.

module hyperpolymath/ephapax/test

extern "wasm" {
fn host_identity(x: I32): I32
}

fn entry(): I32 = host_identity(7)