From e3b20aae416a2c6097d4e298510f5f0fcf191c80 Mon Sep 17 00:00:00 2001 From: Ross Andrews Date: Sat, 5 Aug 2023 11:07:09 -0500 Subject: [PATCH] More refactoring --- forge_core/src/ast.rs | 8 ++--- forge_core/src/compiler.rs | 14 +++------ forge_core/src/forge_parser.rs | 53 ++++++++++++++++++---------------- forge_core/src/new.pest | 2 +- 4 files changed, 37 insertions(+), 40 deletions(-) diff --git a/forge_core/src/ast.rs b/forge_core/src/ast.rs index be45fab..d0c7289 100644 --- a/forge_core/src/ast.rs +++ b/forge_core/src/ast.rs @@ -137,7 +137,7 @@ pub struct RepeatLoop { } /// One of the five arithmetical operators -#[derive(Debug, PartialEq, Copy, Clone)] +#[derive(Debug, Eq, PartialEq, Copy, Clone)] pub enum Operator { Add, Sub, @@ -162,7 +162,6 @@ pub enum Operator { #[derive(Debug, PartialEq, Clone)] pub enum Suffix { Subscript(BoxExpr), - Arglist(Vec), Member(String), } @@ -170,11 +169,12 @@ pub enum Suffix { pub enum Expr { Number(i32), Name(String), - Expr(BoxExpr), Not(BoxExpr), Neg(BoxExpr), Address(Lvalue), - Suffix(BoxExpr, Suffix), + Call(BoxExpr, Vec), + Subscript(BoxExpr, BoxExpr), + Member(BoxExpr, String), Infix(BoxExpr, Operator, BoxExpr), } diff --git a/forge_core/src/compiler.rs b/forge_core/src/compiler.rs index 9a84d62..44ea4ad 100644 --- a/forge_core/src/compiler.rs +++ b/forge_core/src/compiler.rs @@ -406,11 +406,6 @@ impl Compilable for Expr { None => Err(CompileError(0, 0, format!("Unknown name {}", name))), } } - Expr::Expr(e) => { - // Just an expr containing an expr, recurse - (*e.0).process(state, Some(sig))?; - Ok(()) - } Expr::Neg(e) => { (*e.0).process(state, Some(sig))?; // To arithmetically negate something, invert and increment (2s complement) @@ -425,9 +420,9 @@ impl Compilable for Expr { } // Handling addresses is very easy because processing an lvalue leaves the address on the stack Expr::Address(lvalue) => lvalue.process(state, Some(sig)), - Expr::Suffix(_, _) => { - todo!() - } + Expr::Call(_, _) => todo!(), + Expr::Subscript(_, _) => todo!("Structs and arrays are not yen supported"), + Expr::Member(_, _) => todo!("Structs and arrays are not yen supported"), Expr::Infix(lhs, op, rhs) => { // Recurse on expressions, handling operators (*lhs.0).process(state, Some(&mut sig))?; @@ -531,7 +526,6 @@ pub fn eval_const(expr: Expr, scope: &Scope) -> Result { Err(CompileError(0, 0, format!("Unknown const {}", n))) } } - Expr::Expr(e) => eval_const(*e.0, scope), Expr::Neg(e) => { let val = eval_const(*e.0, scope)?; Ok(-val) @@ -545,7 +539,7 @@ pub fn eval_const(expr: Expr, scope: &Scope) -> Result { 0, String::from("Addresses are not known at compile time"), )), - Expr::Suffix(_, _) => Err(CompileError( + Expr::Call(_, _) | Expr::Subscript(_, _) | Expr::Member(_, _) => Err(CompileError( 0, 0, String::from("Constants must be statically defined"), diff --git a/forge_core/src/forge_parser.rs b/forge_core/src/forge_parser.rs index 5e27f47..1aaff7f 100644 --- a/forge_core/src/forge_parser.rs +++ b/forge_core/src/forge_parser.rs @@ -23,7 +23,9 @@ lazy_static::lazy_static! { .op(Op::infix(add, Left) | Op::infix(sub, Left)) .op(Op::infix(mul, Left) | Op::infix(div, Left) | Op::infix(modulus, Left)) .op(Op::prefix(Rule::prefix)) - .op(Op::postfix(Rule::suffix)) + .op(Op::postfix(Rule::arglist)) + .op(Op::postfix(Rule::subscript)) + .op(Op::postfix(Rule::member)) }; } @@ -462,7 +464,17 @@ impl AstNode for Expr { "!" => Expr::Not(expr.into()), _ => unreachable!(), }) - .map_postfix(|expr, suffix| Expr::Suffix(expr.into(), Suffix::from_pair(suffix))) + .map_postfix(|expr, suffix| match suffix.as_rule() { + Rule::arglist => Expr::Call( + expr.into(), + suffix.into_inner().map(Rvalue::from_pair).collect(), + ), + Rule::subscript => { + Expr::Subscript(expr.into(), Expr::from_pair(suffix.first()).into()) + } + Rule::member => Expr::Member(expr.into(), suffix.first_as_string()), + _ => unreachable!(), + }) .parse(pair.into_inner()) } } @@ -512,8 +524,8 @@ impl AstNode for Suffix { match first.as_rule() { Rule::subscript => Self::Subscript(Expr::from_pair(first.first()).into()), Rule::member => Self::Member(first.first_as_string()), - Rule::arglist => Self::Arglist(first.into_inner().map(Rvalue::from_pair).collect()), - rule => unreachable!("Expected a subscript, member, or arglist, got a {:?}", rule), + //Rule::arglist => Self::Arglist(first.into_inner().map(Rvalue::from_pair).collect()), + rule => unreachable!("Expected a subscript or member, got a {:?}", rule), } } } @@ -746,15 +758,15 @@ mod test { // Simple suffix assert_eq!( Expr::from_str("foo[10]"), - Ok(Expr::Suffix("foo".into(), Subscript(10.into()))) + Ok(Expr::Subscript("foo".into(), 10.into())) ); // Multi-suffix assert_eq!( Expr::from_str("foo[10].bar"), - Ok(Expr::Suffix( - Expr::Suffix("foo".into(), Subscript(10.into())).into(), - Member("bar".into()) + Ok(Expr::Member( + Expr::Subscript("foo".into(), 10.into()).into(), + "bar".into() )) ); @@ -848,21 +860,18 @@ mod test { )) ); - // This is godawful but legal _as long as it parses like this._ The arglist suffix on the end - // goes on the "&foo" expression as a whole, so, it "calls" the address of foo. Essentially: + // This is godawful but legal _as long as it parses like this._ The arglist on the end goes + // on the "&foo" expression as a whole, so, it "calls" the address of foo. Essentially: // "push foo; call" rather than "loadw foo; call" assert_eq!( Expr::from_str("&foo()"), - Ok(Expr::Suffix( - Expr::Address("foo".into()).into(), - Suffix::Arglist(vec![]) - )) + Ok(Expr::Call(Expr::Address("foo".into()).into(), vec![])) ) } #[test] fn parse_calls() { - let blah = Expr::Suffix("blah".into(), Suffix::Arglist(vec![])); + let blah = Expr::Call("blah".into(), vec![]); // Can Node parse a call? assert_eq!(Expr::from_str("blah()"), Ok(blah.clone())); @@ -873,19 +882,13 @@ mod test { // Calls with args assert_eq!( Expr::from_str("blah(1, 2)"), - Ok(Expr::Suffix( - "blah".into(), - Suffix::Arglist(vec![1.into(), 2.into()]) - )) + Ok(Expr::Call("blah".into(), vec![1.into(), 2.into()])) ); //Calls with strings assert_eq!( Expr::from_str("blah(\"foo\", 2)"), - Ok(Expr::Suffix( - "blah".into(), - Suffix::Arglist(vec!["foo".into(), 2.into()]) - )) + Ok(Expr::Call("blah".into(), vec!["foo".into(), 2.into()])) ); } @@ -952,8 +955,8 @@ mod test { assert_eq!( Block::from_str("{ foo(); bar(); }"), Ok(Block(vec![ - Statement::Expr(Expr::Suffix("foo".into(), Suffix::Arglist(vec![]))), - Statement::Expr(Expr::Suffix("bar".into(), Suffix::Arglist(vec![]))), + Statement::Expr(Expr::Call("foo".into(), vec![])), + Statement::Expr(Expr::Call("bar".into(), vec![])), ])) ); } diff --git a/forge_core/src/new.pest b/forge_core/src/new.pest index 248a9d1..d7dbca6 100644 --- a/forge_core/src/new.pest +++ b/forge_core/src/new.pest @@ -67,7 +67,7 @@ operator = _{ expr = { prefix* ~ term ~ suffix* ~ (operator ~ prefix* ~ term ~ suffix*)* } term = _{ number | name | "(" ~ expr ~ ")" | "&" ~ lvalue } -suffix = { modifier | arglist } +suffix = _{ modifier | arglist } modifier = _{ subscript | member } subscript = { "[" ~ expr ~ "]" } arglist = { "(" ~ (rvalue ~ ("," ~ rvalue)*)? ~ ")" }