summaryrefslogtreecommitdiff
path: root/src/visitor.c
diff options
context:
space:
mode:
authorPreston Pan <preston@nullring.xyz>2023-01-08 14:44:25 -0800
committerPreston Pan <preston@nullring.xyz>2023-01-08 14:44:25 -0800
commit87d82ead963c24d84a4f6e417b96b9bf73d132bb (patch)
tree096e60118f6e62508db653d5102d85e77b8d73e9 /src/visitor.c
parentaa1dd020edb82f26dd5bc29378177cfcaa4c53ed (diff)
fix memory problem
Diffstat (limited to 'src/visitor.c')
-rw-r--r--src/visitor.c54
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;