From a8b1fadd149126e9c8d3081a56d206812211f1e6 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Wed, 30 Jun 2021 19:33:55 +0000 Subject: Add builtins for typetests --- TODO | 13 +++--- builtins.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- fns.h | 1 + misc.c | 8 ++++ parser.c | 7 ++- prettyprint.c | 3 ++ 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; -- cgit v1.2.3