From a97987c20b9e8c4d756ead6373a8b228d00f8cb5 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Thu, 27 Sep 2018 22:40:23 -0600 Subject: [PATCH] add error.pl, correct numbervars/3 --- src/prolog/lib/error.pl | 84 +++++++++++++++++++++++++++++++++++++++ src/prolog/lib/terms.pl | 13 +++--- src/prolog/machine/mod.rs | 2 + 3 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 src/prolog/lib/error.pl diff --git a/src/prolog/lib/error.pl b/src/prolog/lib/error.pl new file mode 100644 index 00000000..f58a3d90 --- /dev/null +++ b/src/prolog/lib/error.pl @@ -0,0 +1,84 @@ +:- module(error, [must_be/2, can_be/2]). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Written September 2018 by Markus Triska (triska@metalevel.at) + I place this code in the public domain. Use it in any way you want. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + must_be(Type, Term) + + This predicate is intended for type-checks of built-in predicates. + + It asserts that Term is: + + 1) instantiated *and* + 2) instantiated to an instance of the given Type. + + It corresponds to usage mode +Term. + + Currently, the following types are supported: + + - integer + - atom + - list. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +must_be(Type, Term) :- + must_be_(Type, Term). + + +must_be_(Type, _) :- + var(Type), + instantiation_error(Type). +must_be_(integer, Term) :- check_(integer, integer, Term). +must_be_(atom, Term) :- check_(atom, atom, Term). +must_be_(list, Term) :- check_(ilist, list, Term). + +check_(Pred, Type, Term) :- + ( var(Term) -> instantiation_error(Term) + ; call(Pred, Term) -> true + ; type_error(Type, Term) + ). + +ilist(V) :- var(V), instantiation_error(V). +ilist([]). +ilist([_|Ls]) :- ilist(Ls). + + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + can_be(Type, Term) + + This predicate is intended for type-checks of built-in predicates. + + It asserts that: + + 1) Term is either a variable or instantiated *and* + 2) _if_ it is instantiated, then it is an instance of Type. + + It corresponds to usage mode ?Term. + + It supports the same types as must_be/2. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +can_be(Type, Term) :- + ( var(Term) -> true + ; must_be(Type, Term) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Shorthands for throwing ISO errors. +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + +instantiation_error(_Term) :- + throw(error(instantiation_error, _)). + +domain_error(Type, Term) :- + throw(error(domain_error(Type, Term), _)). + +type_error(Type, Term) :- + throw(error(type_error(Type, Term), _)). diff --git a/src/prolog/lib/terms.pl b/src/prolog/lib/terms.pl index 8e87b975..35cefa4b 100644 --- a/src/prolog/lib/terms.pl +++ b/src/prolog/lib/terms.pl @@ -1,9 +1,12 @@ -:- module(terms, [numbervars/2]). +:- module(terms, [numbervars/3]). -numbervars(Term, N) :- - integer(N), - term_variables(Term, Vars), - numberlist(Vars, N, N1). +:- use_module(library(error)). + +numbervars(Term, N0, N) :- + must_be(integer, N0), + can_be(integer, N), + term_variables(Term, Vars), + numberlist(Vars, N0,N). numberlist([], N,N). numberlist(['$VAR'(N0)|Vars], N0,N) :- diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 8b71383d..e9249983 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -120,6 +120,7 @@ impl<'a> SubModuleUser for MachineCodeIndices<'a> { static LISTS: &str = include_str!("../lib/lists.pl"); static CONTROL: &str = include_str!("../lib/control.pl"); static QUEUES: &str = include_str!("../lib/queues.pl"); +static ERROR: &str = include_str!("../lib/error.pl"); static TERMS: &str = include_str!("../lib/terms.pl"); impl Machine { @@ -144,6 +145,7 @@ impl Machine { compile_user_module(&mut wam, LISTS.as_bytes()); compile_user_module(&mut wam, CONTROL.as_bytes()); compile_user_module(&mut wam, QUEUES.as_bytes()); + compile_user_module(&mut wam, ERROR.as_bytes()); compile_user_module(&mut wam, TERMS.as_bytes()); wam -- 2.54.0