move to a predicate-based module system, move to loader.[rs|pl]-based compilation, add support for incremental clause compilation

This commit is contained in:
Mark Thom
2021-01-30 14:32:47 -07:00
parent b33158b92e
commit a4d15bfb88
55 changed files with 10501 additions and 7601 deletions

View File

@@ -1,73 +1,39 @@
use crate::instructions::*;
use std::collections::VecDeque;
use indexmap::IndexSet;
fn scan_for_trust_me(
code: &Code,
jmp_offsets: &mut VecDeque<usize>,
before_idx: usize,
after_idx: &mut usize,
) {
// record the location of the line after the TrustMe capping the
// choice instruction sequence to after_idx.
loop {
match &code[*after_idx] {
&Line::Choice(ChoiceInstruction::DefaultRetryMeElse(offset)) |
&Line::Choice(ChoiceInstruction::RetryMeElse(offset)) |
&Line::IndexedChoice(IndexedChoiceInstruction::Retry(offset)) => {
*after_idx += offset;
}
&Line::Choice(ChoiceInstruction::DefaultTrustMe) |
&Line::Choice(ChoiceInstruction::TrustMe) |
&Line::IndexedChoice(IndexedChoiceInstruction::Trust(..)) => {
break;
}
_ => {
*after_idx += 1;
fn capture_offset(line: &Line, index: usize, stack: &mut Vec<usize>) -> bool {
match line {
&Line::Choice(ChoiceInstruction::TryMeElse(offset)) if offset > 0 => {
stack.push(index + offset);
}
&Line::Choice(ChoiceInstruction::DefaultRetryMeElse(offset)) |
&Line::Choice(ChoiceInstruction::RetryMeElse(offset)) if offset > 0 => {
stack.push(index + offset);
}
&Line::Control(ControlInstruction::JmpBy(_, offset, _, false)) => {
stack.push(index + offset);
}
&Line::Control(ControlInstruction::JmpBy(_, offset, _, true)) => {
stack.push(index + offset);
return true;
}
&Line::Control(ControlInstruction::Proceed) |
&Line::Control(ControlInstruction::CallClause(_, _, _, true, _)) => {
return true;
}
&Line::Control(ControlInstruction::RevJmpBy(offset)) => {
if offset > 0 {
stack.push(index - offset);
} else {
return true;
}
}
}
// search the code in the range for JmpBy instructions and record their
// offsets for future scanning.
for (idx, instr) in code[before_idx .. *after_idx].iter().enumerate() {
match instr {
&Line::Control(ControlInstruction::JmpBy(_, offset, ..)) => {
jmp_offsets.push_back(before_idx + idx + offset)
}
_ => {
}
_ => {
}
}
};
*after_idx += 1;
}
fn capture_next_range(code: &Code, queue: &mut VecDeque<usize>, last_idx: &mut usize) {
loop {
match &code[*last_idx] {
&Line::Choice(ChoiceInstruction::TryMeElse(offset)) |
&Line::IndexedChoice(IndexedChoiceInstruction::Try(offset)) => {
let before_idx = *last_idx;
*last_idx += offset;
scan_for_trust_me(code, queue, before_idx, last_idx);
}
&Line::Control(ControlInstruction::JmpBy(_, offset, _, false)) => {
queue.push_back(*last_idx + offset);
*last_idx += 1;
}
&Line::Control(ControlInstruction::JmpBy(_, offset, _, true)) => {
queue.push_back(*last_idx + offset);
break;
}
&Line::Control(ControlInstruction::Proceed) |
&Line::Control(ControlInstruction::CallClause(_, _, _, true, _)) =>
break,
_ =>
*last_idx += 1,
};
}
false
}
/* This function walks the code of a single predicate, supposed to
@@ -76,15 +42,22 @@ fn capture_next_range(code: &Code, queue: &mut VecDeque<usize>, last_idx: &mut u
*/
pub fn walk_code(code: &Code, p: usize, mut walker: impl FnMut(&Line))
{
let mut queue = VecDeque::from(vec![p]);
let mut stack = vec![p];
let mut visited_indices = IndexSet::new();
while let Some(first_idx) = queue.pop_front() {
let mut last_idx = first_idx;
while let Some(first_index) = stack.pop() {
if visited_indices.contains(&first_index) {
continue;
} else {
visited_indices.insert(first_index);
}
capture_next_range(code, &mut queue, &mut last_idx);
for instr in &code[first_idx .. last_idx + 1] {
for (index, instr) in code[first_index ..].iter().enumerate() {
walker(instr);
if capture_offset(instr, first_index + index, &mut stack) {
break;
}
}
}
}
@@ -92,6 +65,7 @@ pub fn walk_code(code: &Code, p: usize, mut walker: impl FnMut(&Line))
/* A function for code walking that might result in modification to
* the code. Otherwise identical to walk_code.
*/
/*
pub fn walk_code_mut(code: &mut Code, p: usize, mut walker: impl FnMut(&mut Line))
{
let mut queue = VecDeque::from(vec![p]);
@@ -106,3 +80,4 @@ pub fn walk_code_mut(code: &mut Code, p: usize, mut walker: impl FnMut(&mut Line
}
}
}
*/