mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-14 16:45:07 +01:00
add works
This commit is contained in:
parent
37772658bd
commit
31575cbdfb
6 changed files with 104 additions and 31 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#![allow(dead_code)]
|
||||
#![feature(let_else)]
|
||||
#![allow(dead_code)] // TODO: no
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
|
|
|||
|
|
@ -19,14 +19,17 @@ pub struct ParserError {
|
|||
}
|
||||
|
||||
impl ParserError {
|
||||
#[track_caller]
|
||||
fn new(span: Span, message: String) -> Self {
|
||||
Self { span, message }
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn eof() -> Self {
|
||||
Self::new(Span::default(), "unexpected end of file".to_string())
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn unsupported(span: Span, token: &Tok<'_>) -> Self {
|
||||
Self::new(span, format!("`{token}` is not supported"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,17 +19,19 @@ where
|
|||
}
|
||||
|
||||
fn get_lhs(&mut self) -> Result<Spanned<Expr>> {
|
||||
let (typ, span) = match self.next_t()? {
|
||||
(Tok::Ident(ident), span) => (Atom::Ident(ident.to_string()), span),
|
||||
(Tok::StringLiteral(literal), span) => (Atom::String(literal.to_string()), span),
|
||||
(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(punct), span) => {
|
||||
let (typ, span) = match self.peek_t()? {
|
||||
&(Tok::Ident(ident), span) => (Atom::Ident(ident.to_string()), span),
|
||||
&(Tok::StringLiteral(literal), span) => (Atom::String(literal.to_string()), span),
|
||||
&(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(punct), span) => {
|
||||
let r_bp = prefix_binding_power(&Tok::Punct(punct));
|
||||
let op = unary_op_from_token(&Tok::Punct(punct), span)?;
|
||||
let Some(op) = unary_op_from_token(&Tok::Punct(punct)) else { panic!() };
|
||||
let rhs = self.expr_bp(r_bp)?;
|
||||
|
||||
self.next_t()?;
|
||||
|
||||
return Ok((
|
||||
Expr::Unary(ExprUnary {
|
||||
rhs: Box::new(rhs),
|
||||
|
|
@ -40,12 +42,13 @@ where
|
|||
}
|
||||
(tok, span) => {
|
||||
return Err(ParserError::new(
|
||||
span,
|
||||
*span,
|
||||
format!("expected expression, found {tok}"),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
self.next_t()?;
|
||||
Ok((Expr::Atom(typ), span))
|
||||
}
|
||||
|
||||
|
|
@ -54,11 +57,13 @@ where
|
|||
|
||||
#[allow(clippy::while_let_loop)] // idc
|
||||
loop {
|
||||
let (tok, span) = match self.next_t() {
|
||||
Ok(tok) => tok,
|
||||
let (tok, _) = match self.peek_t() {
|
||||
Ok(&tok) => tok,
|
||||
Err(_) => break,
|
||||
};
|
||||
let op = binary_op_from_token(&tok, span)?;
|
||||
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 {
|
||||
|
|
@ -83,28 +88,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn unary_op_from_token(tok: &Tok<'_>, span: Span) -> Result<UnaryOp> {
|
||||
fn unary_op_from_token(tok: &Tok<'_>) -> Option<UnaryOp> {
|
||||
match tok {
|
||||
Tok::Punct(P::Ampersand) => Ok(UnaryOp::AddrOf),
|
||||
Tok::Punct(P::Asterisk) => Ok(UnaryOp::Deref),
|
||||
Tok::Punct(P::Plus) => Ok(UnaryOp::Plus),
|
||||
Tok::Punct(P::Minus) => Ok(UnaryOp::Minus),
|
||||
Tok::Punct(P::Tilde) => Ok(UnaryOp::Tilde),
|
||||
Tok::Punct(P::Bang) => Ok(UnaryOp::Bang),
|
||||
_ => Err(ParserError::new(
|
||||
span,
|
||||
format!("invalid unary operation: {tok}"),
|
||||
)),
|
||||
Tok::Punct(P::Ampersand) => Some(UnaryOp::AddrOf),
|
||||
Tok::Punct(P::Asterisk) => Some(UnaryOp::Deref),
|
||||
Tok::Punct(P::Plus) => Some(UnaryOp::Plus),
|
||||
Tok::Punct(P::Minus) => Some(UnaryOp::Minus),
|
||||
Tok::Punct(P::Tilde) => Some(UnaryOp::Tilde),
|
||||
Tok::Punct(P::Bang) => Some(UnaryOp::Bang),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn binary_op_from_token(tok: &Tok<'_>, span: Span) -> Result<BinaryOp> {
|
||||
fn binary_op_from_token(tok: &Tok<'_>) -> Option<BinaryOp> {
|
||||
match tok {
|
||||
Tok::Punct(P::Plus) => Ok(BinaryOp::Add),
|
||||
Tok::Punct(P::Minus) => Ok(BinaryOp::Sub),
|
||||
_ => Err(ParserError::new(
|
||||
span,
|
||||
format!("invalid binary operation: {tok}"),
|
||||
)),
|
||||
Tok::Punct(P::Plus) => Some(BinaryOp::Add),
|
||||
Tok::Punct(P::Minus) => Some(BinaryOp::Sub),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
source: parser/src/parser/tests.rs
|
||||
expression: parsed
|
||||
---
|
||||
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,
|
||||
),
|
||||
],
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue