Added ok value typeto represent success of a function, ie load.
'ok' now represents this type and can be compared to, also cannot be used as a symbol/variable.
This commit is contained in:
10
functions.c
10
functions.c
@@ -362,7 +362,7 @@ lval* builtin_envdef(lenv* env, lval* val, char* type){
|
||||
}
|
||||
|
||||
lval_delete(val);
|
||||
return lval_s_expr();
|
||||
return lval_ok();
|
||||
}
|
||||
lval* builtin_var(lenv* env, lval* val) {
|
||||
return builtin_envdef(env, val, "var");
|
||||
@@ -377,7 +377,7 @@ lval* builtin_listenv(lenv* env, lval* val) {
|
||||
lval_println(env->syms[i]->lval);
|
||||
}
|
||||
lval_delete(val);
|
||||
return lval_s_expr();
|
||||
return lval_ok();
|
||||
}
|
||||
|
||||
lval* builtin_exit(lenv* env, lval* val) {
|
||||
@@ -449,7 +449,7 @@ lval* builtin_do_load(lenv* env, lval* val, BOOL loadonce) {
|
||||
|
||||
if (loadonce == TRUE && file_loaded == TRUE) {
|
||||
lval_delete(val);
|
||||
return lval_s_expr();
|
||||
return lval_ok();
|
||||
}
|
||||
|
||||
mpc_result_t result;
|
||||
@@ -458,7 +458,7 @@ lval* builtin_do_load(lenv* env, lval* val, BOOL loadonce) {
|
||||
//Evaluate the read lisp file
|
||||
lval* resultLval = parse(result.output);
|
||||
mpc_ast_delete(result.output);
|
||||
lval_println(resultLval);
|
||||
|
||||
while(resultLval->cell_count > 0) {
|
||||
lval* x = eval(env, lval_pop(resultLval, 0));
|
||||
if (x->type == LVAL_ERR) {
|
||||
@@ -476,7 +476,7 @@ lval* builtin_do_load(lenv* env, lval* val, BOOL loadonce) {
|
||||
lval_delete(resultLval);
|
||||
lval_delete(val);
|
||||
|
||||
return lval_s_expr();
|
||||
return lval_ok();
|
||||
} else {
|
||||
//Parse error
|
||||
char* errorMessage = mpc_err_string(result.error);
|
||||
|
||||
10
lang.c
10
lang.c
@@ -18,6 +18,7 @@ mpc_ast_t* tokenize(char *input) {
|
||||
}
|
||||
void setup_parsers() {
|
||||
mpc_parser_t* Number = mpc_new("number");
|
||||
mpc_parser_t* Ok = mpc_new("ok");
|
||||
mpc_parser_t* Symbol = mpc_new("symbol");
|
||||
mpc_parser_t* String = mpc_new("string");
|
||||
mpc_parser_t* Comment = mpc_new("comment");
|
||||
@@ -29,21 +30,23 @@ void setup_parsers() {
|
||||
mpca_lang(MPCA_LANG_DEFAULT,
|
||||
" \
|
||||
number : /-?[0-9]+(\\.[0-9]+)?/ ; \
|
||||
ok : /ok/ ; \
|
||||
symbol : /[a-zA-Z0-9_+\\-*\\/\\\\=<>!&\\|]+/ ; \
|
||||
string : /\"(\\\\.|[^\"])*\"/ ; \
|
||||
comment : /;[^\\r?\\n]*/ ; \
|
||||
s_expr : '(' <expr>* ')' ; \
|
||||
q_expr : '{' <expr>* '}' ; \
|
||||
expr : <number> | <symbol> | <string> \
|
||||
expr : <number> | <ok> | <symbol> | <string> \
|
||||
| <comment> | <s_expr> | <q_expr> ; \
|
||||
lispy : /^/ <expr>+ /$/ ; \
|
||||
",
|
||||
Number, Symbol, String, Comment, Expr, S_Expr, Q_Expr, Lispy);
|
||||
Number, Ok, Symbol, String, Comment, Expr, S_Expr, Q_Expr, Lispy);
|
||||
|
||||
gLispy = Lispy;
|
||||
gParsers = calloc(20, sizeof(mpc_parser_t*));
|
||||
int i = 0;
|
||||
gParsers[i++] = Number;
|
||||
gParsers[i++] = Ok;
|
||||
gParsers[i++] = Symbol;
|
||||
gParsers[i++] = String;
|
||||
gParsers[i++] = Comment;
|
||||
@@ -69,6 +72,9 @@ lval* parse(mpc_ast_t *t) {
|
||||
double_t d = strtod(t->contents, NULL);
|
||||
return errno != 0 ? lval_err_detail(LERR_BAD_NUM, strerror(errno)) : lval_num(d);
|
||||
}
|
||||
if (strstr(t->tag, "ok")) {
|
||||
return lval_ok();
|
||||
}
|
||||
if (strstr(t->tag, "symbol")) {
|
||||
return lval_sym(t->contents);
|
||||
}
|
||||
|
||||
11
lval.c
11
lval.c
@@ -63,6 +63,10 @@ lval* lval_str(char* str) {
|
||||
val->data.str = strdup(str);
|
||||
return val;
|
||||
}
|
||||
lval* lval_ok() {
|
||||
lval* val = lval_new(LVAL_OK);
|
||||
return val;
|
||||
}
|
||||
|
||||
lval* lval_add(lval* val, lval* x) {
|
||||
val->cell_count++;
|
||||
@@ -149,10 +153,12 @@ BOOL lval_equal(lval* a, lval* b) {
|
||||
|
||||
switch(a->type) {
|
||||
case LVAL_ERR: return a->data.err.num == b->data.err.num;
|
||||
case LVAL_EXIT: return TRUE;
|
||||
case LVAL_NUM: return fabs(a->data.num - b->data.num) <= DBL_EPSILON;
|
||||
case LVAL_SYM: return strcmp(a->data.sym, b->data.sym) == 0;
|
||||
case LVAL_STR: return strcmp(a->data.str, b->data.str) == 0;
|
||||
case LVAL_OK:
|
||||
case LVAL_EXIT:
|
||||
return TRUE;
|
||||
case LVAL_FUNC:
|
||||
if (a->data.func->builtin != NULL) {
|
||||
if (b->data.func->builtin != NULL) {
|
||||
@@ -186,6 +192,7 @@ void lval_delete(lval* val) {
|
||||
switch(val->type) {
|
||||
case LVAL_NUM: break;
|
||||
case LVAL_EXIT: break;
|
||||
case LVAL_OK: break;
|
||||
case LVAL_FUNC:
|
||||
if (val->data.func != NULL) {
|
||||
if (val->data.func->builtin == NULL) {
|
||||
@@ -238,6 +245,7 @@ lval* lval_copy(lval* current) {
|
||||
break;
|
||||
case LVAL_NUM: new->data.num = current->data.num; break;
|
||||
case LVAL_EXIT: break;
|
||||
case LVAL_OK: break;
|
||||
|
||||
case LVAL_SYM: new->data.sym = strdup(current->data.sym); break;
|
||||
case LVAL_STR: new->data.str = strdup(current->data.str); break;
|
||||
@@ -300,6 +308,7 @@ char* lval_str_name(VAL_TYPE type) {
|
||||
case LVAL_S_EXPR: return "S-Expression";
|
||||
case LVAL_EXIT: return "Exit";
|
||||
case LVAL_ERR: return "Error";
|
||||
case LVAL_OK: return "Ok/Success";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
3
lval.h
3
lval.h
@@ -25,7 +25,7 @@ typedef struct lval_func lval_func;
|
||||
#define LVAL_IS_TRUE(val) (val->type == LVAL_NUM && fabs(val->data.num) > DBL_EPSILON)
|
||||
#define LVAL_IS_FALSE(val) (val->type == LVAL_NUM && fabs(val->data.num) <= DBL_EPSILON)
|
||||
|
||||
enum VAL_TYPE { LVAL_ERR, LVAL_NUM, LVAL_SYM, LVAL_FUNC, LVAL_S_EXPR, LVAL_Q_EXPR, LVAL_EXIT, LVAL_STR };
|
||||
enum VAL_TYPE { LVAL_ERR, LVAL_NUM, LVAL_SYM, LVAL_FUNC, LVAL_S_EXPR, LVAL_Q_EXPR, LVAL_EXIT, LVAL_STR, LVAL_OK };
|
||||
enum VAL_ERROR { LERR_DIV_ZERO, LERR_BAD_OP, LERR_BAD_NUM, LERR_BAD_SYM, LERR_OTHER, LERR_SYNTAX };
|
||||
typedef enum VAL_TYPE VAL_TYPE;
|
||||
typedef enum VAL_ERROR VAL_ERROR;
|
||||
@@ -69,6 +69,7 @@ lval* lval_builtin(lbuiltin func, char* name);
|
||||
lval* lval_lambda(lval* formals, lval* body);
|
||||
lval* lval_exit(short exitcode);
|
||||
lval* lval_str(char* str);
|
||||
lval* lval_ok();
|
||||
|
||||
lval* lval_add(lval* val, lval* x);
|
||||
lval* lval_pop(lval* val, int i);
|
||||
|
||||
2
main.c
2
main.c
@@ -30,7 +30,6 @@ int main(int argc, char** argv) {
|
||||
//Attempt to import/run files specified on the command line
|
||||
if (argc > 1) {
|
||||
for(int i = 1; i < argc; i++) {
|
||||
printf("Loading File \"%s\"\n", argv[i]);
|
||||
lval* loadargs = lval_add(lval_s_expr(), lval_str(argv[i]));
|
||||
|
||||
lval* result = builtin_load(env, loadargs);
|
||||
@@ -115,6 +114,7 @@ void lval_print(lval* val) {
|
||||
case LVAL_S_EXPR: lval_expr_print(val, "(", ")"); break;
|
||||
case LVAL_Q_EXPR: lval_expr_print(val, "{", "}"); break;
|
||||
case LVAL_EXIT: printf("exit"); break;
|
||||
case LVAL_OK: printf("ok"); break;
|
||||
case LVAL_FUNC: ;
|
||||
lval_func* func = val->data.func;
|
||||
if (func->builtin != NULL) {
|
||||
|
||||
Reference in New Issue
Block a user