## 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 <- new-pair x, null x2:&:cell <- first y 10:bool/raw <- equal x, x2 11:&:cell/raw <- rest y memory-should-contain [ 10 <- 1 # first is correct 11 <- 0 # rest is nil ] ] ## convert lambda text to a tree of cells def parse in:text -> out:&:cell [ local-scope load-inputs s:&:stream:char <- new-stream in out, s <- parse s trace 2, [app/parse], out ] def parse in:&:stream:char -> out:&:cell, in:&:stream:char [ local-scope load-inputs # skip whitespace in <- skip-whitespace in c:char, eof?:bool <- peek in return-if eof?, null pair?:bool <- equal c, 40/open-paren { break-if pair? # atom buf:&:buffer:char <- new-buffer 30 { done?:bool <- end-of-stream? in break-if done? # stop before close paren or space c:char <- peek in done? <- equal c, 41/close-paren break-if done? done? <- space? c break-if done? c <- read in buf <- append buf, c loop } s:text <- buffer-to-array buf out <- new-atom s } { break-unless pair? # pair read in # skip the open-paren out <- new cell:type # start out with nil # read in first element of pair { end?:bool <- end-of-stream? in not-end?:bool <- not end? assert not-end?, [unbalanced '(' in expression] c <- peek in close-paren?:bool <- equal c, 41/close-paren break-if close-paren? first:&:cell, in <- parse i
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - filesystem.mu</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="none">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 12pt; font-size: 1em; }
.Delimiter { color