Skip to content

Commit

Permalink
feat: type checking pass
Browse files Browse the repository at this point in the history
  • Loading branch information
MilkeeyCat committed Sep 7, 2024
1 parent 69f191d commit 16570df
Show file tree
Hide file tree
Showing 7 changed files with 238 additions and 123 deletions.
3 changes: 2 additions & 1 deletion src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
codegen::CodeGen,
lexer::Lexer,
parser,
passes::{pass::Pass, symbol_resolver::SymbolResolver},
passes::{Pass, SymbolResolver, TypeChecker},
};
use clap::Parser;
use std::{
Expand Down Expand Up @@ -43,6 +43,7 @@ pub fn compile(args: CompileArgs) -> Result<(), Box<dyn std::error::Error>> {
let (mut stmts, mut scope) = parser::Parser::new(lexer)?.into_parts()?;

SymbolResolver::proccess(&mut stmts, &mut scope)?;
TypeChecker::proccess(&mut stmts, &mut scope)?;

dbg!(&stmts);
dbg!(&scope);
Expand Down
1 change: 0 additions & 1 deletion src/lexer/token.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::scope::Scope;
use std::fmt::Display;

#[derive(Debug, PartialEq, Clone, Hash, Eq)]
Expand Down
45 changes: 1 addition & 44 deletions src/parser/expr/expr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::collections::HashSet;

use super::{int_repr::UIntLitRepr, ExprError, IntLitRepr};
use crate::{
archs::ArchError,
Expand Down Expand Up @@ -77,7 +75,7 @@ impl Expr {
}
}

fn int_lit_only(expr: &Expr) -> bool {
pub fn int_lit_only(expr: &Expr) -> bool {
match expr {
Expr::Binary(expr) => {
Expr::int_lit_only(expr.left.as_ref()) && Expr::int_lit_only(expr.right.as_ref())
Expand Down Expand Up @@ -282,12 +280,6 @@ pub struct ExprStruct {
pub fields: Vec<(String, Expr)>,
}

impl ExprStruct {
pub fn new(name: String, fields: Vec<(String, Expr)>) -> Self {
Self { name, fields }
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct ExprArray(pub Vec<Expr>);

Expand All @@ -300,23 +292,6 @@ impl Expression for ExprArray {
}
}

impl ExprArray {
pub fn new(items: Vec<Expr>, scope: &Scope) -> Self {
let unique = items
.iter()
.map(|item| item.type_(scope).unwrap())
.collect::<HashSet<_>>()
.into_iter()
.collect::<Vec<_>>();

if unique.len() != 1 {
panic!("Types only of the same type allowed in an array expression")
}

Self(items)
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct ExprStructAccess {
pub expr: Box<Expr>,
Expand Down Expand Up @@ -391,12 +366,6 @@ pub struct ExprFunctionCall {
pub arguments: Vec<Expr>,
}

impl ExprFunctionCall {
pub fn new(name: String, arguments: Vec<Expr>) -> Self {
Self { name, arguments }
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct ExprArrayAccess {
pub expr: Box<Expr>,
Expand Down Expand Up @@ -501,12 +470,6 @@ impl LValue for ExprUnary {
}
}

impl ExprUnary {
pub fn new(op: UnOp, expr: Box<Expr>) -> Self {
Self { op, expr }
}
}

impl Expression for ExprUnary {
fn type_(&self, scope: &Scope) -> Result<Type, ExprError> {
Ok(match &self.op {
Expand All @@ -529,12 +492,6 @@ pub struct ExprCast {
pub type_: Type,
}

impl ExprCast {
pub fn new(type_: Type, expr: Box<Expr>) -> Self {
Self { type_, expr }
}
}

impl Expression for ExprCast {
fn type_(&self, symbtable: &Scope) -> Result<Type, ExprError> {
let expr_type = self.expr.type_(symbtable)?;
Expand Down
118 changes: 43 additions & 75 deletions src/parser/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,22 +239,15 @@ impl Parser {
fn parse_return(&mut self) -> Result<Stmt, ParserError> {
self.expect(&Token::Return)?;

let mut expr = None;
//let type_;
if !self.cur_token_is(&Token::Semicolon) {
expr = Some(self.expr(Precedence::default())?);
//type_ = expr.as_ref().unwrap().type_(&self.scope)?;
let expr = if !self.cur_token_is(&Token::Semicolon) {
Some(self.expr(Precedence::default())?)
} else {
//type_ = Type::Void;
}
None
};

self.expect(&Token::Semicolon)?;

let (name, return_type) = self.scope.context().unwrap();
//return_type.to_owned().assign(type_).map_err(|e| match e {
// TypeError::Assignment(left, right) => TypeError::Return(left, right),
// e => e,
//})?;
let (name, _) = self.scope.context().unwrap();

Ok(Stmt::Return(StmtReturn {
expr,
Expand All @@ -267,10 +260,6 @@ impl Parser {
self.expect(&Token::If)?;

let condition = self.expr(Precedence::default())?;
//match condition.type_(&self.scope)? {
// Type::Bool => {}
// type_ => return Err(ParserError::Type(TypeError::Mismatched(Type::Bool, type_))),
//}
let consequence = self.compound_statement(self.scope.context().unwrap().to_owned())?;
let alternative = if self.cur_token_is(&Token::Else) {
self.expect(&Token::Else)?;
Expand All @@ -291,10 +280,6 @@ impl Parser {
self.expect(&Token::While)?;

let condition = self.expr(Precedence::default())?;
//match condition.type_(&self.scope)? {
// Type::Bool => {}
// type_ => return Err(ParserError::Type(TypeError::Mismatched(Type::Bool, type_))),
//}
let block = self.compound_statement(self.scope.context().unwrap().to_owned())?;

Ok(Stmt::While(StmtWhile { condition, block }))
Expand All @@ -318,13 +303,7 @@ impl Parser {
let condition = if self.cur_token_is(&Token::Semicolon) {
None
} else {
let condition = self.expr(Precedence::default())?;
//match condition.type_(&self.scope)? {
// Type::Bool => {}
// type_ => return Err(ParserError::Type(TypeError::Mismatched(Type::Bool, type_))),
//}

Some(condition)
Some(self.expr(Precedence::default())?)
};
self.expect(&Token::Semicolon)?;

Expand Down Expand Up @@ -506,7 +485,7 @@ impl Parser {

self.expect(&Token::RBrace)?;

Ok(Expr::Struct(ExprStruct::new(name, fields)))
Ok(Expr::Struct(ExprStruct { name, fields }))
}

fn string_lit(&mut self) -> Result<Expr, ParserError> {
Expand Down Expand Up @@ -537,28 +516,12 @@ impl Parser {
match self.next_token()? {
Token::LParen => match left {
Expr::Ident(ident) => {
//if let Some(Symbol::Function(function)) = self.scope.find_symbol(&ident.0) {
// let function_name = function.name.to_owned();
// let function_params = function.parameters.to_owned();
let args = self.expr_list()?;
// let args_types = args
// .iter()
// .map(|expr| expr.type_(&self.scope))
// .collect::<Result<Vec<_>, _>>()?;
// for (param_type, arg_type) in function_params.iter().zip(&args_types) {
// if let Err(_) = param_type.to_owned().assign(arg_type.to_owned()) {
// return Err(ParserError::FunctionArguments(
// function_name,
// function_params,
// args_types,
// ));
// }
// }

Ok(Expr::FunctionCall(ExprFunctionCall::new(ident.0, args)))
//} else {
// return Err(ParserError::UndeclaredFunction(ident.0));
//}

Ok(Expr::FunctionCall(ExprFunctionCall {
name: ident.0,
arguments: args,
}))
}
_ => todo!("Don't know what error to return yet"),
},
Expand Down Expand Up @@ -618,7 +581,10 @@ impl Parser {
let op = UnOp::try_from(&self.next_token()?).map_err(|e| ParserError::Operator(e))?;
let expr = self.expr(Precedence::Prefix)?;

Ok(Expr::Unary(ExprUnary::new(op, Box::new(expr))))
Ok(Expr::Unary(ExprUnary {
op,
expr: Box::new(expr),
}))
}

fn expr_list(&mut self) -> Result<Vec<Expr>, ParserError> {
Expand Down Expand Up @@ -653,19 +619,21 @@ impl Parser {
panic!("Can't get address of {expr:?}");
}

Ok(Expr::Unary(ExprUnary::new(UnOp::Address, Box::new(expr))))
Ok(Expr::Unary(ExprUnary {
op: UnOp::Address,
expr: Box::new(expr),
}))
}

fn deref_expr(&mut self) -> Result<Expr, ParserError> {
self.expect(&Token::Asterisk)?;

let expr = self.expr(Precedence::Prefix)?;
//match expr.type_(&self.scope)? {
// Type::Ptr(_) => {}
// type_ => panic!("Can't dereference an expression of type {type_}"),
//};

Ok(Expr::Unary(ExprUnary::new(UnOp::Deref, Box::new(expr))))
Ok(Expr::Unary(ExprUnary {
op: UnOp::Deref,
expr: Box::new(expr),
}))
}

fn array_expr(&mut self) -> Result<Expr, ParserError> {
Expand Down Expand Up @@ -720,10 +688,10 @@ mod test {
right: Box::new(Expr::Binary(ExprBinary {
op: BinOp::Add,
left: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(4)))),
right: Box::new(Expr::Cast(ExprCast::new(
Type::U8,
Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))),
))),
right: Box::new(Expr::Cast(ExprCast {
type_: Type::U8,
expr: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))),
})),
})),
})),
}))],
Expand All @@ -742,13 +710,13 @@ mod test {
left: Box::new(Expr::Ident(ExprIdent("foo".to_owned()))),
right: Box::new(Expr::Binary(ExprBinary {
op: BinOp::Add,
left: Box::new(Expr::Cast(ExprCast::new(
Type::U8,
Box::new(Expr::Unary(ExprUnary::new(
UnOp::Negative,
Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))),
))),
))),
left: Box::new(Expr::Cast(ExprCast {
type_: Type::U8,
expr: Box::new(Expr::Unary(ExprUnary {
op: UnOp::Negative,
expr: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))),
})),
})),
right: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(5)))),
})),
})),
Expand All @@ -770,10 +738,10 @@ mod test {
left: Box::new(Expr::Ident(ExprIdent("bar".to_owned()))),
right: Box::new(Expr::Binary(ExprBinary {
op: BinOp::Add,
left: Box::new(Expr::Cast(ExprCast::new(
Type::I8,
Box::new(Expr::Ident(ExprIdent("foo".to_owned()))),
))),
left: Box::new(Expr::Cast(ExprCast {
type_: Type::I8,
expr: Box::new(Expr::Ident(ExprIdent("foo".to_owned()))),
})),
right: Box::new(Expr::Binary(ExprBinary {
op: BinOp::Div,
left: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(5)))),
Expand All @@ -791,10 +759,10 @@ mod test {
",
vec![Stmt::Expr(Expr::Binary(ExprBinary {
op: BinOp::Add,
left: Box::new(Expr::Cast(ExprCast::new(
Type::I8,
Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))),
))),
left: Box::new(Expr::Cast(ExprCast {
type_: Type::I8,
expr: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(1)))),
})),
right: Box::new(Expr::Binary(ExprBinary {
op: BinOp::Div,
left: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(2)))),
Expand Down
9 changes: 7 additions & 2 deletions src/passes/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
pub mod pass;
pub mod symbol_resolver;
mod pass;
mod symbol_resolver;
mod type_checker;

pub use pass::Pass;
pub use symbol_resolver::SymbolResolver;
pub use type_checker::TypeChecker;
Loading

0 comments on commit 16570df

Please sign in to comment.