ableos_userland/programs/aidl/src/parser/expr.rs

104 lines
4.1 KiB
Rust
Raw Normal View History

2023-05-04 17:31:20 +00:00
use std::collections::HashMap;
2023-05-04 16:50:17 +00:00
use crate::{
2023-05-05 09:15:01 +00:00
ast::{Expr, ExprMake, Literal, NumberLiteral},
2023-05-04 17:31:20 +00:00
lexer::{Ident, NumberSuffix, Spanned, Token},
2023-05-04 16:50:17 +00:00
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)
}
2023-05-04 17:31:20 +00:00
Token::Ident(Ident::Make) => {
self.eat();
2023-05-05 11:21:24 +00:00
self._ask_struct_init()?.map(Box::new).map(Expr::Make)
2023-05-04 17:31:20 +00:00
}
2023-05-04 16:50:17 +00:00
_ => return Err(self.expected("an expression")),
})
}
2023-05-05 11:21:24 +00:00
pub fn _ask_number_literal(&mut self) -> Result<Spanned<NumberLiteral>, ParserError> {
match self.tokens.next()? {
Spanned(Token::NumberLiteral(number), mut span) => {
2023-05-04 16:50:17 +00:00
let lit = if let Spanned(Token::NumberSuffix(_), sp) = self.tokens.peek()? {
2023-05-04 17:31:20 +00:00
span += sp;
2023-05-04 16:50:17 +00:00
use NumberLiteral::*;
2023-05-05 11:21:24 +00:00
match unwrap_match!(
2023-05-04 16:50:17 +00:00
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),
2023-05-04 17:31:20 +00:00
NumberSuffix::U32 => U32(number as u32),
NumberSuffix::I32 => I32(number as i32),
NumberSuffix::U64 => U64(number as u64),
NumberSuffix::I64 => I64(number),
_ => return Err(self.expected("a non-floating number suffix"))
2023-05-05 11:21:24 +00:00
}
2023-05-04 16:50:17 +00:00
} else {
2023-05-05 11:21:24 +00:00
NumberLiteral::Infer(number)
2023-05-04 16:50:17 +00:00
};
2023-05-05 11:21:24 +00:00
Ok(Spanned(lit, span))
2023-05-04 16:50:17 +00:00
}
2023-05-05 11:21:24 +00:00
_ => Err(self.expected("a number literal")),
}
}
pub fn _ask_literal(&mut self) -> Result<Spanned<Literal>, ParserError> {
if let Spanned(Token::NumberLiteral(_), _) = self.tokens.peek()? {
return Ok(self._ask_number_literal()?.map(Literal::Number));
};
let Spanned(token, span) = self.tokens.next()?;
Ok(match token {
Token::StringLiteral(string) => Spanned(Literal::String(string), span),
Token::CharLiteral(chr) => Spanned(Literal::Char(chr), span),
2023-05-04 16:50:17 +00:00
_ => return Err(self.expected("a literal")),
})
}
2023-05-04 17:31:20 +00:00
2023-05-05 09:15:01 +00:00
fn _ask_struct_init(&mut self) -> Result<Spanned<ExprMake>, ParserError> {
2023-05-04 17:31:20 +00:00
let Spanned(name, nSp) = self.ask_ident()?;
let Spanned(_, _) = self.get_real(
|token| matches!(token, Token::LeftCurly),
"an opening curly brace (`{`)",
)?;
let mut params = HashMap::<String, Expr>::new();
loop {
match self.tokens.peek()?.0 {
Token::Ident(_) => {
let Spanned(ident, _) = self.ask_ident().unwrap();
self.get_real(|token| matches!(token, Token::Colon), "a colon")?;
let Spanned(value, _) = self.ask_expr()?;
params.insert(ident, value);
2023-05-06 15:57:45 +00:00
match self.tokens.peek()?.0 {
Token::Comma => self.eat(),
Token::RightCurly => {},
_ => return Err(self.expected("a comma or a closing curly brace"))
}
2023-05-04 17:31:20 +00:00
}
Token::RightCurly => break,
_ => return Err(self.expected("an identifier or a closing curly brace (`}`)")),
}
}
if let Spanned(Token::RightCurly, ccSp) = self.tokens.next()? {
2023-05-05 09:15:01 +00:00
return Ok(Spanned(ExprMake { name, params }, nSp + ccSp));
2023-05-04 17:31:20 +00:00
};
2023-05-05 11:21:24 +00:00
Err(self.expected("closing curly braces"))
2023-05-04 17:31:20 +00:00
}
2023-05-04 16:50:17 +00:00
}