aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-01-14 20:03:18 +0100
committerkdx <kikoodx@paranoici.org>2023-01-14 20:03:18 +0100
commit2d40b8053029be33334e143a2ed6ba13bce15e2e (patch)
tree2911e165cd713cbe4c044e39f99e0278327068cc
parent13802c4d560e8e6de4a06fb8f7e707e41436dffe (diff)
downloadsloth-2d40b8053029be33334e143a2ed6ba13bce15e2e.tar.gz
sloth dict
-rw-r--r--README2
-rwxr-xr-xbuild.sh2
-rw-r--r--main.c13
-rw-r--r--sloth.c78
-rw-r--r--sloth.h24
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <xxhash.h>
+
+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 <stdint.h>
#include <stddef.h>
+#include <xxhash.h>
/* 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);