scrapile/lang/typed/
root.rs1use std::collections::HashMap;
2use crate::lang::{error::typed::Error, parser::root::Roots};
3use super::{block::{self, TBlock}, function::FuncSignature, symbol_table::{FuncTable, TypeTable, VarTable, VarTableEntry}};
4
5#[derive(Debug)]
7pub struct Project {
8 pub main: TBlock,
10
11 pub procedures: Vec<(String, TBlock)>,
13}
14
15pub fn wrap_root(roots: &Roots) -> Result<Project, Error> {
17 let type_table = TypeTable(HashMap::new());
18 let mut func_table = FuncTable(HashMap::new());
19
20 for func in roots.funcs.iter() {
22 let signature = (FuncSignature {
23 params: func.0.params.iter()
24 .map(|((ident, ptype), span)| ((ident.clone(), ptype.clone()), span.clone()))
25 .collect::<Vec<_>>(),
26 retrn_type: func.0.retrn_type.clone(),
27 }, func.1.clone());
28
29 if let Some(old) = func_table.0.insert(func.0.ident.clone(), signature) {
31 return Err(Error::MultipleFunc {
32 first_span: old.1,
33 additional_span: func.1.clone(),
34 })
35 }
36 }
37
38 let Some(main) = roots.main.get(0)
40 else {
41 return Err(Error::NoMain)
42 };
43 if let Some(extra) = roots.main.get(1) {
44 return Err(Error::MultipleMain {
45 first_span: main.1.clone(),
46 additional_span: extra.1.clone(),
47 });
48 }
49
50 let main = block::wrap_block(
52 main.0.clone(),
53 &type_table,
54 &func_table,
55 VarTable::new("$root".to_string()),
56 )?.0;
57
58 let mut procedures = Vec::new();
60 for func in roots.funcs.iter() {
61 let mut var_table = VarTable::new(format!("$func${}", func.0.ident));
62
63 for param in func.0.params.iter() {
65 var_table.insert(param.0.0.clone(), VarTableEntry {
66 var_type: param.0.1.clone(),
67 mutable: false,
68 span: param.1.clone(),
69 });
70 }
71
72 let wrapped = block::wrap_block(func.0.body.0.clone(), &type_table, &func_table, var_table)?;
74
75 if wrapped.1 != func.0.retrn_type.0 {
77 return Err(Error::RetrnTypeMismatch {
78 span: wrapped.0.tail.map(|((_, span), _)| span.clone()).unwrap_or_else(|| func.0.body.1.clone()),
79 type_span: func.0.retrn_type.1.clone(),
80 expr_type: wrapped.1.clone(),
81 retrn_type: func.0.retrn_type.0.clone(),
82 })
83 }
84
85 procedures.push((func.0.ident.clone(), wrapped.0));
87 }
88
89 Ok(Project {
90 main,
91 procedures,
92 })
93}