Made union data type for space efficiency
This commit is contained in:
parent
0144d28002
commit
4d86d79a2f
1 changed files with 21 additions and 17 deletions
38
prompt.c
38
prompt.c
|
@ -30,11 +30,15 @@ void add_history(char* unused) {}
|
||||||
#include <editline/readline.h>
|
#include <editline/readline.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef union numerr {
|
||||||
|
long num;
|
||||||
|
int err;
|
||||||
|
} NumErr;
|
||||||
|
|
||||||
// A lispy value can either be a number or an error
|
// A lispy value can either be a number or an error
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int type;
|
int type;
|
||||||
long num;
|
NumErr data;
|
||||||
int err;
|
|
||||||
} lval;
|
} lval;
|
||||||
|
|
||||||
// Possible lispy value types
|
// Possible lispy value types
|
||||||
|
@ -115,17 +119,17 @@ lval eval_op(lval x, char* op, lval y) {
|
||||||
if (x.type == LVAL_ERR) { return x; }
|
if (x.type == LVAL_ERR) { return x; }
|
||||||
if (y.type == LVAL_ERR) { return y; }
|
if (y.type == LVAL_ERR) { return y; }
|
||||||
|
|
||||||
if (strcmp(op, "+") == 0) { return lval_num(x.num + y.num); }
|
if (strcmp(op, "+") == 0) { return lval_num(x.data.num + y.data.num); }
|
||||||
if (strcmp(op, "-") == 0) { return lval_num(x.num - y.num); }
|
if (strcmp(op, "-") == 0) { return lval_num(x.data.num - y.data.num); }
|
||||||
if (strcmp(op, "*") == 0) { return lval_num(x.num * y.num); }
|
if (strcmp(op, "*") == 0) { return lval_num(x.data.num * y.data.num); }
|
||||||
if (strcmp(op, "/") == 0) {
|
if (strcmp(op, "/") == 0) {
|
||||||
// If you try to divide by zero, report an error
|
// If you try to divide by zero, report an error
|
||||||
return y.num == 0 ? lval_err(LERR_DIV_ZERO) : lval_num(x.num / y.num);
|
return y.data.num == 0 ? lval_err(LERR_DIV_ZERO) : lval_num(x.data.num / y.data.num);
|
||||||
}
|
}
|
||||||
if (strcmp(op, "min") == 0) { return lval_num(min(x.num, y.num)); }
|
if (strcmp(op, "min") == 0) { return lval_num(min(x.data.num, y.data.num)); }
|
||||||
if (strcmp(op, "max") == 0) { return lval_num(max(x.num, y.num)); }
|
if (strcmp(op, "max") == 0) { return lval_num(max(x.data.num, y.data.num)); }
|
||||||
if (strcmp(op, "^") == 0) { return lval_num(pow(x.num, y.num)); }
|
if (strcmp(op, "^") == 0) { return lval_num(pow(x.data.num, y.data.num)); }
|
||||||
if (strcmp(op, "%") == 0) { return lval_num(fmod(x.num, y.num)); }
|
if (strcmp(op, "%") == 0) { return lval_num(fmod(x.data.num, y.data.num)); }
|
||||||
|
|
||||||
return lval_err(LERR_BAD_OP);
|
return lval_err(LERR_BAD_OP);
|
||||||
}
|
}
|
||||||
|
@ -134,7 +138,7 @@ lval eval_uni(lval x, char* op) {
|
||||||
// If it's an error, return it
|
// If it's an error, return it
|
||||||
if (x.type == LVAL_ERR) { return x; }
|
if (x.type == LVAL_ERR) { return x; }
|
||||||
|
|
||||||
if (strcmp(op, "-") == 0) { return lval_num(-1 * x.num); }
|
if (strcmp(op, "-") == 0) { return lval_num(-1 * x.data.num); }
|
||||||
|
|
||||||
return lval_err(LERR_BAD_OP);
|
return lval_err(LERR_BAD_OP);
|
||||||
}
|
}
|
||||||
|
@ -187,32 +191,32 @@ long min(long x, long y) {
|
||||||
lval lval_num(long x) {
|
lval lval_num(long x) {
|
||||||
lval v;
|
lval v;
|
||||||
v.type = LVAL_NUM;
|
v.type = LVAL_NUM;
|
||||||
v.num = x;
|
v.data.num = x;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
lval lval_err(int x) {
|
lval lval_err(int x) {
|
||||||
lval v;
|
lval v;
|
||||||
v.type = LVAL_ERR;
|
v.type = LVAL_ERR;
|
||||||
v.err = x;
|
v.data.err = x;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flval_print(FILE* stream, lval v) {
|
void flval_print(FILE* stream, lval v) {
|
||||||
switch (v.type) {
|
switch (v.type) {
|
||||||
// If it's a number, then print it out
|
// If it's a number, then print it out
|
||||||
case LVAL_NUM: fprintf(stream, "%li", v.num); break;
|
case LVAL_NUM: fprintf(stream, "%li", v.data.num); break;
|
||||||
|
|
||||||
// If it's an error, indicate the error
|
// If it's an error, indicate the error
|
||||||
case LVAL_ERR:
|
case LVAL_ERR:
|
||||||
fprintf(stream, "Error: ");
|
fprintf(stream, "Error: ");
|
||||||
if (v.err == LERR_DIV_ZERO) {
|
if (v.data.err == LERR_DIV_ZERO) {
|
||||||
fprintf(stream, "Division by zero");
|
fprintf(stream, "Division by zero");
|
||||||
}
|
}
|
||||||
if (v.err == LERR_BAD_OP) {
|
if (v.data.err == LERR_BAD_OP) {
|
||||||
fprintf(stream, "Invalid Operator");
|
fprintf(stream, "Invalid Operator");
|
||||||
}
|
}
|
||||||
if (v.err == LERR_BAD_NUM) {
|
if (v.data.err == LERR_BAD_NUM) {
|
||||||
fprintf(stream, "Invalid Number");
|
fprintf(stream, "Invalid Number");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Reference in a new issue