Added symbols and errors into the union for lval
This commit is contained in:
parent
da94105307
commit
072b628341
8 changed files with 29 additions and 30 deletions
|
@ -12,6 +12,9 @@ typedef lval* (*lbuiltin) (lenv*, lval*);
|
|||
typedef union typeval {
|
||||
long num;
|
||||
double dec;
|
||||
// Error and symbols contain string data
|
||||
char* err;
|
||||
char* sym;
|
||||
} TypeVal;
|
||||
|
||||
// A lispy value can either be a number, error, symbol, or an expression
|
||||
|
@ -19,10 +22,6 @@ struct lval {
|
|||
int type;
|
||||
TypeVal data;
|
||||
|
||||
// Error and symbols contain string data
|
||||
char* err;
|
||||
char* sym;
|
||||
|
||||
// Function
|
||||
lbuiltin builtin;
|
||||
lenv* env;
|
||||
|
|
|
@ -62,8 +62,8 @@ int lval_eq(lval* x, lval* y) {
|
|||
case LVAL_DOUBLE: return (x->data.dec == y->data.dec);
|
||||
|
||||
// Compare string values
|
||||
case LVAL_ERR: return (strcmp(x->err, y->err) == 0);
|
||||
case LVAL_SYM: return (strcmp(x->sym, y->sym) == 0);
|
||||
case LVAL_ERR: return (strcmp(x->data.err, y->data.err) == 0);
|
||||
case LVAL_SYM: return (strcmp(x->data.sym, y->data.sym) == 0);
|
||||
|
||||
// If builtin compare, otherwise compare formals and body
|
||||
case LVAL_FUN:
|
||||
|
|
|
@ -43,7 +43,7 @@ lval* lenv_get(lenv* e, lval* k) {
|
|||
for (int i = 0; i < e->count; i++) {
|
||||
// Check if the stored string matches the symbol string
|
||||
// If it does, return a copy of hte value
|
||||
if (strcmp(e->syms[i], k->sym) == 0) {
|
||||
if (strcmp(e->syms[i], k->data.sym) == 0) {
|
||||
return lval_copy(e->vals[i]);
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ lval* lenv_get(lenv* e, lval* k) {
|
|||
}
|
||||
|
||||
// If no symbol found and no parent, return error
|
||||
return lval_err("Unbounded symbol %s", k->sym);
|
||||
return lval_err("Unbounded symbol %s", k->data.sym);
|
||||
}
|
||||
|
||||
void lenv_put(lenv* e, lval* k, lval* v) {
|
||||
|
@ -63,7 +63,7 @@ void lenv_put(lenv* e, lval* k, lval* v) {
|
|||
for (int i = 0; i < e->count; i++) {
|
||||
// If a variable is found, delete the item at that position
|
||||
// Then replace it with the data provided by the user
|
||||
if (strcmp(e->syms[i], k->sym) == 0) {
|
||||
if (strcmp(e->syms[i], k->data.sym) == 0) {
|
||||
lval_del(e->vals[i]);
|
||||
e->vals[i] = lval_copy(v);
|
||||
return;
|
||||
|
@ -77,8 +77,8 @@ void lenv_put(lenv* e, lval* k, lval* v) {
|
|||
|
||||
// Copy contents of lval and symbol string
|
||||
e->vals[e->count - 1] = lval_copy(v);
|
||||
e->syms[e->count - 1] = (char*) malloc(strlen(k->sym) + 1);
|
||||
strcpy(e->syms[e->count - 1], k->sym);
|
||||
e->syms[e->count - 1] = (char*) malloc(strlen(k->data.sym) + 1);
|
||||
strcpy(e->syms[e->count - 1], k->data.sym);
|
||||
}
|
||||
|
||||
void lenv_def(lenv* e, lval* k, lval* v) {
|
||||
|
@ -252,7 +252,7 @@ lval* lval_call(lenv* e, lval* f, lval* a) {
|
|||
// Pop the first symbol from the formals
|
||||
lval* sym = lval_pop(f->formals, 0);
|
||||
|
||||
if (strcmp(sym->sym, "&") == 0) {
|
||||
if (strcmp(sym->data.sym, "&") == 0) {
|
||||
// Ensure '&' is followed by another symbol
|
||||
if (f->formals->count != 1) {
|
||||
lval_del(a);
|
||||
|
@ -282,7 +282,7 @@ lval* lval_call(lenv* e, lval* f, lval* a) {
|
|||
|
||||
// If '&' remains in formal list bind to empty list
|
||||
if (f->formals->count > 0 &&
|
||||
strcmp(f->formals->cell[0]->sym, "&") == 0) {
|
||||
strcmp(f->formals->cell[0]->data.sym, "&") == 0) {
|
||||
// Check to ensure that & is no passed invalidly
|
||||
if (f->formals->count != 2) {
|
||||
return lval_err("Function format invalid."
|
||||
|
|
|
@ -13,13 +13,13 @@ lval* lval_err(char* fmt, ...) {
|
|||
va_start(va, fmt);
|
||||
|
||||
// Allocate 512 bytes of space
|
||||
v->err = (char *) malloc(512);
|
||||
v->data.err = (char *) malloc(512);
|
||||
|
||||
//printf the error string with a maximum of 511 characters
|
||||
vsnprintf(v->err, 511, fmt, va);
|
||||
vsnprintf(v->data.err, 511, fmt, va);
|
||||
|
||||
// Reallocate to the number of actual bytes
|
||||
v->err = realloc(v->err, strlen(v->err) + 1);
|
||||
v->data.err = realloc(v->data.err, strlen(v->data.err) + 1);
|
||||
|
||||
// Cleanup our va list
|
||||
va_end(va);
|
||||
|
|
|
@ -58,11 +58,11 @@ lval* lval_take(lval* v, int i) {
|
|||
lval* lval_eval_sexpr(lenv* e, lval* v) {
|
||||
// No argument functions
|
||||
if (v->count == 1 && v->cell[0]->type == LVAL_SYM) {
|
||||
if (strcmp(v->cell[0]->sym, "exit") == 0) { return v; }
|
||||
if (strcmp(v->cell[0]->data.sym, "exit") == 0) { return v; }
|
||||
lval* x = lenv_get(e, v->cell[0]);
|
||||
if (x->type == LVAL_FUN) {
|
||||
lval_del(x);
|
||||
if (strcmp(v->cell[0]->sym, "ls") == 0) {
|
||||
if (strcmp(v->cell[0]->data.sym, "ls") == 0) {
|
||||
lval_del(v);
|
||||
return builtin_ls(e, lval_sexpr());
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ void flval_print(FILE* stream, lval* v) {
|
|||
|
||||
case LVAL_DOUBLE: fprintf(stream, "%lf", v->data.dec); break;
|
||||
|
||||
case LVAL_ERR: fprintf(stream, "Error: %s", v->err); break;
|
||||
case LVAL_ERR: fprintf(stream, "Error: %s", v->data.err); break;
|
||||
|
||||
case LVAL_SYM: fprintf(stream, "%s", v->sym); break;
|
||||
case LVAL_SYM: fprintf(stream, "%s", v->data.sym); break;
|
||||
|
||||
case LVAL_SEXPR: flval_expr_print(stream, v, '(', ')'); break;
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ lval* builtin_op(lenv* e, lval* v, char* sym);
|
|||
lval* lval_sym(char* s) {
|
||||
lval* v = (lval *) malloc(sizeof(lval));
|
||||
v->type = LVAL_SYM;
|
||||
v->sym = (char *) malloc(strlen(s) + 1);
|
||||
strcpy(v->sym, s);
|
||||
v->data.sym = (char *) malloc(strlen(s) + 1);
|
||||
strcpy(v->data.sym, s);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,8 @@ void lval_del(lval* v) {
|
|||
break;
|
||||
|
||||
// Free the string data
|
||||
case LVAL_ERR: free(v->err); break;
|
||||
case LVAL_SYM: free(v->sym); break;
|
||||
case LVAL_ERR: free(v->data.err); break;
|
||||
case LVAL_SYM: free(v->data.sym); break;
|
||||
|
||||
// Delete all elements inside SEXPR or QEXPR
|
||||
case LVAL_QEXPR:
|
||||
|
@ -112,11 +112,11 @@ lval* lval_copy(lval* v) {
|
|||
|
||||
// Copy strings using malloc and strcpy
|
||||
case LVAL_ERR:
|
||||
x->err = (char*) malloc(strlen(v->err) + 1);
|
||||
strcpy(x->err, v->err); break;
|
||||
x->data.err = (char*) malloc(strlen(v->data.err) + 1);
|
||||
strcpy(x->data.err, v->data.err); break;
|
||||
case LVAL_SYM:
|
||||
x->sym = (char*) malloc(strlen(v->sym) + 1);
|
||||
strcpy(x->sym, v->sym); break;
|
||||
x->data.sym = (char*) malloc(strlen(v->data.sym) + 1);
|
||||
strcpy(x->data.sym, v->data.sym); break;
|
||||
|
||||
// Copy lists by copying each sub-expression
|
||||
case LVAL_SEXPR:
|
||||
|
|
4
prompt.c
4
prompt.c
|
@ -85,8 +85,8 @@ int main (int argc, char** argv) {
|
|||
lval_println(result);
|
||||
// mpc_ast_print(r.output);
|
||||
mpc_ast_delete(r.output);
|
||||
if ((result->type == LVAL_SEXPR && result->count > 0 && strcmp(result->cell[0]->sym, "exit") == 0) ||
|
||||
(result->type == LVAL_SYM && strcmp(result->sym, "exit") == 0))
|
||||
if ((result->type == LVAL_SEXPR && result->count > 0 && strcmp(result->cell[0]->data.sym, "exit") == 0) ||
|
||||
(result->type == LVAL_SYM && strcmp(result->data.sym, "exit") == 0))
|
||||
{ lval_del(result); free(input); break; }
|
||||
lval_del(result);
|
||||
|
||||
|
|
Reference in a new issue