From b5ee47d2c8f67cdb660f59a19a10d393998241f0 Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Mon, 18 Nov 2024 22:02:33 -0600 Subject: [PATCH] Drop specific operators as terms, "Binary" or "Unary" ops only This preps for Order of Operations --- src/emitter.rs | 36 +++---------------------------- src/parser.rs | 57 ++++++++++++++++++++++---------------------------- 2 files changed, 28 insertions(+), 65 deletions(-) diff --git a/src/emitter.rs b/src/emitter.rs index f830c88..9f5ff43 100644 --- a/src/emitter.rs +++ b/src/emitter.rs @@ -177,43 +177,13 @@ pub fn emit_expr(w: &mut dyn Write, expr: &parser::Expr, ctx: &mut LexicalContex emit_all(w, body, &mut fun_ctx)?; write!(w, "}}")?; } - parser::Expr::Plus(e1, e2) => { - emit_expr(w, e1.as_ref(), ctx)?; - write!(w, " + ")?; - emit_expr(w, e2.as_ref(), ctx)?; - } - parser::Expr::Minus(e1, e2) => { - emit_expr(w, e1.as_ref(), ctx)?; - write!(w, " - ")?; - emit_expr(w, e2.as_ref(), ctx)?; - } - parser::Expr::Mult(e1, e2) => { - emit_expr(w, e1.as_ref(), ctx)?; - write!(w, " * ")?; - emit_expr(w, e2.as_ref(), ctx)?; - } - parser::Expr::Div(e1, e2) => { - emit_expr(w, e1.as_ref(), ctx)?; - write!(w, " / ")?; - emit_expr(w, e2.as_ref(), ctx)?; - } - parser::Expr::Mod(e1, e2) => { - emit_expr(w, e1.as_ref(), ctx)?; - write!(w, " % ")?; - emit_expr(w, e2.as_ref(), ctx)?; - } - parser::Expr::Equal(e1, e2) => { - emit_expr(w, e1.as_ref(), ctx)?; - write!(w, " == ")?; - emit_expr(w, e2.as_ref(), ctx)?; - } - parser::Expr::Relop(op, e1, e2) => { + parser::Expr::BinaryOp(op, e1, e2) => { emit_expr(w, e1.as_ref(), ctx)?; write!(w, " {} ", op)?; emit_expr(w, e2.as_ref(), ctx)?; } - parser::Expr::UnaryMinus(e) => { - write!(w, "-(")?; + parser::Expr::UnaryOp(op, e) => { + write!(w, "{}(", op)?; emit_expr(w, e.as_ref(), ctx)?; write!(w, ")")?; } diff --git a/src/parser.rs b/src/parser.rs index cd82081..bc9666b 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -14,14 +14,8 @@ pub enum Expr { Atom(Atom), Funcall(String, Vec), Funcdef(Option, Block), - UnaryMinus(Box), - Plus(Box, Box), - Minus(Box, Box), - Mult(Box, Box), - Div(Box, Box), - Mod(Box, Box), - Equal(Box, Box), - Relop(String, Box, Box), + UnaryOp(String, Box), + BinaryOp(String, Box, Box), } pub type Block = Vec; @@ -56,18 +50,18 @@ peg::parser! { l:_loop() { Stmt::Loop(l) } / e:expr() stop() { Stmt::BareExpr(e) } rule expr() -> Expr = precedence! { - e1:(@) "=" _ e2:@ { Expr::Equal(Box::new(e1), Box::new(e2)) } + e1:(@) "=" _ e2:@ { Expr::BinaryOp("=".to_string(), Box::new(e1), Box::new(e2))} -- - e1:(@) r:relop() e2:@ { Expr::Relop(r, Box::new(e1), Box::new(e2)) } + e1:(@) r:relop() e2:@ { Expr::BinaryOp(r, Box::new(e1), Box::new(e2)) } -- - "-" _ e1:@ { Expr::UnaryMinus(Box::new(e1)) } + "-" _ e1:@ { Expr::UnaryOp("-".to_string(), Box::new(e1)) } -- - e1:(@) "+" _ e2:@ { Expr::Plus(Box::new(e1), Box::new(e2)) } - e1:(@) "-" _ e2:@ { Expr::Minus(Box::new(e1), Box::new(e2)) } + e1:(@) "+" _ e2:@ { Expr::BinaryOp("+".to_string(), Box::new(e1), Box::new(e2)) } + e1:(@) "-" _ e2:@ { Expr::BinaryOp("-".to_string(), Box::new(e1), Box::new(e2)) } -- - e1:(@) "*" _ e2:@ { Expr::Mult(Box::new(e1), Box::new(e2)) } - e1:(@) "/" _ e2:@ { Expr::Div(Box::new(e1), Box::new(e2)) } - e1:(@) "%" _ e2:@ { Expr::Mod(Box::new(e1), Box::new(e2)) } + e1:(@) "*" _ e2:@ { Expr::BinaryOp("*".to_string(), Box::new(e1), Box::new(e2)) } + e1:(@) "/" _ e2:@ { Expr::BinaryOp("/".to_string(), Box::new(e1), Box::new(e2)) } + e1:(@) "%" _ e2:@ { Expr::BinaryOp("%".to_string(), Box::new(e1), Box::new(e2)) } -- "(" _ e:expr() ")" _ { e } ['"'] s:$((!['"'] [_] / r#"\""#)*) ['"'] { Expr::Atom(Atom::String(s.to_string())) } @@ -253,15 +247,8 @@ impl fmt::Display for Expr { match self { Expr::Atom(a) => write!(f, "{}", a), Expr::Id(id) => write!(f, "{}", id), - Expr::Equal(e1, e2) => write!(f, "{} = {}", e1, e2), - Expr::Relop(op, e1, e2) => write!(f, "{} {} {}", e1, op, e2), - Expr::Plus(e1, e2) => write!(f, "{} + {}", e1, e2), - Expr::Minus(e1, e2) => write!(f, "{} - {}", e1, e2), - Expr::Div(e1, e2) => write!(f, "{} / {}", e1, e2), - Expr::Mult(e1, e2) => write!(f, "{} * {}", e1, e2), - Expr::Mod(e1, e2) => write!(f, "{} % {}", e1, e2), - Expr::UnaryMinus(e) => write!(f, "-{}", e), - + Expr::BinaryOp(op, e1, e2) => write!(f, "{} {} {}", e1, op, e2), + Expr::UnaryOp(op, e) => write!(f, "{} {}", op, e), Expr::Funcdef(_arg, _block) => todo!(), Expr::Funcall(_id, _args) => todo!(), } @@ -329,18 +316,22 @@ one <- 3 - 2 four <- (3 - 1) * 2"; let expected = vec![ Stmt::Assignment("three".to_string(), - Expr::Plus( + Expr::BinaryOp( + "+".to_string(), Box::new(Expr::Atom(Atom::Num(1.0))), Box::new(Expr::Atom(Atom::Num(2.0))), )), Stmt::Assignment("one".to_string(), - Expr::Minus( + Expr::BinaryOp( + "-".to_string(), Box::new(Expr::Atom(Atom::Num(3.0))), Box::new(Expr::Atom(Atom::Num(2.0))), )), Stmt::Assignment("four".to_string(), - Expr::Mult( - Box::new(Expr::Minus( + Expr::BinaryOp( + "*".to_string(), + Box::new(Expr::BinaryOp( + "-".to_string(), Box::new(Expr::Atom(Atom::Num(3.0))), Box::new(Expr::Atom(Atom::Num(1.0))), )), @@ -355,7 +346,8 @@ four <- (3 - 1) * 2"; let prgm = "apple <- pear(x, y) + z"; let expected = vec![ Stmt::Assignment("apple".to_string(), - Expr::Plus( + Expr::BinaryOp( + "+".to_string(), Box::new(Expr::Funcall( "pear".to_string(), vec![Expr::Id("x".to_string()), Expr::Id("y".to_string())], @@ -402,7 +394,8 @@ foo <- x -> y -> x * y"; Stmt::BareExpr(Expr::Funcdef( Some("y".to_string()), vec![ - Stmt::BareExpr(Expr::Mult( + Stmt::BareExpr(Expr::BinaryOp( + "*".to_string(), Box::new(Expr::Id("x".to_string())), Box::new(Expr::Id("y".to_string())), )) @@ -444,7 +437,7 @@ else fn test_loop() { let prgm = r"loop until i > 100 a"; let expected = vec![Stmt::Loop(Loop::Until(GuardedBlock { - guard: Expr::Relop( + guard: Expr::BinaryOp( ">".to_string(), Box::new(Expr::Id("i".to_string())), Box::new(Expr::Atom(Atom::Num(100.0))),