]> git.lizzy.rs Git - nothing.git/blobdiff - src/ebisp/parser.c
ebisp/std: Validate arglist to defun in the same way as for lambda
[nothing.git] / src / ebisp / parser.c
index b6e19fa5eeb38359c2fff4adbc548a4c4eaab5b9..23d626dbd33bcc274cb657212336b1a34eee1326 100644 (file)
@@ -1,4 +1,4 @@
-#include <assert.h>
+#include "system/stacktrace.h"
 #include <ctype.h>
 #include <errno.h>
 #include <stdint.h>
@@ -157,7 +157,7 @@ static struct ParseResult parse_expr(Gc *gc, struct Token current_token)
             return result;
         }
 
-        result.expr = list(gc, 2, SYMBOL(gc, "quote"), result.expr);
+        result.expr = list(gc, "qe", "quote", result.expr);
 
         return result;
     } break;
@@ -169,7 +169,7 @@ static struct ParseResult parse_expr(Gc *gc, struct Token current_token)
             return result;
         }
 
-        result.expr = list(gc, 2, SYMBOL(gc, "quasiquote"), result.expr);
+        result.expr = list(gc, "qe", "quasiquote", result.expr);
 
         return result;
     } break;
@@ -181,7 +181,7 @@ static struct ParseResult parse_expr(Gc *gc, struct Token current_token)
             return result;
         }
 
-        result.expr = list(gc, 2, SYMBOL(gc, "unquote"), result.expr);
+        result.expr = list(gc, "qe", "unquote", result.expr);
 
         return result;
     } break;
@@ -201,15 +201,15 @@ static struct ParseResult parse_expr(Gc *gc, struct Token current_token)
 
 struct ParseResult read_expr_from_string(Gc *gc, const char *str)
 {
-    assert(gc);
-    assert(str);
+    trace_assert(gc);
+    trace_assert(str);
     return parse_expr(gc, next_token(str));
 }
 
 struct ParseResult read_all_exprs_from_string(Gc *gc, const char *str)
 {
-    assert(gc);
-    assert(str);
+    trace_assert(gc);
+    trace_assert(str);
 
     struct Token current_token = next_token(str);
     struct ParseResult parse_result = parse_expr(gc, current_token);
@@ -239,7 +239,7 @@ struct ParseResult read_all_exprs_from_string(Gc *gc, const char *str)
 
 struct ParseResult read_expr_from_file(Gc *gc, const char *filename)
 {
-    assert(filename);
+    trace_assert(filename);
 
     Lt *lt = create_lt();
     if (lt == NULL) {
@@ -288,6 +288,57 @@ struct ParseResult read_expr_from_file(Gc *gc, const char *filename)
     RETURN_LT(lt, result);
 }
 
+/* TODO(#598): duplicate code in read_all_exprs_from_file and read_expr_from_file  */
+struct ParseResult read_all_exprs_from_file(Gc *gc, const char *filename)
+{
+    trace_assert(filename);
+
+    Lt *lt = create_lt();
+    if (lt == NULL) {
+        return parse_failure("Could not create Lt object", NULL);
+    }
+
+    FILE *stream = PUSH_LT(lt, fopen(filename, "rb"), fclose_lt);
+    if (!stream) {
+        RETURN_LT(lt, parse_failure(strerror(errno), NULL));
+    }
+
+    if (fseek(stream, 0, SEEK_END) != 0) {
+        RETURN_LT(lt, parse_failure("Could not find the end of the file", NULL));
+    }
+
+    const long int buffer_length = ftell(stream);
+
+    if (buffer_length < 0) {
+        RETURN_LT(lt, parse_failure("Couldn't get the size of file", NULL));
+    }
+
+    if (buffer_length == 0) {
+        RETURN_LT(lt, parse_failure("File is empty", NULL));
+    }
+
+    if (buffer_length >= MAX_BUFFER_LENGTH) {
+        RETURN_LT(lt, parse_failure("File is too big", NULL));
+    }
+
+    if (fseek(stream, 0, SEEK_SET) != 0) {
+        RETURN_LT(lt, parse_failure("Could not find the beginning of the file", NULL));
+    }
+
+    char * const buffer = PUSH_LT(lt, malloc((size_t) buffer_length + 1), free);
+    if (buffer == NULL) {
+        RETURN_LT(lt, parse_failure(strerror(errno), NULL));
+    }
+
+    if (fread(buffer, 1, (size_t) buffer_length, stream) != (size_t) buffer_length) {
+        RETURN_LT(lt, parse_failure("Could not read the file", NULL));
+    }
+
+    struct ParseResult result = read_all_exprs_from_string(gc, buffer);
+
+    RETURN_LT(lt, result);
+}
+
 struct ParseResult parse_success(struct Expr expr,
                                  const char *end)
 {