added option to load files once
This commit is contained in:
43
functions.c
43
functions.c
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "lang.h"
|
||||
#include "main.h"
|
||||
#include "util.h"
|
||||
|
||||
void lenv_add_builtin(lenv* env, char* sym, lbuiltin func) {
|
||||
lval* symval = lval_sym(sym);
|
||||
@@ -392,10 +393,38 @@ lval* builtin_lambda(lenv* env, lval* val) {
|
||||
return lambda;
|
||||
}
|
||||
lval* builtin_load(lenv* env, lval* val) {
|
||||
LASSERT_ARG_COUNT("load", val, val, 1);
|
||||
LASSERT_MIN_ARG_COUNT("load", val, val, 1);
|
||||
LASSERT_TYPE("load", val, val->cell_list[0], LVAL_STR);
|
||||
|
||||
char* filename = val->cell_list[0]->data.str;
|
||||
lval* fileval = NULL;
|
||||
lval* option = NULL;
|
||||
|
||||
if (val->cell_count == 1) {
|
||||
fileval = val->cell_list[0];
|
||||
} else if (val->cell_count > 1) {
|
||||
LASSERT_TYPE("load", val, val->cell_list[1], LVAL_STR);
|
||||
option = val->cell_list[0];
|
||||
fileval = val->cell_list[1];
|
||||
}
|
||||
|
||||
lenv* rootenv = lenv_get_root(env);
|
||||
|
||||
char* filename = fileval->data.str;
|
||||
|
||||
BOOL file_loaded = FALSE;
|
||||
for(int i =0 ; i < rootenv->loaded_files_count; i++) {
|
||||
if (strcmp(filename, rootenv->loaded_files[i]) == 0) {
|
||||
file_loaded = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (option != NULL && strcmp(option->data.str, "once") == 0) {
|
||||
if (file_loaded == TRUE) {
|
||||
lval_delete(val);
|
||||
return lval_s_expr();
|
||||
}
|
||||
}
|
||||
|
||||
mpc_result_t result;
|
||||
if (mpc_parse_contents(filename, gLispy, &result)) {
|
||||
@@ -412,6 +441,12 @@ lval* builtin_load(lenv* env, lval* val) {
|
||||
lval_delete(x);
|
||||
}
|
||||
|
||||
if (file_loaded == FALSE) {
|
||||
rootenv->loaded_files = realloc(rootenv->loaded_files, sizeof(char*) * rootenv->loaded_files_count+1);
|
||||
rootenv->loaded_files[rootenv->loaded_files_count] = strdup(filename);
|
||||
rootenv->loaded_files_count++;
|
||||
}
|
||||
|
||||
lval_delete(resultLval);
|
||||
lval_delete(val);
|
||||
|
||||
@@ -421,10 +456,6 @@ lval* builtin_load(lenv* env, lval* val) {
|
||||
char* errorMessage = mpc_err_string(result.error);
|
||||
mpc_err_delete(result.error);
|
||||
|
||||
char cwd[1024];
|
||||
getcwd(cwd, sizeof(cwd)-1);
|
||||
printf("dir: %s\n", cwd);
|
||||
|
||||
lval* err = lval_err_detail(LERR_OTHER,"Load: %s", errorMessage);
|
||||
free(errorMessage);
|
||||
lval_delete(val);
|
||||
|
||||
24
lenv.c
24
lenv.c
@@ -8,15 +8,24 @@ lenv* lenv_new() {
|
||||
env->count = 0;
|
||||
env->parent = NULL;
|
||||
env->syms = NULL;
|
||||
env->loaded_files_count = 0;
|
||||
env->loaded_files = NULL;
|
||||
return env;
|
||||
}
|
||||
void lenv_delete(lenv* env) {
|
||||
for(int i = 0; i < env->count; i++) {
|
||||
lval_delete(env->syms[i]->lval);
|
||||
free(env->syms[i]->sym);
|
||||
free(env->syms[i]);
|
||||
symtab_delete(env->syms[i]);
|
||||
}
|
||||
free(env->syms);
|
||||
for(int i = 0; i < env->loaded_files_count; i++) {
|
||||
free(env->loaded_files[i]);
|
||||
}
|
||||
if (env->loaded_files_count > 0) {
|
||||
free(env->loaded_files);
|
||||
}
|
||||
if (env->syms != NULL) {
|
||||
free(env->syms);
|
||||
}
|
||||
env->parent = NULL;
|
||||
free(env);
|
||||
}
|
||||
lenv* lenv_copy(lenv* env) {
|
||||
@@ -59,6 +68,13 @@ symtab* lenv_search(lenv* env, char* sym) {
|
||||
}
|
||||
return *result;
|
||||
}
|
||||
lenv* lenv_get_root(lenv* env) {
|
||||
if (env->parent == NULL) {
|
||||
return env;
|
||||
} else {
|
||||
return lenv_get_root(env->parent);
|
||||
}
|
||||
}
|
||||
|
||||
lval* lenv_get(lenv* env, lval* sym) {
|
||||
LASSERT(sym, sym->type == LVAL_SYM, LERR_BAD_OP, "Expected symbol");
|
||||
|
||||
3
lenv.h
3
lenv.h
@@ -26,6 +26,8 @@ extern "C" {
|
||||
struct lenv {
|
||||
size_t count;
|
||||
struct lenv* parent;
|
||||
char** loaded_files;
|
||||
size_t loaded_files_count;
|
||||
struct symtab** syms;
|
||||
};
|
||||
|
||||
@@ -36,6 +38,7 @@ extern "C" {
|
||||
int lenv_compare_symtabs(const void *a, const void *b);
|
||||
void lenv_sort(lenv* env);
|
||||
symtab* lenv_search(lenv* env, char* sym);
|
||||
lenv* lenv_get_root(lenv* env);
|
||||
|
||||
lval* lenv_get(lenv* env, lval* sym);
|
||||
void lenv_put(lenv* env, lval* key, lval* val);
|
||||
|
||||
Reference in New Issue
Block a user