]> Repositorios git - scryer-prolog.git/commitdiff
add error.pl, correct numbervars/3
authorMark Thom <[email protected]>
Fri, 28 Sep 2018 04:40:23 +0000 (22:40 -0600)
committerMark Thom <[email protected]>
Fri, 28 Sep 2018 04:40:23 +0000 (22:40 -0600)
src/prolog/lib/error.pl [new file with mode: 0644]
src/prolog/lib/terms.pl
src/prolog/machine/mod.rs

diff --git a/src/prolog/lib/error.pl b/src/prolog/lib/error.pl
new file mode 100644 (file)
index 0000000..f58a3d9
--- /dev/null
@@ -0,0 +1,84 @@
+:- module(error, [must_be/2, can_be/2]).
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+   Written September 2018 by Markus Triska ([email protected])
+   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), _)).
index 8e87b97540c1df0e2dc91e70d2f6537dbc3968b4..35cefa4b4849ee69adb18cbda6c2214bb4ba3088 100644 (file)
@@ -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) :-
index 8b71383d3e945ffb5f459ff0164e6cfe786f7f26..e9249983842e65a224146e8f1e712d1558f92aa0 100644 (file)
@@ -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