Skip to content

Commit 1efacb7

Browse files
committed
Fix crash in comment
Refactor arithmetic operations
1 parent 66864ff commit 1efacb7

1 file changed

Lines changed: 28 additions & 69 deletions

File tree

src/minilisp.c

Lines changed: 28 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,13 @@ static Obj *read_list(void *root) {
174174
for (;;) {
175175
*obj = read_expr(root);
176176
if (!*obj)
177-
error("Unclosed parenthesis", (*obj)->line_num);
177+
error("Unclosed parenthesis", filepos.line_num);
178178
if (*obj == Cparen)
179179
return reverse(*head);
180180
if (*obj == Dot) {
181181
*last = read_expr(root);
182182
if (read_expr(root) != Cparen)
183-
error("Closed parenthesis expected after dot", (*obj)->line_num);
183+
error("Closed parenthesis expected after dot", filepos.line_num);
184184
Obj *ret = reverse(*head);
185185
(*head)->cdr = *last;
186186
return ret;
@@ -660,77 +660,36 @@ static Obj *prim_reverse(void *root, Obj **env, Obj **list) {
660660
}
661661
}
662662

663-
// (+ <integer> ...)
664-
static Obj *prim_plus(void *root, Obj **env, Obj **list) {
665-
long long sum = 0;
666-
for (Obj *args = eval_list(root, env, list); args != Nil; args = args->cdr) {
667-
if (args->car->type != TINT)
668-
error("+ takes only numbers", (*list)->line_num);
669-
sum += args->car->value;
670-
}
671-
return make_int(root, sum);
672-
}
673-
674-
// (* <integer> ...)
675-
static Obj *prim_mult(void *root, Obj **env, Obj **list) {
676-
long long prod = 1;
677-
for (Obj *args = eval_list(root, env, list); args != Nil; args = args->cdr) {
678-
if (args->car->type != TINT)
679-
error("* takes only numbers", (*list)->line_num);
680-
prod *= args->car->value;
681-
}
682-
return make_int(root, prod);
683-
}
684-
685-
// (/ <integer> ...)
686-
static Obj *prim_div(void *root, Obj **env, Obj **list) {
687-
Obj *args = eval_list(root, env, list);
688-
long long r = args->car->value;
689-
for (Obj *p = args->cdr; p != Nil; p = p->cdr){
690-
if (p->car->type != TINT)
691-
error("/ takes only numbers", (*list)->line_num);
692-
r /= p->car->value;
693-
}
694-
return make_int(root, r);
663+
#define PRIM_ARITHMETIC_OP(PRIM_OP, OP, OPEQ) \
664+
static Obj *PRIM_OP(void *root, Obj **env, Obj **list) { \
665+
Obj *args = eval_list(root, env, list); \
666+
long long r = args->car->value; \
667+
for (Obj *p = args->cdr; p != Nil; p = p->cdr) { \
668+
if (p->car->type != TINT) \
669+
error(#OP " takes only numbers", (*list)->line_num); \
670+
r OPEQ p->car->value; \
671+
} \
672+
return make_int(root, r); \
695673
}
696674

697-
// (% <integer> ...)
698-
static Obj *prim_modulo(void *root, Obj **env, Obj **list) {
699-
Obj *args = eval_list(root, env, list);
700-
long long r = args->car->value;
701-
for (Obj *p = args->cdr; p != Nil; p = p->cdr){
702-
if (p->car->type != TINT)
703-
error("mod takes only numbers", (*list)->line_num);
704-
r %= p->car->value;
705-
}
706-
return make_int(root, r);
707-
}
708-
709-
// (- <integer> ...)
710-
static Obj *prim_minus(void *root, Obj **env, Obj **list) {
711-
Obj *args = eval_list(root, env, list);
712-
for (Obj *p = args; p != Nil; p = p->cdr)
713-
if (p->car->type != TINT)
714-
error("- takes only numbers", (*list)->line_num);
715-
if (args->cdr == Nil)
716-
return make_int(root, -args->car->value);
717-
long long r = args->car->value;
718-
for (Obj *p = args->cdr; p != Nil; p = p->cdr)
719-
r -= p->car->value;
720-
return make_int(root, r);
721-
}
675+
// (+ <integer> ...)
676+
PRIM_ARITHMETIC_OP(prim_plus, +, += )
677+
PRIM_ARITHMETIC_OP(prim_minus, -, -= )
678+
PRIM_ARITHMETIC_OP(prim_mult, *, *= )
679+
PRIM_ARITHMETIC_OP(prim_div , /, /= )
680+
PRIM_ARITHMETIC_OP(prim_modulo, %, %= )
722681

723682
// (op <integer> <integer>)
724-
#define PRIM_COMPARISON_OP(PRIM_OP, OP) \
725-
static Obj *PRIM_OP(void *root, Obj **env, Obj **list) { \
726-
Obj *args = eval_list(root, env, list); \
727-
if (length(args) != 2) \
728-
error(#OP " takes only 2 number", (*list)->line_num);\
729-
Obj *x = args->car; \
730-
Obj *y = args->cdr->car; \
731-
if (x->type != TINT || y->type != TINT) \
732-
error(#OP " takes only 2 numbers", (*list)->line_num); \
733-
return x->value OP y->value ? True : Nil; \
683+
#define PRIM_COMPARISON_OP(PRIM_OP, OP) \
684+
static Obj *PRIM_OP(void *root, Obj **env, Obj **list) { \
685+
Obj *args = eval_list(root, env, list); \
686+
if (length(args) != 2) \
687+
error(#OP " takes only 2 number", (*list)->line_num); \
688+
Obj *x = args->car; \
689+
Obj *y = args->cdr->car; \
690+
if (x->type != TINT || y->type != TINT) \
691+
error(#OP " takes only 2 numbers", (*list)->line_num); \
692+
return x->value OP y->value ? True : Nil; \
734693
}
735694

736695
PRIM_COMPARISON_OP(prim_num_eq, ==)

0 commit comments

Comments
 (0)