summaryrefslogtreecommitdiff
path: root/builtins.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtins.c')
-rw-r--r--builtins.c76
1 files changed, 72 insertions, 4 deletions
diff --git a/builtins.c b/builtins.c
index 46b761b..0fede28 100644
--- a/builtins.c
+++ b/builtins.c
@@ -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;
+}
+