#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 : '(' * ')' ; \ qexpr : '{' * '}' ; \ expr : | | | ; \ lispy : /^/ * /$/ ; \ "; /* 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);