From 37b650f1ea6086de77c8a46294cd04c35bcf0e02 Mon Sep 17 00:00:00 2001 From: kdx Date: Sat, 14 Jan 2023 21:14:20 +0100 Subject: compile and exec instructions --- build.sh | 2 +- sloth.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- sloth.h | 31 +++++++++++---- 3 files changed, 147 insertions(+), 17 deletions(-) diff --git a/build.sh b/build.sh index af80bec..1646399 100755 --- a/build.sh +++ b/build.sh @@ -1,2 +1,2 @@ #!/bin/sh -gcc -O3 -Wall -Wextra -o sloth -lxxhash *.c +gcc -O0 -g -Wall -Wextra -o sloth -lxxhash *.c diff --git a/sloth.c b/sloth.c index dced371..7c861c8 100644 --- a/sloth.c +++ b/sloth.c @@ -33,6 +33,16 @@ SlothError sloth_init(Sloth *ctx) sloth_deinit(ctx); return err; } + err = sloth_dict_append(ctx, SLOTH_DICT_C(":", sloth_compile_begin)); + if (err != NULL) { + sloth_deinit(ctx); + return err; + } + err = sloth_dict_append(ctx, SLOTH_DICT_C(";", sloth_compile_end)); + if (err != NULL) { + sloth_deinit(ctx); + return err; + } return NULL; } @@ -44,9 +54,19 @@ void sloth_deinit(Sloth *ctx) } while (ctx->dict != NULL) { SlothDict *const next = ctx->dict->next; + if (ctx->dict->instrs != NULL) { + SlothInstr *const next_instr = ctx->dict->instrs->next; + free(ctx->dict->instrs); + ctx->dict->instrs = next_instr; + } free(ctx->dict); ctx->dict = next; } + if (ctx->comp.instrs != NULL) { + SlothInstr *const next_instr = ctx->comp.instrs->next; + free(ctx->comp.instrs); + ctx->comp.instrs = next_instr; + } } SlothError sloth_dict_append(Sloth *ctx, SlothDict dict) @@ -67,32 +87,97 @@ SlothError sloth_dict_append(Sloth *ctx, SlothDict dict) return NULL; } -SlothError sloth_exec(Sloth *ctx, const char *s) +SlothError sloth_str_to_instr(Sloth *ctx, const char *s, SlothInstr *instr) { - SlothError err; const SlothHash hash = XXH32(s, strlen(s), 0); + instr->next = NULL; for (SlothDict *dict = ctx->dict; dict != NULL; dict = dict->next) if (dict->hash == hash) { - err = dict->func(ctx); - if (err != NULL) - return err; + instr->litteral = 0; + instr->hash = hash; return NULL; } for (size_t i = 0; s[i] != '\0'; i++) if (!isdigit(s[i])) - return "sloth_exec: unrecognized token" - "a litteral"; - err = sloth_push(ctx, atoi(s)); + return "sloth_str_to_instr: unrecognized token"; + instr->litteral = 1; + instr->byte = atoi(s); + return NULL; +} + +SlothError sloth_exec_instr(Sloth *ctx, const SlothInstr *instr) +{ + SlothError err = NULL; + while (instr != NULL) { + if (instr->litteral) + err = sloth_push(ctx, instr->byte); + else for (SlothDict *dict = ctx->dict; dict != NULL; + dict = dict->next) + { + if (dict->hash == instr->hash) { + if (dict->c_func) + err = dict->func(ctx); + else + err = sloth_exec_instr(ctx, dict->instrs); + break; + } + } + if (err != NULL) + return err; + instr = instr->next; + } + return NULL; +} + +SlothError sloth_exec(Sloth *ctx, const char *s) +{ + SlothError err; + SlothInstr instr = {0}; + err = sloth_str_to_instr(ctx, s, &instr); + if (err != NULL) + return err; + err = sloth_exec_instr(ctx, &instr); if (err != NULL) return err; return NULL; } +SlothError sloth_compile(Sloth *ctx, const char *s) +{ + SlothError err; + if (ctx->comp.hash == 0) { + ctx->comp.hash = XXH32(s, strlen(s), 0); + return NULL; + } + SlothInstr instr = {0}; + err = sloth_str_to_instr(ctx, s, &instr); + if (err != NULL) + return err; + SlothInstr **dest; + if (ctx->comp.instrs == NULL) + dest = &ctx->comp.instrs; + else { + SlothInstr *last = ctx->comp.instrs; + while (last->next != NULL) + last = last->next; + dest = &last->next; + } + *dest = malloc(sizeof(SlothInstr)); + if (*dest == NULL) + return "sloth_compile: malloc failed"; + memcpy(*dest, &instr, sizeof(SlothInstr)); + return NULL; +} + SlothError sloth_exec_line(Sloth *ctx, char *s) { + SlothError err = NULL; static const char *sep = "\t\n\v\f\r "; for (char *tok = strtok(s, sep); tok != NULL; tok = strtok(NULL, sep)) { - const SlothError err = sloth_exec(ctx, tok); + if (ctx->compile && strcmp(tok, ";") != 0) + err = sloth_compile(ctx, tok); + else + err = sloth_exec(ctx, tok); if (err != NULL) return err; } @@ -198,6 +283,34 @@ SlothError sloth_compare(Sloth *ctx) return NULL; } +SlothError sloth_compile_begin(Sloth *ctx) +{ + if (ctx->compile) + return "sloth_compile_begin: already in compile mode"; + ctx->comp.hash = 0; + ctx->comp.c_func = 0; + ctx->comp.func = NULL; + ctx->comp.instrs = NULL; + ctx->comp.next = NULL; + ctx->compile = 1; + return NULL; +} + +SlothError sloth_compile_end(Sloth *ctx) +{ + if (!ctx->compile) + return "sloth_compile_end: not in compile mode"; + if (ctx->comp.hash == 0) + return "sloth_compile_end: compiled instruction missing hash"; + const SlothError err = sloth_dict_append(ctx, ctx->comp); + if (err != NULL) + return NULL; + ctx->comp.hash = 0; + ctx->comp.instrs = NULL; + ctx->compile = 0; + return NULL; +} + void sloth_inspect_stack(const Sloth *ctx) { printf("<%lu> ", ctx->stack_size); diff --git a/sloth.h b/sloth.h index 0fc4ceb..cc56b76 100644 --- a/sloth.h +++ b/sloth.h @@ -10,6 +10,17 @@ typedef XXH32_hash_t SlothHash; typedef struct SlothDict SlothDict; typedef const char* SlothError; typedef struct Sloth Sloth; +typedef struct SlothInstr SlothInstr; + +struct SlothDict { + SlothHash hash; + int c_func; + SlothError (*func)(Sloth *ctx); + SlothInstr *instrs; + SlothDict *next; +}; +#define SLOTH_DICT_C(word, func) \ + (SlothDict){XXH32(word, strlen(word), 0), 1, func, NULL, NULL} struct Sloth { SlothByte *stack; @@ -17,20 +28,24 @@ struct Sloth { size_t stack_capacity; SlothByte mem[1 << SLOTH_BITS]; SlothDict *dict; + int compile; + SlothDict comp; }; -struct SlothDict { - SlothHash hash; - int c_func; - SlothError (*func)(Sloth *ctx); - SlothDict *next; +struct SlothInstr { + int litteral; + union { + SlothByte byte; + SlothHash hash; + }; + SlothInstr *next; }; -#define SLOTH_DICT_C(word, func) \ - (SlothDict){XXH32(word, strlen(word), 0), 1, func, NULL} SlothError sloth_init(Sloth *ctx); void sloth_deinit(Sloth *ctx); SlothError sloth_dict_append(Sloth *ctx, SlothDict dict); +SlothError sloth_str_to_instr(Sloth *ctx, const char *s, SlothInstr *instr); +SlothError sloth_exec_instr(Sloth *ctx, const SlothInstr *instr); SlothError sloth_exec(Sloth *ctx, const char *s); SlothError sloth_exec_line(Sloth *ctx, char *s); SlothError sloth_pop(Sloth *ctx, SlothByte *v); @@ -40,4 +55,6 @@ SlothError sloth_write(Sloth *ctx); SlothError sloth_store(Sloth *ctx); SlothError sloth_retrieve(Sloth *ctx); SlothError sloth_compare(Sloth *ctx); +SlothError sloth_compile_begin(Sloth *ctx); +SlothError sloth_compile_end(Sloth *ctx); void sloth_inspect_stack(const Sloth *ctx); -- cgit v1.2.3