// el-ui-compiler — El→browser-target component compiler (STUB). // // The Rust crate transforms `.el` component files into JavaScript using a // real lexer/parser/codegen pipeline backed by the el-ui runtime // (`el-ui.js`). This El surface is a placeholder. // // RUNTIME GAP — load-bearing: // `elc` (the bootstrap El compiler) currently emits C only. There is no // JavaScript or WebAssembly backend yet, so the El surface cannot // actually compile a component to JS today. // // What this vessel provides: // - The shape of the public API (Compiler with runtime_path, // compile_component, compile_app). // - A `CompileResult` record consumers can branch on. // - Stub bodies that return a deterministic "not yet implemented" // module string so downstream tooling can integration-test against // a stable contract. // // When elc gains a JS/Wasm backend, swap the bodies of `lex`, `parse`, // `semantic_check`, and `codegen` for real implementations — the public // surface should not need to change. // ── Errors ────────────────────────────────────────────────────────────────── fn err_lex() -> String { "elc.lex" } fn err_parse() -> String { "elc.parse" } fn err_semantic() -> String { "elc.semantic" } fn err_codegen() -> String { "elc.codegen" } fn err_backend_missing() -> String { "elc.backend_missing" } // ── Compile result ────────────────────────────────────────────────────────── // // Modeled as JSON since the runtime's product types and field accessors // don't yet support the Bool/String mix we want here cleanly. fn result_ok(code: String) -> String { "{\"ok\":true,\"code\":" + json_quote(code) + ",\"error\":\"\"}" } fn result_err(error: String) -> String { "{\"ok\":false,\"code\":\"\",\"error\":\"" + error + "\"}" } // Minimal JSON string quoter (escape backslash + double-quote only). // elc still doesn't expose a json_string_quote builtin. fn json_quote(s: String) -> String { let escaped: String = str_replace(s, "\\", "\\\\") let escaped = str_replace(escaped, "\"", "\\\"") "\"" + escaped + "\"" } fn result_ok_p(result_json: String) -> Bool { json_get_bool(result_json, "ok") } // ── Compiler config ───────────────────────────────────────────────────────── fn compiler_default_runtime_path() -> String { "./el-ui.js" } fn compiler_default_target() -> String { "js" } fn compiler_new() -> String { "{\"runtime_path\":\"./el-ui.js\",\"target\":\"js\"}" } fn compiler_with_runtime(c_json: String, path: String) -> String { json_set(c_json, "runtime_path", json_quote(path)) } fn compiler_with_target(c_json: String, target: String) -> String { json_set(c_json, "target", json_quote(target)) } fn compiler_runtime_path(c_json: String) -> String { json_get_string(c_json, "runtime_path") } fn compiler_target(c_json: String) -> String { json_get_string(c_json, "target") } // ── Pipeline stages (stubs) ───────────────────────────────────────────────── // // Real implementations live in the Rust crate (lexer.rs, parser.rs, // semantic.rs, codegen.rs). These El stubs only validate inputs and // produce a marker payload so callers can wire the contract. fn lex(source: String) -> String { if str_eq(source, "") { return "" } "[]" // would be tokens JSON } fn parse(tokens_json: String) -> String { if str_eq(tokens_json, "") { return "" } "[]" // would be Component AST JSON } fn semantic_check(ast_json: String) -> String { ast_json // pass-through stub } fn codegen(c_json: String, ast_json: String) -> String { let runtime: String = compiler_runtime_path(c_json) let preamble: String = "// AUTOGENERATED by el-ui-compiler (STUB)\n" let import_line: String = "import { register, h } from \"" + runtime + "\";\n" let body: String = "throw new Error(\"" + err_backend_missing() + ": el-ui-compiler has no JS backend yet; emit C with elc instead\");\n" preamble + import_line + body } // ── Public entry points ───────────────────────────────────────────────────── fn compile_component(c_json: String, source: String) -> String { let tokens: String = lex(source) if str_eq(tokens, "") { return result_err(err_lex()) } let ast: String = parse(tokens) if str_eq(ast, "") { return result_err(err_parse()) } let checked: String = semantic_check(ast) if str_eq(checked, "") { return result_err(err_semantic()) } let js: String = codegen(c_json, checked) result_ok(js) } // `entry_source` is the app entry; `components_json` is a JSON object map of // name -> source text. We compile each component first, then the entry. fn compile_app(c_json: String, entry_source: String, components_json: String) -> String { // RUNTIME GAP: no json_object_keys() yet, so we cannot iterate the map // generically here. Real implementation will iterate and short-circuit // on first compile error. For the stub we just compile the entry. compile_component(c_json, entry_source) } // ── Entry — smoke test ────────────────────────────────────────────────────── let c: String = compiler_new() let c = compiler_with_runtime(c, "./el-ui.js") let r: String = compile_component(c, "component Hello { template {
hi
} }") if result_ok_p(r) { println("[el-ui-compiler] STUB compiled (target=" + compiler_target(c) + ")") } else { println("[el-ui-compiler] error: " + json_get_string(r, "error")) }