1pub mod lexer;
21pub mod ast;
22pub mod parser;
23pub mod types;
24pub mod effects;
25pub mod codegen;
26pub mod runtime;
27pub mod stdlib;
28pub mod error;
29pub mod span;
30pub mod comptime;
31pub mod diagnostics;
32pub mod packager;
33pub mod lsp;
34pub mod monomorphize;
35
36
37pub use lexer::Lexer;
38pub use parser::Parser;
39pub use ast::*;
40pub use types::*;
41pub use effects::*;
42pub use error::KainError;
43pub use span::Span;
44
45pub fn compile(source: &str, target: CompileTarget) -> Result<Vec<u8>, KainError> {
47 let tokens = Lexer::new(source).tokenize()?;
49
50 let mut ast = Parser::new(&tokens).parse()?;
52
53 comptime::eval_program(&mut ast)?;
56
57 let mut typed_ast = types::check(&ast)?;
59
60 if matches!(target, CompileTarget::Llvm | CompileTarget::Wasm | CompileTarget::SpirV | CompileTarget::Interpret | CompileTarget::Hybrid) {
62 let mono_prog = monomorphize::monomorphize(&typed_ast)?;
63 typed_ast.items = mono_prog.items;
68 }
69
70 match target {
72 CompileTarget::Wasm => codegen::wasm::generate(&typed_ast),
73 #[cfg(feature = "llvm")]
74 CompileTarget::Llvm => codegen::llvm::generate(&typed_ast),
75 #[cfg(not(feature = "llvm"))]
76 CompileTarget::Llvm => Err(KainError::codegen("LLVM backend not compiled. Rebuild with --features llvm", Span::new(0, 0))),
77 CompileTarget::SpirV => codegen::spirv::generate(&typed_ast),
78 CompileTarget::Hlsl => {
79 let hlsl_code = codegen::hlsl::generate(&typed_ast)?;
80 Ok(hlsl_code.into_bytes())
81 },
82 CompileTarget::Usf => {
83 let usf_code = codegen::usf::generate(&typed_ast)?;
84 Ok(usf_code.into_bytes())
85 },
86 CompileTarget::Js => {
87 let js_code = codegen::js::generate(&typed_ast)?;
88 Ok(js_code.into_bytes())
89 },
90 CompileTarget::Rust => {
91 let rust_code = codegen::rust::generate(&typed_ast)?;
92 Ok(rust_code.into_bytes())
93 },
94 CompileTarget::Interpret => {
95 runtime::interpret(&typed_ast)?;
96 Ok(vec![])
97 }
98 CompileTarget::Test => {
99 runtime::run_tests(&typed_ast)?;
100 Ok(vec![])
101 }
102 CompileTarget::Hybrid => {
103 let hybrid = codegen::hybrid::generate(&typed_ast)?;
106 Ok(hybrid.js.into_bytes())
108 }
109 }
110}
111
112#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub enum CompileTarget {
114 Wasm,
115 Llvm,
116 SpirV,
117 Hlsl,
118 Usf,
119 Js,
120 Rust,
121 Interpret,
122 Test,
123 Hybrid, }
125
126pub const VERSION: &str = "0.1.0";
128pub const LANGUAGE_NAME: &str = "KAIN";
129