Lambda calculus-like library written in TypeScript.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
jlc/src/bf.ts

58 lines
2.7 KiB

import { _, _l, cnst, g, id, n, pipe } from './core';
import { iif } from './bool';
import { Zero, ge, ifz, pred, succ } from './num';
import { x00 } from './byte';
import { fromChar as _c, dec as cdec, inc as cinc, eq, ifn } from './char';
import { Pair, first, fst, second, snd, uncurry } from './pair';
import { cons, head, repeat, set, singleton, tail, update } from './list';
import { Empty, get, len, snoc } from './string';
n('bf');
const done = g('done', uncurry._(_l(p => cnst._(uncurry._(_l(is => _l(cs => ge._(head._(is))._(len._(cs)))))._(p)))));
const command = g('command', _l(c => uncurry._(_l(p => cnst._(eq._(c)._(uncurry._(pipe._(get)._(head))._(p)))))));
const advance = g('advance', first._(first._(update._(succ)._(Zero))));
const save = g('save', first._(first._(_l(is => cons._(head._(is))._(is)))));
const restore = g('restore', first._(first._(tail)));
const reset = g('reset', first._(first._(_l(is => cons._(head._(is))._(tail._(tail._(is)))))));
const inc = g('inc', second._(first._(_l(t => second._(update._(cinc)._(fst._(t)))._(t)))));
const dec = g('dec', second._(first._(_l(t => second._(update._(cdec)._(fst._(t)))._(t)))));
const read = g('read', pipe._(pipe._(uncurry._(get))._(fst))._(snd));
const input = g('input', second._(uncurry._(_l(t => _l(io => Pair._(second._(set._(head._(fst._(io)))._(fst._(t)))._(t))._(first._(tail)._(io)))))));
const output = g('output', second._(uncurry._(_l(t => pipe._(Pair._(t))._(second._(_l(os => snoc._(os)._(uncurry._(get)._(t)))))))));
const next = g('next', second._(first._(first._(succ))));
const prev = g('prev', second._(first._(first._(pred))));
const jump = g('jump', _l(d => _l(s =>
iif._(command._(_c('['))._(s))._(jump._(succ._(d)))
._(iif._(command._(_c(']'))._(s))._(ifz._(pred._(d))._(cnst._(s))._(jump._(pred._(d))))
._(jump._(d)))._(advance._(s)))));
const whlnz = g('whlnz', _l(s => ifn._(read._(s))._(jump._(Zero))._(save)._(s)));
const endwhl = g('endwhl', _l(s => ifn._(read._(s))._(reset)._(pipe._(save)._(restore))._(s)));
const exec = g('exec', _l(s => iif._(done._(s))._(s)._(exec._(advance
._(iif._(command._(_c('>'))._(s))._(next)
._(iif._(command._(_c('<'))._(s))._(prev)
._(iif._(command._(_c('+'))._(s))._(inc)
._(iif._(command._(_c('-'))._(s))._(dec)
._(iif._(command._(_c('.'))._(s))._(output)
._(iif._(command._(_c(','))._(s))._(input)
._(iif._(command._(_c('['))._(s))._(whlnz)
._(iif._(command._(_c(']'))._(s))._(endwhl)
._(id))))))))._(s))))));
export const run = g('run', _l(p => _l(i => snd._(snd._(snd._(exec._(Pair._(Pair._(singleton._(Zero))._(p))._(Pair._(Pair._(Zero)._(repeat._(x00)))._(Pair._(i)._(Empty))))))))));