A LISP/Scheme dialect is implemented as a surface-syntax for uFork programs. It handles both "interpreted" and "compiled" code.
peg-lang
; REPL grammarempty-env
global-env
(quote
expr)
(eval
expr.
optenv)
(apply
proc.
optenv)
(list .
values)
(list*
value.
values)
(lambda
formal.
body)
(vau
formal.
body)
(macro
formal.
body)
(par .
exprs)
(seq .
body)
(define
formal)
(zip
formal)
(cons
head)
(car
list)
(cdr
list)
(cadr
list)
(caar
list)
(cdar
list)
(cddr
list)
(caddr
list)
(cadar
list)
(cadddr
list)
(nth
index)
(null? .
values)
(pair? .
values)
(boolean? .
values)
(number? .
values)
(symbol? .
values)
(actor? .
values)
(if
test)
(cond (
test.
body) .
clauses)
(eq? .
values)
(equal?
value)
(= .
numbers)
(< .
numbers)
(<= .
numbers)
(>= .
numbers)
(> .
numbers)
(not
bool)
(and .
bool)
(or .
bool)
(+ .
numbers)
(- .
numbers)
(* .
numbers)
(length
list)
(append .
lists)
(filter
pred)
(reduce
binop)
(foldl
binop)
(foldr
binop)
(map
proc.
lists)
(reverse
list)
(let ((
var) .
bindings) .
body)
(current-env)
(gensym)
(print .
values)
a-print
(quit)
(CREATE
behavior)
(SEND
actor)
(BECOME
behavior)
SELF
(BEH
formal.
body)
(CALL
actor)
(define sink-beh (BEH _))
(define a-sink (CREATE sink-beh))
(define fwd-beh
(lambda (delegate)
(BEH message
(SEND delegate message))))
;(SEND (CREATE (fwd-beh a-print)) '(1 2 3))
(define once-beh
(lambda (delegate)
(BEH message
(SEND delegate message)
(BECOME sink-beh))))
;(define once (CREATE (once-beh a-print)))
;(par (SEND once 1) (SEND once 2) (SEND once 3))
(define label-beh
(lambda (cust label)
(BEH msg
(SEND cust (cons label msg)))))
;(define b (label-beh a-print 'foo))
;(define a (CREATE b))
;(SEND a '(bar baz))
(define tag-beh
(lambda (cust)
(BEH msg
(SEND cust (cons SELF msg)))))
(define a-crowd
(CREATE
(BEH (cust count)
(if (<= count 0)
(SEND cust SELF)
(seq
(SEND SELF (list cust (- count 1)))
(SEND SELF (list cust (- count 1)))) ))))
;(SEND a-crowd (list a-print 3))
(define broadcast-beh
(lambda (value)
(BEH actors
(if (pair? actors)
(seq
(SEND (car actors) value)
(SEND SELF (cdr actors))) ))))
;(define a (CREATE (tag-beh a-print)))
;(define b (CREATE (tag-beh a-print)))
;(define c (CREATE (tag-beh a-print)))
;(SEND (CREATE (broadcast-beh 42)) (list a b c))
(peg-source
list)
(peg-start
peg)
(peg-chain
peg)
peg-empty
peg-fail
peg-any
(peg-eq
token)
(peg-or
first)
(peg-and
first)
(peg-not
peg)
(peg-class .
classes)
(peg-opt
peg)
(peg-plus
peg)
(peg-star
peg)
(peg-alt .
pegs)
(peg-seq .
pegs)
(peg-call
name)
(peg-pred
pred)
(peg-xform
func)
(list->number
chars)
(list->symbol
chars)
(define peg-end (peg-not peg-any)) ; end of input
(define peg-peek (lambda (ptrn) (peg-not (peg-not ptrn)))) ; positive lookahead
(define peg-ok? (lambda (x) (if (pair? x) (if (actor? (cdr x)) #f #t) #f)))
(define peg-value (lambda (x) (if (pair? x) (if (actor? (cdr x)) #? (car x)) #?)))
Message to Grammar:
NIL (on end-of-stream)
--->[custs,context]--->[accum,in]---> or
| | [token,next]--->
v v |
[ok,fail] v
/ \
v v
Reply to ok customer:
NIL (on end-of-stream)
--->[accum,in]---> or
| [token,next]--->
v |
v
Reply to fail customer:
NIL (on end-of-stream)
---> or
[token,next]--->
|
v
(define lex-eol (peg-eq 10)) ; end of line
(define lex-optwsp (peg-star (peg-class WSP)))
(define scm-to-eol (peg-or lex-eol (peg-and peg-any (peg-call scm-to-eol))))
(define scm-comment (peg-and (peg-eq 59) scm-to-eol))
(define scm-optwsp (peg-star (peg-or scm-comment (peg-class WSP))))
(define lex-eot (peg-not (peg-class DGT UPR LWR SYM))) ; end of token
(define lex-sign (peg-or (peg-eq 45) (peg-eq 43))) ; [-+]
(define lex-digit (peg-or (peg-class DGT) (peg-eq 95))) ; [0-9_]
(define lex-digits (peg-xform car (peg-and (peg-plus lex-digit) lex-eot)))
(define lex-number (peg-xform list->number (peg-or (peg-and lex-sign lex-digits) lex-digits)))
(define scm-ignore (peg-xform (lambda _ '_) (peg-and (peg-plus (peg-eq 95)) lex-eot)))
(define scm-const (peg-xform cadr (peg-seq
(peg-eq 35)
(peg-alt
(peg-xform (lambda _ #f) (peg-eq 102))
(peg-xform (lambda _ #t) (peg-eq 116))
(peg-xform (lambda _ #?) (peg-eq 63))
(peg-xform (lambda _ #unit) (peg-seq (peg-eq 117) (peg-eq 110) (peg-eq 105) (peg-eq 116))))
lex-eot)))
(define scm-symbol (peg-xform list->symbol (peg-plus (peg-class DGT UPR LWR SYM))))
(define scm-quoted (peg-alt
(peg-xform (lambda (x) (list 'quote (cdr x)))
(peg-and (peg-eq 39) (peg-call scm-expr)))
(peg-xform (lambda (x) (list 'quasiquote (cdr x)))
(peg-and (peg-eq 96) (peg-call scm-expr)))
(peg-xform (lambda (x) (list 'unquote-splicing (cddr x)))
(peg-and (peg-eq 44) (peg-and (peg-eq 64) (peg-call scm-expr))))
(peg-xform (lambda (x) (list 'unquote (cdr x)))
(peg-and (peg-eq 44) (peg-call scm-expr)))
(peg-xform (lambda (x) (list 'placeholder (cdr x)))
(peg-and (peg-eq 63) (peg-call scm-expr)))
))
(define scm-dotted (peg-xform caddr
(peg-seq scm-optwsp (peg-eq 46) (peg-call scm-sexpr) scm-optwsp (peg-eq 41))))
(define scm-tail (peg-xform cdr (peg-and
scm-optwsp
(peg-or
(peg-xform (lambda _ ()) (peg-eq 41))
(peg-and
(peg-call scm-expr)
(peg-or scm-dotted (peg-call scm-tail)) )) )))
(define scm-list (peg-xform cdr (peg-and (peg-eq 40) scm-tail)))
(define scm-expr (peg-alt scm-list scm-ignore scm-const lex-number scm-quoted scm-symbol))
(define scm-sexpr (peg-xform cdr (peg-and scm-optwsp scm-expr)))
;(define src (peg-source '(9 40 97 32 46 32 98 41 10))) ; "\t(a . b)\n"
;(define rv (peg-start scm-sexpr src))
;
; meta-actor transaction = {t:Fexpr_T, x:self, y:outbox, z:beh}
;
(define meta-actor-beh
(lambda (beh)
(BEH msg
(define txn (cell Fexpr_T SELF () beh))
(SEND beh (cons txn msg))
(BECOME (meta-busy-beh txn ())) )))
(define meta-busy-beh
(lambda (txn pending)
(BEH msg
(cond
((eq? msg txn) ; end txn
(define beh (get-z msg))
(define outbox (get-y msg))
(map (lambda (x) (SEND (car x) (cdr x))) outbox) ; (send-msgs outbox)
(cond
((pair? pending)
(define txn (cell Fexpr_T SELF () beh))
(SEND beh (cons txn (car pending)))
(BECOME (meta-busy-beh txn (cdr pending))))
(#t
(BECOME (meta-actor-beh beh)))))
(#t
(BECOME (meta-busy-beh txn (cons msg pending)))) ))))
(define meta-CREATE ; (CREATE behavior)
(CREATE
(BEH (cust . args)
(SEND cust (CREATE (meta-actor-beh (car args)))) )))
(define meta-SEND ; (SEND actor message)
(lambda (txn)
(lambda (actor msg)
(set-y txn (cons (cons actor msg) (get-y txn))) )))
(define meta-BECOME ; (BECOME behavior)
(lambda (txn)
(lambda (beh)
(set-z txn beh) )))
(define actor-env ; extend environment with actor primitives
(lambda (txn env)
(zip
'(SEND BECOME SELF)
((CREATE (meta-SEND txn)) (CREATE (meta-BECOME txn)) (get-x txn))
env)))
(define a-meta-beh ; actor meta-behavior
(lambda (frml body env)
(BEH (txn . msg)
(define aenv (scope (actor-env txn env)))
(evbody #unit body (zip frml msg aenv))
(SEND (get-x txn) txn) )))
(define meta-BEH ; (BEH <frml> . <body>)
(CREATE
(BEH (cust opnds env)
(SEND cust
(CREATE (a-meta-beh (car opnds) (cdr opnds) env))) )))
- literals:
UNDEF
,NIL
,FALSE
,TRUE
,UNIT
- type-ids:
Literal_T
,Type_T
,Event_T
,Instr_T
,Actor_T
,Fixnum_T
,Symbol_T
,Pair_T
,Fexpr_T
,Free_T
- op-codes:
VM_typeq
,VM_cell
,VM_get
,VM_set
,VM_pair
,VM_part
,VM_nth
,VM_push
,VM_depth
,VM_drop
,VM_pick
,VM_dup
,VM_roll
,VM_alu
,VM_eq
,VM_cmp
,VM_if
,VM_msg
,VM_self
,VM_send
,VM_new
,VM_beh
,VM_end
,VM_cvt
,VM_putc
,VM_getc
,VM_debug
VM_get
,VM_set
:FLD_T
,FLD_X
,FLD_Y
,FLD_Z
VM_alu
:ALU_NOT
,ALU_AND
,ALU_OR
,ALU_XOR
,ALU_ADD
,ALU_SUB
,ALU_MUL
VM_cmp
:CMP_EQ
,CMP_GE
,CMP_GT
,CMP_LT
,CMP_LE
,CMP_NE
,CMP_CLS
- classes:
CTL
,DGT
,UPR
,LWR
,DLM
,SYM
,HEX
,WSP
VM_end
:END_ABORT
,END_STOP
,END_COMMIT
,END_RELEASE
VM_cvt
:CVT_LST_NUM
,CVT_LST_SYM
- continuations:
RV_SELF
,CUST_SEND
,SEND_0
,COMMIT
,RESEND
,RELEASE_0
,RELEASE
,RV_FALSE
,RV_TRUE
,RV_NIL
,RV_UNDEF
,RV_UNIT
,RV_ZERO
,RV_ONE
(cell
T)
(get-t
cell)
(get-x
cell)
(get-y
cell)
(get-z
cell)
(set-t
cell)
--DEPRECATED--(set-x
cell)
--DEPRECATED--(set-y
cell)
--DEPRECATED--(set-z
cell)
--DEPRECATED--
(define print
(cell Actor_T ; --DEPRECATED--
(cell Instr_T VM_msg 1
(cell Instr_T VM_push a-print
(cell Instr_T VM_send 0
RV_UNIT)))
()))
(define gensym
(lambda ()
(cell Symbol_T (get-x '_) (get-y '_))))
(define disasm
(lambda (ip)
(list (get-t ip) (get-x ip) (get-y ip) (get-z ip))))