why not literals
This commit is contained in:
parent
836445d5e2
commit
d89faedfb1
|
@ -1,4 +1,5 @@
|
||||||
Type Byte = U8;
|
Type Byte = U8;
|
||||||
|
Type Int = U32;
|
||||||
Type String = Vector<Byte>;
|
Type String = Vector<Byte>;
|
||||||
|
|
||||||
Enumurate Boolean {
|
Enumurate Boolean {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// core provides lots of useful types like String and Byte
|
// core provides lots of useful types like String and Byte
|
||||||
Use core;
|
Use core;
|
||||||
|
|
||||||
Constant VERSION Version {
|
Constant VERSION = Version {
|
||||||
major: 1,
|
major: 1,
|
||||||
minor: 0,
|
minor: 0,
|
||||||
patch: 0,
|
patch: 0,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
Use core.Byte;
|
Use core.Byte;
|
||||||
Use core.Int;
|
Use core.Int;
|
||||||
|
|
||||||
Alias Thing = Byte;
|
Constant Hi = "WHY???/\n";
|
||||||
|
Alias Yo = Byte;
|
||||||
|
|
|
@ -40,6 +40,7 @@ pub struct ItemAlias {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ItemConstant {
|
pub struct ItemConstant {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub expr: Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -56,6 +57,7 @@ pub enum Expr {
|
||||||
pub enum Literal {
|
pub enum Literal {
|
||||||
String(String),
|
String(String),
|
||||||
Number(NumberLiteral),
|
Number(NumberLiteral),
|
||||||
|
Char(char)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -41,6 +41,19 @@ pub enum Token {
|
||||||
#[token(".")]
|
#[token(".")]
|
||||||
Dot,
|
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))]
|
#[regex(r#"[a-zA-Z_][a-zA-Z\d_]*"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))]
|
||||||
Ident(Ident),
|
Ident(Ident),
|
||||||
|
|
||||||
|
@ -62,10 +75,36 @@ pub enum Ident {
|
||||||
Alias,
|
Alias,
|
||||||
#[token("Use")]
|
#[token("Use")]
|
||||||
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),
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Span(pub Range<usize>);
|
pub struct Span(pub Range<usize>);
|
||||||
impl Span {
|
impl Span {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
|
#![feature(result_option_inspect)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
|
use lexer::Token;
|
||||||
|
use logos::Logos;
|
||||||
use parser::Parser;
|
use parser::Parser;
|
||||||
|
|
||||||
mod ast;
|
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::{
|
use crate::{
|
||||||
ast::{IDLModule, Item, ItemAlias, ItemConstant, ItemInterface, ModulePath, UseDecl},
|
ast::{IDLModule, Item, ItemAlias, ItemConstant, ItemInterface, ModulePath, UseDecl},
|
||||||
lexer::{Ident, Span, Spanned, Token},
|
lexer::{Ident, Span, Spanned, Token},
|
||||||
};
|
};
|
||||||
use std::iter::{Filter, Iterator, Peekable};
|
use std::iter::Iterator;
|
||||||
|
|
||||||
type Wtf<'a> = Peekable<Filter<&'a mut Lexer<'a, Token>, Box<dyn Fn(&Result<Token, ()>) -> bool>>>;
|
|
||||||
|
|
||||||
struct TokenIterator<'a> {
|
struct TokenIterator<'a> {
|
||||||
lexer: Lexer<'a, Token>,
|
lexer: Lexer<'a, Token>,
|
||||||
|
@ -54,7 +56,7 @@ impl<'a> TokenIterator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Parser<'a> {
|
pub(crate) struct Parser<'a> {
|
||||||
tokens: TokenIterator<'a>,
|
tokens: TokenIterator<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +67,10 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn eat(&mut self) {
|
||||||
|
let _ = self.tokens.next();
|
||||||
|
}
|
||||||
|
|
||||||
fn get_real(
|
fn get_real(
|
||||||
&mut self,
|
&mut self,
|
||||||
matcher: impl Fn(&Token) -> bool,
|
matcher: impl Fn(&Token) -> bool,
|
||||||
|
@ -163,7 +169,15 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ask_constant(&mut self) -> Result<Spanned<ItemConstant>, ParserError> {
|
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> {
|
fn ask_item(&mut self) -> Result<Spanned<Item>, ParserError> {
|
||||||
|
@ -228,6 +242,10 @@ fn fill_while<T>(
|
||||||
Ok(real)
|
Ok(real)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse(source: &str) -> Result<IDLModule, ParserError> {
|
||||||
|
Parser::new(source).parse()
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum ParserError {
|
pub enum ParserError {
|
||||||
// expected, got
|
// 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