parser: small refactor around Invocations

TODO: merge Expression and Object, their distinction makes little sense
This commit is contained in:
Alain Zscheile 2023-05-22 00:58:10 +02:00
parent d17524a7d2
commit 599721de7c

View file

@ -36,8 +36,8 @@ pub struct Entry {
pub enum Object { pub enum Object {
Code { Code {
cfe: bool, cfe: bool,
data: Box<[Statement]>, data: Box<[Expression]>,
ret: Option<Statement>, ret: Option<Box<Expression>>,
}, },
Module(Module), Module(Module),
Alias(FullIdentifier), Alias(FullIdentifier),
@ -58,22 +58,15 @@ pub struct Path {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum StmtArgs { pub enum Expression {
Single(Box<Object>), InvocationSingle {
Multi(BTreeMap<Box<[Atom]>, (Location, Object)>), obj: Object,
} arg: Object,
},
impl Default for StmtArgs { InvocationMulti {
#[inline] obj: Object,
fn default() -> Self { args: BTreeMap<Box<[Atom]>, (Location, Object)>,
StmtArgs::Multi(BTreeMap::new()) },
}
}
#[derive(Clone, Debug)]
pub struct Statement {
pub sel: FullIdentifier,
pub args: StmtArgs,
} }
pub struct Error { pub struct Error {
@ -188,11 +181,11 @@ impl FullIdentifier {
} }
} }
impl Statement { impl Expression {
fn parse_high(ctx: &mut ParserContext<'_>) -> Result<Self, Error> { fn parse_high(ctx: &mut ParserContext<'_>) -> Result<Self, Error> {
let sel = FullIdentifier::parse_high(ctx)?; let obj = Object::parse_high(ctx)?;
let args = if let Some(&(_, Token::Comma)) = ctx.pklx.peek() { Ok(if let Some(&(_, Token::Comma)) = ctx.pklx.peek() {
let mut args = BTreeMap::new(); let mut args = BTreeMap::new();
while ctx.maybe_eat_token(Token::Comma).is_some() { while ctx.maybe_eat_token(Token::Comma).is_some() {
let Path { loc, idents } = Path::parse_high(ctx)?; let Path { loc, idents } = Path::parse_high(ctx)?;
@ -205,16 +198,20 @@ impl Statement {
}); });
} }
} }
StmtArgs::Multi(args) Expression::InvocationMulti { obj, args }
} else if matches!(ctx.pklx.peek(), Some(&(_, Token::SemiColon)) | None) { } else if matches!(ctx.pklx.peek(), Some(&(_, Token::SemiColon)) | None) {
// do nothing, there won't be an argument // do nothing, there won't be an argument
// this escape hatch is a bit ugly, idk... // this escape hatch is a bit ugly, idk...
StmtArgs::default() Expression::InvocationMulti {
obj,
args: BTreeMap::new(),
}
} else { } else {
StmtArgs::Single(Box::new(Object::parse_high(ctx)?)) Expression::InvocationSingle {
}; obj,
arg: Object::parse_high(ctx)?,
Ok(Statement { sel, args }) }
})
} }
} }
@ -235,11 +232,11 @@ impl Object {
let mut codata = Vec::new(); let mut codata = Vec::new();
let mut ret = None; let mut ret = None;
while ctx.maybe_eat_token(Token::CloseBrace).is_none() { while ctx.maybe_eat_token(Token::CloseBrace).is_none() {
let stmt = Statement::parse_high(ctx)?; let expr = Expression::parse_high(ctx)?;
if ctx.maybe_eat_token(Token::SemiColon).is_some() { if ctx.maybe_eat_token(Token::SemiColon).is_some() {
codata.push(stmt); codata.push(expr);
} else { } else {
ret = Some(stmt); ret = Some(Box::new(expr));
// we don't go back to the loop header, so do it here. // we don't go back to the loop header, so do it here.
ctx.expect_token(Token::CloseBrace, /* { */ "}")?; ctx.expect_token(Token::CloseBrace, /* { */ "}")?;
break; break;