Skip to content

Commit

Permalink
[YCC] implementing more math operations
Browse files Browse the repository at this point in the history
  • Loading branch information
Cr0a3 committed Nov 11, 2024
1 parent 280b47f commit b49c0f6
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 2 deletions.
9 changes: 9 additions & 0 deletions tools/ycc/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ pub enum AstOperand {
And,
Shl,
Shr,
OrOr,
AndAnd,
Not,
BitwiseNot,
}

#[derive(Debug, Clone)]
Expand All @@ -103,6 +107,11 @@ pub enum Expr {
StringLiteral(String),
CharLiteral(char),

Unary {
op: AstOperand,
expr: Box<Expr>,
},

Var(String),
}

Expand Down
141 changes: 139 additions & 2 deletions tools/ycc/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,125 @@ impl<'a> Parser<'a> {
}

fn parse_expr(&mut self) -> Option<Expr> {
let mut ls = self.parse_bitwise_or()?;

loop {
let op;

let current = &self.current()?.ty;

if let TokenType::OrOr = current {
op = AstOperand::OrOr;
} else if let TokenType::AndAnd = current {
op = AstOperand::AndAnd;
} else {
break;
}
self.advance(); // operator

let rs = self.parse_bitwise_or()?;

ls = Box::new(Expr::Binary { ls: ls, op: op, rs: rs });
}

Some(*ls)
}

fn parse_bitwise_or(&mut self) -> Option<Box<Expr>> {
let mut ls = self.parse_bitwise_xor()?;

loop {
let op;

let current = &self.current()?.ty;

if let TokenType::Or = current {
op = AstOperand::Or;
} else {
break;
}
self.advance(); // operator

let rs = self.parse_bitwise_xor()?;

ls = Box::new(Expr::Binary { ls: ls, op: op, rs: rs });
}

Some(ls)
}

fn parse_bitwise_xor(&mut self) -> Option<Box<Expr>> {
let mut ls = self.parse_bitwise_and()?;

loop {
let op;

let current = &self.current()?.ty;

if let TokenType::Xor = current {
op = AstOperand::Xor;
} else {
break;
}
self.advance(); // operator

let rs = self.parse_bitwise_and()?;

ls = Box::new(Expr::Binary { ls: ls, op: op, rs: rs });
}

Some(ls)
}

fn parse_bitwise_and(&mut self) -> Option<Box<Expr>> {
let mut ls = self.parse_shift()?;

loop {
let op;

let current = &self.current()?.ty;

if let TokenType::And = current {
op = AstOperand::And;
} else {
break;
}
self.advance(); // operator

let rs = self.parse_shift()?;

ls = Box::new(Expr::Binary { ls: ls, op: op, rs: rs });
}

Some(ls)
}

fn parse_shift(&mut self) -> Option<Box<Expr>> {
let mut ls = self.parse_add_sub()?;

loop {
let op;

let current = &self.current()?.ty;

if let TokenType::ShiftLeft = current {
op = AstOperand::Shl;
} else if let TokenType::ShiftRight = current {
op = AstOperand::Shr;
} else {
break;
}
self.advance(); // operator

let rs = self.parse_add_sub()?;

ls = Box::new(Expr::Binary { ls: ls, op: op, rs: rs });
}

Some(ls)
}

fn parse_add_sub(&mut self) -> Option<Box<Expr>> {
let mut ls = self.parse_term()?;

loop {
Expand All @@ -348,7 +467,7 @@ impl<'a> Parser<'a> {
ls = Box::new(Expr::Binary { ls: ls, op: op, rs: rs });
}

Some(*ls)
Some(ls)
}

fn parse_term(&mut self) -> Option<Box<Expr>> {
Expand All @@ -363,7 +482,9 @@ impl<'a> Parser<'a> {
op = AstOperand::Mul;
} else if let TokenType::Div = current {
op = AstOperand::Div;
} else {
} else if let TokenType::Mod = current {
op = AstOperand::Mod;
} else{
break;
}
self.advance(); // operator
Expand All @@ -377,6 +498,22 @@ impl<'a> Parser<'a> {
}

fn parse_factor(&mut self) -> Option<Box<Expr>> {
// check for unary op

let op = match self.current()?.ty {
TokenType::Not => Some(AstOperand::Not),
TokenType::BitwiseNot => Some(AstOperand::BitwiseNot),
_ => None,
};

if let Some(op) = op {
self.advance(); // op
let expr = self.parse_factor()?;
return Some(Box::new(Expr::Unary { op: op, expr: expr}))
}

// normal factor

let current = self.advance().ty.to_owned();

match current {
Expand Down

0 comments on commit b49c0f6

Please sign in to comment.