mirror of
https://github.com/nineties/planckforth
synced 2025-01-13 08:01:10 +01:00
Add c-version and python-version
This commit is contained in:
parent
c01cd8cc50
commit
d197737bcc
2 changed files with 354 additions and 0 deletions
133
others/planck.c
Normal file
133
others/planck.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* planck -
|
||||
* Copyright (C) 2021 nineties
|
||||
*/
|
||||
#ifndef INCLUDE_DEFS
|
||||
#define INCLUDE_DEFS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef uintptr_t cell;
|
||||
typedef void (**cfa)();
|
||||
|
||||
#define CELL sizeof(cell)
|
||||
#define STACK_SIZE 1024
|
||||
#define RSTACK_SIZE 1024
|
||||
#define MEMORY_SIZE 0x100000
|
||||
|
||||
typedef struct builtin {
|
||||
struct builtin *prev;
|
||||
char len;
|
||||
char name;
|
||||
char padding[CELL-2];
|
||||
void (*fun)();
|
||||
} builtin;
|
||||
|
||||
static cell stack[STACK_SIZE];
|
||||
static cell rstack[RSTACK_SIZE];
|
||||
static cell *dsp = stack + STACK_SIZE;
|
||||
static cell *rsp = rstack + RSTACK_SIZE;
|
||||
|
||||
static cell memory[MEMORY_SIZE];
|
||||
static builtin *latest = 0;
|
||||
static cell *here = memory;
|
||||
static cell *pc = NULL;
|
||||
static cfa ip = NULL;
|
||||
|
||||
#define next() (*(ip = (cfa)(*pc++)))()
|
||||
|
||||
static void push(cell v) { *(--dsp) = v; }
|
||||
static cell pop(void) { return *dsp++; }
|
||||
static void rpush(cell v) { *(--rsp) = v; }
|
||||
static cell rpop(void) { return *rsp++; }
|
||||
|
||||
static void docol(void) {
|
||||
rpush((cell) pc);
|
||||
pc = (cell*)ip + 1;
|
||||
next();
|
||||
}
|
||||
|
||||
static cfa find(char c) {
|
||||
for (builtin *it = latest; it; it = it->prev)
|
||||
if (it->len == 1 && it->name == c)
|
||||
return &it->fun;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define defcode(name, label) \
|
||||
static void label()
|
||||
#include "planck.c"
|
||||
#undef defcode
|
||||
|
||||
int main(void) {
|
||||
#define defcode(c, label) \
|
||||
memcpy(here, &(builtin){ latest, 1, c, {0}, label }, 3*CELL); \
|
||||
latest = (builtin*)here; \
|
||||
here += 3; \
|
||||
if (0) // skip function body
|
||||
#include "planck.c"
|
||||
|
||||
cfa start = (cfa) here;
|
||||
*here++ = (cell) find('k');
|
||||
*here++ = (cell) find('f');
|
||||
*here++ = (cell) find('x');
|
||||
*here++ = (cell) find('j');
|
||||
*here++ = (cell) -4 * CELL;
|
||||
pc = (cell*) start;
|
||||
next();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
defcode('Q', quit) { exit(0); }
|
||||
defcode('C', cell_) { push(CELL); next(); }
|
||||
defcode('h', here_) { push((cell)&here); next(); }
|
||||
defcode('l', latest_) { push((cell)&latest); next(); }
|
||||
defcode('i', docol_) { push((cell)docol); next(); }
|
||||
defcode('e', exit_) { pc = (cell*)rpop(); next(); }
|
||||
defcode('@', fetch) { cell *p = (cell*)pop(); push(*p); next(); }
|
||||
defcode('!', store) { cell *p = (cell*)pop(); *p = pop(); next(); }
|
||||
defcode('?', cfetch) { char *p = (char*)pop(); push(*p); next(); }
|
||||
defcode('$', cstore) { char *p = (char*)pop(); *p = pop(); next(); }
|
||||
defcode('d', dfetch) { push((cell)dsp); next(); }
|
||||
defcode('D', dstore) { dsp = (cell*) pop(); next(); }
|
||||
defcode('r', rfetch) { push((cell)rsp); next(); }
|
||||
defcode('R', rstore) { rsp = (cell*) pop(); next(); }
|
||||
defcode('j', jump) { pc += (int)*pc/CELL; next(); }
|
||||
defcode('J', jump0) { pc += (int)(pop()?1:*pc/CELL); next(); }
|
||||
defcode('L', lit) { push(*pc++); next(); }
|
||||
defcode('S', litstring) {
|
||||
int len = *pc++;
|
||||
push((cell) pc);
|
||||
push(len);
|
||||
pc += (len + CELL - 1)/CELL;
|
||||
}
|
||||
defcode('k', key) {
|
||||
int c = getchar();
|
||||
if (c <= 0)
|
||||
exit(0);
|
||||
push(c);
|
||||
next();
|
||||
}
|
||||
defcode('t', type) { putchar(pop()); next(); }
|
||||
defcode('x', exec) { (*(ip = (cfa) pop()))(); }
|
||||
defcode('f', find_) { push((cell) find(pop())); next(); }
|
||||
#define defbinary(c, label, op, ty) \
|
||||
defcode(c, label) { \
|
||||
ty b = (ty) pop(); \
|
||||
*dsp = (cell)((ty) *dsp op b); \
|
||||
next(); \
|
||||
}
|
||||
defbinary('+', add, +, intptr_t)
|
||||
defbinary('-', sub, -, intptr_t)
|
||||
defbinary('*', mul, *, intptr_t)
|
||||
defbinary('/', div_, /, intptr_t)
|
||||
defbinary('%', mod, %, intptr_t)
|
||||
defbinary('&', and, &, uintptr_t)
|
||||
defbinary('|', or, |, uintptr_t)
|
||||
defbinary('^', xor, ^, uintptr_t)
|
||||
defbinary('<', lt, <, intptr_t)
|
||||
defbinary('=', eq, ==, intptr_t)
|
||||
|
||||
#endif
|
221
others/planck.py
Normal file
221
others/planck.py
Normal file
|
@ -0,0 +1,221 @@
|
|||
# planck -
|
||||
# Copyright (C) 2021 nineties
|
||||
#
|
||||
|
||||
import sys
|
||||
CELL = 4
|
||||
MEMORY_SIZE = 0x08000000
|
||||
STACK_SIZE = 0x400
|
||||
RSTACK_SIZE = 0x400
|
||||
HERE_CELL = 0
|
||||
LATEST_CELL = CELL
|
||||
|
||||
memory = bytearray(MEMORY_SIZE)
|
||||
sp = MEMORY_SIZE
|
||||
rp = MEMORY_SIZE - STACK_SIZE
|
||||
ip = 0
|
||||
pc = 0
|
||||
|
||||
def read(addr):
|
||||
return int.from_bytes(
|
||||
memory[addr:addr+CELL], 'little', signed=True)
|
||||
|
||||
def write(addr, v):
|
||||
memory[addr:addr+CELL] = v.to_bytes(4, 'little', signed=True)
|
||||
|
||||
def read_byte(addr):
|
||||
return memory[addr]
|
||||
|
||||
def write_byte(addr, v):
|
||||
memory[addr] = v
|
||||
|
||||
next_builtin_id = 1
|
||||
def add_builtin(c):
|
||||
global next_builtin_id
|
||||
builtin_id = next_builtin_id
|
||||
next_builtin_id += 1
|
||||
|
||||
here = read(HERE_CELL)
|
||||
latest = read(LATEST_CELL)
|
||||
write(here, latest)
|
||||
write_byte(here + CELL, 1)
|
||||
write_byte(here + CELL + 1, ord(c))
|
||||
write(here + 2*CELL, builtin_id)
|
||||
|
||||
write(HERE_CELL, here + 3*CELL)
|
||||
write(LATEST_CELL, here)
|
||||
return builtin_id
|
||||
|
||||
def find(c):
|
||||
it = read(LATEST_CELL)
|
||||
while it != 0:
|
||||
n = read_byte(it + CELL)
|
||||
C = chr(read_byte(it + CELL + 1))
|
||||
if (c == C and n == 1):
|
||||
return it + 2*CELL
|
||||
it = read(it)
|
||||
raise Exception('Unknown word: {}'.format(c))
|
||||
|
||||
def push(v):
|
||||
global sp
|
||||
sp -= CELL
|
||||
write(sp, v)
|
||||
|
||||
def pop():
|
||||
global sp
|
||||
v = read(sp)
|
||||
sp += CELL
|
||||
return v
|
||||
|
||||
def rpush(v):
|
||||
global rp
|
||||
rp -= CELL
|
||||
write(rp, v)
|
||||
|
||||
def rpop():
|
||||
global rp
|
||||
v = read(rp)
|
||||
rp += CELL
|
||||
return v
|
||||
|
||||
write(HERE_CELL, 2*CELL)
|
||||
write(LATEST_CELL, 0)
|
||||
|
||||
DOCOL_ = 0
|
||||
QUIT = add_builtin('Q')
|
||||
CELLSIZE = add_builtin('C')
|
||||
HERE = add_builtin('h')
|
||||
LATEST = add_builtin('l')
|
||||
KEY = add_builtin('k')
|
||||
EMIT = add_builtin('t')
|
||||
JUMP = add_builtin('j')
|
||||
JUMP0 = add_builtin('J')
|
||||
FIND = add_builtin('f')
|
||||
EXECUTE = add_builtin('x')
|
||||
FETCH = add_builtin('@')
|
||||
STORE = add_builtin('!')
|
||||
CFETCH = add_builtin('?')
|
||||
CSTORE = add_builtin('$')
|
||||
DFETCH = add_builtin('d')
|
||||
DSTORE = add_builtin('D')
|
||||
RFETCH = add_builtin('r')
|
||||
RSTORE = add_builtin('R')
|
||||
DOCOL = add_builtin('i')
|
||||
EXIT = add_builtin('e')
|
||||
LIT = add_builtin('L')
|
||||
LITSTRING = add_builtin('S')
|
||||
ADD = add_builtin('+')
|
||||
SUB = add_builtin('-')
|
||||
MUL = add_builtin('*')
|
||||
DIV = add_builtin('/')
|
||||
MOD = add_builtin('%')
|
||||
AND = add_builtin('&')
|
||||
OR = add_builtin('|')
|
||||
XOR = add_builtin('^')
|
||||
LESS = add_builtin('<')
|
||||
EQUAL = add_builtin('=')
|
||||
|
||||
here = read(HERE_CELL)
|
||||
write(here, find('k'))
|
||||
write(here + CELL, find('f'))
|
||||
write(here + 2*CELL, find('x'))
|
||||
write(here + 3*CELL, find('j'))
|
||||
write(here + 4*CELL, -4*CELL)
|
||||
write(HERE_CELL, here + 5*CELL)
|
||||
|
||||
pc = here
|
||||
ip = read(pc)
|
||||
pc += CELL
|
||||
while True:
|
||||
code = read(ip)
|
||||
if code == DOCOL_:
|
||||
rpush(pc)
|
||||
pc = ip + CELL
|
||||
elif code == QUIT:
|
||||
exit(0)
|
||||
elif code == CELLSIZE:
|
||||
push(CELL)
|
||||
elif code == HERE:
|
||||
push(HERE_CELL)
|
||||
elif code == LATEST:
|
||||
push(LATEST_CELL)
|
||||
elif code == KEY:
|
||||
push(ord(sys.stdin.read(1)))
|
||||
elif code == EMIT:
|
||||
sys.stdout.write(chr(pop()))
|
||||
elif code == JUMP:
|
||||
pc += read(pc)
|
||||
elif code == JUMP0:
|
||||
if pop() == 0:
|
||||
pc += read(pc)
|
||||
else:
|
||||
pc += CELL
|
||||
elif code == FIND:
|
||||
push(find(chr(pop())))
|
||||
elif code == EXECUTE:
|
||||
ip = pop()
|
||||
continue
|
||||
elif code == FETCH:
|
||||
push(read(pop()))
|
||||
elif code == STORE:
|
||||
addr = pop()
|
||||
write(addr, pop())
|
||||
elif code == CFETCH:
|
||||
push(read_byte(pop()))
|
||||
elif code == CSTORE:
|
||||
addr = pop()
|
||||
write_byte(addr, pop())
|
||||
elif code == DFETCH:
|
||||
push(sp)
|
||||
elif code == DSTORE:
|
||||
sp = pop()
|
||||
elif code == RFETCH:
|
||||
push(rp)
|
||||
elif code == RSTORE:
|
||||
rp = pop()
|
||||
elif code == DOCOL:
|
||||
push(DOCOL_)
|
||||
elif code == EXIT:
|
||||
pc = rpop()
|
||||
elif code == LIT:
|
||||
push(read(pc))
|
||||
pc += CELL
|
||||
elif code == LITSTRING:
|
||||
n = read(pc)
|
||||
push(pc + CELL)
|
||||
push(n)
|
||||
pc = (pc + 2*CELL + n - 1) & ~CELL
|
||||
elif code == ADD:
|
||||
b = pop()
|
||||
push(pop() + b)
|
||||
elif code == SUB:
|
||||
b = pop()
|
||||
push(pop() - b)
|
||||
elif code == MUL:
|
||||
b = pop()
|
||||
push(pop() * b)
|
||||
elif code == DIV:
|
||||
b = pop()
|
||||
push(pop() // b)
|
||||
elif code == MOD:
|
||||
b = pop()
|
||||
push(pop() % b)
|
||||
elif code == AND:
|
||||
b = pop()
|
||||
push(pop() & b)
|
||||
elif code == OR:
|
||||
b = pop()
|
||||
push(pop() | b)
|
||||
elif code == XOR:
|
||||
b = pop()
|
||||
push(pop() ^ b)
|
||||
elif code == LESS:
|
||||
b = pop()
|
||||
push(pop() < b)
|
||||
elif code == EQUAL:
|
||||
b = pop()
|
||||
push(pop() == b)
|
||||
else:
|
||||
raise Exception('Invalid Code Pointer: {}'.format(code))
|
||||
ip = read(pc)
|
||||
pc += CELL
|
Loading…
Reference in a new issue