shithub: pprolog

Download patch

ref: 6d3d4a2dbba8c3092b39bbb51d155b1df653ca5f
parent: 9d5c9d3fe5d8951fac0902abf125c68a6e720e52
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Tue Jul 13 14:51:22 EDT 2021

Add atom_length/2

--- a/builtins.c
+++ b/builtins.c
@@ -54,6 +54,7 @@
 BuiltinProto(builtinassertz);
 BuiltinProto(builtinretractone);
 BuiltinProto(builtinabolish);
+BuiltinProto(builtinatomlength);
 
 int compareterms(Term *, Term *);
 
@@ -151,6 +152,8 @@
 		return builtinretractone;
 	if(Match(L"abolish", 1))
 		return builtinabolish;
+	if(Match(L"atom_length", 2))
+		return builtinatomlength;
 
 	return nil;
 }
@@ -1107,4 +1110,25 @@
 		}
 	}
 	return 1;
+}
+
+int
+builtinatomlength(Term *goal, Binding **bindings, Module *module)
+{
+	USED(module);
+	Term *atom = goal->children;
+	Term *length = atom->next;
+	
+	if(atom->tag == VariableTerm)
+		Throw(instantiationerror());
+	if(atom->tag != AtomTerm)
+		Throw(typeerror(L"atom", atom));
+	if(length->tag != VariableTerm && length->tag != IntegerTerm)
+		Throw(typeerror(L"integer", length));
+	if(length->tag == IntegerTerm && length->ival < 0)
+		Throw(domainerror(L"not_less_than_zero", length));
+
+	int len = runestrlen(atom->text);
+	Term *reallength = mkinteger(len);
+	return unify(length, reallength, bindings);
 }
\ No newline at end of file