diff options
author | Preston Pan <preston@nullring.xyz> | 2023-01-08 14:44:25 -0800 |
---|---|---|
committer | Preston Pan <preston@nullring.xyz> | 2023-01-08 14:44:25 -0800 |
commit | 87d82ead963c24d84a4f6e417b96b9bf73d132bb (patch) | |
tree | 096e60118f6e62508db653d5102d85e77b8d73e9 /src/visitor.c | |
parent | aa1dd020edb82f26dd5bc29378177cfcaa4c53ed (diff) |
fix memory problem
Diffstat (limited to 'src/visitor.c')
-rw-r--r-- | src/visitor.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/visitor.c b/src/visitor.c index 6fd487a..65af934 100644 --- a/src/visitor.c +++ b/src/visitor.c @@ -449,6 +449,60 @@ ast_t *eval_list(visitor_t *v, ast_t *e) { print(arg1); printf("\n"); return arg1; + } else if (strcmp(function->string_value, "read") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + if (arg1->type == AST_STRING) { + char *buffer = 0; + long length; + FILE *f = fopen(arg1->string_value, "rb"); + + if (f) { + fseek(f, 0, SEEK_END); + length = ftell(f); + fseek(f, 0, SEEK_SET); + buffer = malloc(length); + if (buffer) { + fread(buffer, 1, length, f); + } + fclose(f); + } else { + eval_error(v, e); + } + + if (buffer) { + return init_ast_string(buffer); + } else { + eval_error(v, e); + } + } + } else if (strcmp(function->string_value, "bound?") == 0) { + if (cmp != 1) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + + if (arg1->type == AST_SYMBOL) { + if (hash_table_exists(v->p->symbol_table, arg1->string_value)) { + return init_ast_bool(true); + } + return init_ast_bool(false); + } else + eval_error(v, e); + } else if (strcmp(function->string_value, "at") == 0) { + if (cmp != 2) + eval_error(v, e); + + ast_t *arg1 = eval_expr(v, args->car); + ast_t *arg2 = eval_expr(v, args->cdr->car); + if (arg1->type == AST_STRING && arg2->type == AST_INT && + arg2->int_value < strlen(arg1->string_value)) { + return init_ast_string( + char_to_string(arg1->string_value[arg2->int_value])); + } else + eval_error(v, e); } return NULL; |