scryer-prolog 0.8.81

A modern Prolog implementation written mostly in Rust.
use l3::ast::*;

use std::cell::Cell;

grammar;

pub TopLevel: TopLevel = {
    "?-" <t:Term> "." => TopLevel::Query(t),
    <Predicate> => TopLevel::Predicate(<>),
    <Rule>  "." => TopLevel::Rule(<>),
    <Term>  "." => TopLevel::Fact(<>)    
};

Atom : Atom = {
    r"[a-z][a-z0-9_]*" => <>.trim().to_string(),
};

BoxedTerm : Box<Term> = {
    <t:Term> => Box::new(t)
};

Clause : Term = {
    <a:Atom> "(" <ts: (<BoxedTerm> ",")*> <t:BoxedTerm> ")" => {
     	let mut ts = ts;
     	ts.push(t);
	Term::Clause(Cell::new(RegType::Temp(0)), a, ts)
    }
};

Predicate : Vec<PredicateClause> = {
    <pcs: (<PredicateClause>)+> <pc: PredicateClause> => {
        let mut pcs = pcs;
	pcs.push(pc);
	pcs
    }  
};

PredicateClause : PredicateClause = {
    <Rule> "." => PredicateClause::Rule(<>),
    <Term> "." => PredicateClause::Fact(<>)
};

Rule : Rule = {
    <c:Clause> ":-" <h:Term> <cs: ("," <Term>)*> =>
         Rule { head: (c, h), clauses: cs },
    <a:Atom> ":-" <h:Term> <cs: ("," <Term>)*> =>
         Rule { head: (Term::Atom(Cell::new(RegType::Temp(0)), a), h),
	        clauses: cs }
};

Term : Term = {
    <Clause> => <>,
    <Atom>   => Term::Atom(Cell::new(RegType::Temp(0)), <>),
    <Var>    => Term::Var(Cell::new(VarReg::Norm(RegType::Temp(0))), <>)
};

Var : Var = {
    r"[A-Z][a-z0-9_]*" => <>.trim().to_string(),
};