~/bend-docscommunity

core.bend source

core.bend on the hub · documented module

import Base# Tiny Haskell-Core-like language in Bend: de Bruijn indices (no names, so# no equality dispatch is ever needed), lazy thunks, Nat-shaped case# (zero branch vs succ branch binding the predecessor -- no comparison# primop required). ONE fuel-stepped def (c_run); Bend forbids mutual# recursion, so sequencing uses explicit tasks + continuations, exactly# like the lisp.bend machine. Parallel from the start: CAdd evaluates# both sides as a parallel pair, c_batch runs whole programs in parallel,# c_batch_gpu is the same runner handed to the GPU with `!`.type CExp is Data:  CVar{idx: U32}  CLit{val: Nat}  CAdd{a: CExp, b: CExp}  CLam{body: CExp}  CApp{f: CExp, x: CExp}  CLet{v: CExp, b: CExp}  CCase{s: CExp, z: CExp, sd: CExp}type CVal is Data:  VNum{v: Nat}  VClos{body: CExp, env: List<&2, CVal>}  VThunk{e: CExp, env: List<&2, CVal>}type CK is Data:  CDone{}  CAddR{a: CVal, k: CK}  CAppA{x: CExp, env: List<&2, CVal>, k: CK}  CCaseK{z: CExp, sd: CExp, env: List<&2, CVal>, k: CK}type CTask is Data:  CEval{e: CExp, env: List<&2, CVal>, k: CK}  CRet{k: CK, v: CVal}  CLook{n: Nat, env: List<&2, CVal>, k: CK}def c_num_add(+a: CVal, +b: CVal) -> CVal:  match a b:    case VNum{x} VNum{y}:      VNum{Nat.add(x, y)}    case _ _:      VNum{0n}def c_run(+f: Nat, +t: CTask) -> CVal:  match f:    case 0n:      VNum{0n}    case 1n+p:      match t:        case CEval{e, env, k}:          match e:            case CVar{i}:              c_run(p, CLook{U32.to_nat(i), env, k})            case CLit{v}:              c_run(p, CRet{k, VNum{v}})            case CAdd{a, b}:              av bv = c_run(p, CEval{a, env, CDone{}}) c_run(p, CEval{b, env, CDone{}})              c_num_add(av, bv)            case CLam{body}:              c_run(p, CRet{k, VClos{body, env}})            case CApp{f, x}:              c_run(p, CEval{f, env, CAppA{x, env, k}})            case CLet{v, b}:              c_run(p, CEval{b, Con{VThunk{v, env}, env}, k})            case CCase{s, z, sd}:              c_run(p, CEval{s, env, CCaseK{z, sd, env, k}})        case CRet{k, v}:          match k:            case CDone{}:              v            case CAddR{a, k2}:              c_num_add(a, v)            case CAppA{x, env, k2}:              match v:                case VClos{body, cenv}:                  c_run(p, CEval{body, Con{VThunk{x, env}, cenv}, k2})                case VThunk{e, eenv}:                  c_run(p, CEval{e, eenv, CAppA{x, env, k2}})                case _:                  c_run(p, CRet{k2, VNum{0n}})            case CCaseK{z, sd, env, k2}:              match v:                case VNum{n}:                  match n:                    case 0n:                      c_run(p, CEval{z, env, k2})                    case 1n+m:                      c_run(p, CEval{sd, Con{VNum{m}, env}, k2})                case _:                  c_run(p, CRet{k2, VNum{0n}})        case CLook{n, env, k}:          match n env:            case 0n Con{v, vs}:              match v:                case VThunk{e, eenv}:                  c_run(p, CEval{e, eenv, k})                case _:                  c_run(p, CRet{k, v})            case 1n+m Con{v, vs}:              c_run(p, CLook{m, vs, k})            case _ _:              c_run(p, CRet{k, VNum{0n}})def c_eval(+f: Nat, +e: CExp) -> CVal:  c_run(f, CEval{e, Nil{}, CDone{}})def c_batch(+f: Nat, +es: List<&2, CExp>) -> List<&2, CVal>:  match es:    case Nil{}:      Nil{}    case Con{h, t}:      r rs = c_eval(f, h) c_batch(f, t)      Con{r, rs}def c_batch_gpu(+f: Nat, +es: List<&2, CExp>) -> List<&2, CVal>:  c_batch!(f, es)def main() -> List<&2, CVal>:  c_batch(30n, [CLit{5n}, CAdd{CLit{2n}, CLit{3n}}, CLet{CLit{3n}, CAdd{CVar{0}, CLit{4n}}}])