#define LASSERT(args, cond, err) \
|
|
if (!(cond)) { lval_del(args); return lval_err(err); }
|
|
|
|
|
|
static char* lispy_version = "Lispy version 0.0.0.0.6";
|
|
|
|
|
|
/* Parser language defintion */
|
|
static char* parser =
|
|
" \
|
|
number : /-?[0-9]+([.][0-9]*|[0-9]*)/ ; \
|
|
symbol : \"list\" | \"head\" | \"tail\" | \"join\" | \
|
|
\"eval\" | \"len\" | \"init\" | \"cons\" | \
|
|
'+' | '-' | '*' | '/' | '%' | \
|
|
'^' | \"min\" | \"max\" ; \
|
|
sexpr : '(' <expr>* ')' ; \
|
|
qexpr : '{' <expr>* '}' ; \
|
|
expr : <number> | <symbol> | <sexpr> | <qexpr>; \
|
|
lispy : /^/ <expr>* /$/ ; \
|
|
";
|
|
|
|
|
|
/* Declare new lval struct */
|
|
typedef struct lval {
|
|
int type;
|
|
/* only one of the two number/decimal is valid in a
|
|
lval instance, so we can use an anonymous union */
|
|
union {
|
|
long num;
|
|
double dec;
|
|
};
|
|
/* Error & symbol types have some string data */
|
|
char* err;
|
|
char* sym;
|
|
/* Counter & pointer to a list of lval */
|
|
size_t count;
|
|
struct lval** cell;
|
|
} lval;
|
|
|
|
|
|
/* Create enumeration of possible lval types */
|
|
enum lval_types {LVAL_NUM, LVAL_DEC, LVAL_SYM, LVAL_SEXPR,
|
|
LVAL_QEXPR, LVAL_ERR};
|
|
|
|
/* lval constructor functions */
|
|
lval* lval_num(long x);
|
|
lval* lval_dec(double x);
|
|
lval* lval_err(char* m);
|
|
lval* lval_sym(char* s);
|
|
lval* lval_sexpr(void);
|
|
lval* lval_qexpr(void);
|
|
|
|
/* lval destructor function */
|
|
void lval_del(lval* v);
|
|
|
|
/* lval manipulating functions */
|
|
lval* lval_add(lval* v, lval* x);
|
|
lval* lval_pop(lval* v, size_t i);
|
|
lval* lval_take(lval* v, size_t i);
|
|
|
|
lval* lval_read_num(mpc_ast_t* t);
|
|
lval* lval_read(mpc_ast_t* t);
|
|
lval* lval_eval_sexpr(lval* v);
|
|
lval* lval_eval(lval* v);
|
|
|
|
/* lval print functions */
|
|
void lval_expr_print(lval* v, char open, char close);
|
|
void lval_print(lval* v);
|
|
void lval_println(lval* v);
|
|
|
|
/* language built-in operators and functions */
|
|
long min(long x, long y);
|
|
long max(long x, long y);
|
|
lval* builtin(lval* a, char* func);
|
|
lval* builtin_op(lval* a, char* op);
|
|
lval* builtin_head(lval* a);
|
|
lval* builtin_tail(lval* a);
|
|
lval* builtin_list(lval* a);
|
|
lval* builtin_eval(lval* a);
|
|
lval* builtin_join(lval* a);
|
|
lval* lval_join(lval* x, lval* y);
|
|
lval* builtin_cons(lval* a);
|
|
lval* builtin_len(lval* a);
|
|
lval* builtin_init(lval* a);
|