Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: New list syntax with enforced ,-operator #100

Merged
merged 42 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
d081d26
Char<...> syntax for character classes
phorward Jan 1, 2023
2773fe5
Use of new Char-syntax in tokay.tok
phorward Jan 1, 2023
10c8888
Op::collect() with sequence mode
phorward Jan 2, 2023
c097b5b
Drafting new dict/list syntax
phorward Jan 2, 2023
65a6ba0
Fixing tests for new Char<...> syntax
phorward Jan 2, 2023
27b1363
Substitute `Any` by `Char`
phorward Jan 2, 2023
c0d24dc
Merge branch 'Char-tokens' into new-list-syntax
phorward Jan 2, 2023
56fc036
Merge branch 'main' into new-list-syntax
phorward Jan 9, 2023
7d5f393
Adding `|`-syntax inside `[...]` as well
phorward Jan 12, 2023
274e590
Merge branch 'main' into new-list-syntax
phorward Feb 22, 2023
578006f
Merge branch 'main' into new-list-syntax
phorward Mar 4, 2023
e9e3a0e
Merge branch 'main' into new-list-syntax
phorward Jun 13, 2023
8ee9da4
Merge branch 'generic-parselets' into new-list-syntax
phorward Jun 13, 2023
bcd22b9
Remove compiler warning
phorward Jun 13, 2023
56e974e
Regenerating parser
phorward Jun 14, 2023
d9c66bb
Merge branch 'main' into new-list-syntax
phorward Oct 28, 2023
e85e2b7
Restored original parser
phorward Oct 28, 2023
e87d814
Rebuild parser from tokay.tok
phorward Oct 28, 2023
871a12c
Merge branch 'main' into new-list-syntax
phorward Oct 28, 2023
4a956b4
Some tests and experiments
phorward Nov 1, 2023
56539a4
Starting with alternative list syntax
phorward Nov 5, 2023
b23e718
repr lists in brackets
phorward Nov 8, 2023
32b6c78
Merge branch 'main' into alt-new-list-syntax
phorward Nov 9, 2023
e8929e5
Improving the new list (,) syntax
phorward Nov 10, 2023
ed45c92
Implementing InlineExpressionList & InlineHoldAssignment
phorward Nov 12, 2023
648c2f3
Fixing some testcases
phorward Nov 13, 2023
ac09d47
Introducting InlineAssignment
phorward Nov 18, 2023
878279e
Improving inline syntax to just one path
phorward Nov 18, 2023
11cb756
Further experiments with the sequence/inline_sequence syntax
phorward Nov 22, 2023
ed7fdf6
Merge branch 'main' into new-list-syntax
phorward Dec 3, 2023
2f05bf2
Distinguish inlined lists and sequences
phorward Dec 4, 2023
96521e2
Improving sequence, fixing tests/inline_parseable_sequence.tok
phorward Dec 4, 2023
34ce7c5
Replacing `inline_sequence` by just `sequence`
phorward Dec 4, 2023
4ecc167
Still unclear on sequence/list severity on inline syntax
phorward Dec 5, 2023
9da5a4e
Draft for a cleaner, less ambigous syntax for inlined list and sequen…
phorward Dec 5, 2023
32835d6
assign_drop
phorward Dec 5, 2023
3f51fea
Fixing tests/dict.tok for now
phorward Dec 6, 2023
1029674
Optimizing Assignment parselets
phorward Dec 7, 2023
74840d4
Merge branch 'main' into new-list-syntax
phorward Dec 9, 2023
ba11dda
Compacting tokay.tok by using generic Assignment parselet
phorward Dec 9, 2023
d233e86
Merge branch 'main' into new-list-syntax
phorward Dec 16, 2023
a3cf507
Merge branch 'main' into new-list-syntax
phorward Dec 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 28 additions & 17 deletions src/compiler/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,8 @@ fn traverse_node(compiler: &mut Compiler, node: &Dict) -> ImlOp {

let mut ops = Vec::new();

if parts.len() > 1 && parts[1] != "hold" {
/* assignment with operation */
if parts.len() > 1 && !["copy", "drop", "hold"].contains(&parts[1]) {
ops.push(traverse_node_lvalue(compiler, lvalue, false, false));
ops.push(traverse_node_rvalue(compiler, value, Rvalue::Load));

Expand All @@ -793,18 +794,26 @@ fn traverse_node(compiler: &mut Compiler, node: &Dict) -> ImlOp {
_ => unreachable!(),
});

if *parts.last().unwrap() != "hold" {
ops.push(Op::Inv.into());
match *parts.last().unwrap() {
"hold" => {}
"copy" => ops.push(Op::Sep.into()),
_ => ops.push(Op::Inv.into()),
}
} else {
}
/* normal assignment without operation */
else {
ops.push(traverse_node_rvalue(compiler, value, Rvalue::Load));
ops.push(traverse_offset(node));
ops.push(traverse_node_lvalue(
compiler,
lvalue,
true,
*parts.last().unwrap() == "hold",
["copy", "hold"].contains(parts.last().unwrap()),
));

if *parts.last().unwrap() == "copy" {
ops.push(Op::Sep.into())
}
}

ImlOp::from(ops)
Expand Down Expand Up @@ -1594,14 +1603,16 @@ fn traverse_node(compiler: &mut Compiler, node: &Dict) -> ImlOp {
ImlOp::from(ops)
}

// sequence ------------------------------------------------------
"sequence" | "inline_sequence" | "list" => {
// sequence, dict, list -----------------------------------------
"sequence" | "dict" | "list" => {
let children = if let Some(children) = node.get_str("children") {
List::from(children)
} else {
List::new()
};

//println!("{} => {:?}", emit, children);

let mut ops = Vec::new();

for node in children.iter() {
Expand All @@ -1612,14 +1623,14 @@ fn traverse_node(compiler: &mut Compiler, node: &Dict) -> ImlOp {
));
}

// Lists are definitive lists with a given length and only non-aliased values
if emit == "list" {
ops.push(Op::MakeList(children.len()).into());
ImlOp::from(ops)
}
// In most cases, lists are parsed as sequences;
else {
ImlOp::seq(ops, true)
match emit {
"list" if ops.is_empty() => ImlOp::from(Op::MakeList(0)),
"list" => {
ops.push(ImlOp::from(Op::MakeList(ops.len())));
ImlOp::seq(ops, false)
}
"dict" if ops.is_empty() => ImlOp::from(Op::MakeDict(0)),
_ => ImlOp::seq(ops, true),
}
}

Expand Down Expand Up @@ -1701,7 +1712,7 @@ tokay_function!("ast : @emit, value=void, flatten=true, debug=false", {
let value = if value.is_void() {
Some(
context
.collect(capture_start, false, debug.is_true())
.collect(capture_start, false, true, debug.is_true())
.extract(&context.thread.reader),
)
} else {
Expand Down Expand Up @@ -1733,7 +1744,7 @@ tokay_function!("ast : @emit, value=void, flatten=true, debug=false", {
ret.insert_str("children", value.clone());
}
// Otherwise this is a value
else {
else if !value.is_void() {
ret.insert_str("value", value.clone());
}
}
Expand Down
22 changes: 7 additions & 15 deletions src/compiler/iml/imlop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ pub(in crate::compiler) enum ImlOp {
// Sequence of ops, optionally a collection
Seq {
seq: Vec<ImlOp>,
collection: bool, /* According to these operation's semantics, or when an entire sequence is completely recognized,
the sequence is getting accepted. Incomplete sequences are rejected, but might partly be
processed, including data changes, which is a wanted behavior. */
collect: bool, // Run a Context::collect() on successfull sequence match
},

// Conditional block
Expand All @@ -53,14 +51,14 @@ pub(in crate::compiler) enum ImlOp {

impl ImlOp {
/// Creates a sequence from items, and optimizes stacked, unframed sequences
pub fn seq(items: Vec<ImlOp>, collection: bool) -> ImlOp {
pub fn seq(items: Vec<ImlOp>, collect: bool) -> ImlOp {
let mut seq = Vec::new();

for item in items {
match item {
ImlOp::Nop => {}
ImlOp::Seq {
collection: false,
collect: false,
seq: items,
} => seq.extend(items),
item => seq.push(item),
Expand All @@ -69,8 +67,8 @@ impl ImlOp {

match seq.len() {
0 => ImlOp::Nop,
1 if !collection => seq.pop().unwrap(),
_ => ImlOp::Seq { seq, collection },
1 if !collect => seq.pop().unwrap(),
_ => ImlOp::Seq { seq, collect },
}
}

Expand Down Expand Up @@ -213,19 +211,13 @@ impl ImlOp {

ops.extend(ret);
}
ImlOp::Seq { seq, collection } => {
ImlOp::Seq { seq, collect } => {
for item in seq.iter() {
item.compile(program, current, ops);
}

// Check if the sequence exists of more than one operational instruction
if *collection
&& ops[start..]
.iter()
.map(|op| if matches!(op, Op::Offset(_)) { 0 } else { 1 })
.sum::<usize>()
> 1
{
if *collect {
ops.insert(start, Op::Frame(0));
ops.push(Op::Collect);
ops.push(Op::Close);
Expand Down
Loading
Loading