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));
|
||||||
|
}
|
||||||
|
}
|
101
test.mcl
101
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;
|
//
|
||||||
|
//fn main() {
|
||||||
/// Different kinds of functions
|
// let obj = Foo::new();
|
||||||
// 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"
|
|
||||||
// } else
|
|
||||||
// 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