mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-17 10:05:07 +01:00
lmao what
This commit is contained in:
parent
2e5dfb24e2
commit
eb68c2b207
6 changed files with 221 additions and 4 deletions
|
|
@ -6,6 +6,7 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
dbg-pls = { version = "0.3.2", features = ["derive", "colors"] }
|
||||||
peekmore = { version = "1.0.0", features = ["smallvec"] }
|
peekmore = { version = "1.0.0", features = ["smallvec"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
||||||
25
parser/src/ast.rs
Normal file
25
parser/src/ast.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
use dbg_pls::DebugPls;
|
||||||
|
|
||||||
|
use crate::Span;
|
||||||
|
|
||||||
|
pub type Spanned<T> = (T, Span);
|
||||||
|
|
||||||
|
#[derive(Debug, DebugPls)]
|
||||||
|
pub enum TypeSpecifier {
|
||||||
|
Void,
|
||||||
|
Char,
|
||||||
|
Short,
|
||||||
|
Int,
|
||||||
|
Long,
|
||||||
|
Float,
|
||||||
|
Double,
|
||||||
|
Signed,
|
||||||
|
Unsigned,
|
||||||
|
Bool,
|
||||||
|
Complex,
|
||||||
|
// TODO
|
||||||
|
// atomic-type-specifier
|
||||||
|
// struct-or-union-specifier
|
||||||
|
// enum-specifier
|
||||||
|
// typedef-name
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
|
mod ast;
|
||||||
|
mod parser;
|
||||||
mod pre;
|
mod pre;
|
||||||
mod token;
|
mod token;
|
||||||
|
|
||||||
|
|
|
||||||
59
parser/src/parser.rs
Normal file
59
parser/src/parser.rs
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
use peekmore::PeekMoreIterator;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ast::{Spanned, TypeSpecifier},
|
||||||
|
token::{Keyword as Kw, Token as Tok},
|
||||||
|
Span,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParserError {
|
||||||
|
span: Span,
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParserError {
|
||||||
|
fn new(span: Span, message: String) -> Self {
|
||||||
|
Self { span, message }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn eof() -> Self {
|
||||||
|
Self::new(0..0, "unexpected end of file".to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Result<T, E = ParserError> = std::result::Result<T, E>;
|
||||||
|
|
||||||
|
struct Parser<'src, I>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = (Tok<'src>, Span)>,
|
||||||
|
{
|
||||||
|
lex: PeekMoreIterator<I>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'src, I> Parser<'src, I>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = (Tok<'src>, Span)>,
|
||||||
|
{
|
||||||
|
fn type_specifier(&mut self) -> Result<Spanned<TypeSpecifier>> {
|
||||||
|
let (token, span) = self.next_t()?;
|
||||||
|
let ty = match token {
|
||||||
|
Tok::Kw(Kw::Void) => TypeSpecifier::Void,
|
||||||
|
Tok::Kw(Kw::Char) => TypeSpecifier::Char,
|
||||||
|
Tok::Kw(Kw::Short) => TypeSpecifier::Short,
|
||||||
|
Tok::Kw(Kw::Int) => TypeSpecifier::Int,
|
||||||
|
Tok::Kw(Kw::Long) => TypeSpecifier::Long,
|
||||||
|
Tok::Kw(Kw::Float) => TypeSpecifier::Float,
|
||||||
|
Tok::Kw(Kw::Double) => TypeSpecifier::Double,
|
||||||
|
Tok::Kw(Kw::Signed) => TypeSpecifier::Signed,
|
||||||
|
Tok::Kw(Kw::Unsigned) => TypeSpecifier::Unsigned,
|
||||||
|
Tok::Kw(Kw::Bool) => TypeSpecifier::Bool,
|
||||||
|
Tok::Kw(Kw::Complex) => return Err(ParserError::new(span, "tf are you doing with complex numbers".to_string())),
|
||||||
|
tok => return Err(ParserError::new(span, format!("Invalid token: `{tok}`"))),
|
||||||
|
};
|
||||||
|
Ok((ty, span))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_t(&mut self) -> Result<(Tok<'src>, Span)> {
|
||||||
|
self.lex.next().ok_or_else(ParserError::eof)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
//!
|
//!
|
||||||
//! Code might be bad. Possibly.
|
//! Code might be bad. Possibly.
|
||||||
|
|
||||||
use std::ops::Not;
|
use std::{ops::Not, fmt::Display};
|
||||||
|
|
||||||
use peekmore::PeekMore;
|
use peekmore::PeekMore;
|
||||||
|
|
||||||
|
|
@ -119,6 +119,60 @@ pub enum Punctuator {
|
||||||
HashHash,
|
HashHash,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Punctuator {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Punctuator::BracketOpen => f.write_str("["),
|
||||||
|
Punctuator::BracketClose => f.write_str("]"),
|
||||||
|
Punctuator::ParenOpen => f.write_str("("),
|
||||||
|
Punctuator::ParenClose => f.write_str(")"),
|
||||||
|
Punctuator::BraceOpen => f.write_str("{"),
|
||||||
|
Punctuator::BraceClose => f.write_str("}"),
|
||||||
|
Punctuator::Dot => f.write_str("."),
|
||||||
|
Punctuator::Arrow => f.write_str("->"),
|
||||||
|
Punctuator::PlusPlus => f.write_str("++"),
|
||||||
|
Punctuator::MinusMinus => f.write_str("--"),
|
||||||
|
Punctuator::Ampersand => f.write_str("&"),
|
||||||
|
Punctuator::Asterisk => f.write_str("*"),
|
||||||
|
Punctuator::Plus => f.write_str("+"),
|
||||||
|
Punctuator::Minus => f.write_str("-"),
|
||||||
|
Punctuator::Tilde => f.write_str("~"),
|
||||||
|
Punctuator::Bang => f.write_str("!"),
|
||||||
|
Punctuator::Percent => f.write_str("%"),
|
||||||
|
Punctuator::LeftLeftChevron => f.write_str("<<"),
|
||||||
|
Punctuator::RightRightChevron => f.write_str(">>"),
|
||||||
|
Punctuator::LeftChevron => f.write_str("<"),
|
||||||
|
Punctuator::RightChevron => f.write_str(">"),
|
||||||
|
Punctuator::LeftChevronEq => f.write_str("<="),
|
||||||
|
Punctuator::RightChevronEq => f.write_str(">="),
|
||||||
|
Punctuator::EqEq => f.write_str("=="),
|
||||||
|
Punctuator::BangEq => f.write_str("!="),
|
||||||
|
Punctuator::Caret => f.write_str("^"),
|
||||||
|
Punctuator::Pipe => f.write_str("|"),
|
||||||
|
Punctuator::AmpersandAmpersand => f.write_str("&&"),
|
||||||
|
Punctuator::PipePipe => f.write_str("||"),
|
||||||
|
Punctuator::QuestionMark => f.write_str("?"),
|
||||||
|
Punctuator::Colon => f.write_str(":"),
|
||||||
|
Punctuator::Semicolon => f.write_str(";"),
|
||||||
|
Punctuator::DotDotDot => f.write_str("..."),
|
||||||
|
Punctuator::Eq => f.write_str("="),
|
||||||
|
Punctuator::AsteriskEq => f.write_str("*="),
|
||||||
|
Punctuator::SlashEq => f.write_str("/="),
|
||||||
|
Punctuator::PercentEq => f.write_str("%="),
|
||||||
|
Punctuator::PlusEq => f.write_str("+="),
|
||||||
|
Punctuator::MinusEq => f.write_str("-="),
|
||||||
|
Punctuator::LeftLeftChevronEq => f.write_str("<<="),
|
||||||
|
Punctuator::RightRightChevronEq => f.write_str(">>="),
|
||||||
|
Punctuator::AmspersandEq => f.write_str("&="),
|
||||||
|
Punctuator::CaretEq => f.write_str("^="),
|
||||||
|
Punctuator::PipeEq => f.write_str("|="),
|
||||||
|
Punctuator::Comma => f.write_str(","),
|
||||||
|
Punctuator::Hash => f.write_str("#"),
|
||||||
|
Punctuator::HashHash => f.write_str("##"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct PLexer<'src, I>
|
struct PLexer<'src, I>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = (usize, u8)>,
|
I: Iterator<Item = (usize, u8)>,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
pre::{PToken, Punctuator},
|
pre::{PToken, Punctuator},
|
||||||
Span,
|
Span,
|
||||||
|
|
@ -11,7 +13,7 @@ use crate::{
|
||||||
/// punctuator
|
/// punctuator
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Token<'src> {
|
pub enum Token<'src> {
|
||||||
Keyword(Keyword),
|
Kw(Keyword),
|
||||||
Identifier(&'src str),
|
Identifier(&'src str),
|
||||||
Constant(Constant),
|
Constant(Constant),
|
||||||
StringLiteral(&'src str),
|
StringLiteral(&'src str),
|
||||||
|
|
@ -137,7 +139,7 @@ pub fn pre_tokens_to_tokens<'src>(
|
||||||
let token = match token {
|
let token = match token {
|
||||||
PToken::HeaderName(_) => todo!("header names aren't real, wake up"),
|
PToken::HeaderName(_) => todo!("header names aren't real, wake up"),
|
||||||
PToken::Identifier(ident) => match ident_to_keyword(ident) {
|
PToken::Identifier(ident) => match ident_to_keyword(ident) {
|
||||||
Some(keyword) => Token::Keyword(keyword),
|
Some(keyword) => Token::Kw(keyword),
|
||||||
None => Token::Identifier(ident),
|
None => Token::Identifier(ident),
|
||||||
},
|
},
|
||||||
PToken::PpNumber(number) => pp_number_to_constant(number)
|
PToken::PpNumber(number) => pp_number_to_constant(number)
|
||||||
|
|
@ -153,6 +155,80 @@ pub fn pre_tokens_to_tokens<'src>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Token<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Token::Kw(kw) => Display::fmt(kw, f),
|
||||||
|
Token::Identifier(ident) => Display::fmt(ident, f),
|
||||||
|
Token::Constant(c) => Display::fmt(c, f),
|
||||||
|
Token::StringLiteral(str) => write!(f, "\"{}\"", str),
|
||||||
|
Token::Punctuator(p) => Display::fmt(p, f),
|
||||||
|
Token::Error => f.write_str("<invalid token>"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Keyword {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Keyword::Auto => f.write_str("auto"),
|
||||||
|
Keyword::Break => f.write_str("break"),
|
||||||
|
Keyword::Case => f.write_str("case"),
|
||||||
|
Keyword::Char => f.write_str("char"),
|
||||||
|
Keyword::Const => f.write_str("const"),
|
||||||
|
Keyword::Continue => f.write_str("continue"),
|
||||||
|
Keyword::Default => f.write_str("default"),
|
||||||
|
Keyword::Do => f.write_str("do"),
|
||||||
|
Keyword::Double => f.write_str("double"),
|
||||||
|
Keyword::Else => f.write_str("else"),
|
||||||
|
Keyword::Enum => f.write_str("enum"),
|
||||||
|
Keyword::Extern => f.write_str("extern"),
|
||||||
|
Keyword::Float => f.write_str("float"),
|
||||||
|
Keyword::For => f.write_str("for"),
|
||||||
|
Keyword::Goto => f.write_str("goto"),
|
||||||
|
Keyword::If => f.write_str("if"),
|
||||||
|
Keyword::Inline => f.write_str("inline"),
|
||||||
|
Keyword::Int => f.write_str("int"),
|
||||||
|
Keyword::Long => f.write_str("long"),
|
||||||
|
Keyword::Register => f.write_str("register"),
|
||||||
|
Keyword::Restrict => f.write_str("restrict"),
|
||||||
|
Keyword::Return => f.write_str("return"),
|
||||||
|
Keyword::Short => f.write_str("short"),
|
||||||
|
Keyword::Signed => f.write_str("signed"),
|
||||||
|
Keyword::Sizeof => f.write_str("sizeof"),
|
||||||
|
Keyword::Static => f.write_str("static"),
|
||||||
|
Keyword::Struct => f.write_str("struct"),
|
||||||
|
Keyword::Switch => f.write_str("switch"),
|
||||||
|
Keyword::Typedef => f.write_str("typedef"),
|
||||||
|
Keyword::Union => f.write_str("union"),
|
||||||
|
Keyword::Unsigned => f.write_str("unsigned"),
|
||||||
|
Keyword::Void => f.write_str("void"),
|
||||||
|
Keyword::Volatile => f.write_str("volatile"),
|
||||||
|
Keyword::While => f.write_str("while"),
|
||||||
|
Keyword::Alignas => f.write_str("_Alignas"),
|
||||||
|
Keyword::Alignof => f.write_str("_Alignof"),
|
||||||
|
Keyword::Atomic => f.write_str("_Atomic"),
|
||||||
|
Keyword::Bool => f.write_str("_Bool"),
|
||||||
|
Keyword::Complex => f.write_str("_Complex"),
|
||||||
|
Keyword::Generic => f.write_str("_Generic"),
|
||||||
|
Keyword::Imaginary => f.write_str("_Imaginary"),
|
||||||
|
Keyword::Noreturn => f.write_str("_Noreturn"),
|
||||||
|
Keyword::StaticAssert => f.write_str("_Static_assert"),
|
||||||
|
Keyword::ThreadLocal => f.write_str("_Thread_local"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Constant {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Constant::Int(int) => Display::fmt(int, f),
|
||||||
|
Constant::Float(float) => Display::fmt(float, f),
|
||||||
|
Constant::Char(c) => write!(f, "'{}'", *c as char),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
macro_rules! lex_test {
|
macro_rules! lex_test {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue