mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-14 08:35:08 +01:00
array indexing and a bunch of other stuff
This commit is contained in:
parent
e7597dab07
commit
94229110cc
5 changed files with 172 additions and 20 deletions
|
|
@ -33,6 +33,7 @@ pub enum BinaryOp {
|
|||
Add,
|
||||
Sub,
|
||||
Comma,
|
||||
Index, // lhs[rhs]
|
||||
}
|
||||
|
||||
#[derive(Debug, DebugPls)]
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ where
|
|||
lex: PeekMoreIterator<I>,
|
||||
}
|
||||
|
||||
macro_rules! expect {
|
||||
// HACK: It's called `_parser` as a workaround this being ambiguous with the `#[expect]` attribute
|
||||
macro_rules! expect_parser {
|
||||
($self:ident, $pat:pat) => {
|
||||
match $self.next_t()? {
|
||||
($pat, span) => span,
|
||||
|
|
@ -68,6 +69,8 @@ macro_rules! expect {
|
|||
};
|
||||
}
|
||||
|
||||
use expect_parser as expect;
|
||||
|
||||
macro_rules! eat {
|
||||
($self:ident, $pat:pat) => {
|
||||
match $self.peek_t() {
|
||||
|
|
@ -77,6 +80,8 @@ macro_rules! eat {
|
|||
};
|
||||
}
|
||||
|
||||
use eat;
|
||||
|
||||
/// Can be called for the start of a sequence of tokens that could be a type.
|
||||
#[rustfmt::skip]
|
||||
fn is_tok_start_of_ty(tok: &Tok<'_>) -> bool {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
use crate::{
|
||||
ast::{Atom, BinaryOp, Expr, ExprBinary, ExprUnary, UnaryOp},
|
||||
parser::{Parser, ParserError, Result},
|
||||
parser::{expect, Parser, ParserError, Result},
|
||||
pre::Punctuator as P,
|
||||
token::{Constant, Token as Tok},
|
||||
Span, Spanned,
|
||||
|
|
@ -25,6 +25,13 @@ where
|
|||
&(Tok::Constant(Constant::Int(int)), span) => (Atom::Int(int), span),
|
||||
&(Tok::Constant(Constant::Float(float)), span) => (Atom::Float(float), span),
|
||||
&(Tok::Constant(Constant::Char(char)), span) => (Atom::Char(char), span),
|
||||
&(Tok::Punct(P::ParenOpen), _) => {
|
||||
// TODO: casts... yikes
|
||||
self.next_t()?;
|
||||
let lhs = self.expr_bp(0);
|
||||
expect!(self, Tok::Punct(P::ParenClose));
|
||||
return lhs;
|
||||
}
|
||||
&(Tok::Punct(punct), span) => {
|
||||
let r_bp = prefix_binding_power(&Tok::Punct(punct));
|
||||
let Some(op) = unary_op_from_token(&Tok::Punct(punct)) else { panic!() };
|
||||
|
|
@ -61,27 +68,52 @@ where
|
|||
Ok(&tok) => tok,
|
||||
Err(_) => break,
|
||||
};
|
||||
let Some(op) = binary_op_from_token(&tok) else { break; };
|
||||
|
||||
self.next_t()?;
|
||||
|
||||
let (l_bp, r_bp) = infix_binding_power(&tok);
|
||||
if l_bp < min_bp {
|
||||
break;
|
||||
if let Some(l_bp) = postfix_binding_power(&tok) {
|
||||
if l_bp < min_bp {
|
||||
break;
|
||||
}
|
||||
let (tok, _) = self.next_t()?;
|
||||
if let Tok::Punct(P::BracketOpen) = tok {
|
||||
let rhs = self.expr_bp(0)?;
|
||||
let span = expect!(self, Tok::Punct(P::BracketClose));
|
||||
let span = lhs.1.extend(span);
|
||||
lhs = (
|
||||
Expr::Binary(ExprBinary {
|
||||
lhs: Box::new(lhs),
|
||||
rhs: Box::new(rhs),
|
||||
op: BinaryOp::Index,
|
||||
}),
|
||||
span,
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
let rhs = self.expr_bp(r_bp)?;
|
||||
if let Some(op) = binary_op_from_token(&tok) {
|
||||
let (l_bp, r_bp) = infix_binding_power(&tok);
|
||||
if l_bp < min_bp {
|
||||
break;
|
||||
}
|
||||
|
||||
let span = lhs.1.extend(rhs.1);
|
||||
self.next_t()?;
|
||||
|
||||
lhs = (
|
||||
Expr::Binary(ExprBinary {
|
||||
lhs: Box::new(lhs),
|
||||
rhs: Box::new(rhs),
|
||||
op,
|
||||
}),
|
||||
span,
|
||||
)
|
||||
let rhs = self.expr_bp(r_bp)?;
|
||||
|
||||
let span = lhs.1.extend(rhs.1);
|
||||
|
||||
lhs = (
|
||||
Expr::Binary(ExprBinary {
|
||||
lhs: Box::new(lhs),
|
||||
rhs: Box::new(rhs),
|
||||
op,
|
||||
}),
|
||||
span,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Ok(lhs)
|
||||
|
|
@ -122,3 +154,10 @@ fn infix_binding_power(tok: &Tok<'_>) -> (u8, u8) {
|
|||
_ => panic!("invalid token in expression! {tok:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn postfix_binding_power(tok: &Tok<'_>) -> Option<u8> {
|
||||
match tok {
|
||||
Tok::Punct(P::BracketOpen) => Some(45),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
---
|
||||
source: parser/src/parser/tests.rs
|
||||
expression: parsed_pretty
|
||||
---
|
||||
Ok([
|
||||
(
|
||||
Decl(
|
||||
Normal(NormalDecl {
|
||||
decl_spec: DeclSpec {
|
||||
ty: Int,
|
||||
attrs: "(empty)",
|
||||
},
|
||||
init_declarators: [
|
||||
(
|
||||
InitDecl {
|
||||
declarator: Declarator {
|
||||
decl: Ident(("x", 5..6)),
|
||||
pointer: false,
|
||||
},
|
||||
init: Some((
|
||||
Binary(ExprBinary {
|
||||
lhs: (Atom(Int(1)), 9..10),
|
||||
rhs: (Atom(Int(1)), 13..14),
|
||||
op: Add,
|
||||
}),
|
||||
9..14,
|
||||
)),
|
||||
},
|
||||
5..6,
|
||||
),
|
||||
],
|
||||
}),
|
||||
),
|
||||
1..6,
|
||||
),
|
||||
(
|
||||
Decl(
|
||||
Normal(NormalDecl {
|
||||
decl_spec: DeclSpec {
|
||||
ty: Int,
|
||||
attrs: "(empty)",
|
||||
},
|
||||
init_declarators: [
|
||||
(
|
||||
InitDecl {
|
||||
declarator: Declarator {
|
||||
decl: Ident(("y", 21..22)),
|
||||
pointer: false,
|
||||
},
|
||||
init: Some((
|
||||
Binary(ExprBinary {
|
||||
lhs: (Atom(Int(1)), 26..27),
|
||||
rhs: (
|
||||
Binary(ExprBinary {
|
||||
lhs: (Atom(Int(2)), 31..32),
|
||||
rhs: (Atom(Int(3)), 35..36),
|
||||
op: Sub,
|
||||
}),
|
||||
31..36,
|
||||
),
|
||||
op: Add,
|
||||
}),
|
||||
26..36,
|
||||
)),
|
||||
},
|
||||
21..22,
|
||||
),
|
||||
],
|
||||
}),
|
||||
),
|
||||
17..22,
|
||||
),
|
||||
(
|
||||
Decl(
|
||||
Normal(NormalDecl {
|
||||
decl_spec: DeclSpec {
|
||||
ty: Int,
|
||||
attrs: "(empty)",
|
||||
},
|
||||
init_declarators: [
|
||||
(
|
||||
InitDecl {
|
||||
declarator: Declarator {
|
||||
decl: Ident(("z", 45..46)),
|
||||
pointer: false,
|
||||
},
|
||||
init: Some((
|
||||
Binary(ExprBinary {
|
||||
lhs: (Atom(Ident("array")), 50..55),
|
||||
rhs: (Atom(Int(9)), 56..57),
|
||||
op: Index,
|
||||
}),
|
||||
50..58,
|
||||
)),
|
||||
},
|
||||
45..46,
|
||||
),
|
||||
],
|
||||
}),
|
||||
),
|
||||
41..46,
|
||||
),
|
||||
])
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
use super::{Parser, Tok};
|
||||
use super::Tok;
|
||||
use crate::Span;
|
||||
|
||||
fn lex_and_pre(src: &str) -> impl Iterator<Item = (Tok<'_>, Span)> + '_ {
|
||||
|
|
@ -63,10 +63,14 @@ int function();
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn small_expression() {
|
||||
fn small_expressions() {
|
||||
parse_test!(
|
||||
r#"
|
||||
int x = 1 + 1;
|
||||
|
||||
int y = (1 + (2 - 3));
|
||||
|
||||
int z = (array[9]);
|
||||
"#
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue