summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Mikkelsen <peter@pmikkelsen.com>2021-06-30 19:33:55 +0000
committerPeter Mikkelsen <peter@pmikkelsen.com>2021-06-30 19:33:55 +0000
commita8b1fadd149126e9c8d3081a56d206812211f1e6 (patch)
tree0e841a4c080daa9e6a6697df6630a147bbef3db6
parentbaea4aa939861fd4efbc71b96f93ba890f01ac40 (diff)
Add builtins for typetests
-rw-r--r--TODO13
-rw-r--r--builtins.c142
-rw-r--r--fns.h1
-rw-r--r--misc.c8
-rw-r--r--parser.c7
-rw-r--r--prettyprint.c3
6 files changed, 160 insertions, 14 deletions
diff --git a/TODO b/TODO
index a9b0bd8..5bb5070 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,6 @@
-1) Add a repl
-2) Figure out how to print the final bindings after running a query
-3) Stop comparing strings all the time
-4) Stop copying the entire goal stack into every choicepoint
-5) Stop creating choicepoints when it is not needed
-6) How to implement builtins nicely?
-7) Right now we copy and allocate a lot, but almost never free stuff. \ No newline at end of file
+* Add a repl
+* Stop comparing strings all the time
+* Stop copying the entire goal stack into every choicepoint
+* Stop creating choicepoints when it is not needed
+* How to implement builtins nicely?
+* Right now we copy and allocate a lot, but almost never free stuff. \ No newline at end of file
diff --git a/builtins.c b/builtins.c
index b6031fe..f66cd5e 100644
--- a/builtins.c
+++ b/builtins.c
@@ -4,9 +4,21 @@
#include "dat.h"
#include "fns.h"
-int builtinfail(Term *, Term *, Goal **, Choicepoint **, Binding **);
-int builtincall(Term *, Term *, Goal **, Choicepoint **, Binding **);
-int builtincut(Term *, Term *, Goal **, Choicepoint **, Binding **);
+#define BuiltinProto(name) int name(Term *, Term *, Goal **, Choicepoint **, Binding **)
+#define Match(X, Y) (runestrcmp(name, X) == 0 && arity == Y)
+
+BuiltinProto(builtinfail);
+BuiltinProto(builtincall);
+BuiltinProto(builtincut);
+BuiltinProto(builtinvar);
+BuiltinProto(builtinatom);
+BuiltinProto(builtininteger);
+BuiltinProto(builtinfloat);
+BuiltinProto(builtinatomic);
+BuiltinProto(builtincompound);
+BuiltinProto(builtinnonvar);
+BuiltinProto(builtinnumber);
+BuiltinProto(builtinstring);
Builtin
findbuiltin(Term *goal)
@@ -27,12 +39,31 @@ findbuiltin(Term *goal)
return nil;
}
- if(!runestrcmp(name, L"fail") && arity == 0)
+ /* Rewrite this so its not just a long if chain */
+ if(Match(L"fail", 0))
return builtinfail;
- if(!runestrcmp(name, L"call") && arity == 1)
+ if(Match(L"call", 1))
return builtincall;
- if(!runestrcmp(name, L"!") && arity == 0)
+ if(Match(L"!", 0))
return builtincut;
+ if(Match(L"var", 1))
+ return builtinvar;
+ if(Match(L"atom", 1))
+ return builtinatom;
+ if(Match(L"integer", 1))
+ return builtininteger;
+ if(Match(L"float", 1))
+ return builtinfloat;
+ if(Match(L"atomic", 1))
+ return builtinatomic;
+ if(Match(L"compound", 1))
+ return builtincompound;
+ if(Match(L"nonvar", 1))
+ return builtinnonvar;
+ if(Match(L"number", 1))
+ return builtinnumber;
+ if(Match(L"string", 1))
+ return builtinstring;
return nil;
}
@@ -79,4 +110,103 @@ builtincut(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack,
cp = cp->next;
*choicestack = cp;
return 1;
+}
+
+int
+builtinvar(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ USED(bindings);
+ Term *arg = goal->children;
+ return (arg->tag == VariableTerm);
+}
+
+int
+builtinatom(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ USED(bindings);
+ Term *arg = goal->children;
+ return (arg->tag == AtomTerm);
+}
+
+int
+builtininteger(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ USED(bindings);
+ Term *arg = goal->children;
+ return (arg->tag == NumberTerm && arg->numbertype == NumberInt);
+}
+
+int
+builtinfloat(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ USED(bindings);
+ Term *arg = goal->children;
+ return (arg->tag == NumberTerm && arg->numbertype == NumberFloat);
+}
+
+int
+builtinatomic(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ USED(bindings);
+ Term *arg = goal->children;
+ return (arg->tag == AtomTerm || arg->tag == NumberTerm);
+}
+
+int
+builtincompound(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ USED(bindings);
+ Term *arg = goal->children;
+ return (arg->tag == CompoundTerm);
+}
+
+int
+builtinnonvar(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ USED(bindings);
+ Term *arg = goal->children;
+ return (arg->tag != VariableTerm);
+}
+
+int
+builtinnumber(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ USED(bindings);
+ Term *arg = goal->children;
+ return (arg->tag == NumberTerm);
+}
+
+int
+builtinstring(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings)
+{
+ USED(database);
+ USED(goals);
+ USED(choicestack);
+ USED(bindings);
+ Term *arg = goal->children;
+ return (arg->tag == StringTerm);
} \ No newline at end of file
diff --git a/fns.h b/fns.h
index d145b81..54db8dc 100644
--- a/fns.h
+++ b/fns.h
@@ -12,6 +12,7 @@ Term *mkatom(Rune *);
Term *mkvariable(Rune *);
Term *mkcompound(Rune *, int, Term *);
Term *mknumber(int, vlong, double);
+Term *mkstring(Rune *);
/* eval.c */
int evalquery(Term *, Term *, Binding **);
diff --git a/misc.c b/misc.c
index c047159..261cc99 100644
--- a/misc.c
+++ b/misc.c
@@ -90,3 +90,11 @@ mknumber(int type, vlong ival, double dval)
t->dval = dval;
return t;
}
+
+Term *
+mkstring(Rune *text)
+{
+ Term *t = mkterm(StringTerm);
+ t->text = text;
+ return t;
+} \ No newline at end of file
diff --git a/parser.c b/parser.c
index e1a7de8..577c338 100644
--- a/parser.c
+++ b/parser.c
@@ -186,8 +186,12 @@ term(void)
result = fullterm(ParenRightTok, nil, nil);
match(ParenRightTok);
break;
+ case StringTok:
+ result = mkstring(lookahead.text);
+ match(StringTok);
+ break;
default:
- print("Cant parse term of token type %d\n", lookahead.tag);
+ print("Can't parse term of token type %d\n", lookahead.tag);
syntaxerror("term");
result = nil;
}
@@ -513,6 +517,7 @@ nexttoken(void)
numD += (peek - L'0') / (10 * place);
peek = Bgetrune(parsein);
}
+ Bungetrune(parsein);
/* Should also lex 123.45E10 */
lookahead.tag = FloatTok;
lookahead.dval = negative ? -numD : numD;
diff --git a/prettyprint.c b/prettyprint.c
index fb6bcb0..bf66dc2 100644
--- a/prettyprint.c
+++ b/prettyprint.c
@@ -30,6 +30,9 @@ prettyprint(Term *t)
else
result = runesmprint("%f", t->dval);
break;
+ case StringTerm:
+ result = runesmprint("\"%S\"", t->text);
+ break;
default:
result = runesmprint("cant print term with tag %d", t->tag);
break;