From: Alexander Goussas Date: Thu, 31 Oct 2024 23:35:41 +0000 (-0500) Subject: feat: eval load commands X-Git-Url: http://git.frustrated-labs.net/?a=commitdiff_plain;h=fca0a01c11ec30817fb0b26dba4ef670373cad45;p=so-test.git feat: eval load commands --- diff --git a/.gitignore b/.gitignore index d6536ba..fb9c60c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build compile_commands.json +.idea diff --git a/CMakeLists.txt b/CMakeLists.txt index aa67808..fe96359 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 index 0000000..b5cf0c7 --- /dev/null +++ b/interpreter.c @@ -0,0 +1,66 @@ +#include "interpreter.h" +#include +#include +#include +#include +#include "parser.h" + +#include + +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 index 0000000..2e15685 --- /dev/null +++ b/interpreter.h @@ -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 index 0000000..501bbc5 Binary files /dev/null and b/lib/libm.so.6 differ diff --git a/main.c b/main.c index c5d417f..4ad6192 100644 --- a/main.c +++ b/main.c @@ -1,41 +1,32 @@ #include #include -#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(); } }