Skip to content

Instantly share code, notes, and snippets.

@dramforever
Last active November 1, 2023 15:29
Show Gist options
  • Save dramforever/b20912a79724d5b1c66f010238fd8a5c to your computer and use it in GitHub Desktop.
Save dramforever/b20912a79724d5b1c66f010238fd8a5c to your computer and use it in GitHub Desktop.
#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);
}
// "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