#![allow(clippy::collapsible_match)]
pub mod backend;
pub mod go;
pub mod javascript;
pub mod rust;
pub mod wasm;
pub mod wasm_component_generator;
pub mod wgsl;
pub use rust::CodeGenerator;
use crate::parser::Program;
use anyhow::Result;
use backend::{CodegenConfig, CodegenOutput, Target};
pub fn generate(
program: &Program,
target: Target,
config: Option<CodegenConfig>,
) -> Result<CodegenOutput> {
let config = config.unwrap_or_else(|| CodegenConfig {
target,
..Default::default()
});
let backend = backend::create_backend(target);
let mut output = backend.generate(program, &config)?;
if config.idiomatic_output {
output.source = backend.make_idiomatic(output.source, &config)?;
}
if config.type_definitions {
if let Some(type_defs) = backend.generate_type_definitions(program) {
output.type_definitions = Some(type_defs);
}
}
let additional = backend.generate_additional_files(program, &config);
for (filename, content) in additional {
output.add_file(filename, content);
}
Ok(output)
}
pub fn generate_rust(program: &Program) -> Result<String> {
let output = generate(program, Target::Rust, None)?;
Ok(output.source)
}
pub fn generate_go(program: &Program) -> Result<CodegenOutput> {
generate(program, Target::Go, None)
}
pub fn generate_javascript(program: &Program) -> Result<CodegenOutput> {
generate(program, Target::JavaScript, None)
}
pub fn generate_wasm(program: &Program) -> Result<CodegenOutput> {
generate(program, Target::WebAssembly, None)
}
#[cfg(test)]
mod tests {
use super::*;
fn create_test_program() -> Program<'static> {
Program { items: vec![] }
}
#[test]
fn test_generate_rust() {
let program = create_test_program();
let result = generate_rust(&program);
assert!(result.is_ok());
}
#[test]
fn test_generate_javascript() {
let program = create_test_program();
let result = generate_javascript(&program);
assert!(result.is_ok());
if let Ok(output) = result {
assert_eq!(output.extension, "js");
assert!(output.source.contains("JavaScript"));
}
}
#[test]
fn test_generate_wasm() {
let program = create_test_program();
let result = generate_wasm(&program);
assert!(result.is_ok());
}
#[test]
fn test_target_dispatch() {
let program = create_test_program();
let rust_output = generate(&program, Target::Rust, None);
assert!(rust_output.is_ok());
let js_output = generate(&program, Target::JavaScript, None);
assert!(js_output.is_ok());
let wasm_output = generate(&program, Target::WebAssembly, None);
assert!(wasm_output.is_ok());
}
}