{ _binary <- 0 _string <- 1 _int <- 2 _symbol <- 3 _call <- 4 _object <- 5 _sequence <- 6 _assignment <- 7 _lambda <- 8 #{ binary <- { _binary } stringlit <- { _string } intlit <- { _int } sym <- { _symbol } call <- { _call } obj <- { _object } sequence <- { _sequence } assignment <- { _assignment } lambda <- { _lambda } binaryOp:withArgs <- :opname :_left _right { #{ nodeType <- { _binary } left <- _left op <- opname right <- _right leftAssociative? <- { op != "|" } stringIndent <- :indent { (left stringIndent: indent) . " " . op . (right stringIndent: indent) } string <- { stringIndent: "" } fold:with <- :acc :fun { acc <- fun: acc self acc <- _left fold: acc with: fun _right fold: acc with: fun } } } stringLit <- :_val { #{ nodeType <- { _string } val <- _val stringIndent <- :indent { "\"" . val . "\"" } string <- { stringIndent: "" } fold:with <- :acc :fun { fun: acc self } } } intLit:withBits:andBase:signed? <- :_val :_bits :_base :_signed? { #{ nodeType <- { _int } val <- _val base <- _base bits <- _bits size <- { _bits / 8 } signed? <- _signed? stringIndent <- :indent { suffix <- "" if: bits != 32 || (not: signed?) { suffix <- (if: signed? {"i"} else: {"u"}) . bits } if: base = 16 { "0x" . (hex: val) . suffix } else: { if: base = 2 { str <- "0b" i <- bits - 1 printzero <- false while: { i >= 0 } do: { str <- str . (if: (lshift: 1 by: i) and val > 0 { printzero <- true "1" } else: { if: printzero {"0"} else: {""} }) i <- i - 1 } str . suffix } else: { (string: val) . suffix } } } string <- { stringIndent: "" } fold:with <- :acc :fun { fun: acc self } } } symbol <- :_name { #{ nodeType <- { _symbol } name <- _name stringIndent <- :indent { name } string <- { stringIndent: "" } fold:with <- :acc :fun { fun: acc self } } } funcall:withArgs:hasReceiver? <- :_tocall :_args :_receiver? { #{ nodeType <- { _call } tocall <- _tocall args <- _args hasReceiver? <- _receiver? llMessage? <- { (tocall nodeType) = _symbol && (tocall name) = "llMessage:withVars:andCode" } stringIndent <- :indent { argparts <- [] if: (tocall nodeType) = _symbol { argparts <- (tocall name) splitOn: ":" } else: { argparts <- [tocall stringIndent: indent] } curarg <- args str <- "" if: hasReceiver? { str <- ((curarg value) stringIndent: indent) . " " curarg <- curarg tail } foreach: argparts :idx part { str <- str . part . ":" if: (not: (curarg empty?)) { str <- str . " " . ((curarg value) stringIndent: indent) curarg <- curarg tail } } while: { not: (curarg empty?) } do: { str <- str . " " . ((curarg value) stringIndent: indent) curarg <- curarg tail } str } string <- { stringIndent: "" } fold:with <- :acc :fun { acc <- fun: acc self _args fold: acc with: :acc el { el fold: acc with: fun } } } } object <- :_messages { #{ nodeType <- { _object } messages <- _messages stringIndent <- :indent { nextindent <- "\t" . indent (messages fold: "#{" with: :acc el { acc . "\n" . nextindent . (el stringIndent: nextindent) }) . "\n" . indent . "}" } string <- { stringIndent: "" } fold:with <- :acc :fun { acc <- fun: acc self messages fold: acc with: :acc el { el fold: acc with: fun } } } } seqLit:array? <- :_els :_array? { #{ nodeType <- { _sequence } els <- _els array? <- _array? stringIndent <- :indent { nextIndent <- "\t" . indent (els fold: (if: array? {"#["} else: {"["}) with: :acc el { acc . "\n" . nextIndent . (el stringIndent: nextIndent) }) . "\n" . indent . "]" } string <- { stringIndent: "" } fold:with <- :acc :fun { acc <- fun: acc self els fold: acc with: :acc el { el fold: acc with: fun } } } } assign:to <- :_expr :_sym { #{ nodeType <- { _assignment } assign <- _expr to <- _sym stringIndent <- :indent { (to stringIndent: indent) . " <- " . (assign stringIndent: indent) } string <- { stringIndent: "" } fold:with <- :acc :fun { acc <- fun: acc self acc <- _sym fold: acc with: fun _expr fold: acc with: fun } } } lambda:withArgs <- :_exprs :_args { #{ nodeType <- { _lambda } args <- _args expressions <- _exprs stringIndent <- :indent { argStr <- args join: " " if: (argStr length) > 0 { argStr <- argStr . " " } nextIndent <- "\t" . indent (expressions fold: argStr . "{" with: :acc el { acc . "\n" . nextIndent . (el stringIndent: nextIndent) }) . "\n" . indent . "}" } string <- { stringIndent: "" } fold:with <- :acc :fun { acc <- fun: acc self expressions fold: acc with: :acc el { el fold: acc with: fun } } } } } }