why not literals
This commit is contained in:
parent
836445d5e2
commit
d89faedfb1
|
@ -1,4 +1,5 @@
|
|||
Type Byte = U8;
|
||||
Type Int = U32;
|
||||
Type String = Vector<Byte>;
|
||||
|
||||
Enumurate Boolean {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Use core.Byte;
|
||||
Use core.Int;
|
||||
|
||||
Alias Thing = Byte;
|
||||
Constant Hi = "WHY???/\n";
|
||||
Alias Yo = Byte;
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#![feature(result_option_inspect)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use lexer::Token;
|
||||
use logos::Logos;
|
||||
use parser::Parser;
|
||||
|
||||
mod ast;
|
||||
|
|
51
programs/aidl/src/parser/expr.rs
Normal file
51
programs/aidl/src/parser/expr.rs
Normal 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")),
|
||||
})
|
||||
}
|
||||
}
|
0
programs/aidl/src/parser/interface.rs
Normal file
0
programs/aidl/src/parser/interface.rs
Normal 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
|
0
programs/aidl/src/parser/structure.rs
Normal file
0
programs/aidl/src/parser/structure.rs
Normal file
8
programs/aidl/status.md
Normal file
8
programs/aidl/status.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
# aidl status
|
||||
|
||||
## parser
|
||||
[x] `Use module.thing`
|
||||
[x] `Alias Thing = OtherThing`
|
||||
|
||||
## codegen
|
||||
TODO!
|
Loading…
Reference in a new issue