Skip to content

Commit ace8ad3

Browse files
committed
Coerce eq and string=.
Fix regression in prim_minus
1 parent 3b305e8 commit ace8ad3

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

src/minilisp.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -674,11 +674,24 @@ static Obj *PRIM_OP(void *root, Obj **env, Obj **list) { \
674674

675675
// (+ <integer> ...)
676676
PRIM_ARITHMETIC_OP(prim_plus, +, += )
677-
PRIM_ARITHMETIC_OP(prim_minus, -, -= )
678677
PRIM_ARITHMETIC_OP(prim_mult, *, *= )
679678
PRIM_ARITHMETIC_OP(prim_div , /, /= )
680679
PRIM_ARITHMETIC_OP(prim_modulo, %, %= )
681680

681+
// (- <integer> ...)
682+
static Obj *prim_minus(void *root, Obj **env, Obj **list) {
683+
Obj *args = eval_list(root, env, list);
684+
for (Obj *p = args; p != Nil; p = p->cdr)
685+
if (p->car->type != TINT)
686+
error("- takes only numbers", (*list)->line_num);
687+
if (args->cdr == Nil)
688+
return make_int(root, -args->car->value);
689+
long long r = args->car->value;
690+
for (Obj *p = args->cdr; p != Nil; p = p->cdr)
691+
r -= p->car->value;
692+
return make_int(root, r);
693+
}
694+
682695
// (op <integer> <integer>)
683696
#define PRIM_COMPARISON_OP(PRIM_OP, OP) \
684697
static Obj *PRIM_OP(void *root, Obj **env, Obj **list) { \
@@ -860,9 +873,17 @@ static Obj *prim_if(void *root, Obj **env, Obj **list) {
860873
// (eq expr expr)
861874
static Obj *prim_eq(void *root, Obj **env, Obj **list) {
862875
if (length(*list) != 2)
863-
error("Malformed eq", (*list)->line_num);
876+
error("eq takes 2 arguments only", (*list)->line_num);
864877
Obj *values = eval_list(root, env, list);
865-
return values->car == values->cdr->car ? True : Nil;
878+
Obj *first = values->car;
879+
Obj *second = values->cdr->car;
880+
if (first->type == TSTRING){
881+
if (second->type == TSTRING)
882+
return strcmp(first->name, second->name) == 0 ? True : Nil;
883+
else
884+
error("The 2 arguments of eq must be of the same type", (*list)->line_num);
885+
}
886+
return first == second ? True : Nil;
866887
}
867888

868889
// String primitives
@@ -931,18 +952,6 @@ static Obj *prim_string_to_symbol(void *root, Obj **env, Obj **list) {
931952
return intern(root, args->car->name);
932953
}
933954

934-
// String comparison
935-
static Obj *prim_string_eq(void *root, Obj **env, Obj **list) {
936-
Obj *args = eval_list(root, env, list);
937-
if (length(args) != 2)
938-
error("string= requires 2 arguments", (*list)->line_num);
939-
940-
if (args->car->type != TSTRING || args->cdr->car->type != TSTRING)
941-
error("string= arguments must be strings", (*list)->line_num);
942-
943-
return strcmp(args->car->name, args->cdr->car->name) == 0 ? True : Nil;
944-
}
945-
946955
static void add_primitive(void *root, Obj **env, char *name, Primitive *fn) {
947956
DEFINE2(sym, prim);
948957
*sym = intern(root, name);
@@ -994,7 +1003,6 @@ static void define_primitives(void *root, Obj **env) {
9941003
add_primitive(root, env, "string-concat", prim_string_concat);
9951004
add_primitive(root, env, "symbol->string", prim_symbol_to_string);
9961005
add_primitive(root, env, "string->symbol", prim_string_to_symbol);
997-
add_primitive(root, env, "string=", prim_string_eq);
9981006
add_primitive(root, env, "load", prim_load);
9991007
add_primitive(root, env, "exit", prim_exit);
10001008
}

test.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ run eq t "(eq 'foo 'foo)"
146146
run eq t "(eq + +)"
147147
run eq '()' "(eq 'foo 'bar)"
148148
run eq '()' "(eq + 'bar)"
149+
run eq '()' '(eq "hello" "Hello")'
150+
run eq t '(eq "hello" "hello")'
149151

150152
# gensym
151153
run gensym G__0 '(gensym)'
@@ -165,8 +167,6 @@ run restargs '(3 5 7)' '(defun f (x . y) (cons x y)) (f 3 5 7)'
165167
run restargs '(3)' '(defun f (x . y) (cons x y)) (f 3)'
166168

167169
# strings
168-
run string= '()' '(string= "hello" "Hello")'
169-
run string= t '(string= "hello" "hello")'
170170
run 'symbol->string' 'twelve' "
171171
(define twelve 12)
172172
(symbol->string 'twelve)"

0 commit comments

Comments
 (0)