merge Object and Expression
This commit is contained in:
parent
599721de7c
commit
3703b65e41
|
@ -27,13 +27,13 @@ pub struct Entry {
|
|||
// technically this is a set, but that would just waste space here...
|
||||
pub args: Box<[Atom]>,
|
||||
// might be a dummy
|
||||
pub obj: Option<Object>,
|
||||
pub obj: Option<Expression>,
|
||||
// we use a bitflag here to conserve memory
|
||||
pub flags: EntryFlags,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Object {
|
||||
pub enum Expression {
|
||||
Code {
|
||||
cfe: bool,
|
||||
data: Box<[Expression]>,
|
||||
|
@ -42,6 +42,11 @@ pub enum Object {
|
|||
Module(Module),
|
||||
Alias(FullIdentifier),
|
||||
Integer(i64),
|
||||
InvocationSingle(Box<(Expression, Expression)>),
|
||||
InvocationMulti {
|
||||
obj: Box<Expression>,
|
||||
args: BTreeMap<Box<[Atom]>, (Location, Expression)>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -57,18 +62,6 @@ pub struct Path {
|
|||
pub idents: Box<[Atom]>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Expression {
|
||||
InvocationSingle {
|
||||
obj: Object,
|
||||
arg: Object,
|
||||
},
|
||||
InvocationMulti {
|
||||
obj: Object,
|
||||
args: BTreeMap<Box<[Atom]>, (Location, Object)>,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct Error {
|
||||
pub loc: Location,
|
||||
pub kind: ErrorKind,
|
||||
|
@ -182,40 +175,6 @@ impl FullIdentifier {
|
|||
}
|
||||
|
||||
impl Expression {
|
||||
fn parse_high(ctx: &mut ParserContext<'_>) -> Result<Self, Error> {
|
||||
let obj = Object::parse_high(ctx)?;
|
||||
|
||||
Ok(if let Some(&(_, Token::Comma)) = ctx.pklx.peek() {
|
||||
let mut args = BTreeMap::new();
|
||||
while ctx.maybe_eat_token(Token::Comma).is_some() {
|
||||
let Path { loc, idents } = Path::parse_high(ctx)?;
|
||||
ctx.expect_token(Token::Assign, "=")?;
|
||||
let obj = Object::parse_high(ctx)?;
|
||||
if args.insert(idents, (loc, obj)).is_some() {
|
||||
return Err(Error {
|
||||
loc,
|
||||
kind: ErrorKind::DuplicateIdentifier,
|
||||
});
|
||||
}
|
||||
}
|
||||
Expression::InvocationMulti { obj, args }
|
||||
} else if matches!(ctx.pklx.peek(), Some(&(_, Token::SemiColon)) | None) {
|
||||
// do nothing, there won't be an argument
|
||||
// this escape hatch is a bit ugly, idk...
|
||||
Expression::InvocationMulti {
|
||||
obj,
|
||||
args: BTreeMap::new(),
|
||||
}
|
||||
} else {
|
||||
Expression::InvocationSingle {
|
||||
obj,
|
||||
arg: Object::parse_high(ctx)?,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Object {
|
||||
fn parse_high(ctx: &mut ParserContext<'_>) -> Result<Self, Error> {
|
||||
let mut cfe = false;
|
||||
for (_, i) in ctx.pklx.peeking_take_while(|(_, t)| t.is_cobj_attr()) {
|
||||
|
@ -225,7 +184,7 @@ impl Object {
|
|||
}
|
||||
}
|
||||
|
||||
match ctx.pklx.peek() {
|
||||
let obj = match ctx.pklx.peek() {
|
||||
None => Err(ctx.make_eof()),
|
||||
Some((_, Token::OpenBrace)) => {
|
||||
ctx.pklx.next();
|
||||
|
@ -242,7 +201,7 @@ impl Object {
|
|||
break;
|
||||
}
|
||||
}
|
||||
Ok(Object::Code {
|
||||
Ok(Expression::Code {
|
||||
cfe,
|
||||
data: codata.into_boxed_slice(),
|
||||
ret,
|
||||
|
@ -257,17 +216,40 @@ impl Object {
|
|||
// expect a single code object descriptor => alias, or number.
|
||||
Some(&(_, Token::Integer(i))) => {
|
||||
ctx.pklx.next();
|
||||
Ok(Object::Integer(i))
|
||||
Ok(Expression::Integer(i))
|
||||
}
|
||||
Some((_, Token::Module)) => {
|
||||
ctx.pklx.next();
|
||||
ctx.expect_token(Token::OpenBrace, "{")?;
|
||||
let m = Module::parse_high(ctx)?;
|
||||
ctx.expect_token(Token::CloseBrace, "}")?;
|
||||
Ok(Object::Module(m))
|
||||
Ok(Expression::Module(m))
|
||||
}
|
||||
_ => FullIdentifier::parse_high(ctx).map(Object::Alias),
|
||||
}
|
||||
_ => FullIdentifier::parse_high(ctx).map(Expression::Alias),
|
||||
}?;
|
||||
|
||||
Ok(if let Some(&(_, Token::Comma)) = ctx.pklx.peek() {
|
||||
let mut args = BTreeMap::new();
|
||||
while ctx.maybe_eat_token(Token::Comma).is_some() {
|
||||
let Path { loc, idents } = Path::parse_high(ctx)?;
|
||||
ctx.expect_token(Token::Assign, "=")?;
|
||||
let obj = Expression::parse_high(ctx)?;
|
||||
if args.insert(idents, (loc, obj)).is_some() {
|
||||
return Err(Error {
|
||||
loc,
|
||||
kind: ErrorKind::DuplicateIdentifier,
|
||||
});
|
||||
}
|
||||
}
|
||||
Expression::InvocationMulti {
|
||||
obj: Box::new(obj),
|
||||
args,
|
||||
}
|
||||
} else if matches!(ctx.pklx.peek(), Some(&(_, Token::SemiColon)) | None) {
|
||||
obj
|
||||
} else {
|
||||
Expression::InvocationSingle(Box::new((obj, Expression::parse_high(ctx)?)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,8 +328,8 @@ impl Module {
|
|||
}
|
||||
|
||||
let obj = if ctx.maybe_eat_token(Token::Assign).is_some() {
|
||||
let obj = Object::parse_high(ctx)?;
|
||||
if let Object::Code { cfe: true, .. } = obj {
|
||||
let obj = Expression::parse_high(ctx)?;
|
||||
if let Expression::Code { cfe: true, .. } = obj {
|
||||
flags |= EntryFlags::CTRLFE;
|
||||
}
|
||||
Some(obj)
|
||||
|
@ -355,7 +337,6 @@ impl Module {
|
|||
None
|
||||
};
|
||||
|
||||
// code object
|
||||
ret.entries.insert(
|
||||
name,
|
||||
Entry {
|
||||
|
|
Loading…
Reference in New Issue