From 78248427046f857271058f9da71e408e71453801 Mon Sep 17 00:00:00 2001 From: Brandon Rozek Date: Thu, 7 Jun 2018 19:10:53 -0400 Subject: [PATCH] Refactored code into subfiles --- Makefile | 14 +- lval.h | 16 +++ lval/base.h | 24 ++++ lval/expressions.c | 85 ++++++++++++ lval/expressions.h | 26 ++++ lval/io.c | 37 +++++ lval/io.h | 11 ++ lval/numbers.c | 100 ++++++++++++++ lval/numbers.h | 28 ++++ lval/operations.c | 87 ++++++++++++ lval/operations.h | 19 +++ prompt.c | 326 +-------------------------------------------- 12 files changed, 446 insertions(+), 327 deletions(-) create mode 100644 lval.h create mode 100644 lval/base.h create mode 100644 lval/expressions.c create mode 100644 lval/expressions.h create mode 100644 lval/io.c create mode 100644 lval/io.h create mode 100644 lval/numbers.c create mode 100644 lval/numbers.h create mode 100644 lval/operations.c create mode 100644 lval/operations.h diff --git a/Makefile b/Makefile index c17aa7e..122990f 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,14 @@ -run: prompt.c mpc.o - cc -std=c99 -Wall prompt.c mpc.o -ledit -lm -o prompt -mpc:o mpc.c mpc.h +run: prompt.c loperations.o lnumbers.o lexpressions.o lio.o mpc.o + cc -std=c99 -Wall prompt.c loperations.o lnumbers.o lexpressions.o lio.o mpc.o -ledit -lm -o prompt +loperations.o: lval/operations.c lval/operations.h + cc -std=c99 -Wall -c lval/operations.c -o loperations.o +lnumbers.o: lval/numbers.c lval/numbers.h + cc -std=c99 -Wall -c lval/numbers.c -o lnumbers.o +lexpressions.o: lval/expressions.c lval/expressions.h + cc -std=c99 -Wall -c lval/expressions.c -o lexpressions.o +lio.o: lval/io.c lval/io.h + cc -std=c99 -Wall -c lval/io.c -o lio.o +mpc.o: mpc.c mpc.h cc -std=c99 -Wall -lm -c mpc.c clean: rm *.o diff --git a/lval.h b/lval.h new file mode 100644 index 0000000..6046b6f --- /dev/null +++ b/lval.h @@ -0,0 +1,16 @@ + +#ifndef LVAL_H +#define LVAL_H + +// Bring in the lval struct and lispy types +#include "lval/base.h" +// Adds functionality for the numeric data type +#include "lval/numbers.h" +// Adds functionality for the expression (Q or S) data type +#include "lval/expressions.h" +// Add read, write, and error functionality +#include "lval/operations.h" +// Add the ability to print out lval structures +#include "lval/io.h" + +#endif diff --git a/lval/base.h b/lval/base.h new file mode 100644 index 0000000..2547c99 --- /dev/null +++ b/lval/base.h @@ -0,0 +1,24 @@ +#ifndef LVAL_BASE +#define LVAL_BASE +typedef union typeval { + long num; + double dec; +} TypeVal; + +// A lispy value can either be a number, error, symbol, or an expression +typedef struct lval { + int type; + TypeVal data; + + // Error and symbols contain string data + char* err; + char* sym; + + // Count and pointer to a list of lval* + int count; + struct lval** cell; +} lval; + +// Possible lispy value types +enum { LVAL_ERR, LVAL_LONG, LVAL_DOUBLE, LVAL_SYM, LVAL_SEXPR, LVAL_QEXPR }; +#endif diff --git a/lval/expressions.c b/lval/expressions.c new file mode 100644 index 0000000..4ade6ff --- /dev/null +++ b/lval/expressions.c @@ -0,0 +1,85 @@ +#include +#include +#include + +#include "operations.h" +#include "expressions.h" + +// Think about where to put this declaration later +lval* builtin_op(lval* v, char* op); + +lval* lval_sexpr(void) { + lval* v = (lval *) malloc(sizeof(lval)); + v->type = LVAL_SEXPR; + v->count = 0; + v->cell = NULL; + return v; +} +lval* lval_qexpr(void) { + lval* v = (lval *) malloc(sizeof(lval)); + v->type = LVAL_QEXPR; + v->count = 0; + v->cell = NULL; + return v; +} + +lval* lval_add(lval* v, lval* x) { + v->count++; + v->cell = (lval **) realloc(v->cell, sizeof(lval*) * v->count); + v->cell[v->count - 1] = x; + return v; +} + +lval* lval_pop(lval* v, int i) { + // Find the item at i + lval* x = v->cell[i]; + + // Shift the memory after the item i over the top + memmove(&v->cell[i], &v->cell[i + 1], sizeof(lval*) * (v->count - i - 1)); + + // Decrease the count of items in the list + v->count--; + + // Reallocate the memory used + v->cell = (lval **) realloc(v->cell, sizeof(lval*) * v->count); + return x; +} + +lval* lval_take(lval* v, int i) { + lval* x = lval_pop(v, i); + lval_del(v); + return x; +} + +lval* lval_eval_sexpr(lval* v) { + // Evaluate children + for (int i = 0; i < v->count; i++) { + v->cell[i] = lval_eval(v->cell[i]); + } + + // Error checking [If there's an error, return it] + for (int i = 0; i < v->count; i++) { + if (v->cell[i]->type == LVAL_ERR) { return lval_take(v, i); } + } + + // Empty expression + if (v->count == 0) { return v; } + + // Single expression + if (v->count == 1) { return lval_take(v, 0); } + + // Ensure first element is a symbol otherwise + lval* f = lval_pop(v, 0); + if (f->type != LVAL_SYM) { + printf("The type of f is %d\n", f->type); + lval_del(f); lval_del(v); + return lval_err("S-expression does not start with symbol"); + } + + lval* result = builtin_op(v, f->sym); + lval_del(f); + return result; +} + + + diff --git a/lval/expressions.h b/lval/expressions.h new file mode 100644 index 0000000..a813281 --- /dev/null +++ b/lval/expressions.h @@ -0,0 +1,26 @@ +#ifndef LVAL_EXPRESSIONS +#define LVAL_EXPRESSIONS +#include "base.h" + +// Constructors for the SEXPR and QEXPR data type +lval* lval_sexpr(void); +lval* lval_qexpr(void); + +/* +-------------------------------------------------------- + Add the functionality to be able to add or remove + expressions from the group +*/ +lval* lval_add(lval* v, lval* x); +// Remove an expression from the group and return it +lval* lval_pop(lval* v, int i); +// Remove an expression from the group and delete the rest the group +lval* lval_take(lval* v, int i); + +/* ----------------------------------------------------*/ + +// Adds the ability to evalutate each expression in the group +lval* lval_eval_sexpr(lval* v); + + +#endif diff --git a/lval/io.c b/lval/io.c new file mode 100644 index 0000000..8c2a9b3 --- /dev/null +++ b/lval/io.c @@ -0,0 +1,37 @@ +#include +#include "io.h" + +void flval_expr_print(FILE* stream, lval* v, char open, char close) { + putchar(open); + for (int i = 0; i < v->count; i++) { + // Print value contained within + flval_print(stream, v->cell[i]); + + // Put a trailing whitespace unless its the last element + if (i != (v->count - 1)) { + putchar(' '); + } + } + putchar(close); +} + +void flval_print(FILE* stream, lval* v) { + switch (v->type) { + // If it's an integer, then print it out + case LVAL_LONG: fprintf(stream, "%li", v->data.num); break; + + case LVAL_DOUBLE: fprintf(stream, "%lf", v->data.dec); break; + + case LVAL_ERR: fprintf(stream, "Error: %s", v->err); break; + + case LVAL_SYM: fprintf(stream, "%s", v->sym); break; + + case LVAL_SEXPR: flval_expr_print(stream, v, '(', ')'); break; + + case LVAL_QEXPR: flval_expr_print(stream, v, '{', '}'); break; + } +} + +void lval_print(lval* v) { flval_print(stdout, v); } + +void lval_println(lval* v) { lval_print(v); putchar('\n'); } \ No newline at end of file diff --git a/lval/io.h b/lval/io.h new file mode 100644 index 0000000..5b40e14 --- /dev/null +++ b/lval/io.h @@ -0,0 +1,11 @@ + +#ifndef LVAL_IO +#define LVAL_IO +#include "base.h" + +void flval_expr_print(FILE* stream, lval* v, char open, char close); +void flval_print(FILE* stream, lval* v); +void lval_print(lval* v); +void lval_println(lval* v); + +#endif diff --git a/lval/numbers.c b/lval/numbers.c new file mode 100644 index 0000000..c5b14d7 --- /dev/null +++ b/lval/numbers.c @@ -0,0 +1,100 @@ +#include +#include "numbers.h" + +lval* lval_long(long x) { + lval* v = (lval *) malloc(sizeof(lval)); + v->type = LVAL_LONG; + v->data.num = x; + return v; +} + +lval* lval_double(double x) { + lval* v = (lval *) malloc(sizeof(lval)); + v->type = LVAL_DOUBLE; + v->data.dec = x; + return v; +} + +size_t treeContentsLength(mpc_ast_t* t) { + size_t result = strlen(t->contents); + if (t->children_num == 0) { + return result; + } + + for (int i = 0; i < t->children_num; i++) { + result += treeContentsLength(t->children[i]); + } + return result; +} + +char* concatTreeContents(mpc_ast_t* t) { + // Calculate size needed for the string + size_t totalLength = treeContentsLength(t); + + // Allocate memory for string and null terminator + char* stringToExtend = (char *) malloc(totalLength + 1); + // [TODO] Write an allocation error handler + + size_t currentLength = 0; + concatNodeContents(stringToExtend, t, ¤tLength); + + stringToExtend[totalLength] = '\0'; + + return stringToExtend; +} + +void concatNodeContents(char* stringToExtend, mpc_ast_t* t, size_t* currentLength) { + size_t leafLength = strlen(t->contents); + + memcpy(stringToExtend + (*currentLength), t->contents, leafLength); + *currentLength = *currentLength + leafLength; + + if (t->children_num != 0) { + for (int i = 0; i < t->children_num; i++) { + concatNodeContents(stringToExtend, t->children[i], currentLength); + } + } + +} + +lval* lval_read_double(mpc_ast_t* t) { + char* treeString = concatTreeContents(t); + + // Check to see if there's some error in conversion + errno = 0; + double x = strtod(treeString, NULL); + + free(treeString); + + return errno != ERANGE ? lval_double(x) : lval_err("Invalid Number"); +} +lval* lval_read_long(mpc_ast_t* t) { + // Grab the contents of all the nodes in the tree otherwise you might not get the string you expect + char* treeString = concatTreeContents(t); + + // Check to see if there's some error in conversion + errno = 0; + long x = strtol(treeString, NULL, 10); + + // Free the memory allocated in treestring since it's no longer needed + free(treeString); + + return errno != ERANGE ? lval_long(x) : lval_err("Invalid Number"); +} + + +double lval_getData(lval* x) { + if (x->type == LVAL_LONG) { + return x->data.num; + } + return x->data.dec; +} + +void lval_updateData(lval* x, double val, int type) { + if (type == LVAL_LONG) { + x->data.num = val; + return; + } + x->data.dec = val; +} + diff --git a/lval/numbers.h b/lval/numbers.h new file mode 100644 index 0000000..05f8478 --- /dev/null +++ b/lval/numbers.h @@ -0,0 +1,28 @@ +#ifndef LVALIO_NUMBERS +#define LVALIO_NUMBERS +#include +#include "../mpc.h" +#include "base.h" +// Including operations.h for lval_err +#include "operations.h" + +// Constructors for numeric data types +lval* lval_long(long x); +lval* lval_double(double x); + +// Helper functions to parse the tree and obtain the full string to parse +size_t treeContentsLength(mpc_ast_t* t); +char* concatTreeContents(mpc_ast_t* t); +void concatNodeContents(char* stringToExtend, mpc_ast_t* t, size_t* currentLength); + +// Parsing of numeric types +lval* lval_read_double(mpc_ast_t* t); +lval* lval_read_long(mpc_ast_t* t); + +// Accessing the numeric data in a lval structure +// TODO: Rename these methods +double lval_getData(lval* x); +void lval_updateData(lval* x, double val, int type); + + +#endif diff --git a/lval/operations.c b/lval/operations.c new file mode 100644 index 0000000..d6049c3 --- /dev/null +++ b/lval/operations.c @@ -0,0 +1,87 @@ +#include +#include +#include "numbers.h" +#include "expressions.h" +#include "operations.h" + +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); + return v; +} + +lval* lval_err(char* m) { + lval* v = (lval *) malloc(sizeof(lval)); + v->type = LVAL_ERR; + v->err = (char *) malloc(strlen(m) + 1); + strcpy(v->err, m); + return v; +} + +lval* lval_read(mpc_ast_t* t) { + // If symbol or number, convert + if (strstr(t->tag, "long")) { return lval_read_long(t); } + if (strstr(t->tag, "double")) { return lval_read_double(t); } + if (strstr(t->tag, "symbol")) { return lval_sym(t->contents); } + + // If root or sexpr, then create an empty list + lval* x = NULL; + if (strcmp(t->tag, ">") == 0 || strstr(t->tag, "sexpr")) { + x = lval_sexpr(); + } + + if (strstr(t->tag, "qexpr")) { + x = lval_qexpr(); + } + + // Fill the list with any valid expression contained + for (int i = 0; i < t->children_num; i++) { + if (strcmp(t->children[i]->contents, "(") == 0) { continue; } + if (strcmp(t->children[i]->contents, ")") == 0) { continue; } + if (strcmp(t->children[i]->contents, "{") == 0) { continue; } + if (strcmp(t->children[i]->contents, "}") == 0) { continue; } + if (strcmp(t->children[i]->tag, "regex") == 0) { continue; } + x = lval_add(x, lval_read(t->children[i])); + } + + return x; +} + + +lval* lval_eval(lval* v) { + // Evauluate sexpressions + if (v->type == LVAL_SEXPR) { return lval_eval_sexpr(v); } + + // All other lval types remail the same + return v; +} + + +void lval_del(lval* v) { + switch (v->type) { + case LVAL_LONG: break; + case LVAL_DOUBLE: break; + + // Free the string data + case LVAL_ERR: free(v->err); break; + case LVAL_SYM: free(v->sym); break; + + // Delete all elements inside SEXPR or QEXPR + case LVAL_QEXPR: + case LVAL_SEXPR: + for (int i = 0; i < v->count; i++) { + lval_del(v->cell[i]); + } + // Also free the memory allocated to contain the pointers + free(v->cell); + break; + + } + + // // Free the memory allocated for the lval struct itself + free(v); +} + + diff --git a/lval/operations.h b/lval/operations.h new file mode 100644 index 0000000..7acea43 --- /dev/null +++ b/lval/operations.h @@ -0,0 +1,19 @@ +#ifndef LVAL_OPERATIONS +#define LVAL_OPERATIONS + +#include "../mpc.h" +#include "base.h" + +// Constructor for other data types +lval* lval_sym(char* s); +lval* lval_err(char* m); + +/* + Methods to read (parse AST), evaluate, + and delete lval structures +*/ +lval* lval_read(mpc_ast_t* t); +lval* lval_eval(lval* v); +void lval_del(lval* v); + +#endif diff --git a/prompt.c b/prompt.c index 6ee3507..0fb3be7 100644 --- a/prompt.c +++ b/prompt.c @@ -1,6 +1,7 @@ #include #include #include "mpc.h" +#include "lval.h" // Undefine min/max macros if existent #undef max @@ -30,53 +31,10 @@ void add_history(char* unused) {} #include #endif -typedef union typeval { - long num; - double dec; -} TypeVal; - -// A lispy value can either be a number or an error -typedef struct lval { - int type; - TypeVal data; - - // Error and symbols contain string data - char* err; - char* sym; - - // Count and pointer to a list of lval* - int count; - struct lval** cell; -} lval; - -// Possible lispy value types -enum { LVAL_ERR, LVAL_LONG, LVAL_DOUBLE, LVAL_SYM, LVAL_SEXPR, LVAL_QEXPR }; - double max(double x, double y); double min(double x, double y); -lval* lval_long(long x); -lval* lval_double(double x); -lval* lval_err(char* m); -lval* lval_sym(char* s); -lval* lval_sexpr(void); -double lval_getData(lval* x); -void lval_updateData(lval* x, double val, int type); -void lval_del(lval* v); -lval* lval_read_long(mpc_ast_t* t); -lval* lval_read_double(mpc_ast_t* t); -lval* lval_read(mpc_ast_t* t); -lval* lval_add(lval* v, lval* x); -lval* lval_eval_sexpr(lval* v); -lval* lval_eval(lval* v); -lval* lval_take(lval* v, int i); -lval* lval_pop(lval* v, int i); lval* builtin_op(lval* v, char* op); -void flval_print(FILE* stream, lval* v); -void lval_print(lval* v); -void lval_println(lval* v); -size_t treeContentsLength(mpc_ast_t* t); -char* concatTreeContents(mpc_ast_t* t); -void concatNodeContents(char* stringToExtend, mpc_ast_t* t, size_t* currentLength); + int main (int argc, char** argv) { @@ -156,274 +114,10 @@ double min(double x, double y) { return y; } -lval* lval_long(long x) { - lval* v = malloc(sizeof(lval)); - v->type = LVAL_LONG; - v->data.num = x; - return v; -} - -lval* lval_double(double x) { - lval* v = malloc(sizeof(lval)); - v->type = LVAL_DOUBLE; - v->data.dec = x; - return v; -} - -lval* lval_err(char* m) { - lval* v = malloc(sizeof(lval)); - v->type = LVAL_ERR; - v->err = malloc(strlen(m) + 1); - strcpy(v->err, m); - return v; -} - -lval* lval_sym(char* s) { - lval* v = malloc(sizeof(lval)); - v->type = LVAL_SYM; - v->sym = malloc(strlen(s) + 1); - strcpy(v->sym, s); - return v; -} - -lval* lval_sexpr(void) { - lval* v = malloc(sizeof(lval)); - v->type = LVAL_SEXPR; - v->count = 0; - v->cell = NULL; - return v; -} - -lval* lval_qexpr(void) { - lval* v = malloc(sizeof(lval)); - v->type = LVAL_QEXPR; - v->count = 0; - v->cell = NULL; - return v; -} -void lval_del(lval* v) { - switch (v->type) { - case LVAL_LONG: break; - case LVAL_DOUBLE: break; - - // Free the string data - case LVAL_ERR: free(v->err); break; - case LVAL_SYM: free(v->sym); break; - - // Delete all elements inside SEXPR or QEXPR - case LVAL_QEXPR: - case LVAL_SEXPR: - for (int i = 0; i < v->count; i++) { - lval_del(v->cell[i]); - } - // Also free the memory allocated to contain the pointers - free(v->cell); - break; - - } - - // // Free the memory allocated for the lval struct itself - free(v); -} - -lval* lval_read_long(mpc_ast_t* t) { - // Grab the contents of all the nodes in the tree otherwise you might not get the string you expect - char* treeString = concatTreeContents(t); - - // Check to see if there's some error in conversion - errno = 0; - long x = strtol(treeString, NULL, 10); - - // Free the memory allocated in treestring since it's no longer needed - free(treeString); - - return errno != ERANGE ? lval_long(x) : lval_err("Invalid Number"); -} - -lval* lval_read_double(mpc_ast_t* t) { - char* treeString = concatTreeContents(t); - - // Check to see if there's some error in conversion - errno = 0; - double x = strtod(treeString, NULL); - - free(treeString); - - return errno != ERANGE ? lval_double(x) : lval_err("Invalid Number"); -} - -lval* lval_read(mpc_ast_t* t) { - // If symbol or number, convert - if (strstr(t->tag, "long")) { return lval_read_long(t); } - if (strstr(t->tag, "double")) { return lval_read_double(t); } - if (strstr(t->tag, "symbol")) { return lval_sym(t->contents); } - - // If root or sexpr, then create an empty list - lval* x = NULL; - if (strcmp(t->tag, ">") == 0 || strstr(t->tag, "sexpr")) { - x = lval_sexpr(); - } - - if (strstr(t->tag, "qexpr")) { - x = lval_qexpr(); - } - - // Fill the list with any valid expression contained - for (int i = 0; i < t->children_num; i++) { - if (strcmp(t->children[i]->contents, "(") == 0) { continue; } - if (strcmp(t->children[i]->contents, ")") == 0) { continue; } - if (strcmp(t->children[i]->contents, "{") == 0) { continue; } - if (strcmp(t->children[i]->contents, "}") == 0) { continue; } - if (strcmp(t->children[i]->tag, "regex") == 0) { continue; } - x = lval_add(x, lval_read(t->children[i])); - } - - return x; -} - -lval* lval_add(lval* v, lval* x) { - v->count++; - v->cell = realloc(v->cell, sizeof(lval*) * v->count); - v->cell[v->count - 1] = x; - return v; -} - -void flval_expr_print(FILE* stream, lval* v, char open, char close) { - putchar(open); - for (int i = 0; i < v->count; i++) { - // Print value contained within - flval_print(stream, v->cell[i]); - - // Put a trailing whitespace unless its the last element - if (i != (v->count - 1)) { - putchar(' '); - } - } - putchar(close); -} - -void flval_print(FILE* stream, lval* v) { - switch (v->type) { - // If it's an integer, then print it out - case LVAL_LONG: fprintf(stream, "%li", v->data.num); break; - - case LVAL_DOUBLE: fprintf(stream, "%lf", v->data.dec); break; - - case LVAL_ERR: fprintf(stream, "Error: %s", v->err); break; - - case LVAL_SYM: fprintf(stream, "%s", v->sym); break; - - case LVAL_SEXPR: flval_expr_print(stream, v, '(', ')'); break; - - case LVAL_QEXPR: flval_expr_print(stream, v, '{', '}'); break; - } -} - -void lval_print(lval* v) { flval_print(stdout, v); } - -void lval_println(lval* v) { lval_print(v); putchar('\n'); } - -size_t treeContentsLength(mpc_ast_t* t) { - size_t result = strlen(t->contents); - if (t->children_num == 0) { - return result; - } - - for (int i = 0; i < t->children_num; i++) { - result += treeContentsLength(t->children[i]); - } - return result; -} - -char* concatTreeContents(mpc_ast_t* t) { - // Calculate size needed for the string - size_t totalLength = treeContentsLength(t); - - // Allocate memory for string and null terminator - char* stringToExtend = malloc(totalLength + 1); - // [TODO] Write an allocation error handler - - size_t currentLength = 0; - concatNodeContents(stringToExtend, t, ¤tLength); - - stringToExtend[totalLength] = '\0'; - - return stringToExtend; -} - -void concatNodeContents(char* stringToExtend, mpc_ast_t* t, size_t* currentLength) { - size_t leafLength = strlen(t->contents); - - memcpy(stringToExtend + (*currentLength), t->contents, leafLength); - *currentLength = *currentLength + leafLength; - - if (t->children_num != 0) { - for (int i = 0; i < t->children_num; i++) { - concatNodeContents(stringToExtend, t->children[i], currentLength); - } - } - -} -lval* lval_eval_sexpr(lval* v) { - // Evaluate children - for (int i = 0; i < v->count; i++) { - v->cell[i] = lval_eval(v->cell[i]); - } - // Error checking [If there's an error, return it] - for (int i = 0; i < v->count; i++) { - if (v->cell[i]->type == LVAL_ERR) { return lval_take(v, i); } - } - // Empty expression - if (v->count == 0) { return v; } - - // Single expression - if (v->count == 1) { return lval_take(v, 0); } - - // Ensure first element is a symbol otherwise - lval* f = lval_pop(v, 0); - if (f->type != LVAL_SYM) { - printf("The type of f is %d\n", f->type); - lval_del(f); lval_del(v); - return lval_err("S-expression does not start with symbol"); - } - - lval* result = builtin_op(v, f->sym); - lval_del(f); - return result; -} - -lval* lval_eval(lval* v) { - // Evauluate sexpressions - if (v->type == LVAL_SEXPR) { return lval_eval_sexpr(v); } - - // All other lval types remail the same - return v; -} - -lval* lval_pop(lval* v, int i) { - // Find the item at i - lval* x = v->cell[i]; - - // Shift the memory after the item i over the top - memmove(&v->cell[i], &v->cell[i + 1], sizeof(lval*) * (v->count - i - 1)); - - // Decrease the count of items in the list - v->count--; - - // Reallocate the memory used - v->cell = realloc(v->cell, sizeof(lval*) * v->count); - return x; -} - -lval* lval_take(lval* v, int i) { - lval* x = lval_pop(v, i); - lval_del(v); - return x; -} lval* builtin_op(lval* a, char* op) { // Ensure all arguments are numbers @@ -464,19 +158,3 @@ lval* builtin_op(lval* a, char* op) { lval_del(a); return x; } - - -double lval_getData(lval* x) { - if (x->type == LVAL_LONG) { - return x->data.num; - } - return x->data.dec; -} - -void lval_updateData(lval* x, double val, int type) { - if (type == LVAL_LONG) { - x->data.num = val; - return; - } - x->data.dec = val; -}