@@ -674,11 +674,24 @@ static Obj *PRIM_OP(void *root, Obj **env, Obj **list) { \
674674
675675// (+ <integer> ...)
676676PRIM_ARITHMETIC_OP (prim_plus , + , += )
677- PRIM_ARITHMETIC_OP (prim_minus , - , -= )
678677PRIM_ARITHMETIC_OP (prim_mult , * , *= )
679678PRIM_ARITHMETIC_OP (prim_div , /, /= )
680679PRIM_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 ) \
684697static 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)
861874static 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-
946955static 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}
0 commit comments