Archive Rust bootstrap — El compiler is now self-hosting

This commit is contained in:
Will Anderson
2026-04-29 22:21:31 -05:00
parent 9a0747aa13
commit 4f3543b068
139 changed files with 8980 additions and 1778 deletions
@@ -0,0 +1,20 @@
[package]
name = "elvm"
description = "El Virtual Machine — executes compiled El bytecode (.elc) natively"
version.workspace = true
edition.workspace = true
license.workspace = true
[[bin]]
name = "elvm"
path = "src/main.rs"
[dependencies]
el-compiler = { workspace = true }
el-vm = { workspace = true }
clap = { workspace = true }
# Native window / WebView (macOS: WKWebView via wry)
wry = { version = "0.47", default-features = false }
winit = { version = "0.29", default-features = false, features = ["rwh_05", "rwh_06"] }
dpi = "0.1"
@@ -0,0 +1,146 @@
//! elvm — El Virtual Machine
//!
//! The standalone El VM binary. Loads and executes compiled El bytecode (.elc)
//! files produced by `el compile` or `el build-file`.
//!
//! # Usage
//!
//! elvm <file.elc> [args...]
//! elvm --version
//! elvm --help
//!
//! If the environment variable `NEURON_WINDOW_URL` is set, elvm opens a native
//! macOS window (WKWebView via wry) at that URL instead of executing bytecode.
//! This allows UI apps to be launched as proper desktop windows:
//!
//! NEURON_WINDOW_URL="http://localhost:7749" elvm dist/neuron-ui.elc
use clap::Parser;
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(
name = "elvm",
about = "El Virtual Machine — execute compiled El bytecode (.elc)",
long_about = "The El VM is the native El execution substrate.\n\
Run .elc files produced by `el compile` or `el build-file`.\n\n\
Set NEURON_WINDOW_URL=<url> to open a native WebView window instead.",
version
)]
struct Cli {
/// Compiled El bytecode file to execute (*.elc).
file: PathBuf,
/// Arguments forwarded to the program (accessible via `args()`).
#[arg(trailing_var_arg = true)]
args: Vec<String>,
}
fn main() {
let cli = Cli::parse();
// If NEURON_WINDOW_URL is set, open a native WebView window at that URL.
if let Ok(url) = std::env::var("NEURON_WINDOW_URL") {
if let Err(e) = open_window(&url) {
eprintln!("elvm: window error: {e}");
std::process::exit(1);
}
return;
}
if let Err(e) = run(cli) {
eprintln!("elvm: error: {e}");
std::process::exit(1);
}
}
fn run(cli: Cli) -> Result<(), Box<dyn std::error::Error>> {
let bytes = std::fs::read(&cli.file)
.map_err(|e| format!("cannot read {}: {e}", cli.file.display()))?;
let instructions = el_compiler::Bytecode::deserialize_all(&bytes)
.map_err(|e| format!("cannot load bytecode from {}: {e}", cli.file.display()))?;
// Detect format and print diagnostic.
let is_elvm_container = bytes.starts_with(el_compiler::ELVM_MAGIC);
if is_elvm_container {
// Normal path — ELVM container.
} else {
eprintln!("elvm: warning: {} does not have an ELVM header — treating as legacy JSON bytecode", cli.file.display());
}
let mut vm = el_vm::ElVm::new();
vm.run(&instructions, &cli.args);
Ok(())
}
/// Opens a native WebView window at `url`.
///
/// On macOS: uses wry (WKWebView) + winit for a proper native desktop window.
/// On other platforms: prints the URL (fallback).
fn open_window(url: &str) -> Result<(), Box<dyn std::error::Error>> {
#[cfg(target_os = "macos")]
return open_native_window(url);
#[cfg(not(target_os = "macos"))]
{
eprintln!("elvm: native window not supported on this platform");
println!("elvm: open {url} in your browser");
Ok(())
}
}
#[cfg(target_os = "macos")]
fn open_native_window(url: &str) -> Result<(), Box<dyn std::error::Error>> {
use dpi::LogicalSize;
use winit::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
use wry::{Rect, WebViewBuilder};
let event_loop = EventLoop::new().map_err(|e| format!("event loop: {e}"))?;
let window = WindowBuilder::new()
.with_title("Neuron")
.with_inner_size(winit::dpi::LogicalSize::new(1600u32, 1000u32))
.with_min_inner_size(winit::dpi::LogicalSize::new(900u32, 600u32))
.with_resizable(true)
.build(&event_loop)
.map_err(|e| format!("window: {e}"))?;
let url_owned = url.to_string();
let webview = WebViewBuilder::new()
.with_url(&url_owned)
.build_as_child(&window)
.map_err(|e| format!("webview: {e}"))?;
event_loop
.run(move |event, evl| {
evl.set_control_flow(ControlFlow::Wait);
match event {
Event::WindowEvent {
event: WindowEvent::Resized(size),
..
} => {
let scale = window.scale_factor();
let logical = size.to_logical::<u32>(scale);
let _ = webview.set_bounds(Rect {
position: dpi::LogicalPosition::new(0, 0).into(),
size: LogicalSize::new(logical.width, logical.height).into(),
});
}
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => evl.exit(),
_ => {}
}
})
.map_err(|e| format!("event loop run: {e}"))?;
Ok(())
}