This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use crate::allocator::*;
|
use crate::allocator::*;
|
||||||
use crate::arena::*;
|
use crate::arena::*;
|
||||||
use crate::atom_table::*;
|
use crate::atom_table::*;
|
||||||
use crate::fixtures::*;
|
use crate::debray_allocator::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::instructions::*;
|
use crate::instructions::*;
|
||||||
use crate::iterators::*;
|
use crate::iterators::*;
|
||||||
@@ -143,8 +143,8 @@ impl<'a> Iterator for ArithInstructionIterator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct ArithmeticEvaluator<'a, TermMarker> {
|
pub(crate) struct ArithmeticEvaluator<'a> {
|
||||||
marker: &'a mut TermMarker,
|
marker: &'a mut DebrayAllocator,
|
||||||
interm: Vec<ArithmeticTerm>,
|
interm: Vec<ArithmeticTerm>,
|
||||||
interm_c: usize,
|
interm_c: usize,
|
||||||
}
|
}
|
||||||
@@ -184,8 +184,8 @@ fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), Ari
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, TermMarker: Allocator> ArithmeticEvaluator<'a, TermMarker> {
|
impl<'a> ArithmeticEvaluator<'a> {
|
||||||
pub(crate) fn new(marker: &'a mut TermMarker, target_int: usize) -> Self {
|
pub(crate) fn new(marker: &'a mut DebrayAllocator, target_int: usize) -> Self {
|
||||||
ArithmeticEvaluator {
|
ArithmeticEvaluator {
|
||||||
marker,
|
marker,
|
||||||
interm: Vec::new(),
|
interm: Vec::new(),
|
||||||
@@ -317,6 +317,7 @@ impl<'a, TermMarker: Allocator> ArithmeticEvaluator<'a, TermMarker> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
src: &'a Term,
|
src: &'a Term,
|
||||||
term_loc: GenContext,
|
term_loc: GenContext,
|
||||||
|
arg: usize,
|
||||||
) -> Result<ArithCont, ArithmeticError>
|
) -> Result<ArithCont, ArithmeticError>
|
||||||
{
|
{
|
||||||
let mut code = vec![];
|
let mut code = vec![];
|
||||||
@@ -326,7 +327,15 @@ impl<'a, TermMarker: Allocator> ArithmeticEvaluator<'a, TermMarker> {
|
|||||||
match term_ref? {
|
match term_ref? {
|
||||||
ArithTermRef::Literal(c) => push_literal(&mut self.interm, c)?,
|
ArithTermRef::Literal(c) => push_literal(&mut self.interm, c)?,
|
||||||
ArithTermRef::Var(lvl, cell, name) => {
|
ArithTermRef::Var(lvl, cell, name) => {
|
||||||
let r = if lvl == Level::Shallow && term_loc.is_last() {
|
let r = if lvl == Level::Shallow {
|
||||||
|
self.marker.mark_non_callable(
|
||||||
|
name.clone(),
|
||||||
|
arg,
|
||||||
|
term_loc,
|
||||||
|
cell,
|
||||||
|
&mut code,
|
||||||
|
)
|
||||||
|
} else if term_loc.is_last() || cell.get().norm().reg_num() == 0 {
|
||||||
self.marker.mark_var::<QueryInstruction>(
|
self.marker.mark_var::<QueryInstruction>(
|
||||||
name.clone(),
|
name.clone(),
|
||||||
lvl,
|
lvl,
|
||||||
@@ -335,26 +344,7 @@ impl<'a, TermMarker: Allocator> ArithmeticEvaluator<'a, TermMarker> {
|
|||||||
&mut code,
|
&mut code,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.interm.push(ArithmeticTerm::Reg(temp_v!(2)));
|
self.marker.get_binding(&name).unwrap()
|
||||||
continue;
|
|
||||||
} else if cell.get().norm().reg_num() == 0 {
|
|
||||||
self.marker.mark_var::<QueryInstruction>(
|
|
||||||
name.clone(),
|
|
||||||
lvl,
|
|
||||||
cell,
|
|
||||||
term_loc,
|
|
||||||
&mut code,
|
|
||||||
);
|
|
||||||
|
|
||||||
match self.marker.bindings().get(&name) {
|
|
||||||
Some(&VarData::Temp(_, t, _)) if t != 0 =>
|
|
||||||
RegType::Temp(t),
|
|
||||||
Some(&VarData::Perm(p)) if p != 0 =>
|
|
||||||
RegType::Perm(p),
|
|
||||||
_ => {
|
|
||||||
unreachable!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
cell.get().norm()
|
cell.get().norm()
|
||||||
};
|
};
|
||||||
|
|||||||
238
src/codegen.rs
238
src/codegen.rs
@@ -4,6 +4,7 @@ use crate::{perm_v, temp_v};
|
|||||||
|
|
||||||
use crate::allocator::*;
|
use crate::allocator::*;
|
||||||
use crate::arithmetic::*;
|
use crate::arithmetic::*;
|
||||||
|
use crate::debray_allocator::*;
|
||||||
use crate::fixtures::*;
|
use crate::fixtures::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::indexing::*;
|
use crate::indexing::*;
|
||||||
@@ -198,9 +199,9 @@ impl CodeGenSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct CodeGenerator<'a, TermMarker> {
|
pub(crate) struct CodeGenerator<'a> {
|
||||||
pub(crate) atom_tbl: &'a mut AtomTable,
|
pub(crate) atom_tbl: &'a mut AtomTable,
|
||||||
marker: TermMarker,
|
marker: DebrayAllocator,
|
||||||
pub(crate) var_count: IndexMap<Rc<String>, usize>,
|
pub(crate) var_count: IndexMap<Rc<String>, usize>,
|
||||||
settings: CodeGenSettings,
|
settings: CodeGenSettings,
|
||||||
pub(crate) skeleton: PredicateSkeleton,
|
pub(crate) skeleton: PredicateSkeleton,
|
||||||
@@ -208,11 +209,55 @@ pub(crate) struct CodeGenerator<'a, TermMarker> {
|
|||||||
global_jmp_by_locs_offset: usize,
|
global_jmp_by_locs_offset: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
impl DebrayAllocator {
|
||||||
|
fn mark_var_in_non_callable(
|
||||||
|
&mut self,
|
||||||
|
name: Rc<String>,
|
||||||
|
term_loc: GenContext,
|
||||||
|
vr: &Cell<VarReg>,
|
||||||
|
code: &mut Code,
|
||||||
|
) -> RegType {
|
||||||
|
self.mark_var::<QueryInstruction>(name, Level::Shallow, vr, term_loc, code);
|
||||||
|
vr.get().norm()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub(crate) fn get_binding(&self, name: &String) -> Option<RegType> {
|
||||||
|
match self.bindings().get(name) {
|
||||||
|
Some(&VarData::Temp(_, t, _)) if t != 0 => Some(RegType::Temp(t)),
|
||||||
|
Some(&VarData::Perm(p)) if p != 0 => Some(RegType::Perm(p)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn mark_non_callable(
|
||||||
|
&mut self,
|
||||||
|
name: Rc<String>,
|
||||||
|
arg: usize,
|
||||||
|
term_loc: GenContext,
|
||||||
|
vr: &Cell<VarReg>,
|
||||||
|
code: &mut Code,
|
||||||
|
) -> RegType {
|
||||||
|
match self.get_binding(&name) {
|
||||||
|
Some(RegType::Temp(t)) => RegType::Temp(t),
|
||||||
|
Some(RegType::Perm(p)) => {
|
||||||
|
if let GenContext::Last(_) = term_loc {
|
||||||
|
self.mark_var_in_non_callable(name.clone(), term_loc, vr, code);
|
||||||
|
temp_v!(arg)
|
||||||
|
} else {
|
||||||
|
RegType::Perm(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => self.mark_var_in_non_callable(name, term_loc, vr, code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b> CodeGenerator<'b> {
|
||||||
pub(crate) fn new(atom_tbl: &'b mut AtomTable, settings: CodeGenSettings) -> Self {
|
pub(crate) fn new(atom_tbl: &'b mut AtomTable, settings: CodeGenSettings) -> Self {
|
||||||
CodeGenerator {
|
CodeGenerator {
|
||||||
atom_tbl,
|
atom_tbl,
|
||||||
marker: Allocator::new(),
|
marker: DebrayAllocator::new(),
|
||||||
var_count: IndexMap::new(),
|
var_count: IndexMap::new(),
|
||||||
settings,
|
settings,
|
||||||
skeleton: PredicateSkeleton::new(),
|
skeleton: PredicateSkeleton::new(),
|
||||||
@@ -234,45 +279,6 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
*self.var_count.get(var).unwrap()
|
*self.var_count.get(var).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mark_var_in_non_callable(
|
|
||||||
&mut self,
|
|
||||||
name: Rc<String>,
|
|
||||||
term_loc: GenContext,
|
|
||||||
vr: &Cell<VarReg>,
|
|
||||||
code: &mut Code,
|
|
||||||
) -> RegType {
|
|
||||||
let mut target = Code::new();
|
|
||||||
self.marker.mark_var::<QueryInstruction>(name, Level::Shallow, vr, term_loc, &mut target);
|
|
||||||
|
|
||||||
if !target.is_empty() {
|
|
||||||
code.extend(target.into_iter());
|
|
||||||
}
|
|
||||||
|
|
||||||
vr.get().norm()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mark_non_callable(
|
|
||||||
&mut self,
|
|
||||||
name: Rc<String>,
|
|
||||||
arg: usize,
|
|
||||||
term_loc: GenContext,
|
|
||||||
vr: &Cell<VarReg>,
|
|
||||||
code: &mut Code,
|
|
||||||
) -> RegType {
|
|
||||||
match self.marker.bindings().get(&name) {
|
|
||||||
Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t),
|
|
||||||
Some(&VarData::Perm(p)) if p != 0 => {
|
|
||||||
if let GenContext::Last(_) = term_loc {
|
|
||||||
self.mark_var_in_non_callable(name.clone(), term_loc, vr, code);
|
|
||||||
temp_v!(arg)
|
|
||||||
} else {
|
|
||||||
RegType::Perm(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => self.mark_var_in_non_callable(name, term_loc, vr, code),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_or_increment_void_instr<'a, Target>(target: &mut Code)
|
fn add_or_increment_void_instr<'a, Target>(target: &mut Code)
|
||||||
where
|
where
|
||||||
Target: crate::targets::CompilationTarget<'a>,
|
Target: crate::targets::CompilationTarget<'a>,
|
||||||
@@ -316,9 +322,9 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
&Term::AnonVar => {
|
&Term::AnonVar => {
|
||||||
Self::add_or_increment_void_instr::<Target>(target);
|
Self::add_or_increment_void_instr::<Target>(target);
|
||||||
}
|
}
|
||||||
&Term::Cons(ref cell, ..)
|
&Term::Cons(ref cell, ..) |
|
||||||
| &Term::Clause(ref cell, ..)
|
&Term::Clause(ref cell, ..) |
|
||||||
| Term::PartialString(ref cell, ..) => {
|
Term::PartialString(ref cell, ..) => {
|
||||||
self.marker.mark_non_var::<Target>(Level::Deep, term_loc, cell, target);
|
self.marker.mark_non_var::<Target>(Level::Deep, term_loc, cell, target);
|
||||||
target.push(Target::clause_arg_to_instr(cell.get()));
|
target.push(Target::clause_arg_to_instr(cell.get()));
|
||||||
}
|
}
|
||||||
@@ -501,36 +507,39 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
&InlinedClauseType::CompareNumber(mut cmp) => {
|
&InlinedClauseType::CompareNumber(mut cmp) => {
|
||||||
self.marker.reset_arg(2);
|
self.marker.reset_arg(2);
|
||||||
|
|
||||||
let (mut lcode, at_1) = self.compile_arith_expr(&terms[0], 1, term_loc)?;
|
let (mut lcode, at_1) = self.compile_arith_expr(&terms[0], 1, term_loc, 1)?;
|
||||||
let (mut rcode, at_2) = self.compile_arith_expr(&terms[1], 2, term_loc)?;
|
|
||||||
|
|
||||||
let at_1 = if let &Term::Var(ref vr, ref name) = &terms[0] {
|
if !matches!(terms[0], Term::Var(..)) {
|
||||||
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 1, term_loc, vr, code))
|
|
||||||
} else {
|
|
||||||
self.marker.advance_arg();
|
self.marker.advance_arg();
|
||||||
at_1.unwrap_or(interm!(1))
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let at_2 = if let &Term::Var(ref vr, ref name) = &terms[1] {
|
let (mut rcode, at_2) = self.compile_arith_expr(&terms[1], 2, term_loc, 2)?;
|
||||||
ArithmeticTerm::Reg(self.mark_non_callable(name.clone(), 2, term_loc, vr, code))
|
|
||||||
} else {
|
|
||||||
at_2.unwrap_or(interm!(2))
|
|
||||||
};
|
|
||||||
|
|
||||||
code.append(&mut lcode);
|
code.append(&mut lcode);
|
||||||
code.append(&mut rcode);
|
code.append(&mut rcode);
|
||||||
|
|
||||||
|
let at_1 = at_1.unwrap_or(interm!(1));
|
||||||
|
let at_2 = at_2.unwrap_or(interm!(2));
|
||||||
|
|
||||||
code.push(compare_number_instr!(cmp, at_1, at_2));
|
code.push(compare_number_instr!(cmp, at_1, at_2));
|
||||||
}
|
}
|
||||||
&InlinedClauseType::IsAtom(..) => match &terms[0] {
|
&InlinedClauseType::IsAtom(..) => match &terms[0] {
|
||||||
&Term::Literal(_, Literal::Char(_))
|
&Term::Literal(_, Literal::Char(_)) |
|
||||||
| &Term::Literal(_, Literal::Atom(atom!("[]")))
|
&Term::Literal(_, Literal::Atom(atom!("[]"))) |
|
||||||
| &Term::Literal(_, Literal::Atom(..)) => {
|
&Term::Literal(_, Literal::Atom(..)) => {
|
||||||
code.push(instr!("$succeed", 0));
|
code.push(instr!("$succeed", 0));
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
|
||||||
|
let r = self.marker.mark_non_callable(
|
||||||
|
name.clone(),
|
||||||
|
1,
|
||||||
|
term_loc,
|
||||||
|
vr,
|
||||||
|
code,
|
||||||
|
);
|
||||||
|
|
||||||
code.push(instr!("atom", r, 0));
|
code.push(instr!("atom", r, 0));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -538,7 +547,10 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsAtomic(..) => match &terms[0] {
|
&InlinedClauseType::IsAtomic(..) => match &terms[0] {
|
||||||
&Term::AnonVar | &Term::Clause(..) | &Term::Cons(..) | &Term::PartialString(..) => {
|
&Term::AnonVar |
|
||||||
|
&Term::Clause(..) |
|
||||||
|
&Term::Cons(..) |
|
||||||
|
&Term::PartialString(..) => {
|
||||||
code.push(instr!("$fail", 0));
|
code.push(instr!("$fail", 0));
|
||||||
}
|
}
|
||||||
&Term::Literal(_, Literal::String(_)) => {
|
&Term::Literal(_, Literal::String(_)) => {
|
||||||
@@ -549,18 +561,36 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
|
||||||
|
let r = self.marker.mark_non_callable(
|
||||||
|
name.clone(),
|
||||||
|
1,
|
||||||
|
term_loc,
|
||||||
|
vr,
|
||||||
|
code,
|
||||||
|
);
|
||||||
|
|
||||||
code.push(instr!("atomic", r, 0));
|
code.push(instr!("atomic", r, 0));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsCompound(..) => match &terms[0] {
|
&InlinedClauseType::IsCompound(..) => match &terms[0] {
|
||||||
&Term::Clause(..) | &Term::Cons(..) | &Term::PartialString(..) |
|
&Term::Clause(..) |
|
||||||
|
&Term::Cons(..) |
|
||||||
|
&Term::PartialString(..) |
|
||||||
&Term::Literal(_, Literal::String(..)) => {
|
&Term::Literal(_, Literal::String(..)) => {
|
||||||
code.push(instr!("$succeed", 0));
|
code.push(instr!("$succeed", 0));
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
|
||||||
|
let r = self.marker.mark_non_callable(
|
||||||
|
name.clone(),
|
||||||
|
1,
|
||||||
|
term_loc,
|
||||||
|
vr,
|
||||||
|
code,
|
||||||
|
);
|
||||||
|
|
||||||
code.push(instr!("compound", r, 0));
|
code.push(instr!("compound", r, 0));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -573,7 +603,7 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
let r = self.marker.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
||||||
code.push(instr!("rational", r, 0));
|
code.push(instr!("rational", r, 0));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -586,7 +616,15 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
|
||||||
|
let r = self.marker.mark_non_callable(
|
||||||
|
name.clone(),
|
||||||
|
1,
|
||||||
|
term_loc,
|
||||||
|
vr,
|
||||||
|
code,
|
||||||
|
);
|
||||||
|
|
||||||
code.push(instr!("float", r, 0));
|
code.push(instr!("float", r, 0));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -594,15 +632,23 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsNumber(..) => match &terms[0] {
|
&InlinedClauseType::IsNumber(..) => match &terms[0] {
|
||||||
&Term::Literal(_, Literal::Float(_))
|
&Term::Literal(_, Literal::Float(_)) |
|
||||||
| &Term::Literal(_, Literal::Rational(_))
|
&Term::Literal(_, Literal::Rational(_)) |
|
||||||
| &Term::Literal(_, Literal::Integer(_))
|
&Term::Literal(_, Literal::Integer(_)) |
|
||||||
| &Term::Literal(_, Literal::Fixnum(_)) => {
|
&Term::Literal(_, Literal::Fixnum(_)) => {
|
||||||
code.push(instr!("$succeed", 0));
|
code.push(instr!("$succeed", 0));
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
|
||||||
|
let r = self.marker.mark_non_callable(
|
||||||
|
name.clone(),
|
||||||
|
1,
|
||||||
|
term_loc,
|
||||||
|
vr,
|
||||||
|
code,
|
||||||
|
);
|
||||||
|
|
||||||
code.push(instr!("number", r, 0));
|
code.push(instr!("number", r, 0));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -615,7 +661,15 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
|
||||||
|
let r = self.marker.mark_non_callable(
|
||||||
|
name.clone(),
|
||||||
|
1,
|
||||||
|
term_loc,
|
||||||
|
vr,
|
||||||
|
code,
|
||||||
|
);
|
||||||
|
|
||||||
code.push(instr!("nonvar", r, 0));
|
code.push(instr!("nonvar", r, 0));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -623,12 +677,21 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsInteger(..) => match &terms[0] {
|
&InlinedClauseType::IsInteger(..) => match &terms[0] {
|
||||||
&Term::Literal(_, Literal::Integer(_)) | &Term::Literal(_, Literal::Fixnum(_)) => {
|
&Term::Literal(_, Literal::Integer(_)) |
|
||||||
|
&Term::Literal(_, Literal::Fixnum(_)) => {
|
||||||
code.push(instr!("$succeed", 0));
|
code.push(instr!("$succeed", 0));
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
|
||||||
|
let r = self.marker.mark_non_callable(
|
||||||
|
name.clone(),
|
||||||
|
1,
|
||||||
|
term_loc,
|
||||||
|
vr,
|
||||||
|
code,
|
||||||
|
);
|
||||||
|
|
||||||
code.push(instr!("integer", r, 0));
|
code.push(instr!("integer", r, 0));
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -636,10 +699,10 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsVar(..) => match &terms[0] {
|
&InlinedClauseType::IsVar(..) => match &terms[0] {
|
||||||
&Term::Literal(..)
|
&Term::Literal(..) |
|
||||||
| &Term::Clause(..)
|
&Term::Clause(..) |
|
||||||
| &Term::Cons(..)
|
&Term::Cons(..) |
|
||||||
| &Term::PartialString(..) => {
|
&Term::PartialString(..) => {
|
||||||
code.push(instr!("$fail", 0));
|
code.push(instr!("$fail", 0));
|
||||||
}
|
}
|
||||||
&Term::AnonVar => {
|
&Term::AnonVar => {
|
||||||
@@ -647,7 +710,15 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
&Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.mark_non_callable(name.clone(), 1, term_loc, vr, code);
|
|
||||||
|
let r = self.marker.mark_non_callable(
|
||||||
|
name.clone(),
|
||||||
|
1,
|
||||||
|
term_loc,
|
||||||
|
vr,
|
||||||
|
code,
|
||||||
|
);
|
||||||
|
|
||||||
code.push(instr!("var", r, 0));
|
code.push(instr!("var", r, 0));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -661,9 +732,10 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
term: &Term,
|
term: &Term,
|
||||||
target_int: usize,
|
target_int: usize,
|
||||||
term_loc: GenContext,
|
term_loc: GenContext,
|
||||||
|
arg: usize,
|
||||||
) -> Result<ArithCont, ArithmeticError> {
|
) -> Result<ArithCont, ArithmeticError> {
|
||||||
let mut evaluator = ArithmeticEvaluator::new(&mut self.marker, target_int);
|
let mut evaluator = ArithmeticEvaluator::new(&mut self.marker, target_int);
|
||||||
evaluator.compile_is(term, term_loc)
|
evaluator.compile_is(term, term_loc, arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_is_call(
|
fn compile_is_call(
|
||||||
@@ -675,7 +747,7 @@ impl<'b, TermMarker: Allocator> CodeGenerator<'b, TermMarker> {
|
|||||||
) -> Result<(), CompilationError> {
|
) -> Result<(), CompilationError> {
|
||||||
macro_rules! compile_expr {
|
macro_rules! compile_expr {
|
||||||
($self:expr, $terms:expr, $term_loc:expr, $code:expr) => ({
|
($self:expr, $terms:expr, $term_loc:expr, $code:expr) => ({
|
||||||
let (acode, at) = $self.compile_arith_expr(&$terms[1], 1, $term_loc)?;
|
let (acode, at) = $self.compile_arith_expr(&$terms[1], 1, $term_loc, 2)?;
|
||||||
$code.extend(acode.into_iter());
|
$code.extend(acode.into_iter());
|
||||||
at
|
at
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use crate::atom_table::*;
|
use crate::atom_table::*;
|
||||||
use crate::codegen::*;
|
use crate::codegen::*;
|
||||||
use crate::debray_allocator::*;
|
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::indexing::{merge_clause_index, remove_index};
|
use crate::indexing::{merge_clause_index, remove_index};
|
||||||
use crate::instructions::*;
|
use crate::instructions::*;
|
||||||
@@ -47,7 +46,7 @@ pub(super) fn bootstrapping_compile(
|
|||||||
|
|
||||||
// throw errors if declaration or query found.
|
// throw errors if declaration or query found.
|
||||||
pub(super) fn compile_relation(
|
pub(super) fn compile_relation(
|
||||||
cg: &mut CodeGenerator<DebrayAllocator>,
|
cg: &mut CodeGenerator,
|
||||||
tl: &TopLevel,
|
tl: &TopLevel,
|
||||||
) -> Result<Code, CompilationError> {
|
) -> Result<Code, CompilationError> {
|
||||||
match tl {
|
match tl {
|
||||||
@@ -87,7 +86,7 @@ pub(super) fn compile_appendix(
|
|||||||
non_counted_bt,
|
non_counted_bt,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(atom_tbl, settings);
|
let mut cg = CodeGenerator::new(atom_tbl, settings);
|
||||||
|
|
||||||
let tl = queue.pop_front().unwrap();
|
let tl = queue.pop_front().unwrap();
|
||||||
let decl_code = compile_relation(&mut cg, &tl)?;
|
let decl_code = compile_relation(&mut cg, &tl)?;
|
||||||
@@ -1345,7 +1344,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let clause = self.try_term_to_tl(term, &mut preprocessor)?;
|
let clause = self.try_term_to_tl(term, &mut preprocessor)?;
|
||||||
let queue = preprocessor.parse_queue(self)?;
|
let queue = preprocessor.parse_queue(self)?;
|
||||||
|
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(
|
let mut cg = CodeGenerator::new(
|
||||||
&mut LS::machine_st(&mut self.payload).atom_tbl,
|
&mut LS::machine_st(&mut self.payload).atom_tbl,
|
||||||
settings,
|
settings,
|
||||||
);
|
);
|
||||||
@@ -1388,7 +1387,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
|
|
||||||
let queue = preprocessor.parse_queue(self)?;
|
let queue = preprocessor.parse_queue(self)?;
|
||||||
|
|
||||||
let mut cg = CodeGenerator::<DebrayAllocator>::new(
|
let mut cg = CodeGenerator::new(
|
||||||
&mut LS::machine_st(&mut self.payload).atom_tbl,
|
&mut LS::machine_st(&mut self.payload).atom_tbl,
|
||||||
settings,
|
settings,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ impl Fixnum {
|
|||||||
.with_num(u64::from_ne_bytes(num.to_ne_bytes()) & ((1 << 56) - 1))
|
.with_num(u64::from_ne_bytes(num.to_ne_bytes()) & ((1 << 56) - 1))
|
||||||
.with_tag(HeapCellValueTag::Fixnum as u8)
|
.with_tag(HeapCellValueTag::Fixnum as u8)
|
||||||
.with_m(false)
|
.with_m(false)
|
||||||
//num as u64).with__m(false)
|
.with_f(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -500,6 +500,7 @@ impl Fixnum {
|
|||||||
if LOWER_BOUND <= num && num <= UPPER_BOUND {
|
if LOWER_BOUND <= num && num <= UPPER_BOUND {
|
||||||
Ok(Fixnum::new()
|
Ok(Fixnum::new()
|
||||||
.with_m(false)
|
.with_m(false)
|
||||||
|
.with_f(false)
|
||||||
.with_tag(HeapCellValueTag::Fixnum as u8)
|
.with_tag(HeapCellValueTag::Fixnum as u8)
|
||||||
.with_num(u64::from_ne_bytes(num.to_ne_bytes()) & ((1 << 56) - 1)))
|
.with_num(u64::from_ne_bytes(num.to_ne_bytes()) & ((1 << 56) - 1)))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user