summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/hash_table.c11
-rw-r--r--src/include/macros.h2
-rw-r--r--src/lexer.c8
-rw-r--r--src/macros.c7
-rw-r--r--src/main.c11
-rw-r--r--src/parser.c4
-rw-r--r--src/visitor.c54
7 files changed, 82 insertions, 15 deletions
diff --git a/src/hash_table.c b/src/hash_table.c
index 6648bd1..29946b1 100644
--- a/src/hash_table.c
+++ b/src/hash_table.c
@@ -78,6 +78,15 @@ void sl_list_add(sl_list_t *l, char *key, ast_t *value) {
}
}
+void sl_list_modify(sl_list_t *l, char *key, ast_t *value) {
+ sl_node_t *cur = l->head;
+ while (cur != NULL) {
+ if (strcmp(cur->value->key, key) == 0)
+ cur->value->value = value;
+ cur = cur->next;
+ }
+}
+
ast_t *sl_list_get(sl_list_t *l, char *key) {
sl_node_t *cur = l->head;
for (int i = 0; i < l->size; i++) {
@@ -123,6 +132,8 @@ hash_table_t *init_hash_table(int size) {
void hash_table_add(hash_table_t *h, char *key, ast_t *value) {
sl_list_t *l = h->buckets[hash(key, h->size)];
+ if (sl_list_exists(l, key))
+ sl_list_modify(l, key, value);
sl_list_add(l, key, value);
}
diff --git a/src/include/macros.h b/src/include/macros.h
index ee89597..bbf541e 100644
--- a/src/include/macros.h
+++ b/src/include/macros.h
@@ -82,4 +82,6 @@
#define COLOR_RESET "\e[0m"
void die(char *message);
+
+char *char_to_string(char c);
#endif
diff --git a/src/lexer.c b/src/lexer.c
index e58197a..4e03a02 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -57,13 +57,6 @@ static bool is_valid_id_char(char c) {
return true;
}
-static char *char_to_string(char c) {
- char *s = (char *)malloc(2 * sizeof(char));
- s[0] = c;
- s[1] = '\0';
- return s;
-}
-
token_t *lexer_collect_bool(lexer_t *lexer) {
lexer_move(lexer);
if (lexer->c == 't') {
@@ -158,7 +151,6 @@ start:
return lexer_move_with(
lexer, init_token(TOKEN_PERIOD, ".", lexer->row, lexer->col));
else {
- printf("returns null\n");
return NULL;
}
}
diff --git a/src/macros.c b/src/macros.c
index 1effefe..1643168 100644
--- a/src/macros.c
+++ b/src/macros.c
@@ -8,3 +8,10 @@ void die(char *message) {
fprintf(stderr, "%sFATAL ERROR: %s%s\n", RED, message, reset);
exit(EXIT_FAILURE);
}
+
+char *char_to_string(char c) {
+ char *s = malloc(2);
+ s[0] = c;
+ s[1] = '\0';
+ return s;
+}
diff --git a/src/main.c b/src/main.c
index c75ef85..ba710bf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -12,9 +12,6 @@
#include <stdlib.h>
#include <string.h>
-// Read the file into allocated memory.
-// Return NULL on error.
-
int main(int argc, char **argv) {
/* DONE: TEST LEXER */
/* lexer_t *lexer = init_lexer("'(fasd asdf)"); */
@@ -134,6 +131,8 @@ int main(int argc, char **argv) {
if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) {
printf("nxs, version 1.2 alpha\n");
exit(0);
+ } else if (strcmp(argv[1], "-r") == 0 || strcmp(argv[1], "--repl") == 0) {
+ /* Start a REPL */
}
char *filename = argv[1];
@@ -145,13 +144,13 @@ int main(int argc, char **argv) {
fseek(f, 0, SEEK_END);
length = ftell(f);
fseek(f, 0, SEEK_SET);
- buffer = malloc(length);
+ buffer = malloc(length + 1);
if (buffer) {
fread(buffer, 1, length, f);
}
fclose(f);
}
-
+ buffer[length] = '\0';
if (buffer) {
/* lexer_t *lexer = init_lexer(buffer); */
/* token_t *t = lexer_collect_next(lexer); */
@@ -163,7 +162,7 @@ int main(int argc, char **argv) {
lexer_t *lexer = init_lexer(buffer);
parser_t *parser = init_parser(lexer);
visitor_t *visitor = init_visitor(parser);
- ast_t *root = eval(visitor);
+ eval(visitor);
/* print_root(root); */
}
diff --git a/src/parser.c b/src/parser.c
index 157bc4d..0f1ba69 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -30,6 +30,7 @@ parser_t *init_parser_copy_hash(lexer_t *lexer, hash_table_t *h) {
p->tokens[size - 1] = t;
if (t == NULL)
break;
+ /* printf("%d: %s\n", t->type, t->value); */
}
p->size = size;
return p;
@@ -185,7 +186,7 @@ ast_t *parse_include(parser_t *parser) {
fseek(f, 0, SEEK_END);
length = ftell(f);
fseek(f, 0, SEEK_SET);
- buffer = malloc(length);
+ buffer = malloc(length + 1);
if (buffer) {
fread(buffer, 1, length, f);
}
@@ -194,6 +195,7 @@ ast_t *parse_include(parser_t *parser) {
parser_error(parser);
}
if (buffer) {
+ buffer[length] = '\0';
lexer_t *lexer = init_lexer(buffer);
parser_t *p = init_parser_copy_hash(lexer, parser->symbol_table);
ast_t *root = parse_all(p);
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;