From 2d40b8053029be33334e143a2ed6ba13bce15e2e Mon Sep 17 00:00:00 2001 From: kdx Date: Sat, 14 Jan 2023 20:03:18 +0100 Subject: sloth dict --- README | 2 -- build.sh | 2 +- main.c | 13 ++++++++--- sloth.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- sloth.h | 24 +++++++++++++++++--- 5 files changed, 108 insertions(+), 11 deletions(-) diff --git a/README b/README index a4b3e29..81948dc 100644 --- a/README +++ b/README @@ -10,8 +10,6 @@ supports string literal (array of bytes) : ( switch to compile ) ; ( switch out of compile ) -push ( a -- ) -pop ( -- a ) @ ( a b -- ) ! ( a -- b ) + ( a b -- c ) diff --git a/build.sh b/build.sh index 54681ca..af80bec 100755 --- a/build.sh +++ b/build.sh @@ -1,2 +1,2 @@ #!/bin/sh -gcc -Wall -Wextra -o sloth *.c +gcc -O3 -Wall -Wextra -o sloth -lxxhash *.c diff --git a/main.c b/main.c index d6d8b1b..390c6ee 100644 --- a/main.c +++ b/main.c @@ -11,15 +11,22 @@ int main(int argc, char **argv) SlothError err; if (sloth == NULL) return 1; + err = sloth_init(sloth); + if (err != NULL) { + fprintf(stderr, "%s\n", err); + free(sloth); + return 1; + } + puts("sloth v0.0.0, Copyright (c) 2023 kdx"); + puts("sloth comes with ABSOLUTELY NO WARRANTY."); + puts("Enter EOF to exit."); /* Read stdin line by line until exhaustion. */ char *line = NULL; while ((line = getln(stdin)) != NULL) { err = sloth_exec_line(sloth, line); free(line); - if (err != NULL) { + if (err != NULL) fprintf(stderr, "%s\n", err); - break; - } } /* Free everything. */ getln_cleanup(); diff --git a/sloth.c b/sloth.c index 5db7df0..9cb045a 100644 --- a/sloth.c +++ b/sloth.c @@ -2,6 +2,23 @@ #include #include #include +#include + +SlothError sloth_init(Sloth *ctx) +{ + SlothError err; + err = sloth_dict_append(ctx, SLOTH_DICT_C("+", sloth_add)); + if (err != NULL) { + sloth_deinit(ctx); + return err; + } + err = sloth_dict_append(ctx, SLOTH_DICT_C(".", sloth_write)); + if (err != NULL) { + sloth_deinit(ctx); + return err; + } + return NULL; +} void sloth_deinit(Sloth *ctx) { @@ -9,14 +26,43 @@ void sloth_deinit(Sloth *ctx) free(ctx->stack); ctx->stack = NULL; } + while (ctx->dict != NULL) { + SlothDict *const next = ctx->dict->next; + free(ctx->dict); + ctx->dict = next; + } } -SlothError sloth_exec(Sloth *ctx, const char *s) +SlothError sloth_dict_append(Sloth *ctx, SlothDict dict) { - printf("exec %s\n", s); + SlothDict **dest; + if (ctx->dict == NULL) + dest = &ctx->dict; + else { + SlothDict *last = ctx->dict; + while (last->next != NULL) + last = last->next; + dest = &last->next; + } + *dest = malloc(sizeof(SlothDict)); + if (*dest == NULL) + return "sloth_dict_append: malloc failed"; + memcpy(*dest, &dict, sizeof(SlothDict)); return NULL; } +SlothError sloth_exec(Sloth *ctx, const char *s) +{ + const SlothHash hash = XXH32(s, strlen(s), 0); + for (SlothDict *dict = ctx->dict; dict != NULL; dict = dict->next) + if (dict->hash == hash) { + const SlothError err = dict->func(ctx); + if (err != NULL) + return err; + } + return "sloth_exec: unrecognized token"; +} + SlothError sloth_exec_line(Sloth *ctx, char *s) { static const char *sep = "\t\n\v\f\r "; @@ -56,6 +102,34 @@ SlothError sloth_push(Sloth *ctx, SlothByte v) return NULL; } +SlothError sloth_add(Sloth *ctx) +{ + SlothError err; + SlothByte a, b; + err = sloth_pop(ctx, &a); + if (err != NULL) + return err; + err = sloth_pop(ctx, &b); + if (err != NULL) + return err; + a += b; + err = sloth_push(ctx, a); + if (err != NULL) + return err; + return NULL; +} + +SlothError sloth_write(Sloth *ctx) +{ + SlothError err; + SlothByte a; + err = sloth_pop(ctx, &a); + if (err != NULL) + return err; + printf("%c", (unsigned char)a); + return NULL; +} + void sloth_inspect_stack(const Sloth *ctx) { printf("<%lu> ", ctx->stack_size); diff --git a/sloth.h b/sloth.h index 809b99d..8032403 100644 --- a/sloth.h +++ b/sloth.h @@ -1,22 +1,40 @@ #pragma once #include #include +#include /* Replace '16' by desired byte size on both following lines. */ #define SLOTH_BITS 16 typedef uint16_t SlothByte; - +typedef XXH32_hash_t SlothHash; +typedef struct SlothDict SlothDict; typedef const char* SlothError; -typedef struct Sloth { +typedef struct Sloth Sloth; + +struct Sloth { SlothByte *stack; size_t stack_size; size_t stack_capacity; SlothByte mem[1 << SLOTH_BITS]; -} Sloth; + SlothDict *dict; +}; + +struct SlothDict { + SlothHash hash; + int c_func; + SlothError (*func)(Sloth *ctx); + SlothDict *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_exec(Sloth *ctx, const char *s); SlothError sloth_exec_line(Sloth *ctx, char *s); SlothError sloth_pop(Sloth *ctx, SlothByte *v); SlothError sloth_push(Sloth *ctx, SlothByte v); +SlothError sloth_add(Sloth *ctx); +SlothError sloth_write(Sloth *ctx); void sloth_inspect_stack(const Sloth *ctx); -- cgit v1.2.3