201 lines
5.8 KiB
Rust
201 lines
5.8 KiB
Rust
use crate::parser::ast::*;
|
|
|
|
use crate::atom_table::*;
|
|
use crate::forms::*;
|
|
use crate::instructions::*;
|
|
use crate::iterators::*;
|
|
use crate::types::*;
|
|
|
|
pub(crate) struct FactInstruction;
|
|
pub(crate) struct QueryInstruction;
|
|
|
|
pub(crate) trait CompilationTarget<'a> {
|
|
type Iterator: Iterator<Item = TermRef<'a>>;
|
|
|
|
fn iter(term: &'a Term) -> Self::Iterator;
|
|
|
|
fn to_constant(lvl: Level, literal: Literal, r: RegType) -> Instruction;
|
|
fn to_list(lvl: Level, r: RegType) -> Instruction;
|
|
fn to_structure(name: Atom, arity: usize, r: RegType) -> Instruction;
|
|
|
|
fn to_void(num_subterms: usize) -> Instruction;
|
|
fn is_void_instr(instr: &Instruction) -> bool;
|
|
|
|
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Instruction;
|
|
|
|
fn incr_void_instr(instr: &mut Instruction);
|
|
|
|
fn constant_subterm(literal: Literal) -> Instruction;
|
|
|
|
fn argument_to_variable(r: RegType, r: usize) -> Instruction;
|
|
fn argument_to_value(r: RegType, val: usize) -> Instruction;
|
|
fn unsafe_argument_to_value(r: RegType, val: usize) -> Instruction;
|
|
|
|
fn move_to_register(r: RegType, val: usize) -> Instruction;
|
|
|
|
fn subterm_to_variable(r: RegType) -> Instruction;
|
|
fn subterm_to_value(r: RegType) -> Instruction;
|
|
fn unsafe_subterm_to_value(r: RegType) -> Instruction;
|
|
|
|
fn clause_arg_to_instr(r: RegType) -> Instruction;
|
|
}
|
|
|
|
impl<'a> CompilationTarget<'a> for FactInstruction {
|
|
type Iterator = FactIterator<'a>;
|
|
|
|
fn iter(term: &'a Term) -> Self::Iterator {
|
|
breadth_first_iter(term, RootIterationPolicy::NotIterated)
|
|
}
|
|
|
|
fn to_constant(lvl: Level, constant: Literal, reg: RegType) -> Instruction {
|
|
Instruction::GetConstant(lvl, HeapCellValue::from(constant), reg)
|
|
}
|
|
|
|
fn to_structure(name: Atom, arity: usize, reg: RegType) -> Instruction {
|
|
Instruction::GetStructure(name, arity, reg)
|
|
}
|
|
|
|
fn to_list(lvl: Level, reg: RegType) -> Instruction {
|
|
Instruction::GetList(lvl, reg)
|
|
}
|
|
|
|
fn to_void(num_subterms: usize) -> Instruction {
|
|
Instruction::UnifyVoid(num_subterms)
|
|
}
|
|
|
|
fn is_void_instr(instr: &Instruction) -> bool {
|
|
match instr {
|
|
&Instruction::UnifyVoid(_) => true,
|
|
_ => false,
|
|
}
|
|
}
|
|
|
|
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Instruction {
|
|
Instruction::GetPartialString(lvl, string, r, has_tail)
|
|
}
|
|
|
|
fn incr_void_instr(instr: &mut Instruction) {
|
|
match instr {
|
|
&mut Instruction::UnifyVoid(ref mut incr) => *incr += 1,
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn constant_subterm(constant: Literal) -> Instruction {
|
|
Instruction::UnifyConstant(HeapCellValue::from(constant))
|
|
}
|
|
|
|
fn argument_to_variable(arg: RegType, val: usize) -> Instruction {
|
|
Instruction::GetVariable(arg, val)
|
|
}
|
|
|
|
fn move_to_register(arg: RegType, val: usize) -> Instruction {
|
|
Instruction::GetVariable(arg, val)
|
|
}
|
|
|
|
fn argument_to_value(arg: RegType, val: usize) -> Instruction {
|
|
Instruction::GetValue(arg, val)
|
|
}
|
|
|
|
fn unsafe_argument_to_value(arg: RegType, val: usize) -> Instruction {
|
|
Instruction::GetValue(arg, val)
|
|
}
|
|
|
|
fn subterm_to_variable(val: RegType) -> Instruction {
|
|
Instruction::UnifyVariable(val)
|
|
}
|
|
|
|
fn subterm_to_value(val: RegType) -> Instruction {
|
|
Instruction::UnifyValue(val)
|
|
}
|
|
|
|
fn unsafe_subterm_to_value(val: RegType) -> Instruction {
|
|
Instruction::UnifyLocalValue(val)
|
|
}
|
|
|
|
fn clause_arg_to_instr(val: RegType) -> Instruction {
|
|
Instruction::UnifyVariable(val)
|
|
}
|
|
}
|
|
|
|
impl<'a> CompilationTarget<'a> for QueryInstruction {
|
|
type Iterator = QueryIterator<'a>;
|
|
|
|
fn iter(term: &'a Term) -> Self::Iterator {
|
|
post_order_iter(term)
|
|
}
|
|
|
|
fn to_structure(name: Atom, arity: usize, r: RegType) -> Instruction {
|
|
Instruction::PutStructure(name, arity, r)
|
|
}
|
|
|
|
fn to_constant(lvl: Level, constant: Literal, reg: RegType) -> Instruction {
|
|
Instruction::PutConstant(lvl, HeapCellValue::from(constant), reg)
|
|
}
|
|
|
|
fn to_list(lvl: Level, reg: RegType) -> Instruction {
|
|
Instruction::PutList(lvl, reg)
|
|
}
|
|
|
|
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Instruction {
|
|
Instruction::PutPartialString(lvl, string, r, has_tail)
|
|
}
|
|
|
|
fn to_void(subterms: usize) -> Instruction {
|
|
Instruction::SetVoid(subterms)
|
|
}
|
|
|
|
fn is_void_instr(instr: &Instruction) -> bool {
|
|
match instr {
|
|
&Instruction::SetVoid(_) => true,
|
|
_ => false,
|
|
}
|
|
}
|
|
|
|
fn incr_void_instr(instr: &mut Instruction) {
|
|
match instr {
|
|
&mut Instruction::SetVoid(ref mut incr) => *incr += 1,
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
fn constant_subterm(constant: Literal) -> Instruction {
|
|
Instruction::SetConstant(HeapCellValue::from(constant))
|
|
}
|
|
|
|
fn argument_to_variable(arg: RegType, val: usize) -> Instruction {
|
|
Instruction::PutVariable(arg, val)
|
|
}
|
|
|
|
fn move_to_register(arg: RegType, val: usize) -> Instruction {
|
|
Instruction::GetVariable(arg, val)
|
|
}
|
|
|
|
fn argument_to_value(arg: RegType, val: usize) -> Instruction {
|
|
Instruction::PutValue(arg, val)
|
|
}
|
|
|
|
fn unsafe_argument_to_value(arg: RegType, val: usize) -> Instruction {
|
|
match arg {
|
|
RegType::Perm(p) => Instruction::PutUnsafeValue(p, val),
|
|
RegType::Temp(_) => Instruction::PutValue(arg, val),
|
|
}
|
|
}
|
|
|
|
fn subterm_to_variable(val: RegType) -> Instruction {
|
|
Instruction::SetVariable(val)
|
|
}
|
|
|
|
fn subterm_to_value(val: RegType) -> Instruction {
|
|
Instruction::SetValue(val)
|
|
}
|
|
|
|
fn unsafe_subterm_to_value(val: RegType) -> Instruction {
|
|
Instruction::SetLocalValue(val)
|
|
}
|
|
|
|
fn clause_arg_to_instr(val: RegType) -> Instruction {
|
|
Instruction::SetValue(val)
|
|
}
|
|
}
|