Last active
November 1, 2023 15:29
-
-
Save dramforever/b20912a79724d5b1c66f010238fd8a5c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#define DECL_STATE \ | |
[[maybe_unused]] const struct word *const *ip, \ | |
[[maybe_unused]] size_t *sp, \ | |
[[maybe_unused]] const struct word *const **rsp | |
#define STATE ip, sp, rsp | |
struct word { | |
void (*code)(DECL_STATE); | |
const struct word *payload[]; | |
}; | |
void run_exit(DECL_STATE) { exit(1); } | |
const struct word _f_exit = { .code = run_exit }; | |
void run_print(DECL_STATE) { | |
size_t data = *(--sp); | |
printf("%zd\n", data); | |
ip++; | |
(*ip)->code(STATE); | |
} | |
const struct word _f_print = { .code = run_print }; | |
void run_add(DECL_STATE) { | |
size_t n2 = *(--sp); | |
size_t n1 = *(--sp); | |
*(sp++) = n1 + n2; | |
ip++; | |
(*ip)->code(STATE); | |
} | |
const struct word _f_add = { .code = run_add }; | |
void run_one(DECL_STATE) { | |
*(sp++) = 1; | |
ip++; | |
(*ip)->code(STATE); | |
} | |
const struct word _f_one = { .code = run_one }; | |
void run_return(DECL_STATE) { | |
ip = *(--rsp); | |
(*ip)->code(STATE); | |
} | |
const struct word _f_return = { .code = run_return }; | |
void run_itc(DECL_STATE) { | |
const struct word *self = *ip; | |
ip++; | |
*(rsp++) = ip; | |
ip = self->payload; | |
(*ip)->code(STATE); | |
} | |
const struct word _f_two = { | |
.code = run_itc, | |
.payload = { &_f_one, &_f_one, &_f_add, &_f_return }, | |
}; | |
const struct word _f_four = { | |
.code = run_itc, | |
.payload = { &_f_two, &_f_two, &_f_add, &_f_return }, | |
}; | |
const struct word _f_main = { | |
.code = run_itc, | |
.payload = { &_f_four, &_f_print, &_f_exit }, | |
}; | |
int main() { | |
const struct word *const *ip = _f_main.payload; | |
size_t sp[32]; | |
const struct word *const *rsp[32]; | |
(*ip)->code(STATE); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// "Primitive-centric threaded code" | |
// | |
// See: https://gforth.org/manual/Direct-or-Indirect-Threaded_003f.html | |
#include <inttypes.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
struct state; | |
struct instr { | |
void (*code)(intptr_t data, struct state *s); | |
intptr_t data; | |
}; | |
struct state { | |
struct instr const *ip; | |
intptr_t *sp; | |
struct instr const **rsp; | |
}; | |
struct word { | |
struct instr ins; | |
struct instr payload[]; | |
}; | |
// Words defined in C | |
void run_return(intptr_t, struct state *s) { | |
s->ip = *(--s->rsp); | |
} | |
const struct word _f_return = { | |
.ins = { .code = run_return }, | |
}; | |
void run_add(intptr_t, struct state *s) { | |
intptr_t n2 = *(--s->sp); | |
intptr_t n1 = *(--s->sp); | |
*(s->sp++) = n1 + n2; | |
s->ip++; | |
} | |
const struct word _f_add = { | |
.ins = { .code = run_add }, | |
}; | |
void run_print(intptr_t, struct state *s) { | |
intptr_t value = *(--s->sp); | |
printf("%" PRIdPTR "\n", value); | |
s->ip++; | |
} | |
const struct word _f_print = { | |
.ins = { .code = run_print }, | |
}; | |
void run_exit(intptr_t, struct state *) { | |
exit(0); | |
} | |
const struct word _f_exit = { | |
.ins = { .code = run_exit }, | |
}; | |
// Some more C code to use in words that uses the data field | |
void run_literal(intptr_t data, struct state *s) { | |
*(s->sp++) = data; | |
s->ip++; | |
} | |
void run_tc(intptr_t data, struct state *s) { | |
s->ip++; | |
*(s->rsp++) = s->ip; | |
s->ip = (struct instr const *)data; | |
} | |
// (maybe) | |
// 1 constant one | |
const struct word _f_one = { | |
.ins = { .code = run_literal, .data = 1 }, | |
}; | |
// : two one one + ; | |
const struct word _f_two = { | |
.ins = { .code = run_tc, .data = (intptr_t)&_f_two.payload }, | |
.payload = { _f_one.ins, _f_one.ins, _f_add.ins, _f_return.ins }, | |
}; | |
// : four two two + ; | |
const struct word _f_four = { | |
.ins = { .code = run_tc, .data = (intptr_t)&_f_four.payload }, | |
.payload = { _f_two.ins, _f_two.ins, _f_add.ins, _f_return.ins }, | |
}; | |
// : main four print exit ; | |
const struct word _f_main = { | |
.ins = { .code = run_tc, .data = (intptr_t)&_f_main.payload }, | |
.payload = { _f_four.ins, _f_print.ins, _f_exit.ins, _f_return.ins }, | |
}; | |
int main() { | |
intptr_t stack[32]; | |
struct instr const *rstack[32]; | |
struct state s = { | |
.ip = &_f_main.payload[0], | |
.sp = stack, | |
.rsp = rstack, | |
}; | |
for (;;) { | |
struct instr ins = *s.ip; | |
ins.code(ins.data, &s); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment