From e5d5aee39e20dc97942f7f8ea9bb2f1af622d3a6 Mon Sep 17 00:00:00 2001 From: Brandon Rozek Date: Sat, 9 Jun 2018 18:40:32 -0400 Subject: [PATCH] Started on function type and added copy operation --- Makefile | 6 ++++-- lval.h | 2 ++ lval/base.h | 18 ++++++++++++++---- lval/environment.c | 8 ++++++++ lval/environment.h | 7 +++++++ lval/io.c | 2 ++ lval/operations.c | 33 +++++++++++++++++++++++++++++++++ lval/operations.h | 5 +++-- prompt.c | 7 +------ 9 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 lval/environment.c create mode 100644 lval/environment.h diff --git a/Makefile b/Makefile index f407181..b2e5b91 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -run: prompt.c loperations.o lnumbers.o lexpressions.o lio.o lerror.o mpc.o - cc -std=c99 -Wall prompt.c loperations.o lnumbers.o lexpressions.o lio.o lerror.o mpc.o -ledit -lm -o prompt +run: prompt.c loperations.o lnumbers.o lexpressions.o lio.o lerror.o lenvironment.o mpc.o + cc -std=c99 -Wall prompt.c loperations.o lnumbers.o lexpressions.o lio.o lerror.o lenvironment.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 @@ -10,6 +10,8 @@ lio.o: lval/io.c lval/io.h cc -std=c99 -Wall -c lval/io.c -o lio.o lerror.o: lval/error.c lval/error.h cc -std=c99 -Wall -c lval/error.c -o lerror.o +lenvironment.o: lval/environment.c lval/environment.h + cc -std=c99 -Wall -c lval/environment.c -o lenvironment.o mpc.o: mpc.c mpc.h cc -std=c99 -Wall -lm -c mpc.c clean: diff --git a/lval.h b/lval.h index 0fe7489..5fb708e 100644 --- a/lval.h +++ b/lval.h @@ -14,5 +14,7 @@ #include "lval/operations.h" // Add the ability to print out lval structures #include "lval/io.h" +// Add environments, variables, and functions +#include "lval/environment.h" #endif diff --git a/lval/base.h b/lval/base.h index 2547c99..16dd3e7 100644 --- a/lval/base.h +++ b/lval/base.h @@ -1,24 +1,34 @@ #ifndef LVAL_BASE #define LVAL_BASE + +struct lval; +struct lenv; + +typedef struct lval lval; +typedef struct lenv lenv; + +typedef lval* (*lbuiltin) (lenv*, lval*); + typedef union typeval { long num; double dec; } TypeVal; // A lispy value can either be a number, error, symbol, or an expression -typedef struct lval { +struct lval { int type; TypeVal data; // Error and symbols contain string data char* err; char* sym; + lbuiltin fun; // Count and pointer to a list of lval* int count; - struct lval** cell; -} lval; + lval** cell; +}; // Possible lispy value types -enum { LVAL_ERR, LVAL_LONG, LVAL_DOUBLE, LVAL_SYM, LVAL_SEXPR, LVAL_QEXPR }; +enum { LVAL_ERR, LVAL_LONG, LVAL_DOUBLE, LVAL_SYM, LVAL_SEXPR, LVAL_QEXPR, LVAL_FUN }; #endif diff --git a/lval/environment.c b/lval/environment.c new file mode 100644 index 0000000..ebc513c --- /dev/null +++ b/lval/environment.c @@ -0,0 +1,8 @@ +#include "environment.h" + +lval* lval_fun(lbuiltin func) { + lval* v = malloc(sizeof(lval)); + v->type = LVAL_FUN; + v->fun = func; + return v; +} \ No newline at end of file diff --git a/lval/environment.h b/lval/environment.h new file mode 100644 index 0000000..5a8eced --- /dev/null +++ b/lval/environment.h @@ -0,0 +1,7 @@ +#ifndef LVAL_ENVIRONMENT +#define LVAL_ENVIRONMENT +#include "base.h" + +lval* lval_fun(lbuiltin func); + +#endif diff --git a/lval/io.c b/lval/io.c index 8c2a9b3..1a05b3e 100644 --- a/lval/io.c +++ b/lval/io.c @@ -29,6 +29,8 @@ void flval_print(FILE* stream, lval* v) { case LVAL_SEXPR: flval_expr_print(stream, v, '(', ')'); break; case LVAL_QEXPR: flval_expr_print(stream, v, '{', '}'); break; + + case LVAL_FUN: fprintf(stream, ""); break; } } diff --git a/lval/operations.c b/lval/operations.c index 67611ad..cf8a122 100644 --- a/lval/operations.c +++ b/lval/operations.c @@ -54,6 +54,7 @@ void lval_del(lval* v) { switch (v->type) { case LVAL_LONG: break; case LVAL_DOUBLE: break; + case LVAL_FUN: break; // Free the string data case LVAL_ERR: free(v->err); break; @@ -75,4 +76,36 @@ void lval_del(lval* v) { free(v); } +lval* lval_copy(lval* v) { + lval* x = (lval*) malloc(sizeof(lval)); + x->type = v->type; + + switch (v->type) { + // Copy numbers and functions directly + case LVAL_LONG: x->data.num = v->data.num; break; + case LVAL_DOUBLE: x->data.dec = v->data.dec; break; + case LVAL_FUN: x->fun = v->fun; break; + + // Copy strings using malloc and strcpy + case LVAL_ERR: + x->err = (char*) malloc(strlen(v->err) + 1); + strcpy(x->err, v->err); break; + case LVAL_SYM: + x->sym = (char*) malloc(strlen(v->sym) + 1); + strcpy(x->sym, v->sym); break; + + // Copy lists by copying each sub-expression + case LVAL_SEXPR: + case LVAL_QEXPR: + x->count = v->count; + x->cell = (lval**) malloc(sizeof(lval*) * x->count); + for (int i = 0; i < x->count; i++) { + x->cell[i] = lval_copy(v->cell[i]); + } + break; + } + + return x; +} + diff --git a/lval/operations.h b/lval/operations.h index 501e2e4..64f56e4 100644 --- a/lval/operations.h +++ b/lval/operations.h @@ -8,11 +8,12 @@ lval* lval_sym(char* s); /* - Methods to read (parse AST), evaluate, - and delete lval structures + Methods to read (parse AST), evaluate, + copy, and delete lval structures */ lval* lval_read(mpc_ast_t* t); lval* lval_eval(lval* v); void lval_del(lval* v); +lval* lval_copy(lval* v); #endif diff --git a/prompt.c b/prompt.c index 3701c44..bf813b4 100644 --- a/prompt.c +++ b/prompt.c @@ -53,12 +53,7 @@ int main (int argc, char** argv) { "number : /[0-9]+/; " "long : /-?[0-9]+/; " "double : '.' ; " - "symbol : '+' | '-' | '*' | '/' | '%' \ - | '^' | \"min\" | \"max\" \ - | \"list\" | \"head\" | \"tail\" \ - | \"join\" | \"eval\" | \"len\" \ - | \"init\" | \"cons\"; " - + "symbol : /[a-zA-Z0-9_+\\-*\\/\\\\=<>!&]+/; " "sexpr : '(' * ')'; " "qexpr : '{' * '}'; " "expr : ( | ) | | | ; "