Started on function type and added copy operation
This commit is contained in:
parent
a47f72f510
commit
e5d5aee39e
9 changed files with 74 additions and 14 deletions
6
Makefile
6
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:
|
||||
|
|
2
lval.h
2
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
|
||||
|
|
18
lval/base.h
18
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
|
||||
|
|
8
lval/environment.c
Normal file
8
lval/environment.c
Normal file
|
@ -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;
|
||||
}
|
7
lval/environment.h
Normal file
7
lval/environment.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
#ifndef LVAL_ENVIRONMENT
|
||||
#define LVAL_ENVIRONMENT
|
||||
#include "base.h"
|
||||
|
||||
lval* lval_fun(lbuiltin func);
|
||||
|
||||
#endif
|
|
@ -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, "<function>"); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
7
prompt.c
7
prompt.c
|
@ -53,12 +53,7 @@ int main (int argc, char** argv) {
|
|||
"number : /[0-9]+/; "
|
||||
"long : /-?[0-9]+/; "
|
||||
"double : <long> '.' <number>; "
|
||||
"symbol : '+' | '-' | '*' | '/' | '%' \
|
||||
| '^' | \"min\" | \"max\" \
|
||||
| \"list\" | \"head\" | \"tail\" \
|
||||
| \"join\" | \"eval\" | \"len\" \
|
||||
| \"init\" | \"cons\"; "
|
||||
|
||||
"symbol : /[a-zA-Z0-9_+\\-*\\/\\\\=<>!&]+/; "
|
||||
"sexpr : '(' <expr>* ')'; "
|
||||
"qexpr : '{' <expr>* '}'; "
|
||||
"expr : (<double> | <long>) | <symbol> | <sexpr> | <qexpr>; "
|
||||
|
|
Reference in a new issue