Archived
f4abfe6fdc
Belated rename commit for foundation/el-ui — was missed in the workspace-wide crates→vessels pass earlier today. Same structural intent as the rename in the other repos: 'crates' is the Rust word, 'vessel' is El's, and the directory rename is the marker that this slot holds an El buildable unit even if its current contents are still Rust pending port. Plus the El ports themselves — manifest.el + src/main.el per sub- vessel (el-aop, el-auth, el-config, el-i18n, el-identity, el-layout, el-platform, el-publish, el-secrets, el-services, el-style, el-ui- compiler). The ui-compiler is a stub: elc only emits C right now; generating browser-target JS/Wasm is the biggest open language gap and gets its own project. Until then, el-ui-compiler emits a JS module that throws elc.backend_missing so callers fail loudly. Cross-repo path dependencies in Cargo.toml updated to vessels/.
79 lines
2.4 KiB
Rust
79 lines
2.4 KiB
Rust
//! el-ui-compiler — Transforms `.el` component files into JavaScript.
|
|
//!
|
|
//! Pipeline:
|
|
//! source text → lexer → tokens → parser → AST → codegen → JavaScript
|
|
//!
|
|
//! The output JavaScript uses the el-ui runtime (`el-ui.js`) to register
|
|
//! components, manage a spreading-activation graph for state, and patch the DOM.
|
|
|
|
pub mod ast;
|
|
pub mod codegen;
|
|
pub mod error;
|
|
pub mod lexer;
|
|
pub mod parser;
|
|
pub mod semantic;
|
|
|
|
pub use ast::{Attr, Component, Method, PropDef, StateDef, Template, TemplateNode};
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
pub use codegen::Codegen;
|
|
pub use error::{CompileError, CompileResult};
|
|
|
|
/// High-level compiler entry point.
|
|
pub struct Compiler {
|
|
/// Runtime import path (default: `./el-ui.js`)
|
|
pub runtime_path: String,
|
|
}
|
|
|
|
impl Default for Compiler {
|
|
fn default() -> Self {
|
|
Self { runtime_path: "./el-ui.js".into() }
|
|
}
|
|
}
|
|
|
|
impl Compiler {
|
|
pub fn new() -> Self {
|
|
Self::default()
|
|
}
|
|
|
|
pub fn with_runtime_path(mut self, path: impl Into<String>) -> Self {
|
|
self.runtime_path = path.into();
|
|
self
|
|
}
|
|
|
|
/// Compile a single `.el` source file containing one or more components.
|
|
/// Returns the JavaScript module string.
|
|
pub fn compile_component(&self, source: &str) -> CompileResult<String> {
|
|
let tokens = lexer::tokenize(source)?;
|
|
let components = parser::parse(&tokens)?;
|
|
let gen = Codegen::new(&self.runtime_path);
|
|
gen.generate(&components)
|
|
}
|
|
|
|
/// Compile an app entry point, pulling in named component sources.
|
|
/// `components` is a slice of `(name, source)` pairs.
|
|
/// Returns a single JavaScript module that imports from the runtime.
|
|
pub fn compile_app(
|
|
&self,
|
|
entry_source: &str,
|
|
components: &[(&str, &str)],
|
|
) -> CompileResult<String> {
|
|
let mut all_components: Vec<Component> = Vec::new();
|
|
|
|
for (_name, src) in components {
|
|
let tokens = lexer::tokenize(src)?;
|
|
let mut parsed = parser::parse(&tokens)?;
|
|
all_components.append(&mut parsed);
|
|
}
|
|
|
|
// Parse entry last (may reference previously defined components)
|
|
let entry_tokens = lexer::tokenize(entry_source)?;
|
|
let mut entry_parsed = parser::parse(&entry_tokens)?;
|
|
all_components.append(&mut entry_parsed);
|
|
|
|
let gen = Codegen::new(&self.runtime_path);
|
|
gen.generate(&all_components)
|
|
}
|
|
}
|