Created
October 14, 2010 03:27
-
-
Save jido/625506 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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