summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog28
-rw-r--r--eval.c10
-rw-r--r--gc.c12
-rw-r--r--hash.c5
-rw-r--r--lib.c134
-rw-r--r--lib.h7
-rw-r--r--match.c4
-rw-r--r--regex.c5
8 files changed, 103 insertions, 102 deletions
diff --git a/ChangeLog b/ChangeLog
index 43853836..eff28bb2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,33 @@
2012-03-17 Kaz Kylheku <kaz@kylheku.com>
+ Changing type function to not blow up on nil, which makes a lot of code
+ simpler. A pseudo type code is introduced called NIL with value 0.
+
+ * lib.h (enum type): New enumeration value, NIL.
+ (type): Function accepts object nil and maps it to code NIL.
+
+ * eval.c (dwim_loc, op_dwim): test for nil obj and goto hack is gone,
+ just handle NIL in the switch.
+
+ * gc.c (make_obj, mark): Handle new NIL type code in switch.
+
+ * hash.c (equal_hash): Handle NIL in the switch instead of nil test.
+
+ * lib.c (code2type): Map new NIL type code to null.
+ (typeof, typecheck): Code simplified.
+ (class_check, car): Move nil test into switch.
+ (eql, equal, consp, bignump, stringp, lazy_stringp,
+ symbolp, functionp, vectorp, cobjp): Simplified.
+ (length, sub, ref, refset, replace, obj_print, obj_pprint): Handle NIL
+ in switch instead of nil test. goto hack removed from refset.
+
+ * match.c (do_match_line, do_output_line): switch condition simplified.
+
+ * regex.c (regexp): Simplified.
+ (regex_nfa): Assert condition simplified.
+
+2012-03-17 Kaz Kylheku <kaz@kylheku.com>
+
* filter.c (digit_value): static function moved.
(html_hex_continue): Use digit_value instead of hex digits string
literal.
diff --git a/eval.c b/eval.c
index 6cb8721e..fcce0b2f 100644
--- a/eval.c
+++ b/eval.c
@@ -751,9 +751,6 @@ static val *dwim_loc(val form, val env, val op, val newform, val *retval)
val obj = eval_lisp1(second(form), env, form);
val args = eval_args_lisp1(rest(rest(form)), env, form);
- if (!obj)
- goto list;
-
switch (type(obj)) {
case LIT:
case STR:
@@ -839,9 +836,9 @@ static val *dwim_loc(val form, val env, val op, val newform, val *retval)
return vecref_l(obj, index);
}
}
+ case NIL:
case CONS:
case LCONS:
- list:
if (rest(args))
eval_error(form, lit("[~s ...]: list indexing needs one arg"),
obj, nao);
@@ -1102,10 +1099,9 @@ static val op_dwim(val form, val env)
val obj = eval_lisp1(second(form), env, form);
val args = eval_args_lisp1(rest(rest(form)), env, form);
- if (!obj)
- return nil;
-
switch (type(obj)) {
+ case NIL:
+ return nil;
case LIT:
case STR:
case LSTR:
diff --git a/gc.c b/gc.c
index e0697354..b2247a9b 100644
--- a/gc.c
+++ b/gc.c
@@ -184,6 +184,7 @@ val make_obj(void)
static void finalize(val obj)
{
switch (obj->t.type) {
+ case NIL:
case CONS:
return;
case STR:
@@ -256,17 +257,18 @@ tail_call:
#endif
switch (t) {
+ case NIL:
+ case CHR:
+ case NUM:
+ case LIT:
+ case BGNUM:
+ return;
case CONS:
mark_obj(obj->c.car);
mark_obj_tail(obj->c.cdr);
case STR:
mark_obj(obj->st.len);
mark_obj_tail(obj->st.alloc);
- case CHR:
- case NUM:
- case LIT:
- case BGNUM:
- return;
case SYM:
mark_obj(obj->s.name);
mark_obj(obj->s.value);
diff --git a/hash.c b/hash.c
index a00e3250..c9e69261 100644
--- a/hash.c
+++ b/hash.c
@@ -92,10 +92,9 @@ static unsigned long hash_c_str(const wchar_t *str)
static cnum equal_hash(val obj)
{
- if (obj == nil)
- return NUM_MAX;
-
switch (type(obj)) {
+ case NIL:
+ return NUM_MAX;
case LIT:
return hash_c_str(litptr(obj)) & NUM_MAX;
case CONS:
diff --git a/lib.c b/lib.c
index 7462f685..ec72754f 100644
--- a/lib.c
+++ b/lib.c
@@ -101,6 +101,7 @@ val identity(val obj)
static val code2type(int code)
{
switch ((type_t) code) {
+ case NIL: return null;
case CONS: return cons_s;
case STR: return str_s;
case LIT: return str_s;
@@ -129,25 +130,27 @@ val typeof(val obj)
case TAG_LIT:
return str_s;
case TAG_PTR:
- if (obj == nil) {
- return null;
- } else if (obj->t.type == COBJ) {
- return obj->co.cls;
- } else {
- val type = code2type(obj->t.type);
- if (!type)
- internal_error("corrupt type field");
- return type;
+ {
+ int typecode = type(obj);
+
+ if (typecode == COBJ) {
+ return obj->co.cls;
+ } else {
+ val typesym = code2type(typecode);
+ if (!typesym)
+ internal_error("corrupt type field");
+ return typesym;
+ }
}
default:
internal_error("invalid type tag");
}
}
-val type_check(val obj, int type)
+val type_check(val obj, int typecode)
{
- if (!is_ptr(obj) || obj->t.type != type)
- type_mismatch(lit("~s is not of type ~s"), obj, code2type(type), nao);
+ if (type(obj) != typecode)
+ type_mismatch(lit("~s is not of type ~s"), obj, code2type(typecode), nao);
return t;
}
@@ -177,9 +180,9 @@ val class_check(val cobj, val class_sym)
val car(val cons)
{
- if (cons == nil)
+ switch (type(cons)) {
+ case NIL:
return nil;
- else switch (type(cons)) {
case CONS:
return cons->c.car;
case LCONS:
@@ -197,9 +200,9 @@ val car(val cons)
val cdr(val cons)
{
- if (cons == nil)
+ switch (type(cons)) {
+ case NIL:
return nil;
- else switch (type(cons)) {
case CONS:
return cons->c.cdr;
case LCONS:
@@ -803,24 +806,18 @@ val eql(val left, val right)
/* eql is same as eq for now, but when we get bignums,
eql will compare different bignum objects which are
the same number as equal. */
- if (is_ptr(left) && type(left) == BGNUM)
+ if (type(left) == BGNUM)
return equal(left, right);
return eq(left, right);
}
val equal(val left, val right)
{
- /* Bitwise equality is equality, period. */
if (left == right)
return t;
- /* Objects are not bitwise equal. If either
- is nil, then they are not equal,
- since nil uses bitwise equality. */
- if (left == nil || right == nil)
- return nil;
-
switch (type(left)) {
+ case NIL:
case CHR:
case NUM:
return nil;
@@ -1014,12 +1011,8 @@ val list(val first, ...)
val consp(val obj)
{
- if (!obj) {
- return nil;
- } else {
- type_t ty = type(obj);
- return (ty == CONS || ty == LCONS) ? t : nil;
- }
+ type_t ty = type(obj);
+ return (ty == CONS || ty == LCONS) ? t : nil;
}
val nullp(val obj)
@@ -1135,7 +1128,7 @@ val fixnump(val num)
val bignump(val num)
{
- return (is_ptr(num) && type(num) == BGNUM) ? t : nil;
+ return (type(num) == BGNUM) ? t : nil;
}
val numberp(val num)
@@ -1399,25 +1392,19 @@ val string_extend(val str, val tail)
val stringp(val str)
{
- switch (tag(str)) {
- case TAG_LIT:
+ switch (type(str)) {
+ case LIT:
+ case STR:
+ case LSTR:
return t;
- case TAG_PTR:
- if (str == nil)
- return nil;
- switch (type(str)) {
- case STR: case LSTR:
- return t;
- default:
- break;
- }
+ default:
+ return nil;
}
- return nil;
}
val lazy_stringp(val str)
{
- return (is_ptr(str) && (type(str) == LSTR)) ? t : nil;
+ return type(str) == LSTR ? t : nil;
}
val length_str(val str)
@@ -2192,7 +2179,13 @@ static val rehome_sym(val sym, val package)
val symbolp(val sym)
{
- return (sym == nil || (is_ptr(sym) && sym->s.type == SYM)) ? t : nil;
+ switch (type(sym)) {
+ case NIL:
+ case SYM:
+ return t;
+ default:
+ return nil;
+ }
}
val keywordp(val sym)
@@ -2525,12 +2518,7 @@ val func_get_env(val fun)
val functionp(val obj)
{
- if (!obj) {
- return nil;
- } else {
- type_t ty = type(obj);
- return (ty == FUN) ? t : nil;
- }
+ return type(obj) == FUN ? t : nil;
}
val interp_fun_p(val obj)
@@ -2966,7 +2954,7 @@ val vector(val length)
val vectorp(val vec)
{
- return (is_ptr(vec) && type(vec) == VEC) ? t : nil;
+ return type(vec) == VEC ? t : nil;
}
val vec_set_length(val vec, val length)
@@ -3448,12 +3436,7 @@ val cobj(mem_t *handle, val cls_sym, struct cobj_ops *ops)
val cobjp(val obj)
{
- if (!obj) {
- return nil;
- } else {
- type_t ty = type(obj);
- return (ty == COBJ) ? t : nil;
- }
+ return type(obj) == COBJ ? t : nil;
}
mem_t *cobj_handle(val cobj, val cls_sym)
@@ -3823,9 +3806,9 @@ val set_diff(val list1, val list2, val testfun, val keyfun)
val length(val seq)
{
- if (seq == nil)
+ switch (type(seq)) {
+ case NIL:
return num(0);
- else switch (type(seq)) {
case CONS:
case LCONS:
return length_list(seq);
@@ -3841,9 +3824,9 @@ val length(val seq)
val sub(val seq, val from, val to)
{
- if (seq == nil)
+ switch (type(seq)) {
+ case NIL:
return nil;
- else switch (type(seq)) {
case CONS:
case LCONS:
return sub_list(seq, from, to);
@@ -3859,9 +3842,9 @@ val sub(val seq, val from, val to)
val ref(val seq, val ind)
{
- if (seq == nil)
+ switch (type(seq)) {
+ case NIL:
return nil;
- else switch (type(seq)) {
case CONS:
case LCONS:
return listref(seq, ind);
@@ -3877,13 +3860,10 @@ val ref(val seq, val ind)
val refset(val seq, val ind, val newval)
{
- if (seq == nil)
- goto list;
-
- else switch (type(seq)) {
+ switch (type(seq)) {
+ case NIL:
case CONS:
case LCONS:
- list:
return *listref_l(seq, ind) = newval;
case LIT:
case STR:
@@ -3898,12 +3878,10 @@ val refset(val seq, val ind, val newval)
val replace(val seq, val items, val from, val to)
{
- if (seq == nil)
- goto list;
switch (type(seq)) {
+ case NIL:
case CONS:
case LCONS:
- list:
return replace_list(seq, items, from, to);
case LIT:
case STR:
@@ -4087,12 +4065,10 @@ val obj_print(val obj, val out)
if (out == nil)
out = std_output;
- if (obj == nil) {
+ switch (type(obj)) {
+ case NIL:
put_string(lit("nil"), out);
return obj;
- }
-
- switch (type(obj)) {
case CONS:
case LCONS:
{
@@ -4243,12 +4219,10 @@ val obj_pprint(val obj, val out)
if (out == nil)
out = std_output;
- if (obj == nil) {
+ switch (type(obj)) {
+ case NIL:
put_string(lit("nil"), out);
return obj;
- }
-
- switch (type(obj)) {
case CONS:
case LCONS:
{
diff --git a/lib.h b/lib.h
index dae6c755..e33667a4 100644
--- a/lib.h
+++ b/lib.h
@@ -38,7 +38,7 @@ typedef int_ptr_t cnum;
#define NUM_MIN (INT_PTR_MIN/4)
typedef enum type {
- NUM = TAG_NUM, CHR = TAG_CHR, LIT = TAG_LIT, CONS,
+ NIL, NUM = TAG_NUM, CHR = TAG_CHR, LIT = TAG_LIT, CONS,
STR, SYM, PKG, FUN, VEC, LCONS, LSTR, COBJ, ENV,
BGNUM
} type_t;
@@ -216,7 +216,10 @@ INLINE int is_lit(val obj) { return tag(obj) == TAG_LIT; }
INLINE type_t type(val obj)
{
- return tag(obj) ? (type_t) tag(obj) : obj->t.type;
+ return obj ? tag(obj)
+ ? (type_t) tag(obj)
+ : obj->t.type
+ : NIL;
}
typedef struct wli wchli_t;
diff --git a/match.c b/match.c
index f381dcd4..cad32714 100644
--- a/match.c
+++ b/match.c
@@ -1112,7 +1112,7 @@ static val do_match_line(match_line_ctx *c, val completely)
debug_check(elem, c->bindings, c->dataline, c->data_lineno,
c->pos, c->base);
- switch (elem ? type(elem) : 0) {
+ switch (type(elem)) {
case CONS: /* directive */
{
val directive = first(elem);
@@ -1583,7 +1583,7 @@ static void do_output_line(val bindings, val specline, val filter, val out)
for (; specline; specline = rest(specline)) {
val elem = first(specline);
- switch (elem ? type(elem) : 0) {
+ switch (type(elem)) {
case CONS:
{
val directive = first(elem);
diff --git a/regex.c b/regex.c
index 9d07f411..2fc08c64 100644
--- a/regex.c
+++ b/regex.c
@@ -1511,13 +1511,12 @@ val regexp(val obj)
if (consp(obj))
return if2(eq(car(obj), compiled_regex_s), t);
- return (is_ptr(obj) && obj->co.type == COBJ && obj->co.cls == regex_s)
- ? t : nil;
+ return typeof(obj) == regex_s ? t : nil;
}
static nfa_t *regex_nfa(val reg)
{
- assert (reg->co.type == COBJ && reg->co.cls == regex_s);
+ assert (typeof(reg) == regex_s);
return (nfa_t *) reg->co.handle;
}