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
|
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 mpc.o -ledit -lm -o prompt
|
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
|
loperations.o: lval/operations.c lval/operations.h
|
||||||
cc -std=c99 -Wall -c lval/operations.c -o loperations.o
|
cc -std=c99 -Wall -c lval/operations.c -o loperations.o
|
||||||
lnumbers.o: lval/numbers.c lval/numbers.h
|
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
|
cc -std=c99 -Wall -c lval/io.c -o lio.o
|
||||||
lerror.o: lval/error.c lval/error.h
|
lerror.o: lval/error.c lval/error.h
|
||||||
cc -std=c99 -Wall -c lval/error.c -o lerror.o
|
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
|
mpc.o: mpc.c mpc.h
|
||||||
cc -std=c99 -Wall -lm -c mpc.c
|
cc -std=c99 -Wall -lm -c mpc.c
|
||||||
clean:
|
clean:
|
||||||
|
|
2
lval.h
2
lval.h
|
@ -14,5 +14,7 @@
|
||||||
#include "lval/operations.h"
|
#include "lval/operations.h"
|
||||||
// Add the ability to print out lval structures
|
// Add the ability to print out lval structures
|
||||||
#include "lval/io.h"
|
#include "lval/io.h"
|
||||||
|
// Add environments, variables, and functions
|
||||||
|
#include "lval/environment.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
18
lval/base.h
18
lval/base.h
|
@ -1,24 +1,34 @@
|
||||||
#ifndef LVAL_BASE
|
#ifndef LVAL_BASE
|
||||||
#define 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 {
|
typedef union typeval {
|
||||||
long num;
|
long num;
|
||||||
double dec;
|
double dec;
|
||||||
} 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
|
||||||
typedef struct lval {
|
struct lval {
|
||||||
int type;
|
int type;
|
||||||
TypeVal data;
|
TypeVal data;
|
||||||
|
|
||||||
// Error and symbols contain string data
|
// Error and symbols contain string data
|
||||||
char* err;
|
char* err;
|
||||||
char* sym;
|
char* sym;
|
||||||
|
lbuiltin fun;
|
||||||
|
|
||||||
// Count and pointer to a list of lval*
|
// Count and pointer to a list of lval*
|
||||||
int count;
|
int count;
|
||||||
struct lval** cell;
|
lval** cell;
|
||||||
} lval;
|
};
|
||||||
|
|
||||||
// Possible lispy value types
|
// 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
|
#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_SEXPR: flval_expr_print(stream, v, '(', ')'); break;
|
||||||
|
|
||||||
case LVAL_QEXPR: 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) {
|
switch (v->type) {
|
||||||
case LVAL_LONG: break;
|
case LVAL_LONG: break;
|
||||||
case LVAL_DOUBLE: break;
|
case LVAL_DOUBLE: break;
|
||||||
|
case LVAL_FUN: break;
|
||||||
|
|
||||||
// Free the string data
|
// Free the string data
|
||||||
case LVAL_ERR: free(v->err); break;
|
case LVAL_ERR: free(v->err); break;
|
||||||
|
@ -75,4 +76,36 @@ void lval_del(lval* v) {
|
||||||
free(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);
|
lval* lval_sym(char* s);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Methods to read (parse AST), evaluate,
|
Methods to read (parse AST), evaluate,
|
||||||
and delete lval structures
|
copy, and delete lval structures
|
||||||
*/
|
*/
|
||||||
lval* lval_read(mpc_ast_t* t);
|
lval* lval_read(mpc_ast_t* t);
|
||||||
lval* lval_eval(lval* v);
|
lval* lval_eval(lval* v);
|
||||||
void lval_del(lval* v);
|
void lval_del(lval* v);
|
||||||
|
lval* lval_copy(lval* v);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
7
prompt.c
7
prompt.c
|
@ -53,12 +53,7 @@ int main (int argc, char** argv) {
|
||||||
"number : /[0-9]+/; "
|
"number : /[0-9]+/; "
|
||||||
"long : /-?[0-9]+/; "
|
"long : /-?[0-9]+/; "
|
||||||
"double : <long> '.' <number>; "
|
"double : <long> '.' <number>; "
|
||||||
"symbol : '+' | '-' | '*' | '/' | '%' \
|
"symbol : /[a-zA-Z0-9_+\\-*\\/\\\\=<>!&]+/; "
|
||||||
| '^' | \"min\" | \"max\" \
|
|
||||||
| \"list\" | \"head\" | \"tail\" \
|
|
||||||
| \"join\" | \"eval\" | \"len\" \
|
|
||||||
| \"init\" | \"cons\"; "
|
|
||||||
|
|
||||||
"sexpr : '(' <expr>* ')'; "
|
"sexpr : '(' <expr>* ')'; "
|
||||||
"qexpr : '{' <expr>* '}'; "
|
"qexpr : '{' <expr>* '}'; "
|
||||||
"expr : (<double> | <long>) | <symbol> | <sexpr> | <qexpr>; "
|
"expr : (<double> | <long>) | <symbol> | <sexpr> | <qexpr>; "
|
||||||
|
|
Reference in a new issue