====================================================================== ==== Testing print. Important since all the other tests rely on it! ==== And we'll test comments while we're at it. print("Hello world!") print("You can ""quote"" me on that.") print(42) // This is a comment. ---------------------------------------------------------------------- Hello world! You can "quote" me on that. 42 ====================================================================== ==== Basic math and operator precedence. print(2 * 3 + 4) print(2 + 3 * .5) print(-2 * -3 - 4) print(-2 - 3 * -4) print(-2^3) ---------------------------------------------------------------------- 10 3.5 2 10 -8 ====================================================================== ==== Logical operators (basics). print(1 and 1 and 1) print(1 and 0 and 1) print(0 and 1 and 1) print(0 and 0.5) print(0.5 and 1) // combines intermediate values by rules of probability! print(0.6 and 0.5) print(1 or 1 or 1) print(1 or 0 or 1) print(0 or 1 or 1) print(0 or 0.5) print(0.6 or 0.3) print(0.5 or 1) print(1 and null) print(1 or null) ---------------------------------------------------------------------- 1 0 0 0 0.5 0.3 1 1 1 0.5 0.72 1 0 1 ====================================================================== ==== Logical operators, short-circuit evaluation. reset = function(); globals.r = []; end function true = function(x); globals.r = r + [x]; return 1; end function false = function(x); globals.r = r + [x]; return 0; end function maybe = function(x); globals.r = r + [x]; return 0.5; end function reset; print((true(1) and true(2) and true(3)) + "; " + r) reset; print((true(1) and true(2) and false(3)) + "; " + r) reset; print((true(1) and false(2) and true(3)) + "; " + r) reset; print((false(1) and true(2) and true(3)) + "; " + r) reset; print((maybe(1) and true(2) and true(3)) + "; " + r); reset; print((false(1) or false(2) or false(3)) + "; " + r); reset; print((false(1) or false(2) or true(3)) + "; " + r); reset; print((false(1) or true(2) or false(3)) + "; " + r); reset; print((true(1) or false(2) or false(3)) + "; " + r); reset; print((maybe(1) or false(2) or false(3)) + "; " + r); ---------------------------------------------------------------------- 1; [1, 2, 3] 0; [1, 2, 3] 0; [1, 2] 0; [1] 0.5; [1, 2, 3] 0; [1, 2, 3] 1; [1, 2, 3] 1; [1, 2] 1; [1] 0.5; [1, 2, 3] ====================================================================== ==== Testing 'if', and what values count as true. if 1 then print(10) end if if -1 then; print(11); end if if 0 then; print(20); end if if 0.001 then; print(30); end if if -0.001 then; print(31); end if if [1] then; print(40); end if if [] then; print(50); end if if null then; print(60); else; print("OK!"); end if ---------------------------------------------------------------------- 10 11 30 31 40 OK! ====================================================================== ===== More complex 'if' structures. if 1 then print(10) else if 1 then print(15) else print(20) end if print(30) if 0 then print(40) else if 1 then print(45) else print(50) end if print(60) if 0 then print(70) else if 0 then print(80) else if 1 then print(90) else print(100) end if if 0 then print(110) else if 0 then print(120) else if 0 then print(130) else print(140) end if print(150) ---------------------------------------------------------------------- 10 30 45 60 90 140 150 ====================================================================== ===== Nested 'if' structures. if 1 then if 1 then; print(101); else; print(102); end if else if 1 then; print(201); else; print(202); end if end if print(300) if 0 then if 1 then; print(401); else; print(402); end if else if 0 then; print(501); else; print(502); end if end if print(999) ---------------------------------------------------------------------- 101 300 502 999 ====================================================================== ==== Variables. x = 6*7 print(x) y = x == 42 print(y) ---------------------------------------------------------------------- 42 1 ====================================================================== ==== List operations. list1 = [0, 10, 20, 30, 40] list2 = [100, -200, 300] print(list1[1]) print(list1[:3]) print(list1[3:]) print(list1[-2]) print(list1[1:-1]) print(list1 + list2) print([10,20,30,40,50][2:4]) print(list2 * 2.5) print(list1 * 0.4) list1[2] = 22 print(list1) ---------------------------------------------------------------------- 10 [0, 10, 20] [30, 40] 30 [10, 20, 30] [0, 10, 20, 30, 40, 100, -200, 300] [30, 40] [100, -200, 300, 100, -200, 300, 100] [0, 10] [0, 10, 22, 30, 40] ====================================================================== ==== String operations. str1 = "apple" str2 = "banana" print(str1[0]) print(str1[-2]) print(str1 + str2) print(str1 * 3) print(str1 * 0.6) print(str2 * 0.5 + str1) print(str2[1:-1]) print(str1[2:4] + str2[-3:5]) ---------------------------------------------------------------------- a l applebanana appleappleapple app banapple anan plan ====================================================================== ==== Basic map functionality. a = {1:1, 2:4} print(a) print(a[2]) print(a + {3:9}) print(a + {1:-1}) a[2] = 44 print(a[2]) ---------------------------------------------------------------------- {1: 1, 2: 4} 4 {1: 1, 2: 4, 3: 9} {1: -1, 2: 4} 44 ====================================================================== ==== Simple intrinsic functions. ==== (Including a range check on rnd, which is about the best we can do.) print(str(4) + str(2)) print(slice([0,10,20,30], 1, -1)) print(rnd >= 0) print(rnd < 1) print(str(42.0)) print(val("40.2")) t1 = time; wait(0.1); e = time - t1 if e >= 0.1 then; print("wait OK"); else; print("wait broken"); end if print(len("hello")) print(len([1,2,3,4])) print(len({1:"one", 2:"two"})) ---------------------------------------------------------------------- 42 [10, 20] 1 1 42 40.2 wait OK 5 4 2 ====================================================================== ==== isIndex and indexOf on strings, lists, and maps. s = "abcde" print(s.hasIndex(4)) // 1 (true) print(s.hasIndex(5)) // 0 print(s.hasIndex(-5)) // 1 print(s.indexOf("cd")) // 2 print(s.indexOf("xy")) // null l = [2,4,6,8] print(l.hasIndex(3)) // 1 (true) print(l.hasIndex(4)) // 0 print(l.hasIndex(-4)) // 1 print(l.indexOf(6)) // 2 print(l.indexOf(5)) // null d = {1:"one", 2:"two", "foo":42} print(d.hasIndex(1)) // 1 (true) print(d.hasIndex("x")) // 0 print(d.indexOf("two")) // 2 print(d.indexOf(42)) // foo print(d.indexOf(999)) // null ---------------------------------------------------------------------- 1 0 1 2 null 1 0 1 2 null 1 0 2 foo null ====================================================================== ==== Trigonometry. print("Pi: " + round(pi, 2)) print("acos(0.5): " + round(acos(0.5), 3)) print("asin(0.5): " + round(asin(0.5), 3)) print("atan(0.5): " + round(atan(0.5), 3)) print("cos(-pi/4): " + round(cos(-pi/4), 3)) print("sin(-pi/4): " + round(sin(-pi/4), 3)) print("tan(1): " + round(tan(1), 3)) ---------------------------------------------------------------------- Pi: 3.14 acos(0.5): 1.047 asin(0.5): 0.524 atan(0.5): 0.464 cos(-pi/4): 0.707 sin(-pi/4): -0.707 tan(1): 1.557 ====================================================================== ==== User-defined functions (including params, with and without default values). ultimateAnswer = function() return 2 + 4*10 end function print(ultimateAnswer) f = function(x, y) return x*2 + y end function print(f(5,2)) g = function(x=10, y=20) return x*2 + y end function print(g) print(g()) print(g(5)) print(g(5, 6)) ---------------------------------------------------------------------- 42 12 40 40 30 16 ====================================================================== ==== Variable scoping tests. f = function(x) print(x) print(y) x = 10 y = 20 end function x = 1 y = 2 f(5) print(x) print(y) ---------------------------------------------------------------------- 5 2 1 2 ====================================================================== ==== Explicit access to globals and locals. count = 0 foo = "bar" f = function(x) globals.count = globals.count + 1 locals.foo = "baz" print(globals.count + ", " + foo) end function f f print(foo) ---------------------------------------------------------------------- 1, baz 2, baz bar ====================================================================== ==== Testing spam generation. spam = function(n) if n == 1 then return "Spam." else return "Spam, " + "spam, " * (n-2) + "spam." end if end function print(spam(1)) print(spam(2)) print(spam(3)) print(spam(7)) ---------------------------------------------------------------------- Spam. Spam, spam. Spam, spam, spam. Spam, spam, spam, spam, spam, spam, spam. ====================================================================== ==== Simple recursion test. recursiveFactorial = function(n) if n == 1 then; return 1; end if return n * recursiveFactorial(n-1) end function print(recursiveFactorial(1)) print(recursiveFactorial(5)) ---------------------------------------------------------------------- 1 120 ====================================================================== ==== Function invocation & referencing. triple = function(n) return n*3 end function print(triple) // NULL, since we didn't supply an argument print(triple(5)) print(@triple) f = @triple print(f(6)) ---------------------------------------------------------------------- null 15 FUNCTION(n) 18 ====================================================================== ==== While loop, with break and continue. i = 0 while i < 20 i = i + 1 if i > 10 then; break; end if if i % 3 == 0 then; continue; end if print(i) end while ---------------------------------------------------------------------- 1 2 4 5 7 8 10 ====================================================================== ==== Test the range() intrinsic. print(range(1,10)) print(range(10,1)) print(range(0, 10, 3)) print(range(10, 0, -3)) ---------------------------------------------------------------------- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] [0, 3, 6, 9] [10, 7, 4, 1] ====================================================================== ==== Test the remove() intrinsic. s = "Hello Bob!" print(s.remove("ell")) print(remove(s, " Bob")) l = [1,2,3,4,5] l.remove(-2) // (second from the end) print(l) d = {1:"one", "foo":"bar"} print(d.remove("no such key")) print(d.remove(1)) print(d) ---------------------------------------------------------------------- Ho Bob! Hello! [1, 2, 3, 5] 0 1 {"foo": "bar"} ====================================================================== ==== For loop, with break and continue. for i in range(0, 100, 7) if i > 50 then; break; end if if i % 3 == 0 then; continue; end if print(i) end for ---------------------------------------------------------------------- 7 14 28 35 49 ====================================================================== ==== For loop iteration over a map (getting key/value pairs). d = {"one":1, "two":2, "three":3} for i in d print(i.key + " maps to " + i.value) end for ---------------------------------------------------------------------- one maps to 1 two maps to 2 three maps to 3 ====================================================================== ==== Function references. f = rnd // here, f is just a single random number a1 = f a2 = f print(a1==a2) // should be true (1) f = @rnd // but now, f is a reference to the rnd function a1 = f a2 = f print(a1==a2) // should be false (0) ---------------------------------------------------------------------- 1 0 ====================================================================== ==== Compile-time error reporting test. x = 1 x = 5$&@*! x = 3 ---------------------------------------------------------------------- Compiler Error: got Unknown($) where EOL is required [line 2] ====================================================================== ==== Run-time error reporting test. x = 1 x = noSuchThingy x = 3 ---------------------------------------------------------------------- Runtime Error: Undefined Identifier: 'noSuchThingy' is unknown in this context [line 2] ====================================================================== ==== Error reporting of unexpected end-of-file. for i in range(0,10) print(i) ---------------------------------------------------------------------- Compiler Error: 'for' without matching 'end for' [line 3] ====================================================================== ==== Testing that objects are distinct, even when new'd in a function. ==== (This was a bug in an early version of MiniScript.) Vec = {"x":0, "y":0} Vec.New = function() return new Vec end function v1 = new Vec v2 = Vec.New v3 = Vec.New v1.x = 1 v2.x = 2 v3.x = 3 print(v1.x) print(v2.x) print(v3.x) ---------------------------------------------------------------------- 1 2 3 ====================================================================== ==== Similar test, for lists. f = function() return [1,2,3] end function a = f b = f a[1] = 22 print(a) print(b) ---------------------------------------------------------------------- [1, 22, 3] [1, 2, 3] ====================================================================== ==== Testing chaining of calls. Vec = {"x":0, "y":0} Vec.New = function(x=0, y=0) result = new Vec result.x = x result.y = y return result end function Vec.Print = function() print("x:" + self.x + " y:" + self.y) end function Vec.New.Print Vec.New(40,2).Print ---------------------------------------------------------------------- x:0 y:0 x:40 y:2 ====================================================================== ==== Example: Summing an array (http://c2.com/cgi/wiki?ArraySum) ==== (trivial thanks to the built-in sum function) print(sum([10,15,20])) list = [100,15,20] print(list.sum) ---------------------------------------------------------------------- 45 135 ====================================================================== ==== Example: Counter (http://c2.com/cgi/wiki?CounterInManyProgrammingLanguages) ==== (Overflows when a signed int is exceeded.) ====================================================================== Counter = {"value":0} Counter.next = function() self.value = self.value + 1 return self.value end function c = new Counter print(c.next) print(c.next) print(c.next) ---------------------------------------------------------------------- 1 2 3 ====================================================================== ==== Example: Dot Product (http://c2.com/cgi/wiki?DotProductInManyProgrammingLanguages) dotProduct = function(a, b) sum = 0 for i in range(0, a.len - 1) sum = sum + a[i] * b[i] end for return sum end function print(dotProduct([1, 2, 3], [10, 100, 1000])) ---------------------------------------------------------------------- 3210 ====================================================================== ==== Example: FizzBuzz (http://rosettacode.org/wiki/FizzBuzz) fizzBuzz = function(n) for i in range(1, n) s = "Fizz" * (i%3==0) + "Buzz" * (i%5==0) if s == "" then; s = str(i); end if print(s) end for end function fizzBuzz(15) ---------------------------------------------------------------------- 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz ====================================================================== ==== Example: Map (http://rosettacode.org/wiki/Apply_a_callback_to_an_array) map = function(f, seq) result = [] for i in seq result = result + [f(i)] end for return result end function square = function(x) return x*x end function list = [2,3,5] print(map(@square, list)) ---------------------------------------------------------------------- [4, 9, 25] ====================================================================== ==== Example: Filter (http://rosettacode.org/wiki/Filter) filter = function(f, seq) result = [] for i in seq if f(i) then; result = result + [i]; end if end for return result end function isEven = function(x) return x % 2 == 0 end function list = [2,3,5,6,8,9] print(filter(@isEven, list)) ---------------------------------------------------------------------- [2, 6, 8] ====================================================================== ==== Sum and Product of an array ==== (http://rosettacode.org/wiki/Sum_and_product_of_an_array) ==== We have a built-in function for the sum, but not the product. product = function(seq) prod = 1 for i in seq prod = prod * i end for return prod end function list = [2, 4, 6] print(list.sum) print(product(list)) // pity we can't add this to the built-in list type! ---------------------------------------------------------------------- 12 48 ====================================================================== ==== Greatest Common Denominator (http://rosettacode.org/wiki/Greatest_common_divisor) gcd = function(a, b) if a == 0 then; return b; end if while b != 0 newA = b b = a % b a = newA end while return abs(a) end function print(gcd(-21, 35)) ---------------------------------------------------------------------- 7 ====================================================================== ==== Max element of a list (http://rosettacode.org/wiki/Greatest_element_of_a_list) max = function(seq) if seq.len == 0 then; return null; end if max = seq[0] for item in seq if item > max then; max = item; end if end for return max end function print(max([5, -2, 12, 7, 0])) ---------------------------------------------------------------------- 12