Start of typechecking and other processing of ast after parsing
This commit is contained in:
		
							parent
							
								
									cb297bf75e
								
							
						
					
					
						commit
						f338f07e7d
					
				| 
						 | 
					@ -24,7 +24,8 @@ fn main() -> anyhow::Result<()> {
 | 
				
			||||||
        info!("Parsing {file}");
 | 
					        info!("Parsing {file}");
 | 
				
			||||||
        let mut prog = mclangc::parser::parse_program(tokens)?;
 | 
					        let mut prog = mclangc::parser::parse_program(tokens)?;
 | 
				
			||||||
        info!("Validating {file}");
 | 
					        info!("Validating {file}");
 | 
				
			||||||
        let validated = mclangc::validator::validate_code(&mut prog)?;
 | 
					        mclangc::validator::validate_code(&mut prog)?;
 | 
				
			||||||
 | 
					        dbg!(&prog);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
use std::collections::HashMap;
 | 
					use std::collections::HashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use statement::{Enum, Function, Struct, TypeAlias};
 | 
					use statement::{Enum, Function, Struct};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::common::loc::LocBox;
 | 
					use crate::{common::loc::LocBox, validator::predefined::TypeType};
 | 
				
			||||||
pub use crate::tokeniser::tokentype::*;
 | 
					pub use crate::tokeniser::tokentype::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod expr;
 | 
					pub mod expr;
 | 
				
			||||||
| 
						 | 
					@ -13,11 +13,11 @@ pub mod typ;
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
pub struct Program {
 | 
					pub struct Program {
 | 
				
			||||||
    pub ast: expr::Block,
 | 
					    pub ast: expr::Block,
 | 
				
			||||||
    pub structs: HashMap<Ident, Struct>,
 | 
					    pub structs: HashMap<Ident, LocBox<Struct>>,
 | 
				
			||||||
    pub enums: HashMap<Ident, Enum>,
 | 
					    pub enums: HashMap<Ident, LocBox<Enum>>,
 | 
				
			||||||
    pub types: HashMap<Ident, TypeAlias>,
 | 
					    pub types: HashMap<Ident, TypeType>,
 | 
				
			||||||
    pub functions: HashMap<Ident, Function>,
 | 
					    pub functions: HashMap<Ident, LocBox<Function>>,
 | 
				
			||||||
    pub member_functions: HashMap<Ident, HashMap<Ident, Function>>,
 | 
					    pub member_functions: HashMap<Ident, HashMap<Ident, LocBox<Function>>>,
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone)]
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ pub mod ast;
 | 
				
			||||||
mod expr;
 | 
					mod expr;
 | 
				
			||||||
mod stat;
 | 
					mod stat;
 | 
				
			||||||
mod utils;
 | 
					mod utils;
 | 
				
			||||||
mod typ;
 | 
					pub mod typ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Result<T> = anyhow::Result<T>;
 | 
					type Result<T> = anyhow::Result<T>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,74 @@
 | 
				
			||||||
use crate::parser::ast::Program;
 | 
					use std::collections::HashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::{common::loc::LocBox, parser::ast::{expr::Block, statement::{Statement, TypeAlias}, Ast, Program}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod predefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn validate_code(prog: &mut Program) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    let Block(items) = prog.ast.clone();
 | 
				
			||||||
 | 
					    predefined::load_builtin(prog);
 | 
				
			||||||
 | 
					    collect_types(prog, &items);
 | 
				
			||||||
 | 
					    //dbg!(&prog.types);
 | 
				
			||||||
 | 
					    //dbg!(&prog.structs);
 | 
				
			||||||
 | 
					    //dbg!(&prog.enums);
 | 
				
			||||||
 | 
					    //dbg!(&prog.member_functions);
 | 
				
			||||||
 | 
					    //dbg!(&prog.functions);
 | 
				
			||||||
 | 
					    for item in items {
 | 
				
			||||||
 | 
					        match item {
 | 
				
			||||||
 | 
					            Ast::Statement(stat) => {
 | 
				
			||||||
 | 
					                match stat.inner() {
 | 
				
			||||||
 | 
					                    Statement::Fn(func) => {}
 | 
				
			||||||
 | 
					                    Statement::Let { name, typ, val } => {}
 | 
				
			||||||
 | 
					                    Statement::ConstVar { name, typ, val } => {}
 | 
				
			||||||
 | 
					                    Statement::StaticVar { name, typ, val } => {}
 | 
				
			||||||
 | 
					                    Statement::Enum(enm) => {}
 | 
				
			||||||
 | 
					                    Statement::Struct(strct) => {}
 | 
				
			||||||
 | 
					                    Statement::TypeAlias(alias) => {}
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Ast::Expr(_) => unreachable!()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn validate_code(prog: &Program) -> anyhow::Result<()> {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn collect_types(prog: &mut Program, items: &Vec<Ast>) {
 | 
				
			||||||
 | 
					    for item in items {
 | 
				
			||||||
 | 
					        match item {
 | 
				
			||||||
 | 
					            Ast::Statement(stat) => {
 | 
				
			||||||
 | 
					                match stat.inner() {
 | 
				
			||||||
 | 
					                    Statement::Fn(func)=> {
 | 
				
			||||||
 | 
					                        if let Some(struct_name) = &func.struct_name {
 | 
				
			||||||
 | 
					                            if let Some(v) = prog.member_functions.get_mut(&struct_name) {
 | 
				
			||||||
 | 
					                                v.insert(func.name.clone(), LocBox::new(stat.loc(), func.clone()));
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                let mut v = HashMap::new();
 | 
				
			||||||
 | 
					                                v.insert(func.name.clone(), LocBox::new(stat.loc(), func.clone()));
 | 
				
			||||||
 | 
					                                prog.member_functions.insert(struct_name.clone(), v);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        } else {   
 | 
				
			||||||
 | 
					                            prog.functions.insert(func.name.clone(), LocBox::new(stat.loc(), func.clone()));
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    } 
 | 
				
			||||||
 | 
					                    Statement::Enum(enm) => {
 | 
				
			||||||
 | 
					                        prog.enums.insert(enm.name.clone(), LocBox::new(stat.loc(), enm.clone()));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Statement::Struct(strct) => {
 | 
				
			||||||
 | 
					                        prog.structs.insert(strct.name.clone(), LocBox::new(stat.loc(), strct.clone()));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Statement::TypeAlias(alias) => {
 | 
				
			||||||
 | 
					                        let typ = alias.clone().typ.inner().clone();
 | 
				
			||||||
 | 
					                        prog.types.insert(alias.name.clone(), predefined::TypeType::Normal(LocBox::new(stat.loc(), typ)));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Statement::Let { .. } |
 | 
				
			||||||
 | 
					                    Statement::ConstVar { .. } |
 | 
				
			||||||
 | 
					                    Statement::StaticVar { .. } => (),
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Ast::Expr(_) => unreachable!()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,71 @@
 | 
				
			||||||
 | 
					use std::collections::HashMap;
 | 
				
			||||||
 | 
					use lazy_static::lazy_static;
 | 
				
			||||||
 | 
					use crate::common::Loc;
 | 
				
			||||||
 | 
					use crate::parser::typ::parse_type;
 | 
				
			||||||
 | 
					use crate::{common::loc::LocBox, parser::ast::{statement::Function, typ::Type, Ident, Program}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(target_arch="x86_64")]
 | 
				
			||||||
 | 
					const SIZE: usize = 8;
 | 
				
			||||||
 | 
					#[cfg(target_arch="x86")]
 | 
				
			||||||
 | 
					const SIZE: usize = 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lazy_static!(
 | 
				
			||||||
 | 
					    pub static ref TYPES_RAW: HashMap<&'static str, usize> = [
 | 
				
			||||||
 | 
					        ("void",  0),
 | 
				
			||||||
 | 
					        ("usize", SIZE),
 | 
				
			||||||
 | 
					        ("isize", SIZE),
 | 
				
			||||||
 | 
					        ("u8",    1),
 | 
				
			||||||
 | 
					        ("u16",   2),
 | 
				
			||||||
 | 
					        ("u32",   4),
 | 
				
			||||||
 | 
					        ("u64",   8),
 | 
				
			||||||
 | 
					        ("i8",    1),
 | 
				
			||||||
 | 
					        ("i16",   2),
 | 
				
			||||||
 | 
					        ("i32",   4),
 | 
				
			||||||
 | 
					        ("i64",   8),
 | 
				
			||||||
 | 
					    ].into();
 | 
				
			||||||
 | 
					    pub static ref FUNCTIONS: HashMap<&'static str, (Vec<(&'static str, &'static str)>, &'static str)> = [
 | 
				
			||||||
 | 
					        ("syscall", (vec![
 | 
				
			||||||
 | 
					            ("arg_count", "&u8"),
 | 
				
			||||||
 | 
					            ("sc_num", "usize"),
 | 
				
			||||||
 | 
					            ("args", "&[&void]")
 | 
				
			||||||
 | 
					        ], "usize")),
 | 
				
			||||||
 | 
					    ].into();
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
 | 
					pub enum TypeType {
 | 
				
			||||||
 | 
					    Normal(LocBox<Type>),
 | 
				
			||||||
 | 
					    Builtin(usize),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn load_builtin(prog: &mut Program) {
 | 
				
			||||||
 | 
					    for (name, size) in TYPES_RAW.iter() {
 | 
				
			||||||
 | 
					        prog.types.insert(Ident(name.to_string()), TypeType::Builtin(*size));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for (name, (args, ret_typ)) in FUNCTIONS.iter() {
 | 
				
			||||||
 | 
					        let mut params = Vec::new();
 | 
				
			||||||
 | 
					        let mut ret_type = None;
 | 
				
			||||||
 | 
					        if ret_typ.len() > 0 {
 | 
				
			||||||
 | 
					            let mut ret_t_tokens = crate::tokeniser::tokenise(&ret_typ, "(internal)").unwrap();
 | 
				
			||||||
 | 
					            let typ = parse_type(&mut ret_t_tokens).unwrap();
 | 
				
			||||||
 | 
					            ret_type = Some(LocBox::new(&Loc::default(), typ.inner().clone()));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (name, typ) in args {
 | 
				
			||||||
 | 
					            let mut tokens = crate::tokeniser::tokenise(&typ, "(internal)").unwrap();
 | 
				
			||||||
 | 
					            let typ = parse_type(&mut tokens).unwrap();
 | 
				
			||||||
 | 
					            params.push((Ident(name.to_string()), LocBox::new(&Loc::new("(internal)", 0, 0), typ.inner().clone()))); 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let f = Function {
 | 
				
			||||||
 | 
					            struct_name: None,
 | 
				
			||||||
 | 
					            name: Ident(name.to_string()),
 | 
				
			||||||
 | 
					            params,
 | 
				
			||||||
 | 
					            ret_type,
 | 
				
			||||||
 | 
					            qual_const: false,
 | 
				
			||||||
 | 
					            qual_extern: None,
 | 
				
			||||||
 | 
					            body: None
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        prog.functions.insert(Ident(name.to_string()), LocBox::new(&Loc::new("(internal)", 0, 0), f));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										99
									
								
								test.mcl
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								test.mcl
									
									
									
									
									
								
							| 
						 | 
					@ -1,86 +1,21 @@
 | 
				
			||||||
 | 
					//type str = [u8];
 | 
				
			||||||
enum Wah {
 | 
					//
 | 
				
			||||||
    A,
 | 
					//struct Foo {
 | 
				
			||||||
    B,
 | 
					//    a: usize,
 | 
				
			||||||
    C,
 | 
					//    b: &str
 | 
				
			||||||
    D
 | 
					//}
 | 
				
			||||||
}
 | 
					//
 | 
				
			||||||
 | 
					//fn Foo.new(a: usize, b: &str) -> Foo {
 | 
				
			||||||
struct Baz {
 | 
					//    return Foo {
 | 
				
			||||||
    owo: i32,
 | 
					//        a: a,
 | 
				
			||||||
    uwu: usize
 | 
					//        b: b
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Type definitions
 | 
					 | 
				
			||||||
// type Rah = &Baz;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// Different kinds of functions
 | 
					 | 
				
			||||||
// Normal function
 | 
					 | 
				
			||||||
// fn main(a: &Foo, b: Rah) -> Nya {
 | 
					 | 
				
			||||||
    /// General expressions (math)
 | 
					 | 
				
			||||||
    // Works
 | 
					 | 
				
			||||||
    // let a = 1 * 3 == 4;
 | 
					 | 
				
			||||||
    // let b = 3/4 == *a;
 | 
					 | 
				
			||||||
    // let c = (a->b.c->d) / 2;
 | 
					 | 
				
			||||||
    // let d = 2 / a->b.c->d;
 | 
					 | 
				
			||||||
    // let e = a->b.c->d / 2;
 | 
					 | 
				
			||||||
    // let f = a.b.c.d / 2;
 | 
					 | 
				
			||||||
    // let g = a.b[a.c] * 5;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // No worky
 | 
					 | 
				
			||||||
    // nothing! yay!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Struct literals
 | 
					 | 
				
			||||||
    // let a = Baz {
 | 
					 | 
				
			||||||
    //     owo: a,
 | 
					 | 
				
			||||||
    //     uwu: b + c / d
 | 
					 | 
				
			||||||
//    };
 | 
					//    };
 | 
				
			||||||
    
 | 
					//}
 | 
				
			||||||
    /// If statement
 | 
					//
 | 
				
			||||||
    // if 1 > 3 {
 | 
					//
 | 
				
			||||||
    //     ";3"
 | 
					//fn main() {
 | 
				
			||||||
    // } else 
 | 
					//    let obj = Foo::new();
 | 
				
			||||||
    // if *a == 3 {
 | 
					//    
 | 
				
			||||||
    //     ":0"
 | 
					 | 
				
			||||||
    // } else {
 | 
					 | 
				
			||||||
    //     ">:("
 | 
					 | 
				
			||||||
//}
 | 
					//}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// 3 kinds of loops all doing the same thing
 | 
					 | 
				
			||||||
    /// While loops
 | 
					 | 
				
			||||||
    // let iw = 0;
 | 
					 | 
				
			||||||
    // while iw < 10 {
 | 
					 | 
				
			||||||
    //     println("Owo");
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// For loops
 | 
					 | 
				
			||||||
    // for let ifr = 0 ; ifr < 20 ; ifr += 1 {
 | 
					 | 
				
			||||||
    //     println("nya");
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    /// Infinite loops
 | 
					 | 
				
			||||||
    // let il = 0;
 | 
					 | 
				
			||||||
    // loop {
 | 
					 | 
				
			||||||
    //     if il > 10 {
 | 
					 | 
				
			||||||
    //         break;
 | 
					 | 
				
			||||||
    //     }
 | 
					 | 
				
			||||||
    //     println("Rah");
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// Function Calls
 | 
					 | 
				
			||||||
    // println(":3");
 | 
					 | 
				
			||||||
//}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Struct member function with inner data
 | 
					 | 
				
			||||||
//fn Baz.main(self: &mut Baz, a: &Foo, b: &mut Bar) -> &Nya;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Struct member function without any data a.k.a a static member func
 | 
					 | 
				
			||||||
//fn Baz.main(a: &Foo, b: &mut Bar) -> &Nya;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user