aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-07-22 15:34:57 +0800
committerMistivia <i@mistivia.com>2025-07-22 15:35:11 +0800
commitea5c15cbd628953e7b9d17b45ea685006a582cd4 (patch)
tree0440a31d4fb2f73cd150fa11f19ac08fd23562f9 /main.c
parentd64a599af8c6b52223b20f727d76a59a562abb75 (diff)
change dir structure
Diffstat (limited to 'main.c')
-rw-r--r--main.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..1911873
--- /dev/null
+++ b/main.c
@@ -0,0 +1,74 @@
+#include "interp.h"
+#include "parser.h"
+#include "sexp.h"
+
+int main(int argc, char **argv) {
+ int mainret = 0;
+ Interp interp;
+ Interp_init(&interp);
+ if (argc > 2) {
+ fprintf(stderr, "Usage: bamboo-lisp [file.lisp]\n");
+ return -1;
+ }
+ if (argc == 2) {
+ const char *filename = argv[1];
+ SExpRef ret = Interp_load_file(&interp, filename);
+ if (Interp_ref(&interp, ret)->type == kErrSignal) {
+ fprintf(stderr, "Error: %s", Interp_ref(&interp, ret)->str);
+ const char *stacktrace = lisp_stacktrace_to_string(&interp, interp.stacktrace);
+ fprintf(stderr, "%s", stacktrace);
+ free((void*)stacktrace);
+ interp.stacktrace = interp.nil;
+ mainret = -1; goto end;
+ }
+ if (Interp_ref(&interp, ret)->type == kExceptionSignal) {
+ const char *exception_str = lisp_to_string(&interp, Interp_ref(&interp, ret)->ret);
+ fprintf(stderr, "Uncatched exception: %s\n", exception_str);
+ free((void*)exception_str);
+ const char *stacktrace = lisp_stacktrace_to_string(&interp, interp.stacktrace);
+ fprintf(stderr, "%s", stacktrace);
+ free((void*)stacktrace);
+ interp.stacktrace = interp.nil;
+ mainret = -1; goto end;
+ }
+ }
+#ifdef WITHREADLINE
+ Parser_set_readline(interp.parser);
+#else
+ Parser_set_file(interp.parser, stdin);
+#endif
+ SExpRef sexp, res;
+ ParseResult parse_result;
+ while (1) {
+#ifndef WITHREADLINE
+ printf(">>> ");
+ fflush(stdout);
+#endif
+ parse_result = parse_sexp(interp.parser);
+ if (parse_result.errmsg != NULL) {
+ if (Parser_peek(interp.parser) == EOF) goto end;
+ fprintf(stderr, "Parsing error: %s", parse_result.errmsg);
+#ifdef WITHREADLINE
+ free((void*)interp.parser->string);
+ Parser_set_readline(interp.parser);
+#endif
+ continue;
+ }
+
+ res = lisp_eval(&interp, parse_result.val, false);
+ if (Interp_ref(&interp, res)->type == kErrSignal) {
+ fprintf(stderr, "Eval error: %s", Interp_ref(&interp, res)->str);
+ continue;
+ }
+ if (Interp_ref(&interp, res)->type == kBreakSignal
+ || Interp_ref(&interp, res)->type == kContinueSignal
+ || Interp_ref(&interp, res)->type == kReturnSignal) {
+ fprintf(stderr, "Eval error: unexpected control flow signal.\n");
+ continue;
+ }
+ lisp_print(&interp, res, stdout);
+ }
+end:
+ Interp_free(&interp);
+ return mainret;
+}