Skip to content

Commit

Permalink
Merge pull request #25 from FrankBro/cmp
Browse files Browse the repository at this point in the history
cmp
  • Loading branch information
FrankBro authored Dec 1, 2023
2 parents a8986f7 + 7f570c2 commit 0328995
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 14 deletions.
18 changes: 12 additions & 6 deletions src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,17 @@ impl Env {
let lhs = lhs.as_int()?;
let rhs = self.eval_inner(rhs)?;
let rhs = rhs.as_int()?;
let i = match op {
IntBinOp::Plus => lhs + rhs,
IntBinOp::Minus => lhs - rhs,
IntBinOp::Multiply => lhs * rhs,
IntBinOp::Divide => lhs / rhs,
let val = match op {
IntBinOp::Plus => Value::Int(lhs + rhs),
IntBinOp::Minus => Value::Int(lhs - rhs),
IntBinOp::Multiply => Value::Int(lhs * rhs),
IntBinOp::Divide => Value::Int(lhs / rhs),
IntBinOp::LessThan => Value::Bool(lhs < rhs),
IntBinOp::LessThanOrEqual => Value::Bool(lhs <= rhs),
IntBinOp::GreaterThan => Value::Bool(lhs > rhs),
IntBinOp::GreaterThanOrEqual => Value::Bool(lhs >= rhs),
};
Ok(Value::Int(i))
Ok(val)
}
Expr::Negate(expr) => {
let v = self.eval_inner(expr)?;
Expand Down Expand Up @@ -308,6 +312,8 @@ mod tests {
"let f({x,y}) = x + y in let x = 1 in let y = 2 in f({x,y})",
Value::Int(3),
),
("2 > 1", Value::Bool(true)),
("2 > 3", Value::Bool(false)),
];
for (expr_str, expected) in cases {
let expr = Parser::expr(expr_str).unwrap();
Expand Down
24 changes: 24 additions & 0 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ pub enum IntBinOp {
Minus,
Multiply,
Divide,
LessThan,
LessThanOrEqual,
GreaterThan,
GreaterThanOrEqual,
}

impl fmt::Display for IntBinOp {
Expand All @@ -20,11 +24,27 @@ impl fmt::Display for IntBinOp {
IntBinOp::Minus => "-",
IntBinOp::Multiply => "*",
IntBinOp::Divide => "/",
IntBinOp::LessThan => "<",
IntBinOp::LessThanOrEqual => "<=",
IntBinOp::GreaterThan => ">",
IntBinOp::GreaterThanOrEqual => ">=",
};
write!(f, "{}", op)
}
}

impl IntBinOp {
pub fn output_ty(&self) -> Type {
match self {
IntBinOp::Plus | IntBinOp::Minus | IntBinOp::Multiply | IntBinOp::Divide => Type::int(),
IntBinOp::LessThan
| IntBinOp::LessThanOrEqual
| IntBinOp::GreaterThan
| IntBinOp::GreaterThanOrEqual => Type::bool(),
}
}
}

#[derive(Clone, Debug, PartialEq)]
pub enum Pattern {
Var(String),
Expand Down Expand Up @@ -280,6 +300,10 @@ pub mod util {
Expr::EqualEqual(lhs.into(), rhs.into())
}

pub fn gt(lhs: Expr, rhs: Expr) -> Expr {
Expr::IntBinOp(IntBinOp::GreaterThan, lhs.into(), rhs.into())
}

pub fn match_(val: Expr, cases: Vec<(&str, &str, Expr)>, def: Option<(&str, Expr)>) -> Expr {
let cases = cases
.into_iter()
Expand Down
5 changes: 3 additions & 2 deletions src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,13 +619,13 @@ impl Env {
match expr {
Expr::Bool(_) => Ok(Type::bool()),
Expr::Int(_) => Ok(Type::int()),
Expr::IntBinOp(_, lhs, rhs) => {
Expr::IntBinOp(op, lhs, rhs) => {
let ty = Type::int();
let lhs_ty = self.infer_inner(level, lhs)?;
self.unify(&ty, &lhs_ty)?;
let rhs_ty = self.infer_inner(level, rhs)?;
self.unify(&ty, &rhs_ty)?;
Ok(ty)
Ok(op.output_ty())
}
Expr::Negate(expr) => {
let ty = Type::bool();
Expand Down Expand Up @@ -1155,6 +1155,7 @@ mod tests {
"forall a b => (a -> b) -> a -> b",
);
pass("1 == 1", "bool");
pass("1 > 2", "bool");
}

#[test]
Expand Down
12 changes: 12 additions & 0 deletions src/lexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ pub enum Token {
Elif,
#[token("else")]
Else,
#[token("<")]
LessThan,
#[token("<=")]
LessThanOrEqual,
#[token(">")]
GreaterThan,
#[token(">=")]
GreaterThanOrEqual,
#[regex("[a-zA-Z_][a-zA-Z0-9_]*", ident)]
Ident(String),
}
Expand Down Expand Up @@ -132,6 +140,10 @@ impl fmt::Display for Token {
Token::Then => "then",
Token::Elif => "elif",
Token::Else => "else",
Token::LessThan => "<",
Token::LessThanOrEqual => "<=",
Token::GreaterThan => ">",
Token::GreaterThanOrEqual => ">=",
};
write!(f, "{}", s)
}
Expand Down
41 changes: 35 additions & 6 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,30 @@ impl<'a> Parser<'a> {
} else if self.matches(Token::EqualEqual)? {
let rhs = self.expr_inner(r_bp)?;
Ok(Expr::EqualEqual(lhs.into(), rhs.into()))
} else if self.matches(Token::LessThan)? {
let rhs = self.expr_inner(r_bp)?;
Ok(Expr::IntBinOp(IntBinOp::LessThan, lhs.into(), rhs.into()))
} else if self.matches(Token::LessThanOrEqual)? {
let rhs = self.expr_inner(r_bp)?;
Ok(Expr::IntBinOp(
IntBinOp::LessThanOrEqual,
lhs.into(),
rhs.into(),
))
} else if self.matches(Token::GreaterThan)? {
let rhs = self.expr_inner(r_bp)?;
Ok(Expr::IntBinOp(
IntBinOp::GreaterThan,
lhs.into(),
rhs.into(),
))
} else if self.matches(Token::GreaterThanOrEqual)? {
let rhs = self.expr_inner(r_bp)?;
Ok(Expr::IntBinOp(
IntBinOp::GreaterThanOrEqual,
lhs.into(),
rhs.into(),
))
} else {
self.expected(
vec![
Expand Down Expand Up @@ -480,7 +504,7 @@ impl<'a> Parser<'a> {

fn prefix_bp(&self) -> Result<u8> {
match self.token {
Some(Token::Negate) => Ok(7),
Some(Token::Negate) => Ok(9),
None => Err(Error::UnexpectedEof),
_ => Err(Error::InvalidPrefix(self.token.clone())),
}
Expand All @@ -489,18 +513,22 @@ impl<'a> Parser<'a> {
// TODO: Not sure how to determine precedence
fn postfix_bp(&self) -> Option<u8> {
match self.token {
Some(Token::LParen) => Some(8),
Some(Token::Dot) => Some(10),
Some(Token::Backslash) => Some(9),
Some(Token::LParen) => Some(10),
Some(Token::Dot) => Some(12),
Some(Token::Backslash) => Some(11),
_ => None,
}
}

fn infix_bp(&self) -> Option<(u8, u8)> {
match self.token {
Some(Token::EqualEqual) => Some((2, 1)),
Some(Token::Plus) | Some(Token::Minus) => Some((3, 4)),
Some(Token::Multiply) | Some(Token::Divide) => Some((5, 6)),
Some(Token::Plus) | Some(Token::Minus) => Some((5, 6)),
Some(Token::Multiply) | Some(Token::Divide) => Some((7, 8)),
Some(Token::LessThan)
| Some(Token::LessThanOrEqual)
| Some(Token::GreaterThan)
| Some(Token::GreaterThanOrEqual) => Some((3, 4)),
_ => None,
}
}
Expand Down Expand Up @@ -731,6 +759,7 @@ mod tests {
"false == !true",
equalequal(bool(false), negate(bool(true))),
);
pass("1 + 2 > 2", gt(plus(int(1), int(2)), int(2)));
}

#[test]
Expand Down

0 comments on commit 0328995

Please sign in to comment.