aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-01-14 21:14:20 +0100
committerkdx <kikoodx@paranoici.org>2023-01-14 21:14:20 +0100
commit37b650f1ea6086de77c8a46294cd04c35bcf0e02 (patch)
treeec2ac3a8774b5189c003ed25772eeff529b04f6d
parentfcd4bafc4a678e4a573ef836bc737ebfb499050a (diff)
downloadsloth-37b650f1ea6086de77c8a46294cd04c35bcf0e02.tar.gz
compile and exec instructions
-rwxr-xr-xbuild.sh2
-rw-r--r--sloth.c131
-rw-r--r--sloth.h31
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);