lmao what

This commit is contained in:
nora 2022-06-21 19:56:57 +02:00
parent 2e5dfb24e2
commit eb68c2b207
6 changed files with 221 additions and 4 deletions

25
parser/src/ast.rs Normal file
View 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
}

View file

@ -1,6 +1,8 @@
#![allow(dead_code)]
#![warn(rust_2018_idioms)]
mod ast;
mod parser;
mod pre;
mod token;

59
parser/src/parser.rs Normal file
View 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)
}
}

View file

@ -3,7 +3,7 @@
//!
//! Code might be bad. Possibly.
use std::ops::Not;
use std::{ops::Not, fmt::Display};
use peekmore::PeekMore;
@ -119,6 +119,60 @@ pub enum Punctuator {
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>
where
I: Iterator<Item = (usize, u8)>,

View file

@ -1,3 +1,5 @@
use std::fmt::Display;
use crate::{
pre::{PToken, Punctuator},
Span,
@ -11,7 +13,7 @@ use crate::{
/// punctuator
#[derive(Debug)]
pub enum Token<'src> {
Keyword(Keyword),
Kw(Keyword),
Identifier(&'src str),
Constant(Constant),
StringLiteral(&'src str),
@ -137,7 +139,7 @@ pub fn pre_tokens_to_tokens<'src>(
let token = match token {
PToken::HeaderName(_) => todo!("header names aren't real, wake up"),
PToken::Identifier(ident) => match ident_to_keyword(ident) {
Some(keyword) => Token::Keyword(keyword),
Some(keyword) => Token::Kw(keyword),
None => Token::Identifier(ident),
},
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)]
mod tests {
macro_rules! lex_test {
@ -173,4 +249,4 @@ int main() {
"#;
lex_test!(src);
}
}
}