diff options
-rw-r--r-- | TODO | 13 | ||||
-rw-r--r-- | builtins.c | 142 | ||||
-rw-r--r-- | fns.h | 1 | ||||
-rw-r--r-- | misc.c | 8 | ||||
-rw-r--r-- | parser.c | 7 | ||||
-rw-r--r-- | prettyprint.c | 3 |
6 files changed, 160 insertions, 14 deletions
@@ -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 @@ -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 @@ -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 **); @@ -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 @@ -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; |