Skip to content

Commit

Permalink
separate type checker and new register manager
Browse files Browse the repository at this point in the history
parser used to perform all the type checks. now, a new module called 'analyzer' has been added for the type checking purpose. Also, the register manager has been rewritten specifically targetting Aarch64 platform
  • Loading branch information
rigel-star committed Oct 31, 2024
1 parent 2a5e7b1 commit a18e1a9
Show file tree
Hide file tree
Showing 27 changed files with 1,509 additions and 695 deletions.
26 changes: 19 additions & 7 deletions src/ast/ast_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ SOFTWARE.

#![allow(non_camel_case_types)]

use crate::{tokenizer::TokenKind, types::{BTypeComparable, LitTypeVariant, TypeSized}};
use crate::{tokenizer::{Token, TokenKind}, types::{BTypeComparable, LitTypeVariant, TypeSized}};

use super::ASTKind;

Expand Down Expand Up @@ -126,7 +126,9 @@ pub struct AST {
pub left: Option<Box<AST>>,
pub mid: Option<Box<AST>>,
pub right: Option<Box<AST>>,
pub result_type: LitTypeVariant
pub result_type: LitTypeVariant,
pub start_token: Option<Token>,
pub end_token: Option<Token>
}

impl AST {
Expand All @@ -137,7 +139,9 @@ impl AST {
left: None,
right: None,
mid: None,
result_type: LitTypeVariant::None
result_type: LitTypeVariant::None,
start_token: None,
end_token: None
}
}

Expand All @@ -154,22 +158,28 @@ impl AST {
left: left.map(Box::new),
mid: None,
right: right.map(Box::new),
result_type
result_type,
start_token: None,
end_token: None
}
}

pub fn create_leaf(
kind: ASTKind,
operation: ASTOperation,
result_type: LitTypeVariant
result_type: LitTypeVariant,
start_tok: Option<Token>,
end_tok: Option<Token>
) -> Self {
Self {
kind,
operation,
left: None,
mid: None,
right: None,
result_type
result_type,
start_token: start_tok,
end_token: end_tok
}
}

Expand All @@ -187,7 +197,9 @@ impl AST {
left: left.map(Box::new),
mid: mid.map(Box::new),
right: right.map(Box::new),
result_type
result_type,
start_token: None,
end_token: None
}
}
}
Expand Down
68 changes: 67 additions & 1 deletion src/ast/expr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use core::panic;
use std::collections::HashMap;

use crate::{error::BTypeErr, types::{are_compatible_for_operation, LitType, LitTypeVariant}};
use lazy_static::lazy_static;

use crate::{error::BTypeErr, semantic::{sa_errors::{SAError, SATypeError}, type_checker::TypeChecker}, types::{are_compatible_for_operation, LitType, LitTypeVariant}};

use super::{ASTOperation, AST};

Expand Down Expand Up @@ -109,4 +112,67 @@ impl Expr {
_ => panic!()
}
}
}

lazy_static! {
static ref TYPE_PRECEDENCE_EXPR: std::collections::HashMap<u8, u8> = {
let mut typ: std::collections::HashMap<u8, u8> = HashMap::new();
typ.insert(LitTypeVariant::I64 as u8, 3);
typ.insert(LitTypeVariant::I32 as u8, 2);
typ.insert(LitTypeVariant::I16 as u8, 1);
typ.insert(LitTypeVariant::U8 as u8, 0);
typ
};
}

impl TypeChecker {
pub fn infer_type(expr: &Expr) -> Result<LitTypeVariant, SAError> {
return match expr {
Expr::LitVal(lit_val_expr) => Ok(lit_val_expr.result_type),
Expr::Ident(ident_expr) => Ok(ident_expr.result_type),
Expr::FuncCall(func_call_expr) => Ok(func_call_expr.result_type),
Expr::Binary(bin_expr) => {
let left_type: LitTypeVariant = TypeChecker::infer_type(&bin_expr.left)?;
let right_type: LitTypeVariant = TypeChecker::infer_type(&bin_expr.right)?;
for typ in [&left_type, &right_type] {
match typ {
LitTypeVariant::Str
| LitTypeVariant::Array
| LitTypeVariant::Null
| LitTypeVariant::Void => {
return Err(
SAError::TypeError(SATypeError::IncompatibleTypes {
a: left_type,
b: right_type,
operation: bin_expr.operation
})
)
},
_ => ()
};
}
if left_type != right_type {
let lprec: Option<&u8> = TYPE_PRECEDENCE_EXPR.get(&(left_type as u8));
let rprec: Option<&u8> = TYPE_PRECEDENCE_EXPR.get(&(right_type as u8));
let lp: u8 = if let Some(lp) = lprec {
*lp
} else {
panic!("Type precedence not defined for operation {:?}", left_type);
};
let rp: u8 = if let Some(rp) = rprec {
*rp
} else {
panic!("Type precedence not defined for operation {:?}", right_type);
};
if lp > rp {
return Ok(left_type);
} else {
return Ok(right_type);
}
}
Ok(left_type)
}
_ => Err(SAError::None)
};
}
}
2 changes: 1 addition & 1 deletion src/ast/stmt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{types::LitType, StorageClass};
use crate::StorageClass;

use super::Expr;

Expand Down
Loading

0 comments on commit a18e1a9

Please sign in to comment.