why not literals

master
nothendev 2023-05-04 19:50:17 +03:00
parent 1687e25bcc
commit 1460d09f95
11 changed files with 132 additions and 9 deletions

View File

@ -1,4 +1,5 @@
Type Byte = U8;
Type Int = U32;
Type String = Vector<Byte>;
Enumurate Boolean {

View File

@ -1,7 +1,7 @@
// core provides lots of useful types like String and Byte
Use core;
Constant VERSION Version {
Constant VERSION = Version {
major: 1,
minor: 0,
patch: 0,

View File

@ -1,4 +1,5 @@
Use core.Byte;
Use core.Int;
Alias Thing = Byte;
Constant Hi = "WHY???/\n";
Alias Yo = Byte;

View File

@ -40,6 +40,7 @@ pub struct ItemAlias {
#[derive(Debug)]
pub struct ItemConstant {
pub name: String,
pub expr: Expr
}
#[derive(Debug)]
@ -56,6 +57,7 @@ pub enum Expr {
pub enum Literal {
String(String),
Number(NumberLiteral),
Char(char)
}
#[derive(Debug)]

View File

@ -41,6 +41,19 @@ pub enum Token {
#[token(".")]
Dot,
// why
#[regex("\"(?s:[^\"\\\\]|\\\\.)*\"", |lex| dbg!(lex.slice()).strip_prefix('"')?.strip_suffix('"').map(ToOwned::to_owned))]
StringLiteral(String),
#[regex(r"'.'", |lex| lex.slice().strip_prefix('\'')?.strip_suffix('\'')?.parse().ok())]
CharLiteral(char),
#[regex(r#"(-)?\d+"#, |lex| lex.slice().parse().ok())]
NumberLiteral(i64),
#[regex(r"(ptr|u8|i8|u16|i16|u32|i32|u64|i64|f32|f64)", |lex| NumberSuffix::lexer(lex.slice()).next().and_then(Result::ok))]
NumberSuffix(NumberSuffix),
#[regex(r#"[a-zA-Z_][a-zA-Z\d_]*"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))]
Ident(Ident),
@ -62,10 +75,36 @@ pub enum Ident {
Alias,
#[token("Use")]
Use,
#[regex(r"[A-z]+", |lex| lex.slice().parse().ok())]
#[regex(r"[a-zA-Z_][a-zA-Z\d_]*", |lex| lex.slice().parse().ok())]
Other(String),
}
#[derive(Logos, Debug, PartialEq, Eq)]
pub enum NumberSuffix {
#[token("Ptr")]
Ptr,
#[token("u8")]
U8,
#[token("i8")]
I8,
#[token("u16")]
U16,
#[token("i16")]
I16,
#[token("u32")]
U32,
#[token("i32")]
I32,
#[token("u64")]
U64,
#[token("i64")]
I64,
#[token("f32")]
F32,
#[token("f64")]
F64,
}
#[derive(Debug, Clone)]
pub struct Span(pub Range<usize>);
impl Span {

View File

@ -1,5 +1,8 @@
#![feature(result_option_inspect)]
#![allow(non_snake_case)]
use lexer::Token;
use logos::Logos;
use parser::Parser;
mod ast;

View File

@ -0,0 +1,51 @@
use crate::{
ast::{Expr, Literal, NumberLiteral},
lexer::{NumberSuffix, Spanned, Token},
unwrap_match,
};
use super::{Parser, ParserError};
impl<'a> Parser<'a> {
pub fn ask_expr(&mut self) -> Result<Spanned<Expr>, ParserError> {
let Spanned(token, _) = self.tokens.peek()?;
Ok(match token {
Token::StringLiteral(_) | Token::NumberLiteral(_) | Token::CharLiteral(_) => {
self._ask_literal()?.map(Expr::Literal)
}
_ => return Err(self.expected("an expression")),
})
}
fn _ask_literal(&mut self) -> Result<Spanned<Literal>, ParserError> {
let Spanned(token, mut span) = self.tokens.next()?;
Ok(match token {
Token::StringLiteral(string) => Spanned(Literal::String(string), span),
Token::CharLiteral(chr) => Spanned(Literal::Char(chr), span),
Token::NumberLiteral(number) => {
let lit = if let Spanned(Token::NumberSuffix(_), sp) = self.tokens.peek()? {
span = span + sp;
use NumberLiteral::*;
Literal::Number(
match unwrap_match!(
self.tokens.next()?, Spanned(Token::NumberSuffix(suffering), _) => suffering) // eat suffix
{
NumberSuffix::Ptr => Ptr(number as usize),
NumberSuffix::U8 => U8(number as u8),
NumberSuffix::I8 => I8(number as i8),
NumberSuffix::U16 => U16(number as u16),
NumberSuffix::I16 => I16(number as i16),
_ => todo!(),
},
)
} else {
Literal::Number(NumberLiteral::Infer(number))
};
Spanned(lit, span)
}
_ => return Err(self.expected("a literal")),
})
}
}

View File

View File

@ -1,12 +1,14 @@
use logos::{Lexer, Logos, SpannedIter};
mod expr;
mod interface;
mod structure;
use logos::{Lexer, Logos};
use crate::{
ast::{IDLModule, Item, ItemAlias, ItemConstant, ItemInterface, ModulePath, UseDecl},
lexer::{Ident, Span, Spanned, Token},
};
use std::iter::{Filter, Iterator, Peekable};
type Wtf<'a> = Peekable<Filter<&'a mut Lexer<'a, Token>, Box<dyn Fn(&Result<Token, ()>) -> bool>>>;
use std::iter::Iterator;
struct TokenIterator<'a> {
lexer: Lexer<'a, Token>,
@ -54,7 +56,7 @@ impl<'a> TokenIterator<'a> {
}
}
pub struct Parser<'a> {
pub(crate) struct Parser<'a> {
tokens: TokenIterator<'a>,
}
@ -65,6 +67,10 @@ impl<'a> Parser<'a> {
}
}
fn eat(&mut self) {
let _ = self.tokens.next();
}
fn get_real(
&mut self,
matcher: impl Fn(&Token) -> bool,
@ -163,7 +169,15 @@ impl<'a> Parser<'a> {
}
fn ask_constant(&mut self) -> Result<Spanned<ItemConstant>, ParserError> {
Err(self.expected("the constant to be implemented"))
let Spanned(_, kSp) = self.get_real(
|token| matches!(token, Token::Ident(Ident::Constant)),
"`Constant`",
)?;
let Spanned(name, nSp) = self.ask_ident()?;
let Spanned(_, eqSp) = self.get_real(|token| matches!(token, Token::Equals), "`=`")?;
let Spanned(expr, exprSp) = self.ask_expr()?;
Ok(Spanned::new(ItemConstant { name, expr }, [kSp, nSp, eqSp, exprSp, self.semi()?]))
}
fn ask_item(&mut self) -> Result<Spanned<Item>, ParserError> {
@ -228,6 +242,10 @@ fn fill_while<T>(
Ok(real)
}
pub fn parse(source: &str) -> Result<IDLModule, ParserError> {
Parser::new(source).parse()
}
#[derive(thiserror::Error, Debug)]
pub enum ParserError {
// expected, got

View File

8
programs/aidl/status.md Normal file
View File

@ -0,0 +1,8 @@
# aidl status
## parser
[x] `Use module.thing`
[x] `Alias Thing = OtherThing`
## codegen
TODO!