diff options
author | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-07-03 18:58:07 +0000 |
---|---|---|
committer | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-07-03 18:58:07 +0000 |
commit | 7db38904537603dabe960f32fa505e27db89e27b (patch) | |
tree | 46ea8abfcc0656a7442363979838f5fa8f9c95a5 /builtins.c | |
parent | d81447526cde6fa98dfa792a65f71acb78ef1398 (diff) |
Start adding support for read_term and write_term
Diffstat (limited to 'builtins.c')
-rw-r--r-- | builtins.c | 76 |
1 files changed, 72 insertions, 4 deletions
@@ -1,5 +1,6 @@ #include <u.h> #include <libc.h> +#include <bio.h> #include "dat.h" #include "fns.h" @@ -41,6 +42,8 @@ BuiltinProto(builtincurrentinput); BuiltinProto(builtincurrentoutput); BuiltinProto(builtinsetinput); BuiltinProto(builtinsetoutput); +BuiltinProto(builtinreadterm); +BuiltinProto(builtinwriteterm); int compareterms(Term *, Term *); @@ -116,6 +119,10 @@ findbuiltin(Term *goal) return builtinsetinput; if(Match(L"set_output", 1)) return builtinsetoutput; + if(Match(L"read_term", 3)) + return builtinreadterm; + if(Match(L"write_term", 3)) + return builtinwriteterm; return nil; } @@ -536,7 +543,7 @@ builtinthrow(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack Term *ball = goal->children; - print("Throwing: %S\n", prettyprint(ball)); + print("Throwing: %S\n", prettyprint(ball, 0, 0, 0)); Goal *g; for(g = *goals; g != nil; g = g->next){ if(g->catcher == nil) @@ -545,7 +552,7 @@ builtinthrow(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack if(unify(g->catcher, ball, bindings)){ if(g->goal == nil){ /* As soon as we have print facilities as builtins, we can avoid this by having the protector frame have a unhandled exception handler*/ - print("Unhandled exception: %S\n", prettyprint(ball)); + print("Unhandled exception: %S\n", prettyprint(ball, 0, 0, 0)); exits("exception"); return 0; }else{ @@ -727,7 +734,6 @@ int builtinsetoutput(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings) { USED(database); - USED(goal); USED(goals); USED(choicestack); USED(bindings); @@ -747,4 +753,66 @@ builtinsetoutput(Term *database, Term *goal, Goal **goals, Choicepoint **choices setcurrentoutputstream(stream); return 1; -}
\ No newline at end of file +} + +int +builtinreadterm(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings) +{ + USED(database); + USED(goals); + USED(choicestack); + USED(bindings); + + Term *stream = goal->children; + Term *term = stream->next; + Term *options = term->next; + + if(stream->tag == VariableTerm) + Throw(instantiationerror()); + if(options->tag != AtomTerm || runestrcmp(options->text, L"[]") != 0) + Throw(typeerror(L"empty_list", options)); + if((stream->tag != NumberTerm || stream->numbertype != NumberInt) && stream->tag != AtomTerm) + Throw(domainerror(L"stream_or_alias", stream)); + if(!isopenstream(stream)) + Throw(existenceerror(L"stream", stream)); + if(isoutputstream(stream)) + Throw(permissionerror(L"input", L"stream", stream)); + if(isbinarystream(stream)) + Throw(permissionerror(L"input", L"binary_stream", stream)); + + Term *realterm; + int error = readterm(stream, options, &realterm); + if(error) + Throw(realterm); + + return unify(term, realterm, bindings); +} + +int +builtinwriteterm(Term *database, Term *goal, Goal **goals, Choicepoint **choicestack, Binding **bindings) +{ + USED(database); + USED(goals); + USED(choicestack); + USED(bindings); + + Term *stream = goal->children; + Term *term = stream->next; + Term *options = term->next; + + if(stream->tag == VariableTerm) + Throw(instantiationerror()); + if(options->tag != AtomTerm || runestrcmp(options->text, L"[]") != 0) + Throw(typeerror(L"empty_list", options)); + if((stream->tag != NumberTerm || stream->numbertype != NumberInt) && stream->tag != AtomTerm) + Throw(domainerror(L"stream_or_alias", stream)); + if(!isopenstream(stream)) + Throw(existenceerror(L"stream", stream)); + if(isinputstream(stream)) + Throw(permissionerror(L"output", L"stream", stream)); + if(isbinarystream(stream)) + Throw(permissionerror(L"output", L"binary_stream", stream)); + writeterm(stream, options, term); + return 1; +} + |