From 4f14d3a2ded6137c5dd6449f4ec2d566947c4157 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 26 Feb 2016 22:42:09 -0800 Subject: Place C standard I/O based streams into subtype. * lib.c (subtypep): Handle subtype check here between stream and stdio-stream as a special case, since streams aren't structures related by inheritance, but built-ins. (class_check): If the type of obj doesn't match the class exactly, use a subtypep check. We need this because stream functions use this check, and stdio streams are not of the stream type now. * stream.c (stdio_stream_s): New global symbol variable. (make_stdio_stream_common): Use stdio_stream_s symbol for the type of stdio streams. (stream_init): Intern the stdio-stream symbol, and store in stdio_stream_s variable. (streamp): Replace exact check with typep. * stream.h (stdio_stream_s): Declared. --- lib.c | 4 +++- stream.c | 7 +++++-- stream.h | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib.c b/lib.c index 817f9449..2f8440e3 100644 --- a/lib.c +++ b/lib.c @@ -222,6 +222,8 @@ val subtypep(val sub, val sup) sub == list_s); } else if (sup == string_s) { return tnil(sub == str_s || sub == lit_s || sub == lstr_s); + } else if (sup == stream_s) { + return tnil(sub == stdio_stream_s); } else { val sub_struct = find_struct_type(sub); val sup_struct = find_struct_type(sup); @@ -269,7 +271,7 @@ val type_check3(val obj, int t1, int t2, int t3) val class_check(val cobj, val class_sym) { type_assert (is_ptr(cobj) && cobj->t.type == COBJ && - cobj->co.cls == class_sym, + (cobj->co.cls == class_sym || subtypep(cobj->co.cls, class_sym)), (lit("~s is not of type ~s"), cobj, class_sym, nao)); return t; } diff --git a/stream.c b/stream.c index 7d35e7e1..2fd6b301 100644 --- a/stream.c +++ b/stream.c @@ -71,6 +71,8 @@ val from_start_k, from_current_k, from_end_k; val real_time_k, name_k, fd_k; val format_s; +val stdio_stream_s; + void strm_base_init(struct strm_base *s) { static struct strm_base init = { indent_off, 60, 10, 0, 0 }; @@ -1106,7 +1108,7 @@ static val set_mode_props(const struct stdio_mode m, val stream) static val make_stdio_stream_common(FILE *f, val descr, struct cobj_ops *ops) { struct stdio_handle *h = coerce(struct stdio_handle *, chk_malloc(sizeof *h)); - val stream = cobj(coerce(mem_t *, h), stream_s, ops); + val stream = cobj(coerce(mem_t *, h), stdio_stream_s, ops); strm_base_init(&h->a); h->f = f; h->descr = descr; @@ -2096,7 +2098,7 @@ val record_adapter(val regex, val stream) val streamp(val obj) { - return typeof(obj) == stream_s ? t : nil; + return typep(obj, stream_s); } val stream_set_prop(val stream, val ind, val prop) @@ -3482,6 +3484,7 @@ void stream_init(void) name_k = intern(lit("name"), keyword_package); fd_k = intern(lit("fd"), keyword_package); format_s = intern(lit("format"), user_package); + stdio_stream_s = intern(lit("stdio-stream"), user_package); reg_var(stdin_s = intern(lit("*stdin*"), user_package), make_stdio_stream(stdin, lit("stdin"))); diff --git a/stream.h b/stream.h index d6abfc21..0891d9bc 100644 --- a/stream.h +++ b/stream.h @@ -88,6 +88,8 @@ extern val from_start_k, from_current_k, from_end_k; extern val real_time_k, name_k, fd_k; extern val format_s; +extern val stdio_stream_s; + extern val stdin_s, stdout_s, stddebug_s, stderr_s, stdnull_s; extern val print_flo_precision_s, print_flo_digits_s, print_flo_format_s; -- cgit v1.2.3