diff options
author | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-07-16 14:19:24 +0000 |
---|---|---|
committer | Peter Mikkelsen <peter@pmikkelsen.com> | 2021-07-16 14:19:24 +0000 |
commit | ee65a81ee5b0112ba4480619ca672c569fb28b45 (patch) | |
tree | 974d03d92ef1b0d1f0badcf2986382236b5d905e /builtins.c | |
parent | 1c8789198373a52da9e80dc9b2b1ee2b67af61c4 (diff) |
Add character input/output
Diffstat (limited to 'builtins.c')
-rw-r--r-- | builtins.c | 123 |
1 files changed, 122 insertions, 1 deletions
@@ -56,6 +56,10 @@ BuiltinProto(builtinretractone); BuiltinProto(builtinabolish); BuiltinProto(builtinatomlength); BuiltinProto(builtinatomcodes); +BuiltinProto(builtingetchar); +BuiltinProto(builtinpeekchar); +BuiltinProto(builtinputchar); +BuiltinProto(builtincharcode); int compareterms(Term *, Term *); @@ -157,6 +161,14 @@ findbuiltin(Term *goal) return builtinatomlength; if(Match(L"atom_codes", 2)) return builtinatomcodes; + if(Match(L"get_char", 2)) + return builtingetchar; + if(Match(L"peek_char", 2)) + return builtinpeekchar; + if(Match(L"put_char", 2)) + return builtinputchar; + if(Match(L"char_code", 2)) + return builtincharcode; return nil; } @@ -1282,4 +1294,113 @@ builtinatomcodes(Term *goal, Binding **bindings, Module *module) Term *realatom = mkatom(buf); return unify(atom, realatom, bindings); } -}
\ No newline at end of file +} + +int +builtingetchar(Term *goal, Binding **bindings, Module *module) +{ + USED(module); + Term *s = goal->children; + Term *ch = s->next; + + if(s->tag == VariableTerm) + Throw(instantiationerror()); + if(ch->tag != VariableTerm && !(ch->tag == AtomTerm && runestrlen(ch->text) == 1)) + Throw(typeerror(L"in_character", ch)); + if(s->tag != IntegerTerm && s->tag != AtomTerm) + Throw(domainerror(L"stream_or_alias", s)); + if(!isopenstream(s)) + Throw(existenceerror(L"stream", s)); + if(isoutputstream(s)) + Throw(permissionerror(L"input", L"stream", s)); + if(isbinarystream(s)) + Throw(permissionerror(L"input", L"binary_stream", s)); + + Rune r = getchar(s); + Term *realch; + if(r == Beof) + realch = mkatom(L"end_of_file"); + else + realch = mkatom(runesmprint("%C", r)); + return unify(ch, realch, bindings); +} + +int +builtinpeekchar(Term *goal, Binding **bindings, Module *module) +{ + USED(module); + Term *s = goal->children; + Term *ch = s->next; + + if(s->tag == VariableTerm) + Throw(instantiationerror()); + if(ch->tag != VariableTerm && !(ch->tag == AtomTerm && runestrlen(ch->text) == 1)) + Throw(typeerror(L"in_character", ch)); + if(s->tag != IntegerTerm && s->tag != AtomTerm) + Throw(domainerror(L"stream_or_alias", s)); + if(!isopenstream(s)) + Throw(existenceerror(L"stream", s)); + if(isoutputstream(s)) + Throw(permissionerror(L"input", L"stream", s)); + if(isbinarystream(s)) + Throw(permissionerror(L"input", L"binary_stream", s)); + + Rune r = peekchar(s); + Term *realch; + if(r == Beof) + realch = mkatom(L"end_of_file"); + else + realch = mkatom(runesmprint("%C", r)); + return unify(ch, realch, bindings); +} + +int +builtinputchar(Term *goal, Binding **bindings, Module *module) +{ + USED(module); + USED(bindings); + Term *s = goal->children; + Term *ch = s->next; + + if(s->tag == VariableTerm || ch->tag == VariableTerm) + Throw(instantiationerror()); + if(ch->tag != AtomTerm || runestrlen(ch->text) != 1) + Throw(typeerror(L"character", ch)); + if(s->tag != IntegerTerm && s->tag != AtomTerm) + Throw(domainerror(L"stream_or_alias", s)); + if(!isopenstream(s)) + Throw(existenceerror(L"stream", s)); + if(!isoutputstream(s)) + Throw(permissionerror(L"output", L"stream", s)); + if(isbinarystream(s)) + Throw(permissionerror(L"output", L"binary_stream", s)); + + putchar(s, ch->text[0]); + return 1; +} + +int +builtincharcode(Term *goal, Binding **bindings, Module *module) +{ + USED(module); + Term *ch = goal->children; + Term *code = ch->next; + + if(ch->tag == VariableTerm && code->tag == VariableTerm) + Throw(instantiationerror()); + if(ch->tag != VariableTerm && !(ch->tag == AtomTerm && runestrlen(ch->text) == 1)) + Throw(typeerror(L"character", ch)); + if(code->tag != VariableTerm && code->tag != IntegerTerm) + Throw(typeerror(L"integer", code)); + if(code->ival < 0) + Throw(representationerror(L"character_code")); + + if(ch->tag == VariableTerm){ + Term *realch = mkatom(runesmprint("%C", (Rune)code->ival)); + return unify(ch, realch, bindings); + }else{ + Term *realcode = mkinteger(ch->text[0]); + return unify(code, realcode, bindings); + } +} + |