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);
|
lval_delete(val);
|
||||||
return lval_s_expr();
|
return lval_ok();
|
||||||
}
|
}
|
||||||
lval* builtin_var(lenv* env, lval* val) {
|
lval* builtin_var(lenv* env, lval* val) {
|
||||||
return builtin_envdef(env, val, "var");
|
return builtin_envdef(env, val, "var");
|
||||||
@@ -377,7 +377,7 @@ lval* builtin_listenv(lenv* env, lval* val) {
|
|||||||
lval_println(env->syms[i]->lval);
|
lval_println(env->syms[i]->lval);
|
||||||
}
|
}
|
||||||
lval_delete(val);
|
lval_delete(val);
|
||||||
return lval_s_expr();
|
return lval_ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
lval* builtin_exit(lenv* env, lval* val) {
|
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) {
|
if (loadonce == TRUE && file_loaded == TRUE) {
|
||||||
lval_delete(val);
|
lval_delete(val);
|
||||||
return lval_s_expr();
|
return lval_ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
mpc_result_t result;
|
mpc_result_t result;
|
||||||
@@ -458,7 +458,7 @@ lval* builtin_do_load(lenv* env, lval* val, BOOL loadonce) {
|
|||||||
//Evaluate the read lisp file
|
//Evaluate the read lisp file
|
||||||
lval* resultLval = parse(result.output);
|
lval* resultLval = parse(result.output);
|
||||||
mpc_ast_delete(result.output);
|
mpc_ast_delete(result.output);
|
||||||
lval_println(resultLval);
|
|
||||||
while(resultLval->cell_count > 0) {
|
while(resultLval->cell_count > 0) {
|
||||||
lval* x = eval(env, lval_pop(resultLval, 0));
|
lval* x = eval(env, lval_pop(resultLval, 0));
|
||||||
if (x->type == LVAL_ERR) {
|
if (x->type == LVAL_ERR) {
|
||||||
@@ -476,7 +476,7 @@ lval* builtin_do_load(lenv* env, lval* val, BOOL loadonce) {
|
|||||||
lval_delete(resultLval);
|
lval_delete(resultLval);
|
||||||
lval_delete(val);
|
lval_delete(val);
|
||||||
|
|
||||||
return lval_s_expr();
|
return lval_ok();
|
||||||
} else {
|
} else {
|
||||||
//Parse error
|
//Parse error
|
||||||
char* errorMessage = mpc_err_string(result.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() {
|
void setup_parsers() {
|
||||||
mpc_parser_t* Number = mpc_new("number");
|
mpc_parser_t* Number = mpc_new("number");
|
||||||
|
mpc_parser_t* Ok = mpc_new("ok");
|
||||||
mpc_parser_t* Symbol = mpc_new("symbol");
|
mpc_parser_t* Symbol = mpc_new("symbol");
|
||||||
mpc_parser_t* String = mpc_new("string");
|
mpc_parser_t* String = mpc_new("string");
|
||||||
mpc_parser_t* Comment = mpc_new("comment");
|
mpc_parser_t* Comment = mpc_new("comment");
|
||||||
@@ -29,21 +30,23 @@ void setup_parsers() {
|
|||||||
mpca_lang(MPCA_LANG_DEFAULT,
|
mpca_lang(MPCA_LANG_DEFAULT,
|
||||||
" \
|
" \
|
||||||
number : /-?[0-9]+(\\.[0-9]+)?/ ; \
|
number : /-?[0-9]+(\\.[0-9]+)?/ ; \
|
||||||
|
ok : /ok/ ; \
|
||||||
symbol : /[a-zA-Z0-9_+\\-*\\/\\\\=<>!&\\|]+/ ; \
|
symbol : /[a-zA-Z0-9_+\\-*\\/\\\\=<>!&\\|]+/ ; \
|
||||||
string : /\"(\\\\.|[^\"])*\"/ ; \
|
string : /\"(\\\\.|[^\"])*\"/ ; \
|
||||||
comment : /;[^\\r?\\n]*/ ; \
|
comment : /;[^\\r?\\n]*/ ; \
|
||||||
s_expr : '(' <expr>* ')' ; \
|
s_expr : '(' <expr>* ')' ; \
|
||||||
q_expr : '{' <expr>* '}' ; \
|
q_expr : '{' <expr>* '}' ; \
|
||||||
expr : <number> | <symbol> | <string> \
|
expr : <number> | <ok> | <symbol> | <string> \
|
||||||
| <comment> | <s_expr> | <q_expr> ; \
|
| <comment> | <s_expr> | <q_expr> ; \
|
||||||
lispy : /^/ <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;
|
gLispy = Lispy;
|
||||||
gParsers = calloc(20, sizeof(mpc_parser_t*));
|
gParsers = calloc(20, sizeof(mpc_parser_t*));
|
||||||
int i = 0;
|
int i = 0;
|
||||||
gParsers[i++] = Number;
|
gParsers[i++] = Number;
|
||||||
|
gParsers[i++] = Ok;
|
||||||
gParsers[i++] = Symbol;
|
gParsers[i++] = Symbol;
|
||||||
gParsers[i++] = String;
|
gParsers[i++] = String;
|
||||||
gParsers[i++] = Comment;
|
gParsers[i++] = Comment;
|
||||||
@@ -69,6 +72,9 @@ lval* parse(mpc_ast_t *t) {
|
|||||||
double_t d = strtod(t->contents, NULL);
|
double_t d = strtod(t->contents, NULL);
|
||||||
return errno != 0 ? lval_err_detail(LERR_BAD_NUM, strerror(errno)) : lval_num(d);
|
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")) {
|
if (strstr(t->tag, "symbol")) {
|
||||||
return lval_sym(t->contents);
|
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);
|
val->data.str = strdup(str);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
lval* lval_ok() {
|
||||||
|
lval* val = lval_new(LVAL_OK);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
lval* lval_add(lval* val, lval* x) {
|
lval* lval_add(lval* val, lval* x) {
|
||||||
val->cell_count++;
|
val->cell_count++;
|
||||||
@@ -149,10 +153,12 @@ BOOL lval_equal(lval* a, lval* b) {
|
|||||||
|
|
||||||
switch(a->type) {
|
switch(a->type) {
|
||||||
case LVAL_ERR: return a->data.err.num == b->data.err.num;
|
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_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_SYM: return strcmp(a->data.sym, b->data.sym) == 0;
|
||||||
case LVAL_STR: return strcmp(a->data.str, b->data.str) == 0;
|
case LVAL_STR: return strcmp(a->data.str, b->data.str) == 0;
|
||||||
|
case LVAL_OK:
|
||||||
|
case LVAL_EXIT:
|
||||||
|
return TRUE;
|
||||||
case LVAL_FUNC:
|
case LVAL_FUNC:
|
||||||
if (a->data.func->builtin != NULL) {
|
if (a->data.func->builtin != NULL) {
|
||||||
if (b->data.func->builtin != NULL) {
|
if (b->data.func->builtin != NULL) {
|
||||||
@@ -186,6 +192,7 @@ void lval_delete(lval* val) {
|
|||||||
switch(val->type) {
|
switch(val->type) {
|
||||||
case LVAL_NUM: break;
|
case LVAL_NUM: break;
|
||||||
case LVAL_EXIT: break;
|
case LVAL_EXIT: break;
|
||||||
|
case LVAL_OK: break;
|
||||||
case LVAL_FUNC:
|
case LVAL_FUNC:
|
||||||
if (val->data.func != NULL) {
|
if (val->data.func != NULL) {
|
||||||
if (val->data.func->builtin == NULL) {
|
if (val->data.func->builtin == NULL) {
|
||||||
@@ -238,6 +245,7 @@ lval* lval_copy(lval* current) {
|
|||||||
break;
|
break;
|
||||||
case LVAL_NUM: new->data.num = current->data.num; break;
|
case LVAL_NUM: new->data.num = current->data.num; break;
|
||||||
case LVAL_EXIT: break;
|
case LVAL_EXIT: break;
|
||||||
|
case LVAL_OK: break;
|
||||||
|
|
||||||
case LVAL_SYM: new->data.sym = strdup(current->data.sym); break;
|
case LVAL_SYM: new->data.sym = strdup(current->data.sym); break;
|
||||||
case LVAL_STR: new->data.str = strdup(current->data.str); 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_S_EXPR: return "S-Expression";
|
||||||
case LVAL_EXIT: return "Exit";
|
case LVAL_EXIT: return "Exit";
|
||||||
case LVAL_ERR: return "Error";
|
case LVAL_ERR: return "Error";
|
||||||
|
case LVAL_OK: return "Ok/Success";
|
||||||
default: return "UNKNOWN";
|
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_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)
|
#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 };
|
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_TYPE VAL_TYPE;
|
||||||
typedef enum VAL_ERROR VAL_ERROR;
|
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_lambda(lval* formals, lval* body);
|
||||||
lval* lval_exit(short exitcode);
|
lval* lval_exit(short exitcode);
|
||||||
lval* lval_str(char* str);
|
lval* lval_str(char* str);
|
||||||
|
lval* lval_ok();
|
||||||
|
|
||||||
lval* lval_add(lval* val, lval* x);
|
lval* lval_add(lval* val, lval* x);
|
||||||
lval* lval_pop(lval* val, int i);
|
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
|
//Attempt to import/run files specified on the command line
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
for(int i = 1; i < argc; i++) {
|
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* loadargs = lval_add(lval_s_expr(), lval_str(argv[i]));
|
||||||
|
|
||||||
lval* result = builtin_load(env, loadargs);
|
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_S_EXPR: lval_expr_print(val, "(", ")"); break;
|
||||||
case LVAL_Q_EXPR: lval_expr_print(val, "{", "}"); break;
|
case LVAL_Q_EXPR: lval_expr_print(val, "{", "}"); break;
|
||||||
case LVAL_EXIT: printf("exit"); break;
|
case LVAL_EXIT: printf("exit"); break;
|
||||||
|
case LVAL_OK: printf("ok"); break;
|
||||||
case LVAL_FUNC: ;
|
case LVAL_FUNC: ;
|
||||||
lval_func* func = val->data.func;
|
lval_func* func = val->data.func;
|
||||||
if (func->builtin != NULL) {
|
if (func->builtin != NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user