fix precedence

This commit is contained in:
2025-04-08 20:19:48 -04:00
parent 26e7a4da4a
commit 920199c567
4 changed files with 49 additions and 17 deletions

View File

@@ -4,6 +4,12 @@ struct Test {
c: 64, c: 64,
} }
struct Test2 {
a: 64,
b: Test,
c: Test,
}
fn start() { fn start() {
println("Helld!"); println("Helld!");
print_hex(rem(10, 7)); print_hex(rem(10, 7));
@@ -52,6 +58,19 @@ fn structer(test: Test) {
test.c = add(test.a, test.b); test.c = add(test.a, test.b);
print_dec(test.c); print_dec(test.c);
println(""); 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() { fn thinger() {

View File

@@ -38,8 +38,8 @@ fn run_file(file: &str, gdb: bool, asm: bool) {
let mut ctx = ParserCtx::from(file); let mut ctx = ParserCtx::from(file);
let res = PModule::parse_node(&mut ctx); let res = PModule::parse_node(&mut ctx);
if ctx.output.errs.is_empty() { if ctx.output.errs.is_empty() {
// println!("Parsed:"); println!("Parsed:");
// println!("{:#?}", res.node); println!("{:#?}", res.node);
if let Some(module) = res.node.as_ref() { if let Some(module) = res.node.as_ref() {
let mut program = IRUProgram::new(); let mut program = IRUProgram::new();
module.lower(&mut program, &mut ctx.output); module.lower(&mut program, &mut ctx.output);

View File

@@ -1,5 +1,7 @@
use std::fmt::{Debug, Write}; use std::fmt::{Debug, Write};
use crate::common::FilePos;
use super::{ use super::{
op::{PInfixOp, UnaryOp}, op::{PInfixOp, UnaryOp},
util::parse_list, util::parse_list,
@@ -110,23 +112,13 @@ impl Parsable for PExpr {
} }
let end = ctx.prev_end(); let end = ctx.prev_end();
let mut recover = false; 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(); 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 res = ctx.parse();
let mut n2 = res.node.bx(); let n2 = res.node.bx();
recover = res.recover; recover = res.recover;
if let Some(box Self::BinaryOp(op2, _, _)) = n2.as_ref() { let (n1, op, n2) = fix_precedence(n1, op, n2, start);
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;
}
}
Self::BinaryOp(op, n1, n2) Self::BinaryOp(op, n1, n2)
} else { } else {
e1 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 { impl Debug for PExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {

View File

@@ -13,7 +13,7 @@ pub enum PInfixOp {
} }
impl PInfixOp { impl PInfixOp {
pub fn presedence(&self) -> u32 { pub fn precedence(&self) -> u32 {
match self { match self {
Self::Assign => 0, Self::Assign => 0,
Self::LessThan => 1, Self::LessThan => 1,