add new keywords and track CtrlFlowEdit in module entries

This commit is contained in:
Alain Zscheile 2023-05-21 13:17:45 +02:00
parent 6297042297
commit 23ce8d0cb9
2 changed files with 28 additions and 18 deletions

View File

@ -6,8 +6,10 @@ pub enum Token<'a> {
CtrlFlowEdit,
Defer,
Final,
Match,
Module,
Public,
Tag,
// single-char keywords
Assign,
@ -177,8 +179,10 @@ impl<'a> Iterator for Lexer<'a> {
"cfe" => Token::CtrlFlowEdit,
"defer" => Token::Defer,
"final" => Token::Final,
"match" => Token::Match,
"module" => Token::Module,
"pub" => Token::Public,
"tag" => Token::Tag,
_ => Token::Identifier(ident),
}
}

View File

@ -16,6 +16,7 @@ bitflags! {
pub struct EntryFlags: u8 {
const PUBLIC = 0x01;
const FINAL = 0x02;
const CTRLFE = 0x04;
}
}
@ -25,14 +26,14 @@ pub struct Entry {
pub nloc: Location,
// technically this is a set, but that would just waste space here...
pub args: Box<[Atom]>,
pub cobj: CodeObject,
pub obj: Object,
// we use a bitflag here to conserve memory
pub flags: EntryFlags,
}
#[derive(Clone, Debug)]
pub enum CodeObject {
Normal {
pub enum Object {
Code {
cfe: bool,
data: Box<[Statement]>,
ret: Option<Statement>,
@ -57,8 +58,8 @@ pub struct Path {
#[derive(Clone, Debug)]
pub enum StmtArgs {
Single(Box<CodeObject>),
Multi(BTreeMap<Box<[Atom]>, (Location, CodeObject)>),
Single(Box<Object>),
Multi(BTreeMap<Box<[Atom]>, (Location, Object)>),
}
impl Default for StmtArgs {
@ -191,8 +192,8 @@ impl Statement {
while ctx.pklx.next_if(|(_, t)| t == &Token::Comma).is_some() {
let Path { loc, idents } = Path::parse_high(ctx)?;
ctx.expect_token(Token::Assign, "=")?;
let cobj = CodeObject::parse_high(ctx)?;
if args.insert(idents, (loc, cobj)).is_some() {
let obj = Object::parse_high(ctx)?;
if args.insert(idents, (loc, obj)).is_some() {
return Err(Error {
loc,
kind: ErrorKind::DuplicateIdentifier,
@ -205,14 +206,14 @@ impl Statement {
// this escape hatch is a bit ugly, idk...
StmtArgs::default()
} else {
StmtArgs::Single(Box::new(CodeObject::parse_high(ctx)?))
StmtArgs::Single(Box::new(Object::parse_high(ctx)?))
};
Ok(Statement { sel, args })
}
}
impl CodeObject {
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()) {
@ -240,7 +241,7 @@ impl CodeObject {
break;
}
}
Ok(CodeObject::Normal {
Ok(Object::Code {
cfe,
data: codata.into_boxed_slice(),
ret,
@ -255,16 +256,16 @@ impl CodeObject {
// expect a single code object descriptor => alias, or number.
Some(&(_, Token::Integer(i))) => {
ctx.pklx.next();
Ok(CodeObject::Integer(i))
Ok(Object::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(CodeObject::Module(m))
Ok(Object::Module(m))
}
_ => FullIdentifier::parse_high(ctx).map(CodeObject::Alias),
_ => FullIdentifier::parse_high(ctx).map(Object::Alias),
}
}
}
@ -281,13 +282,13 @@ impl Module {
// entry attributes
let mut flags = EntryFlags::empty();
for (_, i) in ctx.pklx.peeking_take_while(|(_, t)| t.is_def_attr()) {
match i {
Token::Final => flags |= EntryFlags::FINAL,
Token::Public => flags |= EntryFlags::PUBLIC,
flags |= match i {
Token::Final => EntryFlags::FINAL,
Token::Public => EntryFlags::PUBLIC,
Token::CtrlFlowEdit => EntryFlags::CTRLFE,
_ => unimplemented!(),
}
}
let flags = flags;
// entry name
let (nloc, name) = match ctx.pklx.next_if(|(_, t)| matches!(t, Token::Identifier(_))) {
@ -345,13 +346,18 @@ impl Module {
ctx.expect_token(Token::Assign, "=")?;
let obj = Object::parse_high(ctx)?;
if let Object::Code { cfe: true, .. } = obj {
flags |= EntryFlags::CTRLFE;
}
// code object
ret.entries.insert(
name,
Entry {
nloc,
args: args.into_boxed_slice(),
cobj: CodeObject::parse_high(ctx)?,
obj,
flags,
},
);