1: doctype "calculator-lambda-0_2_1.g.etl";
2: include "prelude-logic.c.etl";
3:
4: /// The construct lazy value from the lambda abstraction
5: ///
6: /// @param f the function
7: /// @return the function that remembers the result invocation of
8: /// the function without arguments
9: let q'&' = {? var f;
10: assert f != null;
11: var value;
12: {?;
13: if(f != null) {
14: value = f();
15: f = null;
16: };
17: value;
18: };
19: };
20: /// The implementation of NotEqualDeref operator
21: to q'!*='(x, y) => * x != * y;
22: /// The implementation of EqualDeref operator
23: to q'=*='(x, y) => * x == * y;
24:
25: /// The maximum value (works for comparable objects)
26: to max(x, y) => x < y ? y : x;
27: /// The minimum value (works for comparable objects)
28: to min(x, y) => x < y ? x : y;
29:
30: /// Ensure that the number in the range of integer values.
31: /// @param x the number to check
32: /// @return itself (to allows variable arguments)
33: to assertIntRange(x) => {
34: assert MIN_INTEGER <= x && x <= MAX_INTEGER : "The value is "+x;
35: assertIntRange;
36: };
37:
38: /// Ensure that the number is the integer (there is no fractional pat).
39: /// @param x the number to check
40: /// @return itself (to allows variable arguments)
41: to assertInt(x) => {
42: assertIntRange(x);
43: assert x % 1 == 0 : "The value is "+x;
44: assertInt;
45: };
46:
47: /// Ensure that the number is the non-negative integer.
48: /// @param x the number to check
49: /// @return itself (to allows variable arguments)
50: to assertNonNegativeInt(x) => {
51: assertInt(x);
52: assert x >= 0 : "The value is "+x;
53: assertNonNegativeInt;
54: };
55:
56: /// The factorial value
57: ///
58: /// @param n the non-negative integer value
59: /// @return the factorial result
60: let factorial = {?n;
61: assertNonNegativeInt(n);
62: to fac(x) => x match { 0 => 1; else x * fac(x-1); };
63: fac(n);
64: };
65:
66: letrec {
67: /// Odd number check
68: ///
69: /// @param x a non-negative integer number
70: /// @return true for odd numbers, false for even ones
71: is_odd = {?x; assertNonNegativeInt(x); x != 0 && !is_even(x-1);};
72: /// Even number check
73: ///
74: /// @param x a non-negative integer number
75: /// @return false for odd numbers, true for even ones
76: to is_even(x) => {assertNonNegativeInt(x); x == 0 || is_odd(x-1);};
77: };
78:
79: /// Repeats execution of the one argument function from low to high
80: /// adding +1 on each step until the resulting value will be higher then
81: /// high. The example below will print numbers 1.5, 2.5, 3.5, and 4.5.
82: /// {@example
83: /// 1.5 #upto 5 {?i;
84: /// print i;
85: /// }; }
86: ///
87: /// If the high value is greater then the low value, the cycle is never executed.
88: ///
89: /// @param low the start value for the loop (must be in integer range)
90: /// @param high the limit value for the loop (must be in integer range)
91: /// @param f the closure to use for the loop.
92: /// If it returns false, the cycle is aborted,
93: /// all other values are ignored.
94: /// @return null value
95: to upto(var low, high, f) => {
96: assertIntRange(low, high);
97: while(low<high && f(low) != false) {
98: low = low + 1;
99: };
100: };
101:
102: /// Repeats execution of the one argument function from start to limit
103: /// adding step on each step until the resulting value will be higher or lower then
104: /// limit (the direction depends on step's sign).
105: /// {@example
106: /// for(5,1,-0.125) {?i;
107: /// print i;
108: /// }; }
109: ///
110: /// If the high value is greater then the low value, the cycle is never executed.
111: ///
112: /// @param start the start value for the loop (start/step must be in integer range)
113: /// @param limit the limit value for the loop (limit/step must be in integer range)
114: /// @param step the loop step (must ot be 0)
115: /// @param f the closure to use for the loop.
116: /// If it returns false, the cycle is aborted,
117: /// all other values are ignored.
118: /// @return null value
119: to for(var start, limit, step, f) => {
120: assert step != 0;
121: assertIntRange(start/step, start/step);
122: while((step > 0 ? start<limit : start>limit) && f(start) != false) {
123: start = start + step;
124: };
125: };
126:
127: /// Convert Java number to integer
128: @JavaMethod("java.lang.Number", "intValue")
129: let toInt;
130:
131: /// Convert a value to string
132: @JavaMethod("java.lang.Object", "toString")
133: let str;
134:
135: @JavaMethod("java.lang.Math", "abs", "double")
136: let abs;
137:
138: @JavaMethod("java.lang.Math", "sin", "double")
139: let sin;
140:
141: @JavaMethod("java.lang.Math", "cos", "double")
142: let cos;
143:
144: /// Sign of the number
145: ///
146: /// @param x the floating point number to check
147: /// @return -1, 0, or 1 depending on th sing of the number
148: let sign = \x => select { x < 0 => -1; x > 0 => 1; else 0; };