Start of typechecking and other processing of ast after parsing

This commit is contained in:
2024-12-22 02:53:21 +02:00
parent cb297bf75e
commit f338f07e7d
6 changed files with 169 additions and 96 deletions

View File

@@ -24,7 +24,8 @@ fn main() -> anyhow::Result<()> {
info!("Parsing {file}");
let mut prog = mclangc::parser::parse_program(tokens)?;
info!("Validating {file}");
let validated = mclangc::validator::validate_code(&mut prog)?;
mclangc::validator::validate_code(&mut prog)?;
dbg!(&prog);
}
Ok(())
}

View File

@@ -1,8 +1,8 @@
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 mod expr;
@@ -13,11 +13,11 @@ pub mod typ;
#[derive(Debug, Clone)]
pub struct Program {
pub ast: expr::Block,
pub structs: HashMap<Ident, Struct>,
pub enums: HashMap<Ident, Enum>,
pub types: HashMap<Ident, TypeAlias>,
pub functions: HashMap<Ident, Function>,
pub member_functions: HashMap<Ident, HashMap<Ident, Function>>,
pub structs: HashMap<Ident, LocBox<Struct>>,
pub enums: HashMap<Ident, LocBox<Enum>>,
pub types: HashMap<Ident, TypeType>,
pub functions: HashMap<Ident, LocBox<Function>>,
pub member_functions: HashMap<Ident, HashMap<Ident, LocBox<Function>>>,
}
#[derive(Debug, Clone)]

View File

@@ -8,7 +8,7 @@ pub mod ast;
mod expr;
mod stat;
mod utils;
mod typ;
pub mod typ;
type Result<T> = anyhow::Result<T>;

View File

@@ -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(())
}
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!()
}
}
}

View File

@@ -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));
}
}