summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <peter@pmikkelsen.com>2021-07-13 19:57:49 +0000
committerPeter Mikkelsen <peter@pmikkelsen.com>2021-07-13 19:57:49 +0000
commit9fd0e7fc78740ec3a0a1a5e97d571d0f9d02b85a (patch)
treef33ed13355fa786220cb16c406f332848d5d0265
parent6d3d4a2dbba8c3092b39bbb51d155b1df653ca5f (diff)
Add atom_codes/2
-rw-r--r--builtins.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/builtins.c b/builtins.c
index 6c2c16a..913de1e 100644
--- a/builtins.c
+++ b/builtins.c
@@ -55,6 +55,7 @@ BuiltinProto(builtinassertz);
BuiltinProto(builtinretractone);
BuiltinProto(builtinabolish);
BuiltinProto(builtinatomlength);
+BuiltinProto(builtinatomcodes);
int compareterms(Term *, Term *);
@@ -154,6 +155,8 @@ findbuiltin(Term *goal)
return builtinabolish;
if(Match(L"atom_length", 2))
return builtinatomlength;
+ if(Match(L"atom_codes", 2))
+ return builtinatomcodes;
return nil;
}
@@ -1131,4 +1134,47 @@ builtinatomlength(Term *goal, Binding **bindings, Module *module)
int len = runestrlen(atom->text);
Term *reallength = mkinteger(len);
return unify(length, reallength, bindings);
+}
+
+int
+builtinatomcodes(Term *goal, Binding **bindings, Module *module)
+{
+ USED(module);
+ Term *atom = goal->children;
+ Term *list = atom->next;
+
+ if(atom->tag == VariableTerm && ispartiallist(list))
+ Throw(instantiationerror());
+ if(atom->tag != VariableTerm && atom->tag != AtomTerm)
+ Throw(typeerror(L"atom", atom));
+ if(atom->tag == VariableTerm && !(islist(list) || ispartiallist(list)))
+ Throw(typeerror(L"list", list));
+
+ if(atom->tag == AtomTerm){
+ int oldflag = flagdoublequotes;
+ flagdoublequotes = DoubleQuotesCodes;
+ Term *reallist = mkstring(atom->text);
+ flagdoublequotes = oldflag;
+ return unify(list, reallist, bindings);
+ }else{
+ int bufsize = 2048;
+ Rune *buf = malloc(sizeof(Rune) * bufsize);
+ int i = 0;
+ Term *c;
+ for(c = list; c->tag == CompoundTerm; c = c->children->next, i++){
+ if(i >= bufsize){
+ bufsize += 2048;
+ buf = realloc(buf, sizeof(Rune) * bufsize);
+ }
+
+ if(c->children->tag == VariableTerm)
+ Throw(instantiationerror());
+ if(c->children->tag != IntegerTerm)
+ Throw(representationerror(L"character_code"));
+ buf[i] = c->children->ival;
+ }
+ buf[i] = '\0';
+ Term *realatom = mkatom(buf);
+ return unify(atom, realatom, bindings);
+ }
} \ No newline at end of file