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 +1,6 @@
|
||||||
# uwuc
|
# uwuc
|
||||||
|
|
||||||
|
# Building
|
||||||
|
|
||||||
|
`uwucc` requires a nightly rust compiler because of the following features:
|
||||||
|
* `let_else`
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
#![allow(dead_code)]
|
#![feature(let_else)]
|
||||||
|
#![allow(dead_code)] // TODO: no
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,17 @@ pub struct ParserError {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParserError {
|
impl ParserError {
|
||||||
|
#[track_caller]
|
||||||
fn new(span: Span, message: String) -> Self {
|
fn new(span: Span, message: String) -> Self {
|
||||||
Self { span, message }
|
Self { span, message }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn eof() -> Self {
|
fn eof() -> Self {
|
||||||
Self::new(Span::default(), "unexpected end of file".to_string())
|
Self::new(Span::default(), "unexpected end of file".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn unsupported(span: Span, token: &Tok<'_>) -> Self {
|
fn unsupported(span: Span, token: &Tok<'_>) -> Self {
|
||||||
Self::new(span, format!("`{token}` is not supported"))
|
Self::new(span, format!("`{token}` is not supported"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,17 +19,19 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lhs(&mut self) -> Result<Spanned<Expr>> {
|
fn get_lhs(&mut self) -> Result<Spanned<Expr>> {
|
||||||
let (typ, span) = match self.next_t()? {
|
let (typ, span) = match self.peek_t()? {
|
||||||
(Tok::Ident(ident), span) => (Atom::Ident(ident.to_string()), span),
|
&(Tok::Ident(ident), span) => (Atom::Ident(ident.to_string()), span),
|
||||||
(Tok::StringLiteral(literal), span) => (Atom::String(literal.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::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(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 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)?;
|
let rhs = self.expr_bp(r_bp)?;
|
||||||
|
|
||||||
|
self.next_t()?;
|
||||||
|
|
||||||
return Ok((
|
return Ok((
|
||||||
Expr::Unary(ExprUnary {
|
Expr::Unary(ExprUnary {
|
||||||
rhs: Box::new(rhs),
|
rhs: Box::new(rhs),
|
||||||
|
|
@ -40,12 +42,13 @@ where
|
||||||
}
|
}
|
||||||
(tok, span) => {
|
(tok, span) => {
|
||||||
return Err(ParserError::new(
|
return Err(ParserError::new(
|
||||||
span,
|
*span,
|
||||||
format!("expected expression, found {tok}"),
|
format!("expected expression, found {tok}"),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.next_t()?;
|
||||||
Ok((Expr::Atom(typ), span))
|
Ok((Expr::Atom(typ), span))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,11 +57,13 @@ where
|
||||||
|
|
||||||
#[allow(clippy::while_let_loop)] // idc
|
#[allow(clippy::while_let_loop)] // idc
|
||||||
loop {
|
loop {
|
||||||
let (tok, span) = match self.next_t() {
|
let (tok, _) = match self.peek_t() {
|
||||||
Ok(tok) => tok,
|
Ok(&tok) => tok,
|
||||||
Err(_) => break,
|
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);
|
let (l_bp, r_bp) = infix_binding_power(&tok);
|
||||||
if l_bp < min_bp {
|
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 {
|
match tok {
|
||||||
Tok::Punct(P::Ampersand) => Ok(UnaryOp::AddrOf),
|
Tok::Punct(P::Ampersand) => Some(UnaryOp::AddrOf),
|
||||||
Tok::Punct(P::Asterisk) => Ok(UnaryOp::Deref),
|
Tok::Punct(P::Asterisk) => Some(UnaryOp::Deref),
|
||||||
Tok::Punct(P::Plus) => Ok(UnaryOp::Plus),
|
Tok::Punct(P::Plus) => Some(UnaryOp::Plus),
|
||||||
Tok::Punct(P::Minus) => Ok(UnaryOp::Minus),
|
Tok::Punct(P::Minus) => Some(UnaryOp::Minus),
|
||||||
Tok::Punct(P::Tilde) => Ok(UnaryOp::Tilde),
|
Tok::Punct(P::Tilde) => Some(UnaryOp::Tilde),
|
||||||
Tok::Punct(P::Bang) => Ok(UnaryOp::Bang),
|
Tok::Punct(P::Bang) => Some(UnaryOp::Bang),
|
||||||
_ => Err(ParserError::new(
|
_ => None,
|
||||||
span,
|
|
||||||
format!("invalid unary operation: {tok}"),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn binary_op_from_token(tok: &Tok<'_>, span: Span) -> Result<BinaryOp> {
|
fn binary_op_from_token(tok: &Tok<'_>) -> Option<BinaryOp> {
|
||||||
match tok {
|
match tok {
|
||||||
Tok::Punct(P::Plus) => Ok(BinaryOp::Add),
|
Tok::Punct(P::Plus) => Some(BinaryOp::Add),
|
||||||
Tok::Punct(P::Minus) => Ok(BinaryOp::Sub),
|
Tok::Punct(P::Minus) => Some(BinaryOp::Sub),
|
||||||
_ => Err(ParserError::new(
|
_ => None,
|
||||||
span,
|
|
||||||
format!("invalid binary operation: {tok}"),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "nightly-2022-06-25"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue