Skip to content

Instantly share code, notes, and snippets.

@jido
Created October 14, 2010 03:27
Show Gist options
  • Save jido/625506 to your computer and use it in GitHub Desktop.
Save jido/625506 to your computer and use it in GitHub Desktop.
# Imported Clojure functions
clojure('=', 2) -> eq
clojure('dec', 1) -> dec
clojure('conj', 2) -> conj
clojure('vector', 0) -> vector
clojure('count', 1) -> count
clojure('merge', 2) -> combine
clojure('first', 1) -> first
clojure('next', 1) -> rest
clojure('concat', 2) -> concat
clojure('list', 0) -> list
clojure('str', 2) -> str
clojure('vec', 1) -> vec
clojure('identity', 1) -> identity
# Generic event
setv(struct, 'message', "An event was raised") -> event
# Type declarations
struct -> Dodo
struct -> Polymorphic
# Define Dodo, the base for other classes
# Make the Dodo type
fun mkDodoType -> return
(
setv(Dodo, 'instance', struct) -> Dodo
setv(Dodo, 'get', getv) -> Dodo
return(Dodo)
)
| mkDodoType
mkDodoType() -> Dodo
# Define the Polymorphic qualifier
# Make the Polymorphic qualifier
fun mkPolymorphicQualifier -> return
(
# Define function 'get' which returns a dispatcher function that invokes the named method
fun P_get -> type, name, return, error
dispatcher('type', name, return) # dispatcher is defined in runner.clj
| P_get
setv(Polymorphic, 'get', P_get) -> Polymorphic
return(Polymorphic)
)
| mkPolymorphicQualifier
mkPolymorphicQualifier() -> Polymorphic
# Helper function 'setInstance' which returns the class updated with a prototype instance
# linked to the class
fun setInstance -> class, v, return
(
setv(class, 'instance', v) -> class
# Update prototype type with class
getv(v, 'type') -> classlink
setlink(classlink, class) ->
return(class)
)
| setInstance
# Helper function 'initInstance' which returns the class with a new prototype instance
# linked to it
fun initInstance -> class, return
(
getv(class, 'instance') -> instance
# Put a new link to its type in the instance
link(0) -> classlink
setv(instance, 'type', classlink) -> instance
setInstance(class, instance, return)
)
| initInstance
# Define Object and class
# We are going reverse with names below, that is to
# help readability of dodo by using familiar words
# Make the Object class
fun mkObjectClass -> return
(
combine(Dodo, Polymorphic) -> Object # Object class
initInstance(Object, return)
)
| mkObjectClass
mkObjectClass() -> Object
# Define class, the prototype instance for objects
getv(Object, 'instance') -> class
# Type declarations
struct -> Iterable
Object -> List
initInstance(List) -> LazyList
initInstance(List) -> SimpleList
# Define an Iterable qualifier
# EndOfYield event
setv(event, 'message', "End of yield") -> endOfYield
# Helper function to make a dodo generator from self.value
fun generator -> self, return
(
fun value -> return, error
(
getv(Object, 'get') -> getter
getter(Object, 'value') -> v
v(self, return, error)
| e
error(e);
)
| value
return(value)
)
| generator
# Make an iterable qualifier
fun mkIterableQualifier -> return
(
# Define function 'append' returning a lazy list of the items in both lists
fun IQ_append -> self, other, return, error
(
fun valueInSeq -> gen1, return, error
(
gen1() -> item, nextval
(
return(item) -> return, error
valueInSeq(nextval, return, error)
)
| dummy # end of yield
(
generator(other) -> gen2
gen2(return, error)
)
)
| valueInSeq
fun gen -> return, error
(
generator(self) -> value
valueInSeq(value, return, error)
)
| gen
getv(LazyList, 'instance') -> proto
setv(proto, 'generator', gen, return)
)
| IQ_append
# Define function 'shift-left' returning a lazy list of the items shifted by n
fun IQ_shiftLeft -> self, n, return, error
(
eq(0, n) -> z
if (z) ->
return(self)
|
fun shiftBy -> n, gen, return
(
eq(0, n) -> z
if (z) ->
(
getv(LazyList, 'instance') -> proto
setv(proto, 'generator', gen, return)
)
|
gen() -> dummy, nextval
dec(n) -> n
shiftBy(n, nextval, return);
| e
error(e)
)
| shiftBy
generator(self) -> value
shiftBy(n, value, return)
)
| IQ_shiftLeft
# Define function 'filter' returning a lazy list of items matching a condition
fun IQ_filter -> self, accept, return, error
(
fun nextItem -> gen, return, error
(
gen() -> item, nextval
(
accept(item) ->
return(item) -> return, error
nextItem(nextval, return, error);
|
nextItem(nextval, return, error)
)
| e
error(e)
)
| nextItem
fun gen -> return, error
(
generator(self) -> value
nextItem(value, return, error)
)
| gen
getv(LazyList, 'instance') -> proto
setv(proto, 'generator', gen)
)
| IQ_filter
# Define function 'apply' returning the result of combining all items of the list
fun IQ_apply -> self, combine, return, error
(
fun fold -> seed, gen, return
(
gen() -> item, nextval
(
combine(seed, item) -> result
fold(result, nextval, return)
| e
error(e)
)
| dummy # end of yield
return(seed)
)
| fold
generator(self) -> value
value() -> seed, nextval
fold(seed, nextval, return)
| e
error(e)
)
| IQ_apply
# Define function 'all' returning a list of transformed items
fun IQ_all -> self, transform, return, error
(
fun getAll -> gen, values, return
gen() -> item, nextval
transform(item) -> result
(
conj(values, result) -> values
getAll(nextval, values, return)
)
| e
error(e);
| dummy # end of yield
return(values);
| getAll
generator(self) -> value
vector() -> emptyvec
getAll(value, emptyvec) -> values
getv(SimpleList, 'instance') -> proto
setv(proto, 'values', values, return)
)
| IQ_all
# Define function 'each' returning a lazy list of transformed items
fun IQ_each -> self, transform, return, error
(
fun transformItem -> gen, return, error
(
gen() -> item, nextval
(
transform(item) -> result
return(result) -> return, error
transformItem(nextval, return, error);
| e
error(e)
)
| e
error(e)
)
| transformItem
fun gen -> return, error
(
generator(self) -> value
transformItem(value, return, error)
)
| gen
getv(LazyList, 'instance') -> proto
setv(proto, 'generator', gen, return)
)
| IQ_each
#setv(Iterable, 'value', nil) -> Iterable
setv(Iterable, 'shift-left', IQ_shiftLeft) -> Iterable
setv(Iterable, 'append', IQ_append) -> Iterable
setv(Iterable, 'filter', IQ_filter) -> Iterable
setv(Iterable, 'apply', IQ_apply) -> Iterable
setv(Iterable, 'all', IQ_all) -> Iterable
setv(Iterable, 'each', IQ_each) -> Iterable
return(Iterable)
)
| mkIterableQualifier
mkIterableQualifier() -> Iterable
# Define a LazyList class
# Make lazy list from Clojure sequence
fun mkLazyList -> sequ, return
(
# Use first and rest to implement a dodo generator
fun valueFromSeq -> sequ, return, error
(
'empty?'(sequ) -> end
if (end) ->
error(endOfYield)
|
first(sequ) -> head
rest(sequ) -> tail
return(head) -> return, error
valueFromSeq(tail, return, error)
)
| valueFromSeq
fun gen -> return, error
valueFromSeq(sequ, return, error)
| gen
getv(LazyList, 'instance') -> proto
setv(proto, 'generator', gen, return)
)
| mkLazyList
# Make lazy list class
fun mkLazyListClass -> return
(
combine(Iterable, LazyList) -> LazyList
# Define function 'value'
fun LL_value -> self, return, error
(
getv(self, 'generator') -> gen
gen(return, error)
)
| LL_value
setv(LazyList, 'value', LL_value) -> LazyList
# Set the prototype instance
list() -> emptylist
mkLazyList(emptylist) -> instance
setInstance(LazyList, instance, return)
)
| mkLazyListClass
mkLazyListClass() -> LazyList
# Define a SimpleList class
# Make simple list from Clojure collection
fun mkSimpleList -> values, return
(
getv(SimpleList, 'instance') -> instance
setv(instance, 'values', values, return)
)
| mkSimpleList
# Make simple list class
fun mkSimpleListClass -> return
(
combine(Iterable, SimpleList) -> SimpleList
# Define function 'value'
fun SL_value -> self, return, error
(
getv(self, 'values') -> values
mkLazyList(values) -> lazy
generator(lazy) -> value
value(return, error)
)
| SL_value
# Define function 'all'
fun SL_all -> self, transform, return, error
(
clojure('map', 2) -> transformAll
dodo2clj(transform) -> maptransform
# Use Clojure 'map' to apply the transform on all items
getv(self, 'values') -> values
transformAll(maptransform, values) -> result
vec(result) -> result
setv(self, 'values', result, return)
)
| SL_all
setv(SimpleList, 'value', SL_value) -> SimpleList
setv(SimpleList, 'all', SL_all) -> SimpleList
# Set the prototype instance
vector() -> emptyvec
mkSimpleList(emptyvec) -> instance
setInstance(SimpleList, instance, return)
)
| mkSimpleListClass
mkSimpleListClass() -> SimpleList
# Test program
# Print out a simple or lazy list
fun printlist -> msg, l, return
(
getv(List, 'get') -> getter
getter(l, 'all') -> all
(
all(l, identity) -> simple
getv(simple, 'values') -> values
println(msg, values, return);
| e
getv(e, 'message') -> msg
println(msg, return)
)
| e
getv(e, 'message') -> msg
println(msg, return)
)
| printlist
# Print out message from exception and quit
fun abort -> e
(
getv(e, 'message') -> msg
println(msg) ->
exit()
)
| abort
# Create simple list with words
'vector'("pumpkin", "Janet", "purple", "pony", "Amsterdam", "three") -> wordsvec
conj(wordsvec, "kiwi") -> wordsvec
mkSimpleList(wordsvec) -> words
printlist("Words:", words) ->
# Count letters for all words
getv(SimpleList, 'get') -> getter
getter(words, 'all') -> all
(
all(words, count) -> counts
(
printlist("Letter counts:", counts) ->
# Concatenate the words from the list together
getter(words, 'apply') -> apply
(
apply(words, concat) -> bigtext
(
println("Concat all:", bigtext) ->
# Ignore first four words from the list
getter(words, 'shift-left') -> shl
(
shl(words, 4) -> lesswords
(
printlist("Without first four:", lesswords) ->
exit()
)
| e
abort(e)
)
| e
abort(e)
)
| e
abort(e)
)
| e
abort(e)
)
| e
abort(e)
)
| e
abort(e)
Pegase:antlr admin$ java -classpath antlr-3.2.jar:../../clojure/clojure-1.2.0/clojure.jar:. clojure.main dodo/runner.clj < lists.do0
Words: [pumpkin Janet purple pony Amsterdam three kiwi]
Letter counts: [7 5 6 4 9 5 4]
Concat all: (p u m p k i n J a n e t p u r p l e p o n y A m s t e r d a m t h r e e k i w i)
Without first four: [Amsterdam three kiwi]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment