Skip to content

Commit

Permalink
feat: pointer arithmetic
Browse files Browse the repository at this point in the history
closes #60
  • Loading branch information
MilkeeyCat committed Oct 10, 2024
1 parent ab5b8a9 commit d183aa6
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
32 changes: 24 additions & 8 deletions src/codegen/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
parser::{
BinOp, BitwiseOp, CmpOp, Expr, ExprArray, ExprArrayAccess, ExprBinary, ExprFunctionCall,
ExprIdent, ExprLit, ExprStruct, ExprStructAccess, ExprStructMethod, ExprUnary, Expression,
Stmt, StmtFor, StmtFunction, StmtIf, StmtReturn, StmtVarDecl, StmtWhile, UnOp,
Stmt, StmtFor, StmtFunction, StmtIf, StmtReturn, StmtVarDecl, StmtWhile, UIntLitRepr, UnOp,
},
register::Register,
scope::Scope,
Expand Down Expand Up @@ -364,17 +364,16 @@ impl CodeGen {

fn bin_expr(
&mut self,
expr: ExprBinary,
mut expr: ExprBinary,
dest: Option<&Destination>,
state: Option<&State>,
) -> Result<(), CodeGenError> {
let left_type = expr.left.type_(&self.scope)?;
let right_type = expr.right.type_(&self.scope)?;
let size = std::cmp::max(
self.arch.size(&left_type, &self.scope),
self.arch.size(&right_type, &self.scope),
let type_ = Type::common_type(
expr.left.type_(&self.scope)?,
expr.right.type_(&self.scope)?,
);
let signed = left_type.signed() || right_type.signed();
let size = self.arch.size(&type_, &self.scope);
let signed = type_.signed();

match &expr.op {
BinOp::Assign => {
Expand Down Expand Up @@ -420,6 +419,23 @@ impl CodeGen {
})
};

expr.canonicalize(&self.scope);

match expr.op {
BinOp::Add | BinOp::Sub => {
if !expr.right.type_(&self.scope)?.ptr() {
expr.right = Box::new(Expr::Binary(ExprBinary {
left: expr.right,
right: Box::new(Expr::Lit(ExprLit::UInt(UIntLitRepr::new(
self.arch.size(&type_.inner().unwrap(), &self.scope) as u64,
)))),
op: BinOp::Mul,
}));
}
}
_ => (),
};

let (expr_dest, dest_r) = match dest {
Destination::Memory(_) => {
let r = self.arch.alloc()?;
Expand Down
19 changes: 19 additions & 0 deletions src/parser/expr/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,25 @@ impl Expression for ExprBinary {
}
}

impl ExprBinary {
pub fn canonicalize(&mut self, scope: &Scope) {
let type_ = self.type_(scope).unwrap();

match self {
ExprBinary {
left,
right,
op: BinOp::Add,
} => {
if type_.ptr() && right.type_(scope).unwrap().ptr() {
std::mem::swap(left.as_mut(), right.as_mut());
}
}
_ => (),
}
}
}

#[derive(Debug, Clone, PartialEq)]
pub enum ExprLit {
Int(IntLitRepr),
Expand Down
1 change: 1 addition & 0 deletions src/types/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ impl Type {

pub fn common_type(lhs: Type, rhs: Type) -> Type {
match (lhs, rhs) {
(lhs, rhs) if lhs == rhs => lhs,
(type_ @ Type::Ptr(_), int) | (int, type_ @ Type::Ptr(_)) if int.int() => type_,
(Type::UInt(lhs), Type::UInt(rhs)) => {
if lhs > rhs {
Expand Down

0 comments on commit d183aa6

Please sign in to comment.