This commit is contained in:
nothendev 2023-05-04 16:47:05 +03:00
parent f0a7166470
commit fd09a6739b
4 changed files with 55 additions and 20 deletions

View file

@ -1,3 +1,4 @@
Use core;
Use core.Byte;
Use core.Int;
Alias Thing = Byte;

View file

@ -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<String>
}

View file

@ -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),
}

View file

@ -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<Spanned<ModulePath>, 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<Spanned<ItemInterface>, 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<IDLModule, ParserError> {