1#[derive(Debug, Clone)]
5pub struct BirFunction {
6 pub name: String,
8 pub params: Vec<String>,
10 pub instructions: Vec<String>,
12}
13
14#[derive(Debug, Clone)]
16pub struct BirModule {
17 pub functions: Vec<BirFunction>,
19}
20
21#[derive(Debug)]
23pub struct ParseError(pub String);
24
25impl std::fmt::Display for ParseError {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(f, "BIR parse error: {}", self.0)
28 }
29}
30
31impl BirModule {
32 pub fn parse(source: &str) -> Result<BirModule, ParseError> {
43 let mut functions = Vec::new();
44 let mut current: Option<BirFunction> = None;
45
46 for (lineno, raw) in source.lines().enumerate() {
47 let line = raw.trim();
48 if line.is_empty() || line.starts_with(';') {
49 continue;
50 }
51
52 if line.starts_with("FUNCTION ") {
53 if let Some(f) = current.take() {
54 functions.push(f);
55 }
56 let rest = &line[9..];
58 let bracket_start = rest.find('[').ok_or_else(|| {
59 ParseError(format!("line {}: missing '[' in FUNCTION", lineno + 1))
60 })?;
61 let name = rest[..bracket_start].trim().to_string();
62 let bracket_end = rest.find(']').ok_or_else(|| {
63 ParseError(format!("line {}: missing ']' in FUNCTION", lineno + 1))
64 })?;
65 let params_str = &rest[bracket_start + 1..bracket_end];
66 let params = params_str
67 .split_whitespace()
68 .filter(|s| !s.is_empty())
69 .map(String::from)
70 .collect();
71 current = Some(BirFunction {
72 name,
73 params,
74 instructions: Vec::new(),
75 });
76 } else if line == "END" {
77 if let Some(f) = current.take() {
78 functions.push(f);
79 }
80 } else if let Some(ref mut f) = current {
81 f.instructions.push(line.to_string());
82 }
83 }
84
85 if let Some(f) = current {
86 functions.push(f);
87 }
88
89 Ok(BirModule { functions })
90 }
91
92 pub fn get_function(&self, name: &str) -> Option<&BirFunction> {
94 self.functions.iter().find(|f| f.name == name)
95 }
96}