## experimental compiler to translate programs written in a generic ## expression-oriented language called 'lambda' into Mu # incomplete; code generator not done # potential enhancements: # symbol table # poor man's macros # substitute one instruction with multiple, parameterized by inputs and products scenario convert-lambda [ run [ local-scope 1:text/raw <- lambda-to-mu [(add a (multiply b c))] 2:@:char/raw <- copy *1:text/raw ] memory-should-contain [ 2:array:character <- [t1 <- multiply b c result <- add a t1] ] ] def lambda-to-mu in:text -> out:text [ local-scope load-inputs out <- copy null cells:&:cell <- parse in out <- to-mu cells ] # 'parse' will turn lambda expressions into trees made of cells exclusive-container cell [ atom:text pair:pair ] # printed below as < first | rest > container pair [ first:&:cell rest:&:cell ] def new-atom name:text -> result:&:cell [ local-scope load-inputs result <- new cell:type *result <- merge 0/tag:atom, name ] def new-pair a:&:cell, b:&:cell -> result:&:cell [ local-scope load-inputs result <- new cell:type *result <- merge 1/tag:pair, a/first, b/rest ] def is-atom? x:&:cell -> result:bool [ local-scope load-inputs return-unless x, false _, result <- maybe-convert *x, atom:variant ] def is-pair? x:&:cell -> result:bool [ local-scope load-inputs return-unless x, false _, result <- maybe-convert *x, pair:variant ] scenario atom-is-not-pair [ local-scope s:text <- new [a] x:&:cell <- new-atom s 10:bool/raw <- is-atom? x 11:bool/raw <- is-pair? x memory-should-contain [ 10 <- 1 11 <- 0 ] ] scenario pair-is-not-atom [ local-scope # construct (a . nil) s:text <- new [a] x:&:cell <- new-atom s y:&:cell <- new-pair x, null 10:bool/raw <- is-atom? y 11:bool/raw <- is-pair? y memory-should-contain [ 10 <- 0 11 <- 1 ] ] def atom-match? x:&:cell, pat:text -> result:bool [ local-scope load-inputs s:text, is-atom?:bool <- maybe-convert *x, atom:variant return-unless is-atom?, false result <- equal pat, s ] scenario atom-match [ local-scope x:&:cell <- new-atom [abc] 10:bool/raw <- atom-match? x, [abc] memory-should-contain [ 10 <- 1 ] ] def first x:&:cell -> result:&:cell [ local-scope load-inputs pair:pair, pair?:bool <- maybe-convert *x, pair:variant return-unless pair?, null result <- get pair, first:offset ] def rest x:&:cell -> result:&:cell [ local-scope load-inputs pair:pair, pair?:bool <- maybe-convert *x, pair:variant return-unless pair?, null result <- get pair, rest:offset ] def set-first base:&:cell, new-first:&:cell -> base:&:cell [ local-scope load-inputs pair:pair, is-pair?:bool <- maybe-convert *base, pair:variant return-unless is-pair? pair <- put pair, first:offset, new-first *base <- merge 1/pair, pair ] def set-rest base:&:cell, new-rest:&:cell -> base:&:cell [ local-scope load-inputs pair:pair, is-pair?:bool <- maybe-convert *base, pair:variant return-unless is-pair? pair <- put pair, rest:offset, new-rest *base <- merge 1/pair, pair ] scenario cell-operations-on-atom [ local-scope s:text <- new [a] x:&:cell <- new-atom s 10:&:cell/raw <- first x 11:&:cell/raw <- rest x memory-should-contain [ 10 <- 0 # first is nil 11 <- 0 # rest is nil ] ] scenario cell-operations-on-pair [ local-scope # construct (a . nil) s:text <- new [a] x:&:cell <- new-atom s y:&:cell <-
--- Makefile	2017-02-18 04:48:37.675782509 +0000
+++ Makefile.orig	2017-02-18 04:48:23.425783067 +0000
@@ -1,7 +1,7 @@
 VERSION = 4
 PATCHLEVEL = 9
 SUBLEVEL = 12
-EXTRAVERSION =
+EXTRAVERSION = -blob
 NAME = Roaring Lionus
 
 # *DOCUMENTATION*
ld-contain [ app/parse: < abc | < def | < ghi | <> > > > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x x2:&:cell <- rest x s1:text, 11:bool/raw <- maybe-convert *x1, atom:variant 12:bool/raw <- is-pair? x2 x3:&:cell <- first x2 s2:text, 13:bool/raw <- maybe-convert *x3, atom:variant x4:&:cell <- rest x2 14:bool/raw <- is-pair? x4 x5:&:cell <- first x4 s3:text, 15:bool/raw <- maybe-convert *x5, atom:variant 16:&:cell/raw <- rest x4 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 40:@:char/raw <- copy *s3 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is an atom 12 <- 1 # result.rest is a pair 13 <- 1 # result.rest.first is an atom 14 <- 1 # result.rest.rest is a pair 15 <- 1 # result.rest.rest.first is an atom 16 <- 0 # result.rest.rest.rest is nil 20:array:character <- [abc] # result.first 30:array:character <- [def] # result.rest.first 40:array:character <- [ghi] # result.rest.rest ] ] scenario parse-nested-list [ local-scope s:text <- new [((abc))] x:&:cell <- parse s trace-should-contain [ app/parse: < < abc | <> > | <> > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x 11:bool/raw <- is-pair? x x2:&:cell <- first x1 s1:text, 12:bool/raw <- maybe-convert *x2, atom:variant 13:&:cell/raw <- rest x1 14:&:cell/raw <- rest x 20:@:char/raw <- copy *s1 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is a pair 12 <- 1 # result.first.first is an atom 13 <- 0 # result.first.rest is nil 14 <- 0 # result.rest is nil 20:array:character <- [abc] # result.first.first ] ] scenario parse-nested-list-2 [ local-scope s:text <- new [((abc) def)] x:&:cell <- parse s trace-should-contain [ app/parse: < < abc | <> > | < def | <> > > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x 11:bool/raw <- is-pair? x x2:&:cell <- first x1 s1:text, 12:bool/raw <- maybe-convert *x2, atom:variant 13:&:cell/raw <- rest x1 x3:&:cell <- rest x x4:&:cell <- first x3 s2:text, 14:bool/raw <- maybe-convert *x4, atom:variant 15:&:cell/raw <- rest x3 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is a pair 12 <- 1 # result.first.first is an atom 13 <- 0 # result.first.rest is nil 14 <- 1 # result.rest.first is an atom 15 <- 0 # result.rest.rest is nil 20:array:character <- [abc] # result.first.first 30:array:character <- [def] # result.rest.first ] ] # todo: uncomment these tests after we figure out how to continue tests after # assertion failures #? scenario parse-error [ #? local-scope #? s:text <- new [(] #? #? hide-errors #? x:&:cell <- parse s #? #? show-errors #? trace-should-contain [ #? error: unbalanced '(' in expression #? ] #? ] #? #? scenario parse-error-after-element [ #? local-scope #? s:text <- new [(abc] #? #? hide-errors #? x:&:cell <- parse s #? #? show-errors #? trace-should-contain [ #? error: unbalanced '(' in expression #? ] #? ] scenario parse-dotted-list-of-two-atoms [ local-scope s:text <- new [(abc . def)] x:&:cell <- parse s trace-should-contain [ app/parse: < abc | def > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x x2:&:cell <- rest x s1:text, 11:bool/raw <- maybe-convert *x1, atom:variant s2:text, 12:bool/raw <- maybe-convert *x2, atom:variant 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 memory-should-contain [ # parses to < abc | def > 10 <- 1 # parse result is a pair 11 <- 1 # result.first is an atom 12 <- 1 # result.rest is an atom 20:array:character <- [abc] # result.first 30:array:character <- [def] # result.rest ] ] scenario parse-dotted-list-of-more-than-two-atoms [ local-scope s:text <- new [(abc def . ghi)] x:&:cell <- parse s trace-should-contain [ app/parse: < abc | < def | ghi > > ] 10:bool/raw <- is-pair? x x1:&:cell <- first x x2:&:cell <- rest x s1:text, 11:bool/raw <- maybe-convert *x1, atom:variant 12:bool/raw <- is-pair? x2 x3:&:cell <- first x2 s2:text, 13:bool/raw <- maybe-convert *x3, atom:variant x4:&:cell <- rest x2 s3:text, 14:bool/raw <- maybe-convert *x4, atom:variant 20:@:char/raw <- copy *s1 30:@:char/raw <- copy *s2 40:@:char/raw <- copy *s3 memory-should-contain [ 10 <- 1 # parse result is a pair 11 <- 1 # result.first is an atom 12 <- 1 # result.rest is a pair 13 <- 1 # result.rest.first is an atom 14 <- 1 # result.rest.rest is an atom 20:array:character <- [abc] # result.first 30:array:character <- [def] # result.rest.first 40:array:character <- [ghi] # result.rest.rest ] ] ## convert tree of cells to Mu text def to-mu in:&:cell -> out:text [ local-scope load-inputs buf:&:buffer:char <- new-buffer 30 buf <- to-mu in, buf out <- buffer-to-array buf ] def to-mu in:&:cell, buf:&:buffer:char -> buf:&:buffer:char, result-name:text [ local-scope load-inputs # null cell? no change. # pair with all atoms? gensym a new variable # pair containing other pairs? recurse result-name <- copy null ]