Archived
1
0
Fork 0

Added symbols and errors into the union for lval

This commit is contained in:
Brandon Rozek 2018-06-17 11:10:57 -04:00
parent da94105307
commit 072b628341
8 changed files with 29 additions and 30 deletions

View file

@ -12,6 +12,9 @@ typedef lval* (*lbuiltin) (lenv*, lval*);
typedef union typeval { typedef union typeval {
long num; long num;
double dec; double dec;
// Error and symbols contain string data
char* err;
char* sym;
} TypeVal; } TypeVal;
// A lispy value can either be a number, error, symbol, or an expression // A lispy value can either be a number, error, symbol, or an expression
@ -19,10 +22,6 @@ struct lval {
int type; int type;
TypeVal data; TypeVal data;
// Error and symbols contain string data
char* err;
char* sym;
// Function // Function
lbuiltin builtin; lbuiltin builtin;
lenv* env; lenv* env;

View file

@ -62,8 +62,8 @@ int lval_eq(lval* x, lval* y) {
case LVAL_DOUBLE: return (x->data.dec == y->data.dec); case LVAL_DOUBLE: return (x->data.dec == y->data.dec);
// Compare string values // Compare string values
case LVAL_ERR: return (strcmp(x->err, y->err) == 0); case LVAL_ERR: return (strcmp(x->data.err, y->data.err) == 0);
case LVAL_SYM: return (strcmp(x->sym, y->sym) == 0); case LVAL_SYM: return (strcmp(x->data.sym, y->data.sym) == 0);
// If builtin compare, otherwise compare formals and body // If builtin compare, otherwise compare formals and body
case LVAL_FUN: case LVAL_FUN:

View file

@ -43,7 +43,7 @@ lval* lenv_get(lenv* e, lval* k) {
for (int i = 0; i < e->count; i++) { for (int i = 0; i < e->count; i++) {
// Check if the stored string matches the symbol string // Check if the stored string matches the symbol string
// If it does, return a copy of hte value // 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]); 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 // 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) { 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++) { for (int i = 0; i < e->count; i++) {
// If a variable is found, delete the item at that position // If a variable is found, delete the item at that position
// Then replace it with the data provided by the user // 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]); lval_del(e->vals[i]);
e->vals[i] = lval_copy(v); e->vals[i] = lval_copy(v);
return; return;
@ -77,8 +77,8 @@ void lenv_put(lenv* e, lval* k, lval* v) {
// Copy contents of lval and symbol string // Copy contents of lval and symbol string
e->vals[e->count - 1] = lval_copy(v); e->vals[e->count - 1] = lval_copy(v);
e->syms[e->count - 1] = (char*) malloc(strlen(k->sym) + 1); e->syms[e->count - 1] = (char*) malloc(strlen(k->data.sym) + 1);
strcpy(e->syms[e->count - 1], k->sym); strcpy(e->syms[e->count - 1], k->data.sym);
} }
void lenv_def(lenv* e, lval* k, lval* v) { 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 // Pop the first symbol from the formals
lval* sym = lval_pop(f->formals, 0); lval* sym = lval_pop(f->formals, 0);
if (strcmp(sym->sym, "&") == 0) { if (strcmp(sym->data.sym, "&") == 0) {
// Ensure '&' is followed by another symbol // Ensure '&' is followed by another symbol
if (f->formals->count != 1) { if (f->formals->count != 1) {
lval_del(a); 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 '&' remains in formal list bind to empty list
if (f->formals->count > 0 && 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 // Check to ensure that & is no passed invalidly
if (f->formals->count != 2) { if (f->formals->count != 2) {
return lval_err("Function format invalid." return lval_err("Function format invalid."

View file

@ -13,13 +13,13 @@ lval* lval_err(char* fmt, ...) {
va_start(va, fmt); va_start(va, fmt);
// Allocate 512 bytes of space // 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 //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 // 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 // Cleanup our va list
va_end(va); va_end(va);

View file

@ -58,11 +58,11 @@ lval* lval_take(lval* v, int i) {
lval* lval_eval_sexpr(lenv* e, lval* v) { lval* lval_eval_sexpr(lenv* e, lval* v) {
// No argument functions // No argument functions
if (v->count == 1 && v->cell[0]->type == LVAL_SYM) { 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]); lval* x = lenv_get(e, v->cell[0]);
if (x->type == LVAL_FUN) { if (x->type == LVAL_FUN) {
lval_del(x); lval_del(x);
if (strcmp(v->cell[0]->sym, "ls") == 0) { if (strcmp(v->cell[0]->data.sym, "ls") == 0) {
lval_del(v); lval_del(v);
return builtin_ls(e, lval_sexpr()); return builtin_ls(e, lval_sexpr());
} }

View file

@ -23,9 +23,9 @@ void flval_print(FILE* stream, lval* v) {
case LVAL_DOUBLE: fprintf(stream, "%lf", v->data.dec); break; 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; case LVAL_SEXPR: flval_expr_print(stream, v, '(', ')'); break;

View file

@ -10,8 +10,8 @@ lval* builtin_op(lenv* e, lval* v, char* sym);
lval* lval_sym(char* s) { lval* lval_sym(char* s) {
lval* v = (lval *) malloc(sizeof(lval)); lval* v = (lval *) malloc(sizeof(lval));
v->type = LVAL_SYM; v->type = LVAL_SYM;
v->sym = (char *) malloc(strlen(s) + 1); v->data.sym = (char *) malloc(strlen(s) + 1);
strcpy(v->sym, s); strcpy(v->data.sym, s);
return v; return v;
} }
@ -72,8 +72,8 @@ void lval_del(lval* v) {
break; break;
// Free the string data // Free the string data
case LVAL_ERR: free(v->err); break; case LVAL_ERR: free(v->data.err); break;
case LVAL_SYM: free(v->sym); break; case LVAL_SYM: free(v->data.sym); break;
// Delete all elements inside SEXPR or QEXPR // Delete all elements inside SEXPR or QEXPR
case LVAL_QEXPR: case LVAL_QEXPR:
@ -112,11 +112,11 @@ lval* lval_copy(lval* v) {
// Copy strings using malloc and strcpy // Copy strings using malloc and strcpy
case LVAL_ERR: case LVAL_ERR:
x->err = (char*) malloc(strlen(v->err) + 1); x->data.err = (char*) malloc(strlen(v->data.err) + 1);
strcpy(x->err, v->err); break; strcpy(x->data.err, v->data.err); break;
case LVAL_SYM: case LVAL_SYM:
x->sym = (char*) malloc(strlen(v->sym) + 1); x->data.sym = (char*) malloc(strlen(v->data.sym) + 1);
strcpy(x->sym, v->sym); break; strcpy(x->data.sym, v->data.sym); break;
// Copy lists by copying each sub-expression // Copy lists by copying each sub-expression
case LVAL_SEXPR: case LVAL_SEXPR:

View file

@ -85,8 +85,8 @@ int main (int argc, char** argv) {
lval_println(result); lval_println(result);
// mpc_ast_print(r.output); // mpc_ast_print(r.output);
mpc_ast_delete(r.output); mpc_ast_delete(r.output);
if ((result->type == LVAL_SEXPR && result->count > 0 && strcmp(result->cell[0]->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->sym, "exit") == 0)) (result->type == LVAL_SYM && strcmp(result->data.sym, "exit") == 0))
{ lval_del(result); free(input); break; } { lval_del(result); free(input); break; }
lval_del(result); lval_del(result);