diff --git a/data/test.lang b/data/test.lang index 1960e98..4a56d5d 100644 --- a/data/test.lang +++ b/data/test.lang @@ -4,6 +4,12 @@ struct Test { c: 64, } +struct Test2 { + a: 64, + b: Test, + c: Test, +} + fn start() { println("Helld!"); print_hex(rem(10, 7)); @@ -52,6 +58,19 @@ fn structer(test: Test) { test.c = add(test.a, test.b); print_dec(test.c); println(""); + + let test2 = Test2 { + a: 3, + b: test, + c: test, + }; + test2.c.c = 20; + print("test2.b.c: "); + print_dec(test2.b.c); + println(""); + print("test2.c.c: "); + print_dec(test2.c.c); + println(""); } fn thinger() { diff --git a/src/main.rs b/src/main.rs index d0a0a39..ddd68a0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,8 +38,8 @@ fn run_file(file: &str, gdb: bool, asm: bool) { let mut ctx = ParserCtx::from(file); let res = PModule::parse_node(&mut ctx); if ctx.output.errs.is_empty() { - // println!("Parsed:"); - // println!("{:#?}", res.node); + println!("Parsed:"); + println!("{:#?}", res.node); if let Some(module) = res.node.as_ref() { let mut program = IRUProgram::new(); module.lower(&mut program, &mut ctx.output); diff --git a/src/parser/v3/nodes/expr.rs b/src/parser/v3/nodes/expr.rs index 4ab9ddf..7f0a52b 100644 --- a/src/parser/v3/nodes/expr.rs +++ b/src/parser/v3/nodes/expr.rs @@ -1,5 +1,7 @@ use std::fmt::{Debug, Write}; +use crate::common::FilePos; + use super::{ op::{PInfixOp, UnaryOp}, util::parse_list, @@ -110,23 +112,13 @@ impl Parsable for PExpr { } let end = ctx.prev_end(); let mut recover = false; - let res = if let Some(mut op) = PInfixOp::from_token(&next.token) { + let res = if let Some(op) = PInfixOp::from_token(&next.token) { ctx.next(); - let mut n1 = Node::new(e1, start.to(end)).bx(); + let n1 = Node::new(e1, start.to(end)).bx(); let res = ctx.parse(); - let mut n2 = res.node.bx(); + let n2 = res.node.bx(); recover = res.recover; - if let Some(box Self::BinaryOp(op2, _, _)) = n2.as_ref() { - if op.presedence() > op2.presedence() { - let Some(box Self::BinaryOp(op2, n21, n22)) = n2.inner else { - unreachable!(); - }; - let end = n21.span.end; - n1 = Node::new(Self::BinaryOp(op, n1, n21), start.to(end)).bx(); - op = op2; - n2 = n22; - } - } + let (n1, op, n2) = fix_precedence(n1, op, n2, start); Self::BinaryOp(op, n1, n2) } else { e1 @@ -135,6 +127,27 @@ impl Parsable for PExpr { } } +pub fn fix_precedence( + mut n1: BoxNode, + mut op: PInfixOp, + mut n2: BoxNode, + start: FilePos, +) -> (BoxNode, PInfixOp, BoxNode) { + if let Some(box PExpr::BinaryOp(op2, _, _)) = n2.as_ref() { + if op.precedence() >= op2.precedence() { + let Some(box PExpr::BinaryOp(op2, n21, n22)) = n2.inner else { + unreachable!(); + }; + let span = start.to(n21.span.end); + let (n11, op1, n12) = fix_precedence(n1, op, n21, start); + n1 = Node::new(PExpr::BinaryOp(op1, n11, n12), span).bx(); + op = op2; + n2 = n22; + } + } + (n1, op, n2) +} + impl Debug for PExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/src/parser/v3/nodes/op.rs b/src/parser/v3/nodes/op.rs index db219ee..148268c 100644 --- a/src/parser/v3/nodes/op.rs +++ b/src/parser/v3/nodes/op.rs @@ -13,7 +13,7 @@ pub enum PInfixOp { } impl PInfixOp { - pub fn presedence(&self) -> u32 { + pub fn precedence(&self) -> u32 { match self { Self::Assign => 0, Self::LessThan => 1,