Skip to main content

ling/core/
mod.rs

1// src/core/mod.rs
2mod config;
3mod error;
4mod result;
5
6pub use config::{CompilerConfig, OptimizationLevel};
7pub use error::LingError;
8pub use result::LingResult;
9
10use crate::mir;
11use ling_codegen::CodegenBackend;
12use std::path::Path;
13
14pub struct LingCompiler {
15    config: CompilerConfig,
16}
17
18impl LingCompiler {
19    pub fn new(config: CompilerConfig) -> Self {
20        Self { config }
21    }
22
23    pub fn compile<P: AsRef<Path>>(&self, input: P, output: P) -> LingResult<()> {
24        let source =
25            std::fs::read_to_string(input.as_ref()).map_err(|e| LingError::Io(e.to_string()))?;
26        let mir = mir::compile_and_optimize(&source, self.config.optimization)?;
27        println!(
28            "compiled {} functions, optimized at {:?}",
29            mir.functions.len(),
30            self.config.optimization
31        );
32
33        let mir_prog = ling_codegen::MirProgram::new(mir, input.as_ref().to_string_lossy());
34        let mut backend = ling_codegen::BytecodeBackend;
35        backend
36            .emit(&mir_prog, output.as_ref())
37            .map_err(|e| LingError::Codegen(e.to_string()))?;
38        println!("bytecode emitted to {}", output.as_ref().display());
39        Ok(())
40    }
41
42    pub fn compile_and_run<P: AsRef<Path>>(&self, input: P) -> LingResult<()> {
43        let source =
44            std::fs::read_to_string(input.as_ref()).map_err(|e| LingError::Io(e.to_string()))?;
45        let mir = mir::compile_and_optimize(&source, self.config.optimization)?;
46        println!(
47            "compiled {} functions, optimized at {:?}",
48            mir.functions.len(),
49            self.config.optimization
50        );
51
52        let vm_prog = ling_codegen::compile_mir_program(&mir);
53        let mut vm = ling_codegen::Vm::new();
54        vm.load(vm_prog);
55        vm.run_main()
56            .map_err(|e| LingError::Codegen(e.to_string()))?;
57        Ok(())
58    }
59
60    pub fn dump_mir<P: AsRef<Path>>(&self, input: P) -> LingResult<()> {
61        let source =
62            std::fs::read_to_string(input.as_ref()).map_err(|e| LingError::Io(e.to_string()))?;
63        let mir = mir::compile_and_optimize(&source, self.config.optimization)?;
64        for func in &mir.functions {
65            println!("=== function: {} ===", func.name);
66            println!("  args: {}, locals: {}", func.arg_count, func.locals.len());
67            for (i, decl) in func.locals.iter().enumerate() {
68                let name = decl.name.as_deref().unwrap_or("_");
69                println!(
70                    "  local {}: {} {:?} mut={} owning={}",
71                    i, name, decl.ty, decl.is_mut, decl.is_owning
72                );
73            }
74            for (bi, bb) in func.basic_blocks.iter().enumerate() {
75                println!("  bb{}:", bi);
76                for stmt in &bb.statements {
77                    println!("    {:?}", stmt.kind);
78                }
79                if let Some(term) = &bb.terminator {
80                    println!("    term: {:?}", term.kind);
81                }
82            }
83        }
84        Ok(())
85    }
86}