code / nomsu

Lines6.6K Lua5.1K PEG1.3K make117
2 others 83
Markdown60 Bourne Again Shell23
(215 lines)
1 #!/usr/bin/env nomsu -V7.0.0
2 ###
3 This file defines some common math literals and functions
5 use "core/metaprogramming"
6 use "core/text"
7 use "core/operators"
8 use "core/control_flow"
9 use "core/collections"
11 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13 external:
14 ### Literals:
15 test:
16 unless (all of [inf, NaN, pi, tau, golden ratio, e]):
17 fail "math constants failed"
18 $nan = (NaN)
19 unless ($nan != $nan):
20 fail "NaN failed"
22 [infinity, inf] all compile to "math.huge"
23 [not a number, NaN, nan] all compile to "(0/0)"
24 [pi, Pi, PI] all compile to "math.pi"
25 [tau, Tau, TAU] all compile to "(2*math.pi)"
26 (golden ratio) compiles to "((1+math.sqrt(5))/2)"
27 (e) compiles to "math.exp(1)"
29 ### Functions:
30 test:
31 assume (("5" as a number) == 5)
32 $($ as a number) = $(tonumber $)
33 $($ as number) = $(tonumber $)
34 test:
35 unless
36 all of [
37 abs 5, | 5 |, sqrt 5, √5, sine 5, cosine 5, tangent 5, arc sine 5, arc cosine 5
38 arc tangent 5, arc tangent 5 / 10, hyperbolic sine 5, hyperbolic cosine 5
39 hyperbolic tangent 5, e^ 5, ln 5, log 5 base 2, floor 5, ceiling 5, round 5
41 ..:
42 fail "math functions failed"
44 [$(absolute value $), $(absolute value of $), $(| $ |), $(abs $)] =
45 [$math.abs, $math.abs, $math.abs, $math.abs]
47 [$(square root $), $(square root of $), $(√$), $(sqrt $)] =
48 [$math.sqrt, $math.sqrt, $math.sqrt, $math.sqrt]
50 [$(sine $), $(sin $)] = [$math.sin, $math.sin]
51 [$(cosine $), $(cos $)] = [$math.cos, $math.cos]
52 [$(tangent $), $(tan $)] = [$math.tan, $math.tan]
53 [$(arc sine $), $(asin $)] = [$math.asin, $math.asin]
54 [$(arc cosine $), $(acos $)] = [$math.acos, $math.acos]
55 [$(arc tangent $), $(atan $)] = [$math.atan, $math.atan]
56 [$(arc tangent $y / $x), $(atan2 $y $x)] = [$math.atan2, $math.atan2]
57 [$(hyperbolic sine $), $(sinh $)] = [$math.sinh, $math.sinh]
58 [$(hyperbolic cosine $), $(cosh $)] = [$math.cosh, $math.cosh]
59 [$(hyperbolic tangent $), $(tanh $)] = [$math.tanh, $math.tanh]
60 [$(e^ $), $(exp $)] = [$math.exp, $math.exp]
61 [$(natural log $), $(ln $), $(log $), $(log $ base $)] =
62 [$math.log, $math.log, $math.log, $math.log]
63 $(floor $) = $math.floor
64 [$(ceiling $), $(ceil $)] = [$math.ceil, $math.ceil]
65 [round $, $ rounded] all mean (floor ($ + 0.5))
66 test:
67 unless ((463 to the nearest 100) == 500): fail "rounding failed"
68 unless ((2.6 to the nearest 0.25) == 2.5): fail "rounding failed"
69 ($n to the nearest $rounder) means ($rounder * (floor ($n / $rounder + 0.5)))
71 ### Any/all
72 [all of $items, all $items] all mean:
73 for $ in $items:
74 unless $:
75 return (no)
77 return (yes)
78 [not all of $items, not all $items] all parse as (not (all of $items))
79 [any of $items, any $items] all mean:
80 for $ in $items:
81 if $:
82 return (yes)
84 return (no)
85 [none of $items, none $items] all parse as (not (any of $items))
87 ### Sum/product
88 [sum of $items, sum $items] all mean:
89 $total = 0
90 for $ in $items:
91 $total += $
92 return $total
94 [product of $items, product $items] all mean:
95 $prod = 1
96 for $ in $items:
97 $prod *= $
98 return $prod
100 [avg of $items, average of $items] all mean ((sum of $items) / #$items)
102 ### Min/max
103 [min of $items, smallest of $items, lowest of $items] all mean:
104 $best = (nil)
105 for $ in $items:
106 if (($best == (nil)) or ($ < $best)): $best = $
107 return $best
109 [max of $items, biggest of $items, largest of $items, highest of $items] all mean:
110 $best = (nil)
111 for $ in $items:
112 if (($best == (nil)) or ($ > $best)): $best = $
113 return $best
115 test:
116 assume ((min of [3, -4, 1, 2] by $ = ($ * $)) == 1)
117 assume ((max of [3, -4, 1, 2] by $ = ($ * $)) == -4)
119 (min of $items by $item = $value_expr) parses as
120 result of:
121 $best = (nil)
122 $best_key = (nil)
123 for $item in $items:
124 $key = $value_expr
125 if (($best == (nil)) or ($key < $best_key)):
126 $best = $item
127 $best_key = $key
129 return $best
131 (max of $items by $item = $value_expr) parses as
132 result of:
133 $best = (nil)
134 $best_key = (nil)
135 for $item in $items:
136 $key = $value_expr
137 if (($best == (nil)) or ($key > $best_key)):
138 $best = $item
139 $best_key = $key
141 return $best
143 test:
144 assume (100 clamped between 0 and 10) == 10
146 ($ clamped between $min and $max) means:
147 when:
148 ($ < $min):
149 return $min
151 ($ > $max):
152 return $max
154 else:
155 return $
157 test:
158 assume (-0.1 smoothed by 2.7) == 0
159 assume (0 smoothed by 2.7) == 0
160 assume (0.5 smoothed by 2.7) == 0.5
161 assume (1 smoothed by 2.7) == 1
162 assume (1.1 smoothed by 2.7) == 1
164 ($ smoothed by $smoothness) means:
165 $ = ($ clamped between 0 and 1)
166 if ($smoothness == 0): return $
167 $k = (2 ^ $smoothness)
168 if ($ < 0.5):
169 return (0.5 * (2 * $) ^ $k)
170 ..else:
171 return (1 - 0.5 * (2 - 2 * $) ^ $k)
173 test:
174 assume (5 to 7 mixed by -1) == 5
175 assume (5 to 7 mixed by 0) == 5
176 assume (5 to 7 mixed by 0.5) == 6
177 assume (5 to 7 mixed by 1) == 7
178 assume (5 to 7 mixed by 2) == 7
180 ($lo to $hi mixed by $amount) means:
181 $ = ($amount clamped between 0 and 1)
182 return ((1 - $) * $lo + $ * $hi)
184 test:
185 assume ([0, 1, 11] mixed by 0) == 0
186 assume ([0, 1, 11] mixed by 0.25) == 0.5
187 assume ([0, 1, 11] mixed by 0.5) == 1
188 assume ([0, 1, 11] mixed by 0.75) == 6
189 assume ([0, 1, 11] mixed by 1) == 11
190 assume ([99] mixed by 0.5) == 99
192 ($nums mixed by $amount) means:
193 $ = ($amount clamped between 0 and 1)
194 $i = (1 + ($ * (#$nums - 1)))
195 if ((floor $i) == #$nums):
196 return $nums.(floor $i)
197 [$lo, $hi] = [$nums.(floor $i), $nums.(floor ($i + 1))]
198 return ($lo to $hi mixed by ($i mod 1))
200 ### Random functions
201 (seed random with $) means:
202 lua> ("
203 math.randomseed(\$);
204 for i=1,20 do math.random(); end
206 (seed random) parses as (seed random with (=lua "os.time()"))
207 [random number, random, rand] all compile to "math.random()"
208 [random int $n, random integer $n, randint $n] all compile to
209 "math.random(\($n as lua expr))"
211 [random from $low to $high, random number from $low to $high, rand $low $high]
212 ..all compile to "math.random(\($low as lua expr), \($high as lua expr))"
214 [random choice from $elements, random choice $elements, random $elements]
215 ..all mean (=lua "\$elements[math.random(#\$elements)]")