changeset 66:1b061b1fecdf

src: Implement parse module as part of the frontend.
author Lewin Bormann <lbo@spheniscida.de>
date Sun, 25 Aug 2019 10:06:54 +0200
parents dd0c65ded420
children b2401225b53f
files .clang src/CMakeLists.txt src/parse.c src/parse.h src/parse_test.c
diffstat 5 files changed, 85 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.clang	Sun Aug 25 10:06:21 2019 +0200
+++ b/.clang	Sun Aug 25 10:06:54 2019 +0200
@@ -1,1 +1,1 @@
-flags = -I. -I./build
+flags = -I. -Ibuild
--- a/src/CMakeLists.txt	Sun Aug 25 10:06:21 2019 +0200
+++ b/src/CMakeLists.txt	Sun Aug 25 10:06:54 2019 +0200
@@ -14,12 +14,17 @@
     func.c
     value.c)
 
+ADD_LIBRARY(frontend STATIC
+    parse.c)
+
 if (CMAKE_BUILD_TYPE STREQUAL "Debug")
     TARGET_LINK_LIBRARIES(core base gcov)
 else ()
     TARGET_LINK_LIBRARIES(core base)
 endif ()
 
+TARGET_LINK_LIBRARIES(frontend core base y_parser)
+
 # Atom test.
 ADD_EXECUTABLE(atom_test atom_test.c)
 TARGET_LINK_LIBRARIES(atom_test core)
@@ -39,3 +44,8 @@
 ADD_EXECUTABLE(sizes_test sizes_test.c)
 TARGET_LINK_LIBRARIES(sizes_test core)
 YADD_TEST(sizes_test)
+
+# Parse test
+ADD_EXECUTABLE(parse_test parse_test.c)
+TARGET_LINK_LIBRARIES(parse_test frontend)
+YADD_TEST(parse_test)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parse.c	Sun Aug 25 10:06:54 2019 +0200
@@ -0,0 +1,17 @@
+#include "parse.h"
+
+// From y.yy
+int parse(FILE* input, yvec_t* out, ystr_t* err);
+
+bool yparse(FILE* input, yexpr_t* result, ystr_t* error) {
+    yvec_t exprs;
+    ystr_init(error, NULL);
+    int ret = parse(input, &exprs, error);
+
+    if (ret > 0) {
+        return false;
+    }
+
+    yexpr_set_list(result, exprs); // don't destroy exprs!
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parse.h	Sun Aug 25 10:06:54 2019 +0200
@@ -0,0 +1,29 @@
+#ifndef src_parse_h
+#define src_parse_h
+
+/**
+ * @file parse.h
+ * @addtogroup frontend
+ * @{
+ */
+
+#include <gen/y.tab.h>
+#include <src/expr.h>
+#include <src/base/str.h>
+
+#include <stdio.h>
+
+/**
+ * @brief Parse `input` (which can be a string, see `fmemopen(3)`).
+ *
+ * If successful, `true` is returned, and the top-level s-exprs are stored as list into `result`.
+ *
+ * If not successful, `false` is returned, and `error` will contain a description of the error.
+ */
+bool yparse(FILE* input, yexpr_t* result, ystr_t* error);
+
+/**
+ * @}
+ */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/parse_test.c	Sun Aug 25 10:06:54 2019 +0200
@@ -0,0 +1,28 @@
+#include "parse.h"
+
+#include <assert.h>
+
+void test_simple_parse(void) {
+    const char* input =
+        "(hello 'world '(this is quoted) (and (this (nested \"with string\" "
+        "1234))))";
+    FILE* input_f =
+        fmemopen((char*)input, strlen(input),
+                 "r");  // const-cast is ok, we open only for reading.
+
+    yexpr_t result = yexpr_new();
+    ystr_t error;
+    bool ret = yparse(input_f, &result, &error);
+    if (!ret) {
+        fputs(ystr_str(&error), stderr);
+        assert(ret /* parse must succeed */);
+    }
+    assert(result.typ == YEXPR_LIST);
+
+    ystr_destroy(&error);
+}
+
+int main(int argc, char** argv) {
+    test_simple_parse();
+    return 0;
+}