From a25b2ac166b2e656b666f54db6d8ca0658b0eb21 Mon Sep 17 00:00:00 2001 From: nothendev Date: Thu, 4 May 2023 16:47:05 +0300 Subject: [PATCH] modpaths --- programs/aidl/assets/why.idl | 3 ++- programs/aidl/src/ast.rs | 12 ++++++++-- programs/aidl/src/lexer.rs | 14 ++++------- programs/aidl/src/parser.rs | 46 ++++++++++++++++++++++++++++++------ 4 files changed, 55 insertions(+), 20 deletions(-) diff --git a/programs/aidl/assets/why.idl b/programs/aidl/assets/why.idl index c6edc6d..d2edc1e 100644 --- a/programs/aidl/assets/why.idl +++ b/programs/aidl/assets/why.idl @@ -1,3 +1,4 @@ -Use core; +Use core.Byte; +Use core.Int; Alias Thing = Byte; diff --git a/programs/aidl/src/ast.rs b/programs/aidl/src/ast.rs index db56496..3d8665f 100644 --- a/programs/aidl/src/ast.rs +++ b/programs/aidl/src/ast.rs @@ -16,7 +16,7 @@ pub struct IDLModule { #[derive(Debug)] pub enum Item { Interface(ItemInterface), - Type(ItemAlias), + Alias(ItemAlias), Constant(ItemConstant), } @@ -44,7 +44,7 @@ pub struct ItemConstant { #[derive(Debug)] pub struct UseDecl { - pub module: String, + pub module: ModulePath, } #[derive(Debug)] @@ -73,4 +73,12 @@ pub enum NumberLiteral { U64(u64), I64(i64), + + Infer(i64) +} + +/// seg1.seg2.seg3.segN +#[derive(Debug)] +pub struct ModulePath { + pub segments: Vec } diff --git a/programs/aidl/src/lexer.rs b/programs/aidl/src/lexer.rs index 55806e4..7377123 100644 --- a/programs/aidl/src/lexer.rs +++ b/programs/aidl/src/lexer.rs @@ -35,18 +35,12 @@ pub enum Token { #[token("=")] Equals, - #[regex(r#"[A-z]+"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))] + #[token(".")] + Dot, + + #[regex(r#"[a-zA-Z_][a-zA-Z\d_]*"#, |lex| Ident::lexer(lex.slice()).next().and_then(Result::ok))] Ident(Ident), - #[regex("use [a-zA-Z/]+;", |lex| lex.slice().parse().ok())] - Component(String), - - #[regex("U[0-9]+", |lex| lex.slice().parse().ok())] - UnsignedType(String), - - #[regex("I[0-9]+", |lex| lex.slice().parse().ok())] - SignedType(String), - #[regex(r"//.*", |lex| lex.slice().parse().ok())] Comment(String), } diff --git a/programs/aidl/src/parser.rs b/programs/aidl/src/parser.rs index 81f19eb..9277e3d 100644 --- a/programs/aidl/src/parser.rs +++ b/programs/aidl/src/parser.rs @@ -1,7 +1,7 @@ use logos::{Lexer, Logos, SpannedIter}; use crate::{ - ast::{IDLModule, Item, ItemAlias, ItemConstant, ItemInterface, UseDecl}, + ast::{IDLModule, Item, ItemAlias, ItemConstant, ItemInterface, ModulePath, UseDecl}, lexer::{Ident, Span, Spanned, Token}, }; use std::iter::{Filter, Iterator, Peekable}; @@ -95,6 +95,41 @@ impl<'a> Parser<'a> { )) } + fn ask_modpath( + &mut self, + end: impl Fn(&Token) -> bool, + ) -> Result, ParserError> { + let mut segments = vec![]; + let mut in_path_seg = false; + let mut waiting_next_seg = true; + let mut span = Span::ZERO; + + loop { + match self.tokens.next()? { + Spanned(Token::Ident(Ident::Other(ident)), span_span) + if !in_path_seg && waiting_next_seg => + { + span = span + span_span; + segments.push(ident); + in_path_seg = true; + waiting_next_seg = false; + } + Spanned(Token::Dot, span_span) if in_path_seg && !waiting_next_seg => { + span = span + span_span; + waiting_next_seg = true; + in_path_seg = false; + } + v if end(&v.0) && (in_path_seg || !waiting_next_seg) => { + span = span + v.1; + break; + } + _ => return Err(self.unexpected("a path segment")), + } + } + + Ok(Spanned(ModulePath { segments }, span)) + } + fn _ask_interface(&mut self) -> Result, ParserError> { let Spanned(_, kSp) = self.get_real( |token| matches!(token, Token::Ident(Ident::Interface)), @@ -138,7 +173,7 @@ impl<'a> Parser<'a> { } Token::Ident(keyword) => match keyword { //Ident::Interface => self.ask_interface()?.map(Item::Interface), - Ident::Alias => self.ask_alias()?.map(Item::Type), + Ident::Alias => self.ask_alias()?.map(Item::Alias), Ident::Constant => self.ask_constant()?.map(Item::Constant), _ => Err(self.unexpected("`Alias` or `Constant`"))?, }, @@ -153,12 +188,9 @@ impl<'a> Parser<'a> { _ => Err(ParserError::PleaseStopParsingUse), } }?; - let Spanned(name, nSp) = self.ask_ident()?; + let Spanned(module, nSp) = self.ask_modpath(|token| matches!(token, Token::Semicolon))?; - Ok(Spanned::new( - UseDecl { module: name }, - [kSp, nSp, self.semi()?], - )) + Ok(Spanned::new(UseDecl { module }, [kSp, nSp])) } pub fn parse(mut self) -> Result {