From 072b6283412d3cf1f308f7073b575b0fcbfad4d5 Mon Sep 17 00:00:00 2001 From: Brandon Rozek Date: Sun, 17 Jun 2018 11:10:57 -0400 Subject: [PATCH] Added symbols and errors into the union for lval --- lval/base.h | 7 +++---- lval/conditionals.c | 4 ++-- lval/environment.c | 14 +++++++------- lval/error.c | 6 +++--- lval/expressions.c | 4 ++-- lval/io.c | 4 ++-- lval/operations.c | 16 ++++++++-------- prompt.c | 4 ++-- 8 files changed, 29 insertions(+), 30 deletions(-) diff --git a/lval/base.h b/lval/base.h index 25216b1..f41b514 100644 --- a/lval/base.h +++ b/lval/base.h @@ -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; diff --git a/lval/conditionals.c b/lval/conditionals.c index 1dab6bd..d1a0ce7 100644 --- a/lval/conditionals.c +++ b/lval/conditionals.c @@ -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: diff --git a/lval/environment.c b/lval/environment.c index 0691a7f..b19dae2 100644 --- a/lval/environment.c +++ b/lval/environment.c @@ -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." diff --git a/lval/error.c b/lval/error.c index f6af656..ef8ddf9 100644 --- a/lval/error.c +++ b/lval/error.c @@ -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); diff --git a/lval/expressions.c b/lval/expressions.c index a84d2de..f44fb26 100644 --- a/lval/expressions.c +++ b/lval/expressions.c @@ -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()); } diff --git a/lval/io.c b/lval/io.c index c1c9aa8..0f0bedb 100644 --- a/lval/io.c +++ b/lval/io.c @@ -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; diff --git a/lval/operations.c b/lval/operations.c index 631054c..11f3641 100644 --- a/lval/operations.c +++ b/lval/operations.c @@ -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: diff --git a/prompt.c b/prompt.c index ee13bf6..58d681e 100644 --- a/prompt.c +++ b/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);