diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index 7923b7da..51dd9d74 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -865,6 +865,13 @@ Go: extensions: - .go +Golo: + type: programming + color: "#195be0" + lexer: Golo + extensions: + - .golo + Gosu: type: programming color: "#82937f" diff --git a/samples/Golo/adapters.golo b/samples/Golo/adapters.golo new file mode 100755 index 00000000..20c7d031 --- /dev/null +++ b/samples/Golo/adapters.golo @@ -0,0 +1,67 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.Adapters + +local function list_sample = |fabric| { + println(">>> list_sample()") + let carbonCopy = list[] + let conf = map[ + ["extends", "java.util.ArrayList"], + ["overrides", map[ + ["*", |super, name, args| { + if name == "add" { + if args: length() == 2 { + carbonCopy: add(args: get(1)) + } else { + carbonCopy: add(args: get(1), args: get(2)) + } + } + return super: invokeWithArguments(args) + } + ]] + ]] + let list = fabric: maker(conf): newInstance() + list: add("bar") + list: add(0, "foo") + list: add("baz") + println(" list: " + list + " " + list: getClass()) + println("carbonCopy: " + carbonCopy + " " + carbonCopy: getClass()) +} + +local function runnable_sample = |fabric| { + println(">>> runnable_sample") + let result = array[1, 2, 3] + let conf = map[ + ["interfaces", ["java.io.Serializable", "java.lang.Runnable"]], + ["implements", map[ + ["run", |this| { + for (var i = 0, i < result: length(), i = i + 1) { + result: set(i, result: get(i) + 10) + } + }] + ]] + ] + let runner = fabric: maker(conf): newInstance() + runner: run() + println(" result: " + result: toString()) + println("serializable? " + (runner oftype java.io.Serializable.class)) + println(" runnable? " + (runner oftype java.lang.Runnable.class)) +} + +function main = |args| { + let fabric = AdapterFabric() + list_sample(fabric) + runnable_sample(fabric) +} diff --git a/samples/Golo/async.golo b/samples/Golo/async.golo new file mode 100755 index 00000000..432f8c94 --- /dev/null +++ b/samples/Golo/async.golo @@ -0,0 +1,84 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.AsyncHelpers + +import gololang.Async +import java.util.concurrent.TimeUnit +import java.util.concurrent.Executors + +local function fib = |n| { + if n <= 1 { + return n + } else { + return fib(n - 1) + fib(n - 2) + } +} + +function main = |args| { + + let executor = newCachedThreadPool() + println("Let's do some useless asynchronous operations...") + + var f = executor: enqueue({ + Thread.sleep(1000_L) + return 666 + }) + f: + onSet(|v| -> println(">>> #slow -> " + v)): + onFail(|e| -> println(">>> #fail -> " + e)) + f: + cancel(true) + + f = executor: enqueue({ + Thread.sleep(1000_L) + return 666 + }) + f: + onSet(|v| -> println(">>> #ok -> " + v)): + onFail(|e| -> println(">>> #wtf? -> " + e)) + + let fib_10 = promise() + let fib_20 = promise() + let fib_30 = promise() + let fib_40 = promise() + + let futures = [ + fib_10: future(), fib_20: future(), + fib_30: future(), fib_40: future() + ] + + executor: submit(-> fib_10: set(fib(10))) + executor: submit(-> fib_20: set(fib(20))) + executor: submit(-> fib_30: set(fib(30))) + executor: submit(-> fib_40: set(fib(40))) + + all(futures): onSet(|results| -> println(">>> Fibs: " + results)) + + let truth = promise() + truth: + future(): + map(|v| -> "truth=" + v): + onSet(|v| -> executor: submit(-> println(">>> (another thread) " + v))): + onSet(|v| -> println(">>> (same thread) " + v)) + executor: submit({ + Thread.sleep(500_L) + truth: set(42) + }) + + Thread.sleep(1000_L) + executor: shutdown() + executor: awaitTermination(2_L, SECONDS()) + println("Bye!") +} diff --git a/samples/Golo/augmentations.golo b/samples/Golo/augmentations.golo new file mode 100755 index 00000000..bed289a4 --- /dev/null +++ b/samples/Golo/augmentations.golo @@ -0,0 +1,37 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.Augmentations + +import java.util.LinkedList + +augment java.util.List { + function with = |this, value| { + this: add(value) + return this + } +} + +augment java.util.Collection { + function doToEach = |this, func| { + foreach (element in this) { + func(element) + } + } +} + +function main = |args| { + let list = LinkedList(): with("foo"): with("bar"): with("baz") + list: doToEach(|value| -> println(">>> " + value)) +} diff --git a/samples/Golo/closures.golo b/samples/Golo/closures.golo new file mode 100755 index 00000000..32378017 --- /dev/null +++ b/samples/Golo/closures.golo @@ -0,0 +1,43 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Closures + +local function sayHello = |who| -> "Hello " + who + "!" + +function main = |args| { + let adder = |a, b| -> a + b + println(adder: invokeWithArguments(1, 2)) + println(adder(1, 2)) + + let addToTen = adder: bindTo(10) + println(addToTen: invokeWithArguments(2)) + println(addToTen(2)) + + let adding = |x| -> |y| -> adder(x, y) + let addingTen = adding(10) + println(addingTen(4)) + println(adding(2)(4)) + + println(sayHello("Julien")) + + let list = java.util.LinkedList() + let pump_it = { + list: add("I heard you say") + list: add("Hey!") + list: add("Hey!") + } + pump_it() + println(list) +} diff --git a/samples/Golo/coin-change.golo b/samples/Golo/coin-change.golo new file mode 100755 index 00000000..fe82bb04 --- /dev/null +++ b/samples/Golo/coin-change.golo @@ -0,0 +1,34 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module CoinChange + +import java.util.LinkedList + +function change = |money, coins| -> match { + when money == 0 then 1 + when (money < 0) or (coins: isEmpty()) then 0 + otherwise change(money - coins: head(), coins) + change(money, coins: tail()) +} + +function main = |args| { + let coins = LinkedList(): append(1, 2, 5, 10, 20) + println("Coins: " + coins) + println("0: " + change(0, coins)) + println("1: " + change(1, coins)) + println("2: " + change(2, coins)) + println("10: " + change(10, coins)) + println("12: " + change(12, coins)) + println("6: " + change(6, coins)) +} diff --git a/samples/Golo/collection-literals.golo b/samples/Golo/collection-literals.golo new file mode 100755 index 00000000..ac19b35e --- /dev/null +++ b/samples/Golo/collection-literals.golo @@ -0,0 +1,55 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.CollectionLiterals + +local function play_with_tuples = { + let hello = ["Hello", "world", "!"] + foreach str in hello { + print(str + " ") + } + println("") + + println(hello: get(0) + "-" + hello: get(1) + "-" + hello: get(2)) + + println(hello: join("/")) +} + +local function play_with_literals = { + let data = [ + [1, 2, 3], + tuple[1, 2, 3], + array[1, 2, 3], + set[1, 2, 3, 3, 1], + map[ + ["a", 10], + ["b", 20] + ], + vector[1, 2, 3], + list[1, 2, 3] + ] + + data: each(|element| { + println(element: toString()) + println(" type: " + element: getClass()) + }) +} + +function main = |args| { + println(">>> Literals") + play_with_literals() + println("\n>>> Tuples") + play_with_tuples() +} + diff --git a/samples/Golo/context-decorator.golo b/samples/Golo/context-decorator.golo new file mode 100755 index 00000000..6a3bb889 --- /dev/null +++ b/samples/Golo/context-decorator.golo @@ -0,0 +1,53 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.ContextDecorator + +import gololang.Decorators + +let myContext = defaultContext(): + count(0): + define("entry", |this, args| { + this: count(this: count() + 1) + println("hello:" + this: count()) + return args + }): + define("exit", |this, result| { + require(result >= 3, "wrong value") + println("goobye") + return result + }): + define("catcher", |this, e| { + println("Caught " + e) + throw e + }): + define("finallizer", |this| {println("do some cleanup")}) + + +@withContext(myContext) +function foo = |a, b| { + println("Hard computation") + return a + b +} + +function main = |args| { + println(foo(1,2)) + println("====") + println(withContext(myContext)(|a| -> 2*a)(3)) + println("====") + try { + println(foo(1, 1)) + } catch (e) { } +} + diff --git a/samples/Golo/decorators.golo b/samples/Golo/decorators.golo new file mode 100755 index 00000000..c3acbfc4 --- /dev/null +++ b/samples/Golo/decorators.golo @@ -0,0 +1,83 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.Decorators + +import java.util.LinkedList + +function simple_decorator = |func| { + return |a,b| -> func(a+1,b+1) +} + +@simple_decorator +function simple_adder = |x,y| -> x + y + +function decorator_with_params = |param1, param2|{ + return |func| { + return |a,b| -> func(a+param1,b+param2) + } +} + +@decorator_with_params(10,2) +function parametrized_adder = |x,y| -> x + y + +function generic_decorator = |func| { + return |args...| { + println("number of params : "+args: length()) + return func: invokeWithArguments(args) + } +} + +@generic_decorator +function generic_adder0 = -> 42 + +@generic_decorator +function generic_adder1 = |x| -> x + +@generic_decorator +function generic_adder2 = |x,y| -> x + y + +@generic_decorator +function generic_adder3 = |x,y,z| -> x + y + z + +function list_sum_decorator = |func| { + return |this| -> func(this) - 8 +} + +augment java.util.List { + + @list_sum_decorator + function sum = |this| { + var acc = 0 + foreach elem in this { + acc = acc + elem + } + return acc + } +} + +function main = |args| { + println(simple_adder(10,30)) + println(parametrized_adder(10,20)) + println(generic_adder0()) + println(generic_adder1(42)) + println(generic_adder2(20,22)) + println(generic_adder3(10,12,20)) + let list = LinkedList() + list: add(5) + list: add(10) + list: add(15) + list: add(20) + println(list: sum()) +} \ No newline at end of file diff --git a/samples/Golo/dynamic-evaluation.golo b/samples/Golo/dynamic-evaluation.golo new file mode 100755 index 00000000..af5351f4 --- /dev/null +++ b/samples/Golo/dynamic-evaluation.golo @@ -0,0 +1,88 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.DynamicEvaluation + +import gololang.EvaluationEnvironment + +local function test_asModule = |env| { + let code = +""" +module foo + +function a = -> "a!" +function b = -> "b!" +""" + let mod = env: asModule(code) + let a = fun("a", mod) + let b = fun("b", mod) + println(">>> asModule()") + println(a()) + println(b()) +} + +local function test_anonymousModule = |env| { + let code = +""" +function a = -> "a." +function b = -> "b." +""" + let mod = env: anonymousModule(code) + let a = fun("a", mod) + let b = fun("b", mod) + println(">>> anonymousModule()") + println(a()) + println(b()) +} + +local function test_asFunction = |env| { + let code = "return (a + b) * 2" + let f = env: asFunction(code, "a", "b") + println(">>> asFunction") + println(f(10, 20)) +} + +local function test_def = |env| { + let code = "|a, b| -> (a + b) * 2" + let f = env: def(code) + println(">>> def") + println(f(10, 20)) +} + +local function test_run = |env| { + let code = """println(">>> run") + foreach (i in range(0, 3)) { + println("w00t") + }""" + env: run(code) +} + +local function test_run_map = |env| { + let code = """println(">>> run_map") + println(a) + println(b) + """ + let values = java.util.TreeMap(): add("a", 1): add("b", 2) + env: run(code, values) +} + +function main = |args| { + let env = EvaluationEnvironment() + test_asModule(env) + test_anonymousModule(env) + test_asFunction(env) + test_def(env) + test_run(env) + test_run_map(env) +} diff --git a/samples/Golo/dynamic-object-person.golo b/samples/Golo/dynamic-object-person.golo new file mode 100755 index 00000000..27f3ab6d --- /dev/null +++ b/samples/Golo/dynamic-object-person.golo @@ -0,0 +1,29 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.DynamicObjectPerson + +local function mrbean = -> DynamicObject(): + name("Mr Bean"): + email("mrbean@gmail.com"): + define("toString", |this| -> this: name() + " <" + this: email() + ">") + +function main = |args| { + + let bean = mrbean() + println(bean: toString()) + + bean: email("mrbean@outlook.com") + println(bean: toString()) +} diff --git a/samples/Golo/echo-args.golo b/samples/Golo/echo-args.golo new file mode 100755 index 00000000..7bf1e093 --- /dev/null +++ b/samples/Golo/echo-args.golo @@ -0,0 +1,34 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module EchoArgs + +function main = |args| { + + println("With a for loop and an index:") + for (var i = 0, i < args: length(), i = i + 1) { + println(" #" + i + " -> " + args: get(i)) + } + + println("With a foreach loop:") + foreach arg in args { + println(" " + arg) + } + + println("With a foreach over a range:") + foreach i in range(0, args: length()) { + println(" #" + i + " -> " + args: get(i)) + } +} + diff --git a/samples/Golo/enums-thread-state.golo b/samples/Golo/enums-thread-state.golo new file mode 100755 index 00000000..4310ea26 --- /dev/null +++ b/samples/Golo/enums-thread-state.golo @@ -0,0 +1,31 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module sample.EnumsThreadState + +import java.lang.Thread$State + +function main = |args| { + + # Call the enum entry like a function + let new = Thread$State.NEW() + println("name=" + new: name() + ", ordinal=" + new: ordinal()) + println("-----------") + + # Walk through all enum entries + foreach element in Thread$State.values() { + println("name=" + element: name() + ", ordinal=" + element: ordinal()) + } +} + diff --git a/samples/Golo/fibonacci.golo b/samples/Golo/fibonacci.golo new file mode 100755 index 00000000..53455a7d --- /dev/null +++ b/samples/Golo/fibonacci.golo @@ -0,0 +1,39 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.Fibonacci + +import java.lang.System + +function fib = |n| { + if n <= 1 { + return n + } else { + return fib(n - 1) + fib(n - 2) + } +} + +local function run = { + let start = System.currentTimeMillis() + let result = fib(40) + let duration = System.currentTimeMillis() - start + println(">>> " + result + " (took " + duration + "ms)") +} + +function main = |args| { + while true { + run() + } +} + diff --git a/samples/Golo/helloworld.golo b/samples/Golo/helloworld.golo new file mode 100755 index 00000000..4800de6d --- /dev/null +++ b/samples/Golo/helloworld.golo @@ -0,0 +1,20 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module hello.World + +function main = |args| { + println("Hello world!") +} + diff --git a/samples/Golo/http-server.golo b/samples/Golo/http-server.golo new file mode 100755 index 00000000..ce4ff857 --- /dev/null +++ b/samples/Golo/http-server.golo @@ -0,0 +1,53 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.WebServer + +import java.lang +import java.net.InetSocketAddress +import com.sun.net.httpserver +import com.sun.net.httpserver.HttpServer + +function main = |args| { + + let server = HttpServer.create(InetSocketAddress("localhost", 8081), 0) + + server: createContext("/", |exchange| { + let headers = exchange: getResponseHeaders() + let response = StringBuilder(): + append("Requested URI: "): + append(exchange: getRequestURI()): + append("\n"): + append("Current time: "): + append(java.util.Date()): + append("\n"): + toString() + headers: set("Content-Type", "text/plain") + exchange: sendResponseHeaders(200, response: length()) + exchange: getResponseBody(): write(response: getBytes()) + exchange: close() + }) + + server: createContext("/shutdown", |exchange| { + let response = "Ok, thanks, bye!" + exchange: getResponseHeaders(): set("Content-Type", "text/plain") + exchange: sendResponseHeaders(200, response: length()) + exchange: getResponseBody(): write(response: getBytes()) + exchange: close() + server: stop(5) + }) + + server: start() + println(">>> http://localhost:8081/") +} diff --git a/samples/Golo/logdeco.golo b/samples/Golo/logdeco.golo new file mode 100755 index 00000000..ae42a133 --- /dev/null +++ b/samples/Golo/logdeco.golo @@ -0,0 +1,65 @@ + +module samples.LogDeco + +function log1 = |msg| { + return |fun| { + return |args...| { + println(msg) + return fun: invokeWithArguments(args) + } + } +} + +@log1("calling foo") +function foo = |a| { + println("foo got a " + a) +} + +@log1("I'am a bar") +function bar = |a| -> 2*a + +let sayHello = log1("Hello") + +@sayHello +function baz = -> "Goodbye" + +function log2 = |msgBefore| -> |msgAfter| -> |func| -> |args...| { + println(msgBefore) + let res = func: invokeWithArguments(args) + println(msgAfter) + return res +} + +@log2("enter foo")("exit foo") +function spam = |a| { + println("foo: " + a) +} + +function logEnterExit = |name| -> log2("# enter " + name)("# exit " + name) + +@logEnterExit("bar") +function egg = { println("doing something...") } + +function main = |args| { + + foo("bar") + + println("---") + println(bar(21)) + + println("---") + println(baz()) + + println("---") + spam("bar") + + println("---") + egg() + + println("---") + let strange_use = log2("hello")("goodbye")({println(":p")}) + strange_use() + + println("---") + log2("another")("use")(|a|{println(a)})("strange") +} diff --git a/samples/Golo/matching-operator.golo b/samples/Golo/matching-operator.golo new file mode 100755 index 00000000..380d2259 --- /dev/null +++ b/samples/Golo/matching-operator.golo @@ -0,0 +1,40 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module Matching + +import java.util.LinkedList + +local function data = { + let list = LinkedList() + list: add("foo@bar.com") + list: add("+33.6.11.22.33") + list: add("http://golo-lang.org/") + list: add("def foo = bar(_._) with :> T") + return list +} + +local function what_it_could_be = |item| -> match { + when item: contains("@") then "an email?" + when item: startsWith("+33") then "a French phone number?" + when item: startsWith("http://") then "a website URL?" + otherwise "I have no clue, mate!" +} + +function main = |args| { + foreach item in data() { + println(item + " => " + what_it_could_be(item)) + } +} + diff --git a/samples/Golo/max-int.golo b/samples/Golo/max-int.golo new file mode 100755 index 00000000..457a5dff --- /dev/null +++ b/samples/Golo/max-int.golo @@ -0,0 +1,24 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.MaxInt + +local function max_int = { + return java.lang.Integer.MAX_VALUE() +} + +function main = |args| { + println(max_int()) +} + diff --git a/samples/Golo/memoize.golo b/samples/Golo/memoize.golo new file mode 100755 index 00000000..8fb1b455 --- /dev/null +++ b/samples/Golo/memoize.golo @@ -0,0 +1,55 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.MemoizeDecorator + +import gololang.Decorators + +import java.lang.System + +let memo = memoizer() + +@memo +function fib = |n| { + if n <= 1 { + return n + } else { + return fib(n - 1) + fib(n - 2) + } +} + +@memo +function foo = |n| -> n + +local function run = { + let start = System.currentTimeMillis() + let result = fib(40) + let duration = System.currentTimeMillis() - start + println(">>> fib(40) = " + result + " (took " + duration + "ms)") +} + +local function run2 = { + let start = System.currentTimeMillis() + let result = foo(40) + let duration = System.currentTimeMillis() - start + println(">>> foo(40) = " + result + " (took " + duration + "ms)") +} + +function main = |args| { + foreach i in range(0, 5) { + println("run " + i) + run() + run2() + } +} diff --git a/samples/Golo/null-safety.golo b/samples/Golo/null-safety.golo new file mode 100755 index 00000000..903f5309 --- /dev/null +++ b/samples/Golo/null-safety.golo @@ -0,0 +1,43 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module DealingWithNull + +import java.util + +function main = |args| { + + # Data model + let contacts = map[ + ["mrbean", map[ + ["email", "bean@gmail.com"], + ["url", "http://mrbean.com"] + ]], + ["larry", map[ + ["email", "larry@iamricherthanyou.com"] + ]] + ] + + # MrBean and Larry + let mrbean = contacts: get("mrbean") + let larry = contacts: get("larry") + + # Illustrates orIfNull + println(mrbean: get("url") orIfNull "n/a") + println(larry: get("url") orIfNull "n/a") + + # Querying a non-existent data model because there is no 'address' entry + println(mrbean: get("address")?: street()?: number() orIfNull "n/a") +} + diff --git a/samples/Golo/prepost-decorators.golo b/samples/Golo/prepost-decorators.golo new file mode 100755 index 00000000..a7ea73ca --- /dev/null +++ b/samples/Golo/prepost-decorators.golo @@ -0,0 +1,65 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.PrepostDecorator + +import gololang.Decorators + +let isInteger = isOfType(Integer.class) + +@checkResult(isString(): andThen(lengthIs(2))) +@checkArguments(isInteger: andThen(isPositive()), isString()) +function foo = |a, b| { + return b + a +} + +let myCheck = checkArguments(isInteger: andThen(isPositive())) + +@myCheck +function inv = |v| -> 1.0 / v + +let isPositiveInt = isInteger: andThen(isPositive()) + +@checkArguments(isPositiveInt) +function mul = |v| -> 10 * v + +@checkArguments(isNumber()) +function num = |v| -> "ok" + +@checkArguments(isNotNull()) +function notnull = |v| -> "ok" + +function main = |args| { + try { println(foo(1, "b")) } catch (e) { println(e) } + try { println(foo(-1, "b")) } catch (e) { println(e) } + try { println(foo("a", 2)) } catch (e) { println(e) } + try { println(foo(1, 2)) } catch (e) { println(e) } + try { println(foo(10, "ab")) } catch (e) { println(e) } + + try { println(inv(10)) } catch (e) { println(e) } + try { println(inv(0)) } catch (e) { println(e) } + + try { println(mul(5)) } catch (e) { println(e) } + try { println(mul(0)) } catch (e) { println(e) } + + try { println(num(1)) } catch (e) { println(e) } + try { println(num(1_L)) } catch (e) { println(e) } + try { println(num(1.5)) } catch (e) { println(e) } + try { println(num(1.5_F)) } catch (e) { println(e) } + try { println(num("a")) } catch (e) { println(e) } + try { println(num('a')) } catch (e) { println(e) } + + try { println(notnull('1')) } catch (e) { println(e) } + try { println(notnull(null)) } catch (e) { println(e) } +} diff --git a/samples/Golo/structs.golo b/samples/Golo/structs.golo new file mode 100755 index 00000000..de18836a --- /dev/null +++ b/samples/Golo/structs.golo @@ -0,0 +1,69 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module StructDemo + +struct Point = { x, y } + +augment StructDemo.types.Point { + + function move = |this, offsetX, offsetY| { + this: x(this: x() + offsetX) + this: y(this: y() + offsetY) + return this + } + + function relative = |this, offsetX, offsetY| -> Point(this: x() + offsetX, this: y() + offsetY) +} + +function main = |args| { + + let p1 = Point(1, 2) + let p2 = Point(): x(1): y(2) + let p3 = p1: frozenCopy() + let p4 = p1: frozenCopy() + + println(p1) + println("x = " + p1: x()) + println("y = " + p1: y()) + + println("p1 == p2 " + (p1 == p2)) + println("p1 == p3 " + (p1 == p3)) + println("p3 == p4 " + (p3 == p4)) + + println("#p1 " + p1: hashCode()) + println("#p2 " + p2: hashCode()) + println("#p3 " + p3: hashCode()) + println("#p4 " + p4: hashCode()) + + println("p1: members() " + p1: members()) + println("p1: values() " + p1: values()) + foreach item in p1 { + println(item: get(0) + " -> " + item: get(1)) + } + + println("p1: set(\"x\", 10) " + p1: set("x", 10)) + println("p1: move(10, 5) " + p1: move(10, 5)) + println("p1: relative(11, 6) " + p1: relative(11, 6)) + + let p5 = ImmutablePoint(10, 20) + println("p5: " + p5) + try { + p5: x(100) + } catch (expected) { + println("p5 is immutable, so... " + expected: getMessage()) + } +} + + diff --git a/samples/Golo/swing-actionlistener.golo b/samples/Golo/swing-actionlistener.golo new file mode 100755 index 00000000..61d0f7f3 --- /dev/null +++ b/samples/Golo/swing-actionlistener.golo @@ -0,0 +1,43 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.SwingActionListener + +import java.awt.event +import javax.swing +import javax.swing.WindowConstants + +local function listener = |handler| -> asInterfaceInstance(ActionListener.class, handler) + +function main = |args| { + + let frame = JFrame("Action listeners") + frame: setDefaultCloseOperation(EXIT_ON_CLOSE()) + + let button = JButton("Click me!") + button: setFont(button: getFont(): deriveFont(96.0_F)) + + # Using a helper function + button: addActionListener(listener(|event| -> println("Clicked!"))) + + # Using a standard augmentation: MethodHandle::to(Class) + button: addActionListener((|event| -> println("[click]")): to(ActionListener.class)) + + # Straight closure passing + button: addActionListener(|event| -> println("( )")) + + frame: getContentPane(): add(button) + frame: pack() + frame: setVisible(true) +} diff --git a/samples/Golo/swing-helloworld.golo b/samples/Golo/swing-helloworld.golo new file mode 100755 index 00000000..9d5e0541 --- /dev/null +++ b/samples/Golo/swing-helloworld.golo @@ -0,0 +1,31 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.SwingHelloWorld + +import javax.swing +import javax.swing.WindowConstants + +function main = |args| { + + let frame = JFrame("Hello world") + frame: setDefaultCloseOperation(EXIT_ON_CLOSE()) + + let label = JLabel("Hello world") + label: setFont(label: getFont(): deriveFont(128.0_F)) + + frame: getContentPane(): add(label) + frame: pack() + frame: setVisible(true) +} diff --git a/samples/Golo/templates-chat-webapp.golo b/samples/Golo/templates-chat-webapp.golo new file mode 100755 index 00000000..a5eab98b --- /dev/null +++ b/samples/Golo/templates-chat-webapp.golo @@ -0,0 +1,90 @@ +# Copyright 2012-2014 Institut National des Sciences Appliquées de Lyon (INSA-Lyon) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +module samples.TemplatesChatWebapp + +import java.lang +import java.io +import java.net.InetSocketAddress +import com.sun.net.httpserver +import com.sun.net.httpserver.HttpServer + +local function redirect = |exchange, to| { + exchange: getResponseHeaders(): set("Location", to) + exchange: sendResponseHeaders(303, 0) + exchange: close() +} + +local function respond = |exchange, body| { + exchange: getResponseHeaders(): set("Content-Type", "text/html") + exchange: sendResponseHeaders(200, body: length()) + exchange: getResponseBody(): write(body: getBytes()) + exchange: close() +} + +# This is leaky and works with just 1 POST parameter... +local function extract_post = |exchange, posts| { + let reader = BufferedReader(InputStreamReader(exchange: getRequestBody())) + var line = reader: readLine() + while line isnt null { + if line: startsWith("msg=") { + posts: add(java.net.URLDecoder.decode(line: substring(4), "UTF-8")) + } + line = reader: readLine() + } + reader: close() +} + + +local function index = |posts, template, exchange| { + if exchange: getRequestMethod() == "POST" { + extract_post(exchange, posts) + redirect(exchange, "/") + } else { + respond(exchange, template(posts)) + } +} + +local function index_template = -> """ +<%@params posts %> + + +
+