use prolog_parser::ast::*;
use prolog::clause_types::*;
use prolog::forms::*;
use std::collections::{HashMap, VecDeque};
pub enum ChoiceInstruction {
DefaultRetryMeElse(usize),
DefaultTrustMe,
RetryMeElse(usize),
TrustMe,
TryMeElse(usize)
}
pub enum CutInstruction {
Cut(RegType),
GetLevel(RegType),
GetLevelAndUnify(RegType),
NeckCut
}
pub enum IndexedChoiceInstruction {
Retry(usize),
Trust(usize),
Try(usize)
}
impl From<IndexedChoiceInstruction> for Line {
fn from(i: IndexedChoiceInstruction) -> Self {
Line::IndexedChoice(i)
}
}
impl IndexedChoiceInstruction {
pub fn offset(&self) -> usize {
match self {
&IndexedChoiceInstruction::Retry(offset) => offset,
&IndexedChoiceInstruction::Trust(offset) => offset,
&IndexedChoiceInstruction::Try(offset) => offset
}
}
}
pub enum Line {
Arithmetic(ArithmeticInstruction),
Choice(ChoiceInstruction),
Control(ControlInstruction),
Cut(CutInstruction),
Fact(FactInstruction),
Indexing(IndexingInstruction),
IndexedChoice(IndexedChoiceInstruction),
Query(QueryInstruction)
}
impl Line {
pub fn is_head_instr(&self) -> bool {
match self {
&Line::Cut(_) => true,
&Line::Fact(_) => true,
&Line::Query(_) => true,
_ => false
}
}
}
#[derive(Clone)]
pub enum ArithmeticInstruction {
Add(ArithmeticTerm, ArithmeticTerm, usize),
Sub(ArithmeticTerm, ArithmeticTerm, usize),
Mul(ArithmeticTerm, ArithmeticTerm, usize),
Pow(ArithmeticTerm, ArithmeticTerm, usize),
IntPow(ArithmeticTerm, ArithmeticTerm, usize),
IDiv(ArithmeticTerm, ArithmeticTerm, usize),
Max(ArithmeticTerm, ArithmeticTerm, usize),
FIDiv(ArithmeticTerm, ArithmeticTerm, usize),
RDiv(ArithmeticTerm, ArithmeticTerm, usize),
Div(ArithmeticTerm, ArithmeticTerm, usize),
Shl(ArithmeticTerm, ArithmeticTerm, usize),
Shr(ArithmeticTerm, ArithmeticTerm, usize),
Xor(ArithmeticTerm, ArithmeticTerm, usize),
And(ArithmeticTerm, ArithmeticTerm, usize),
Or(ArithmeticTerm, ArithmeticTerm, usize),
Mod(ArithmeticTerm, ArithmeticTerm, usize),
Rem(ArithmeticTerm, ArithmeticTerm, usize),
Abs(ArithmeticTerm, usize),
Neg(ArithmeticTerm, usize),
}
pub enum ControlInstruction {
Allocate(usize), CallClause(ClauseType, usize, usize, bool, bool),
Deallocate,
JmpBy(usize, usize, usize, bool), Proceed
}
impl ControlInstruction {
pub fn is_jump_instr(&self) -> bool {
match self {
&ControlInstruction::CallClause(..) => true,
&ControlInstruction::JmpBy(..) => true,
_ => false
}
}
}
pub enum IndexingInstruction {
SwitchOnTerm(usize, usize, usize, usize),
SwitchOnConstant(usize, HashMap<Constant, usize>),
SwitchOnStructure(usize, HashMap<(ClauseName, usize), usize>)
}
impl From<IndexingInstruction> for Line {
fn from(i: IndexingInstruction) -> Self {
Line::Indexing(i)
}
}
#[derive(Clone)]
pub enum FactInstruction {
GetConstant(Level, Constant, RegType),
GetList(Level, RegType),
GetStructure(ClauseType, usize, RegType),
GetValue(RegType, usize),
GetVariable(RegType, usize),
UnifyConstant(Constant),
UnifyLocalValue(RegType),
UnifyVariable(RegType),
UnifyValue(RegType),
UnifyVoid(usize)
}
#[derive(Clone)]
pub enum QueryInstruction {
GetVariable(RegType, usize),
PutConstant(Level, Constant, RegType),
PutList(Level, RegType),
PutStructure(ClauseType, usize, RegType),
PutUnsafeValue(usize, usize),
PutValue(RegType, usize),
PutVariable(RegType, usize),
SetConstant(Constant),
SetLocalValue(RegType),
SetVariable(RegType),
SetValue(RegType),
SetVoid(usize)
}
pub type CompiledFact = Vec<FactInstruction>;
pub type ThirdLevelIndex = Vec<IndexedChoiceInstruction>;
pub type Code = Vec<Line>;
pub type CodeDeque = VecDeque<Line>;