desugar: Add primitive constant folding
This commit is contained in:
parent
cd2e3c3e32
commit
2d706ff582
@ -1,9 +1,11 @@
|
|||||||
//! Desugaring passes for Conlang
|
//! Desugaring passes for Conlang
|
||||||
|
|
||||||
|
pub mod constant_folder;
|
||||||
pub mod path_absoluter;
|
pub mod path_absoluter;
|
||||||
pub mod squash_groups;
|
pub mod squash_groups;
|
||||||
pub mod while_else;
|
pub mod while_else;
|
||||||
|
|
||||||
|
pub use constant_folder::ConstantFolder;
|
||||||
pub use path_absoluter::NormalizePaths;
|
pub use path_absoluter::NormalizePaths;
|
||||||
pub use squash_groups::SquashGroups;
|
pub use squash_groups::SquashGroups;
|
||||||
pub use while_else::WhileElseDesugar;
|
pub use while_else::WhileElseDesugar;
|
||||||
|
89
compiler/cl-ast/src/desugar/constant_folder.rs
Normal file
89
compiler/cl-ast/src/desugar/constant_folder.rs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
use crate::{
|
||||||
|
ast::{ExprKind as Ek, *},
|
||||||
|
ast_visitor::{Fold, fold::or_fold_expr_kind},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ConstantFolder;
|
||||||
|
|
||||||
|
macro bin_rule(
|
||||||
|
match ($kind: ident, $head: expr, $tail: expr) {
|
||||||
|
$(($op:ident, $impl:expr, $($ty:ident -> $rety:ident),*)),*$(,)?
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
#[allow(clippy::all)]
|
||||||
|
match ($kind, $head, $tail) {
|
||||||
|
$($(( BinaryKind::$op,
|
||||||
|
Expr { kind: ExprKind::Literal(Literal::$ty(a)), .. },
|
||||||
|
Expr { kind: ExprKind::Literal(Literal::$ty(b)), .. },
|
||||||
|
) => {
|
||||||
|
ExprKind::Literal(Literal::$rety($impl(a, b)))
|
||||||
|
},)*)*
|
||||||
|
(kind, head, tail) => ExprKind::Binary(Binary {
|
||||||
|
kind,
|
||||||
|
parts: Box::new((head, tail)),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro un_rule(
|
||||||
|
match ($kind: ident, $tail: expr) {
|
||||||
|
$(($op:ident, $impl:expr, $($ty:ident),*)),*$(,)?
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
match ($kind, $tail) {
|
||||||
|
$($((UnaryKind::$op, Expr { kind: ExprKind::Literal(Literal::$ty(v)), .. }) => {
|
||||||
|
ExprKind::Literal(Literal::$ty($impl(v)))
|
||||||
|
},)*)*
|
||||||
|
(kind, tail) => ExprKind::Unary(Unary { kind, tail: Box::new(tail) }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Fold for ConstantFolder {
|
||||||
|
fn fold_expr_kind(&mut self, kind: Ek) -> Ek {
|
||||||
|
match kind {
|
||||||
|
Ek::Group(Group { expr }) => self.fold_expr_kind(expr.kind),
|
||||||
|
Ek::Binary(Binary { kind, parts }) => {
|
||||||
|
let (head, tail) = *parts;
|
||||||
|
bin_rule! (match (kind, self.fold_expr(head), self.fold_expr(tail)) {
|
||||||
|
(Lt, |a, b| a < b, Bool -> Bool, Int -> Bool),
|
||||||
|
(LtEq, |a, b| a <= b, Bool -> Bool, Int -> Bool),
|
||||||
|
(Equal, |a, b| a == b, Bool -> Bool, Int -> Bool),
|
||||||
|
(NotEq, |a, b| a != b, Bool -> Bool, Int -> Bool),
|
||||||
|
(GtEq, |a, b| a >= b, Bool -> Bool, Int -> Bool),
|
||||||
|
(Gt, |a, b| a > b, Bool -> Bool, Int -> Bool),
|
||||||
|
(BitAnd, |a, b| a & b, Bool -> Bool, Int -> Int),
|
||||||
|
(BitOr, |a, b| a | b, Bool -> Bool, Int -> Int),
|
||||||
|
(BitXor, |a, b| a ^ b, Bool -> Bool, Int -> Int),
|
||||||
|
(Shl, |a, b| a << b, Int -> Int),
|
||||||
|
(Shr, |a, b| a >> b, Int -> Int),
|
||||||
|
(Add, |a, b| a + b, Int -> Int),
|
||||||
|
(Sub, |a, b| a - b, Int -> Int),
|
||||||
|
(Mul, |a, b| a * b, Int -> Int),
|
||||||
|
(Div, |a, b| a / b, Int -> Int),
|
||||||
|
(Rem, |a, b| a % b, Int -> Int),
|
||||||
|
// Cursed bit-smuggled float shenanigans
|
||||||
|
(Lt, |a, b| (f64::from_bits(a) < f64::from_bits(b)), Float -> Bool),
|
||||||
|
(LtEq, |a, b| (f64::from_bits(a) >= f64::from_bits(b)), Float -> Bool),
|
||||||
|
(Equal, |a, b| (f64::from_bits(a) == f64::from_bits(b)), Float -> Bool),
|
||||||
|
(NotEq, |a, b| (f64::from_bits(a) != f64::from_bits(b)), Float -> Bool),
|
||||||
|
(GtEq, |a, b| (f64::from_bits(a) <= f64::from_bits(b)), Float -> Bool),
|
||||||
|
(Gt, |a, b| (f64::from_bits(a) > f64::from_bits(b)), Float -> Bool),
|
||||||
|
(Add, |a, b| (f64::from_bits(a) + f64::from_bits(b)).to_bits(), Float -> Float),
|
||||||
|
(Sub, |a, b| (f64::from_bits(a) - f64::from_bits(b)).to_bits(), Float -> Float),
|
||||||
|
(Mul, |a, b| (f64::from_bits(a) * f64::from_bits(b)).to_bits(), Float -> Float),
|
||||||
|
(Div, |a, b| (f64::from_bits(a) / f64::from_bits(b)).to_bits(), Float -> Float),
|
||||||
|
(Rem, |a, b| (f64::from_bits(a) % f64::from_bits(b)).to_bits(), Float -> Float),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Ek::Unary(Unary { kind, tail }) => {
|
||||||
|
un_rule! (match (kind, self.fold_expr(*tail)) {
|
||||||
|
(Not, std::ops::Not::not, Int, Bool),
|
||||||
|
(Neg, std::ops::Not::not, Int, Bool),
|
||||||
|
(Neg, |f| (-f64::from_bits(f)).to_bits(), Float),
|
||||||
|
(At, std::ops::Not::not, Float), /* Lmao */
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => or_fold_expr_kind(self, kind),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -124,6 +124,9 @@ fn live_desugar() -> Result<(), RlError> {
|
|||||||
let code = Parser::new("", Lexer::new(line)).parse::<Stmt>()?;
|
let code = Parser::new("", Lexer::new(line)).parse::<Stmt>()?;
|
||||||
println!("Raw, as parsed:\n{C_LISTING}{code}\x1b[0m");
|
println!("Raw, as parsed:\n{C_LISTING}{code}\x1b[0m");
|
||||||
|
|
||||||
|
let code = ConstantFolder.fold_stmt(code);
|
||||||
|
println!("ConstantFolder\n{C_LISTING}{code}\x1b[0m");
|
||||||
|
|
||||||
let code = SquashGroups.fold_stmt(code);
|
let code = SquashGroups.fold_stmt(code);
|
||||||
println!("SquashGroups\n{C_LISTING}{code}\x1b[0m");
|
println!("SquashGroups\n{C_LISTING}{code}\x1b[0m");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user