]> git.frustrated-labs.net Git - so-test.git/commitdiff
feat: eval load commands
authorAlexander Goussas <[email protected]>
Thu, 31 Oct 2024 23:35:41 +0000 (18:35 -0500)
committerAlexander Goussas <[email protected]>
Thu, 31 Oct 2024 23:35:41 +0000 (18:35 -0500)
.gitignore
CMakeLists.txt
interpreter.c [new file with mode: 0644]
interpreter.h [new file with mode: 0644]
lib/libm.so.6 [new file with mode: 0644]
main.c

index d6536badc8cf2e374b4b10e5df2d60b33d8ab28a..fb9c60ce771214d44c07151d325edb44f0df3f17 100644 (file)
@@ -1,2 +1,3 @@
 build
 compile_commands.json
+.idea
index aa67808f78476477aaac03e56b46ba9e8c3553e3..fe9635947d52d7235111fb4225f57e48521ce3cf 100644 (file)
@@ -4,5 +4,12 @@ project(sotest)
 
 set(CMAKE_C_STANDARD 11)
 
-add_executable(sotest main.c lexer.c ast.c parser.c)
+add_executable(sotest main.c
+        lexer.c
+        ast.c
+        parser.c
+        interpreter.c
+        interpreter.h)
 target_compile_options(sotest PRIVATE -Wall -Wextra)
+
+target_link_libraries(sotest PRIVATE dl ffi)
diff --git a/interpreter.c b/interpreter.c
new file mode 100644 (file)
index 0000000..b5cf0c7
--- /dev/null
@@ -0,0 +1,66 @@
+#include "interpreter.h"
+#include <ffi.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "parser.h"
+
+#include <string.h>
+
+static void eval_load_expr(so_interpreter *, so_expr_load *load, so_expr *expr);
+
+static void eval_call_expr(so_interpreter *, so_expr_call *call, so_expr *expr);
+
+void so_interpreter_init(so_interpreter *interp) {
+    memset(interp->library_handles, 0, sizeof(void *) * MAX_LOAD);
+    memset(interp->library_names, 0, sizeof(char *) * MAX_LOAD);
+    interp->loaded_libraries = 0;
+}
+
+void so_interpreter_deinit(so_interpreter *interp) {
+    for (int i = 0; i < interp->loaded_libraries; i++) {
+        dlclose(interp->library_handles[i]);
+        free(interp->library_names[i]);
+    }
+}
+
+void so_interpreter_run(so_interpreter *interp, const char *source) {
+    so_parser parser;
+    so_parser_init(&parser, source);
+    so_parser_parse(&parser);
+
+    for (int i = 0; i < parser.ncommands; i++) {
+        so_expr *command = parser.commands[i];
+        switch (command->tag) {
+            case SO_EXPR_LOAD:
+                eval_load_expr(interp, &command->as.load, command);
+                break;
+            case SO_EXPR_CALL:
+                eval_call_expr(interp, &command->as.call, command);
+                break;
+            default: break;
+        }
+
+        free_ast(command);
+    }
+
+    so_parser_deinit(&parser);
+}
+
+
+void eval_load_expr(so_interpreter *interp, so_expr_load *load, so_expr *expr) {
+    void *handle = dlopen(load->name, RTLD_LAZY);
+    if (!handle) {
+        fprintf(stderr, "error: failed to load dynamic library: %s\n", load->name);
+        free_ast(expr);
+        so_interpreter_deinit(interp);
+        exit(EXIT_FAILURE);
+    }
+
+    interp->library_handles[interp->loaded_libraries] = handle;
+    interp->library_names[interp->loaded_libraries] = strdup(load->name);
+    interp->loaded_libraries++;
+}
+
+void eval_call_expr(so_interpreter *interp, so_expr_call *call, so_expr *expr) {
+}
diff --git a/interpreter.h b/interpreter.h
new file mode 100644 (file)
index 0000000..2e15685
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef interpreter_h_
+#define interpreter_h_
+
+
+#define MAX_LOAD 100
+
+typedef struct {
+    int loaded_libraries;
+    char *library_names[MAX_LOAD];
+    void *library_handles[MAX_LOAD];
+} so_interpreter;
+
+void so_interpreter_init(so_interpreter *);
+
+void so_interpreter_deinit(so_interpreter *);
+
+void so_interpreter_run(so_interpreter *, const char *source);
+
+#endif
diff --git a/lib/libm.so.6 b/lib/libm.so.6
new file mode 100644 (file)
index 0000000..501bbc5
Binary files /dev/null and b/lib/libm.so.6 differ
diff --git a/main.c b/main.c
index c5d417f6b1f1693be3caff6b56bfb581e1bfac21..4ad6192ef2cfc6b8bba5b1e0a7c7d5c840220a93 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,41 +1,32 @@
 #include <stdio.h>
 #include <string.h>
-#include "parser.h"
 
-int repl()
-{
+#include "interpreter.h"
+
+int repl() {
     char buffer[4096] = {0};
 
-    printf("> ");
+    so_interpreter interp;
+    so_interpreter_init(&interp);
 
-    while (fgets(buffer, sizeof(buffer), stdin) != NULL)
-    {
+    printf("> ");
+    while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
         if (strcmp(buffer, ".quit\n") == 0)
-            return 0;
+            break;
 
-        so_parser parser;
-        so_parser_init(&parser, buffer);
-        so_parser_parse(&parser);
-
-        for (int i = 0; i < parser.ncommands; i++)
-        {
-            print_ast(parser.commands[i]);
-            free_ast(parser.commands[i]);
-        }
-
-        so_parser_deinit(&parser);
+        so_interpreter_run(&interp, buffer);
 
         memset(buffer, 0, sizeof(buffer));
         printf("> ");
     }
 
+    so_interpreter_deinit(&interp);
+
     return 0;
 }
 
-int main(int argc, char **argv)
-{
-    if (argc == 1)
-    {
+int main(int argc, char **argv) {
+    if (argc == 1) {
         return repl();
     }
 }