mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-14 16:45:07 +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,
|
Add,
|
||||||
Sub,
|
Sub,
|
||||||
Comma,
|
Comma,
|
||||||
|
Index, // lhs[rhs]
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, DebugPls)]
|
#[derive(Debug, DebugPls)]
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,8 @@ where
|
||||||
lex: PeekMoreIterator<I>,
|
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) => {
|
($self:ident, $pat:pat) => {
|
||||||
match $self.next_t()? {
|
match $self.next_t()? {
|
||||||
($pat, span) => span,
|
($pat, span) => span,
|
||||||
|
|
@ -68,6 +69,8 @@ macro_rules! expect {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use expect_parser as expect;
|
||||||
|
|
||||||
macro_rules! eat {
|
macro_rules! eat {
|
||||||
($self:ident, $pat:pat) => {
|
($self:ident, $pat:pat) => {
|
||||||
match $self.peek_t() {
|
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.
|
/// Can be called for the start of a sequence of tokens that could be a type.
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
fn is_tok_start_of_ty(tok: &Tok<'_>) -> bool {
|
fn is_tok_start_of_ty(tok: &Tok<'_>) -> bool {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Atom, BinaryOp, Expr, ExprBinary, ExprUnary, UnaryOp},
|
ast::{Atom, BinaryOp, Expr, ExprBinary, ExprUnary, UnaryOp},
|
||||||
parser::{Parser, ParserError, Result},
|
parser::{expect, Parser, ParserError, Result},
|
||||||
pre::Punctuator as P,
|
pre::Punctuator as P,
|
||||||
token::{Constant, Token as Tok},
|
token::{Constant, Token as Tok},
|
||||||
Span, Spanned,
|
Span, Spanned,
|
||||||
|
|
@ -25,6 +25,13 @@ where
|
||||||
&(Tok::Constant(Constant::Int(int)), span) => (Atom::Int(int), span),
|
&(Tok::Constant(Constant::Int(int)), span) => (Atom::Int(int), span),
|
||||||
&(Tok::Constant(Constant::Float(float)), span) => (Atom::Float(float), span),
|
&(Tok::Constant(Constant::Float(float)), span) => (Atom::Float(float), span),
|
||||||
&(Tok::Constant(Constant::Char(char)), span) => (Atom::Char(char), 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) => {
|
&(Tok::Punct(punct), span) => {
|
||||||
let r_bp = prefix_binding_power(&Tok::Punct(punct));
|
let r_bp = prefix_binding_power(&Tok::Punct(punct));
|
||||||
let Some(op) = unary_op_from_token(&Tok::Punct(punct)) else { panic!() };
|
let Some(op) = unary_op_from_token(&Tok::Punct(punct)) else { panic!() };
|
||||||
|
|
@ -61,27 +68,52 @@ where
|
||||||
Ok(&tok) => tok,
|
Ok(&tok) => tok,
|
||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
};
|
};
|
||||||
let Some(op) = binary_op_from_token(&tok) else { break; };
|
|
||||||
|
|
||||||
self.next_t()?;
|
if let Some(l_bp) = postfix_binding_power(&tok) {
|
||||||
|
if l_bp < min_bp {
|
||||||
let (l_bp, r_bp) = infix_binding_power(&tok);
|
break;
|
||||||
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 = (
|
let rhs = self.expr_bp(r_bp)?;
|
||||||
Expr::Binary(ExprBinary {
|
|
||||||
lhs: Box::new(lhs),
|
let span = lhs.1.extend(rhs.1);
|
||||||
rhs: Box::new(rhs),
|
|
||||||
op,
|
lhs = (
|
||||||
}),
|
Expr::Binary(ExprBinary {
|
||||||
span,
|
lhs: Box::new(lhs),
|
||||||
)
|
rhs: Box::new(rhs),
|
||||||
|
op,
|
||||||
|
}),
|
||||||
|
span,
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(lhs)
|
Ok(lhs)
|
||||||
|
|
@ -122,3 +154,10 @@ fn infix_binding_power(tok: &Tok<'_>) -> (u8, u8) {
|
||||||
_ => panic!("invalid token in expression! {tok:?}"),
|
_ => 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 std::fmt::Debug;
|
||||||
|
|
||||||
use super::{Parser, Tok};
|
use super::Tok;
|
||||||
use crate::Span;
|
use crate::Span;
|
||||||
|
|
||||||
fn lex_and_pre(src: &str) -> impl Iterator<Item = (Tok<'_>, Span)> + '_ {
|
fn lex_and_pre(src: &str) -> impl Iterator<Item = (Tok<'_>, Span)> + '_ {
|
||||||
|
|
@ -63,10 +63,14 @@ int function();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn small_expression() {
|
fn small_expressions() {
|
||||||
parse_test!(
|
parse_test!(
|
||||||
r#"
|
r#"
|
||||||
int x = 1 + 1;
|
int x = 1 + 1;
|
||||||
|
|
||||||
|
int y = (1 + (2 - 3));
|
||||||
|
|
||||||
|
int z = (array[9]);
|
||||||
"#
|
"#
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue