Skip to content

Instantly share code, notes, and snippets.

@ktbarrett
Created August 28, 2021 19:57
Show Gist options
  • Save ktbarrett/3bc4d51d33ce782582facfb1869b764f to your computer and use it in GitHub Desktop.
Save ktbarrett/3bc4d51d33ce782582facfb1869b764f to your computer and use it in GitHub Desktop.
#include <stdnoreturn.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
typedef enum {
PUSH,
POP,
ADD,
SUB,
MUL,
DIV,
PRINT,
FINISH,
} op_code;
typedef struct op {
int32_t opcode;
double arg;
} op;
typedef op program[];
typedef double stack[];
typedef noreturn void (*opfunc)(program, stack, double);
static noreturn void dispatch(program, stack);
static noreturn void push(program p, stack s, double arg)
{
*s++ = arg;
dispatch(p, s);
}
static noreturn void pop(program p, stack s, double arg)
{
s--;
dispatch(p, s);
}
static noreturn void add(program p, stack s, double arg)
{
double b = *s--;
double a = *s--;
*s++ = a + b;
dispatch(p, s);
}
static noreturn void sub(program p, stack s, double arg)
{
double b = *s--;
double a = *s--;
*s++ = a - b;
dispatch(p, s);
}
static noreturn void mul(program p, stack s, double arg)
{
double b = *s--;
double a = *s--;
*s++ = a * b;
dispatch(p, s);
}
static noreturn void opdiv(program p, stack s, double arg)
{
double b = *s--;
double a = *s--;
*s++ = a / b;
dispatch(p, s);
}
static noreturn void print(program p, stack s, double arg)
{
printf("%f\n", *s);
dispatch(p, s);
}
static noreturn void finish(program p, stack s, double arg)
{
int rc = *s--;
exit(rc);
}
static noreturn void dispatch(program p, stack s)
{
static opfunc dispatch_table[] = {
push,
pop,
add,
sub,
mul,
opdiv,
print,
finish,
};
op nxt = *p++;
dispatch_table[nxt.opcode](p, s, nxt.arg);
}
int main()
{
program prog = {
{PUSH, 1},
{PUSH, 1},
{ADD, 0},
{PUSH, 2},
{MUL, 0},
{PRINT, 0},
{PUSH, 0},
{FINISH, 0},
};
double s[100];
dispatch(prog, s);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment