2 * Copyright (C) 2024, 2025 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
21 // types hardcoded in type.ajla
27 private type xarray~inline(dim : list(int), t : type);
29 type array(t : type, dim : list(int)) := xarray(dim, t);
32 const unit_value~inline : unit_type;
35 private fn sysprop(p : int) : int;
36 private fn is_privileged : bool;
43 type floating(ex_bits sig_bits : int);
44 private fn floating_internal(const ex_bits sig_bits : int, f : floating(ex_bits, sig_bits)) : int;
50 type fixed_point(base digits : int);
51 type decimal(digits : int) := fixed_point(10, digits);
54 type bytes := list(byte);
57 type string := list(char);
59 record class_eq(t : type) [
60 equal : fn(t, t) : bool;
63 record class_ord(t : type) [
64 equal : fn(t, t) : bool;
65 less : fn(t, t) : bool;
68 record class_logical(t : type) [
75 record class_show(t : type) [
76 to_bytes : fn(t) : bytes;
77 from_bytes : fn(bytes) : t;
80 record class_magma(t : type) [
84 record class_monoid(t : type) [
89 record class_group(t : type) [
93 subtract : fn(t, t) : t;
96 record class_unit_ring(t : type) [
100 subtract : fn(t, t) : t;
101 multiply : fn(t, t) : t;
105 record class_division_ring(t : type) [
109 subtract : fn(t, t) : t;
110 multiply : fn(t, t) : t;
113 divide : fn(t, t) : t;
116 record class_integer_number(t : type) [
120 subtract : fn(t, t) : t;
121 multiply : fn(t, t) : t;
125 power : fn(t, t) : t;
134 equal : fn(t, t) : bool;
135 less : fn(t, t) : bool;
136 bt : fn(t, t) : bool;
141 to_int : fn(t) : int;
142 from_int : fn(int) : t;
143 to_bytes : fn(t) : bytes;
144 to_bytes_base : fn(t, int) : bytes;
145 from_bytes : fn(bytes) : t;
146 from_bytes_base : fn(bytes, int) : t;
149 record class_fixed_integer_number(t : type) [
155 subtract : fn(t, t) : t;
156 multiply : fn(t, t) : t;
160 power : fn(t, t) : t;
169 equal : fn(t, t) : bool;
170 less : fn(t, t) : bool;
171 bt : fn(t, t) : bool;
176 to_int : fn(t) : int;
177 from_int : fn(int) : t;
178 to_bytes : fn(t) : bytes;
179 to_bytes_base : fn(t, int) : bytes;
180 from_bytes : fn(bytes) : t;
181 from_bytes_base : fn(bytes, int) : t;
188 record class_real_number(t : type) [
192 subtract : fn(t, t) : t;
193 multiply : fn(t, t) : t;
196 divide : fn(t, t) : t;
197 modulo : fn(t, t) : t;
198 power : fn(t, t) : t;
199 ldexp : fn(t, t) : t;
200 atan2 : fn(t, t) : t;
227 mantissa : fn(t) : t;
228 exponent : fn(t) : t;
229 next_number : fn(t) : t;
230 prev_number : fn(t) : t;
231 is_negative : fn(t) : bool;
232 is_infinity : fn(t) : bool;
233 equal : fn(t, t) : bool;
234 less : fn(t, t) : bool;
235 to_int : fn(t) : int;
236 from_int : fn(int) : t;
237 to_rational : fn(t) : rational;
238 from_rational : fn(rational) : t;
239 to_bytes : fn(t) : bytes;
240 to_bytes_base_precision : fn(t, int, int) : bytes;
241 from_bytes : fn(bytes) : t;
242 from_bytes_base : fn(bytes, int) : t;
245 record class_functor(f : fn(type) : type) [
246 map : fn (t u : type, l : f(t), m : fn(t) : u) : f(u);
248 fn map(t u : type, const f : fn(type) : type, c : class_functor(f), l : f(t), m : fn(t) : u) : f(u);
250 implicit fn inherit_eq_ord~inline(t : type, c : class_ord(t)) : class_eq(t);
251 implicit fn inherit_magma_monoid~inline(t : type, c : class_monoid(t)) : class_magma(t);
252 implicit fn inherit_monoid_group~inline(t : type, c : class_group(t)) : class_monoid(t);
253 implicit fn inherit_group_unit_ring~inline(t : type, c : class_unit_ring(t)) : class_group(t);
254 implicit fn inherit_unit_ring_division_ring~inline(t : type, c : class_division_ring(t)) : class_unit_ring(t);
255 implicit fn inherit_show_integer_number~inline(t : type, c : class_integer_number(t)) : class_show(t);
256 implicit fn inherit_show_real_number~inline(t : type, c : class_real_number(t)) : class_show(t);
257 implicit fn inherit_ord_integer_number~inline(t : type, c : class_integer_number(t)) : class_ord(t);
258 implicit fn inherit_logical_integer_number~inline(t : type, c : class_integer_number(t)) : class_logical(t);
259 implicit fn inherit_unit_ring_integer_number~inline(t : type, c : class_integer_number(t)) : class_unit_ring(t);
260 implicit fn inherit_integer_number_fixed_integer_number~inline(t : type, c : class_fixed_integer_number(t)) : class_integer_number(t);
261 implicit fn inherit_ord_real_number~inline(t : type, c : class_real_number(t)) : class_ord(t);
262 implicit fn inherit_division_ring_real_number~inline(t : type, c : class_real_number(t)) : class_division_ring(t);
264 implicit fn inherit_eq_list~inline(t : type, c : class_eq(t)) : class_eq(list(t));
265 implicit fn inherit_ord_list~inline(t : type, c : class_ord(t)) : class_ord(list(t));
266 implicit fn instance_monoid_list~inline(t : type) : class_monoid(list(t));
267 implicit fn instance_functor_list~inline : class_functor(list);
269 implicit fn inherit_eq_array~inline(t : type, c : class_eq(t), const dim : list(int)) : class_eq(array(t, dim));
270 implicit fn inherit_ord_array~inline(t : type, c : class_ord(t), const dim : list(int)) : class_ord(array(t, dim));
271 implicit fn instance_functor_array~inline(const dim : list(int)) : class_functor(xarray(dim,));
273 implicit fn instance_logical_bool~inline : class_logical(bool);
274 implicit fn instance_ord_bool~inline : class_ord(bool);
275 implicit fn instance_number_int~inline : class_integer_number(int);
277 operator prefix + 1000 ~inline (t : type, c : class_group(t), val : t) : t;
278 operator prefix - 1000 ~inline ~Un_Neg (t : type, c : class_group(t), val : t) : t;
279 operator * 2000 ~inline ~Bin_Multiply (t : type, c : class_unit_ring(t), val1 val2 : t) : t;
280 operator / 2000 ~inline ~Bin_Divide_Real(t : type, c : class_division_ring(t), val1 val2 : t) : t;
281 operator div 2000 ~inline ~Bin_Divide_Int (t : type, c : class_integer_number(t), val1 val2 : t) : t;
282 operator mod 2000 ~inline ~Bin_Modulo (t : type, c : class_integer_number(t), val1 val2 : t) : t;
283 operator + 3000 ~inline ~Bin_Add (t : type, c : class_magma(t), val1 val2 : t) : t;
284 operator - 3000 ~inline ~Bin_Subtract (t : type, c : class_group(t), val1 val2 : t) : t;
285 operator shl 4000 ~inline ~Bin_Shl (t : type, c : class_integer_number(t), val1 val2 : t) : t;
286 operator shr 4000 ~inline ~Bin_Shr (t : type, c : class_integer_number(t), val1 val2 : t) : t;
287 operator rol 4000 ~inline ~Bin_Rol (t : type, c : class_fixed_integer_number(t), val1 val2 : t) : t;
288 operator ror 4000 ~inline ~Bin_Ror (t : type, c : class_fixed_integer_number(t), val1 val2 : t) : t;
289 operator bts 4000 ~inline ~Bin_Bts (t : type, c : class_integer_number(t), val1 val2 : t) : t;
290 operator btr 4000 ~inline ~Bin_Btr (t : type, c : class_integer_number(t), val1 val2 : t) : t;
291 operator btc 4000 ~inline ~Bin_Btc (t : type, c : class_integer_number(t), val1 val2 : t) : t;
292 operator bt 4000 ~inline ~Bin_Bt (t : type, c : class_integer_number(t), val1 val2 : t) : bool;
293 operator prefix bswap 4000 ~inline ~Un_Bswap (t : type, c : class_fixed_integer_number(t), val : t) : t;
294 operator prefix brev 4000 ~inline ~Un_Brev (t : type, c : class_fixed_integer_number(t), val : t) : t;
295 operator prefix bsf 4000 ~inline ~Un_Bsf (t : type, c : class_integer_number(t), val : t) : t;
296 operator prefix bsr 4000 ~inline ~Un_Bsr (t : type, c : class_integer_number(t), val : t) : t;
297 operator prefix popcnt 4000 ~inline ~Un_Popcnt (t : type, c : class_integer_number(t), val : t) : t;
299 operator prefix is_negative 5000 ~inline (t : type, c : class_real_number(t), val : t) : bool;
300 operator prefix is_infinity 5000 ~inline (t : type, c : class_real_number(t), val : t) : bool;
301 operator prefix is_exception 5000 ~inline (t : type, v : t) : bool;
302 operator prefix exception_class 5000 ~inline (t : type, v : t) : int;
303 operator prefix exception_type 5000 ~inline (t : type, v : t) : int;
304 operator prefix exception_aux 5000 ~inline (t : type, v : t) : int;
305 operator prefix exception_string 5000 ~inline (t : type, v : t) : bytes;
306 operator prefix exception_payload 5000 ~inline (t : type, v : t) : bytes;
307 operator prefix exception_stack 5000 ~inline (t : type, v : t) : bytes;
309 operator = 6000 ~inline ~Bin_Equal (t : type, c : class_eq(t), val1 val2 : t) : bool;
310 operator <> 6000 ~inline ~Bin_NotEqual (t : type, c : class_eq(t), val1 val2 : t) : bool;
311 operator < 6000 ~inline ~Bin_Less (t : type, c : class_ord(t), val1 val2 : t) : bool;
312 operator <= 6000 ~inline ~Bin_LessEqual (t : type, c : class_ord(t), val1 val2 : t) : bool;
313 operator > 6000 ~inline ~Bin_Greater (t : type, c : class_ord(t), val1 val2 : t) : bool;
314 operator >= 6000 ~inline ~Bin_GreaterEqual (t : type, c : class_ord(t), val1 val2 : t) : bool;
315 operator prefix not 7000 ~inline ~Un_Not (t : type, c : class_logical(t), val : t) : t;
316 operator and 8000 ~inline ~Bin_And (t : type, c : class_logical(t), val1 val2 : t) : t;
317 operator xor 9000 ~inline ~Bin_Xor (t : type, c : class_logical(t), val1 val2 : t) : t;
318 operator or 10000 ~inline ~Bin_Or (t : type, c : class_logical(t), val1 val2 : t) : t;
320 operator +< 3000 ~inline (t : type, x : list(t), y : t) : list(t) := x + list(t).[ y ];
321 operator ==> 11000 ~inline (val1 val2 : bool) : bool := val1 <= val2;
323 fn ipower~inline(t : type, c : class_integer_number(t), val1 val2 : t) : t;
324 fn fmod~inline(t : type, c : class_real_number(t), val1 val2 : t) : t;
325 fn power~inline(t : type, c : class_real_number(t), val1 val2 : t) : t;
326 fn ldexp~inline(t : type, c : class_real_number(t), val1 val2 : t) : t;
327 fn atan2~inline(t : type, c : class_real_number(t), val1 val2 : t) : t;
328 fn sqrt~inline(t : type, c : class_real_number(t), val : t) : t;
329 fn cbrt~inline(t : type, c : class_real_number(t), val : t) : t;
330 fn sin~inline(t : type, c : class_real_number(t), val : t) : t;
331 fn cos~inline(t : type, c : class_real_number(t), val : t) : t;
332 fn tan~inline(t : type, c : class_real_number(t), val : t) : t;
333 fn asin~inline(t : type, c : class_real_number(t), val : t) : t;
334 fn acos~inline(t : type, c : class_real_number(t), val : t) : t;
335 fn atan~inline(t : type, c : class_real_number(t), val : t) : t;
336 fn sinh~inline(t : type, c : class_real_number(t), val : t) : t;
337 fn cosh~inline(t : type, c : class_real_number(t), val : t) : t;
338 fn tanh~inline(t : type, c : class_real_number(t), val : t) : t;
339 fn asinh~inline(t : type, c : class_real_number(t), val : t) : t;
340 fn acosh~inline(t : type, c : class_real_number(t), val : t) : t;
341 fn atanh~inline(t : type, c : class_real_number(t), val : t) : t;
342 fn exp2~inline(t : type, c : class_real_number(t), val : t) : t;
343 fn exp~inline(t : type, c : class_real_number(t), val : t) : t;
344 fn exp10~inline(t : type, c : class_real_number(t), val : t) : t;
345 fn log2~inline(t : type, c : class_real_number(t), val : t) : t;
346 fn log~inline(t : type, c : class_real_number(t), val : t) : t;
347 fn log10~inline(t : type, c : class_real_number(t), val : t) : t;
348 fn round~inline(t : type, c : class_real_number(t), val : t) : t;
349 fn ceil~inline(t : type, c : class_real_number(t), val : t) : t;
350 fn floor~inline(t : type, c : class_real_number(t), val : t) : t;
351 fn trunc~inline(t : type, c : class_real_number(t), val : t) : t;
352 fn fract~inline(t : type, c : class_real_number(t), val : t) : t;
353 fn mantissa~inline(t : type, c : class_real_number(t), val : t) : t;
354 fn exponent~inline(t : type, c : class_real_number(t), val : t) : t;
355 fn next_number~inline(t : type, c : class_real_number(t), val : t) : t;
356 fn prev_number~inline(t : type, c : class_real_number(t), val : t) : t;
358 conversion fn integer_number_to_integer_number~inline(t1 : type, c1 : class_integer_number(t1), t2 : type, c2 : class_integer_number(t2), val : t1) : t2;
359 conversion fn integer_number_to_real_number~inline(t1 : type, c1 : class_integer_number(t1), t2 : type, c2 : class_real_number(t2), val : t1) : t2;
360 conversion fn real_number_to_integer_number~inline(t1 : type, c1 : class_real_number(t1), t2 : type, c2 : class_integer_number(t2), val : t1) : t2;
361 conversion fn real_number_to_real_number~inline(t1 : type, c1 : class_real_number(t1), t2 : type, c2 : class_real_number(t2), val : t1) : t2;
363 implicit fn instance_number_int8~inline : class_integer_number(int8);
364 implicit fn instance_number_int16~inline : class_integer_number(int16);
365 implicit fn instance_number_int32~inline : class_integer_number(int32);
366 implicit fn instance_number_int64~inline : class_integer_number(int64);
367 implicit fn instance_number_int128~inline : class_integer_number(int128);
369 implicit fn instance_fixed_integer_number_sint8~inline : class_fixed_integer_number(sint8);
370 implicit fn instance_fixed_integer_number_sint16~inline : class_fixed_integer_number(sint16);
371 implicit fn instance_fixed_integer_number_sint32~inline : class_fixed_integer_number(sint32);
372 implicit fn instance_fixed_integer_number_sint64~inline : class_fixed_integer_number(sint64);
373 implicit fn instance_fixed_integer_number_sint128~inline : class_fixed_integer_number(sint128);
375 implicit fn instance_fixed_integer_number_uint8~inline : class_fixed_integer_number(uint8);
376 implicit fn instance_fixed_integer_number_uint16~inline : class_fixed_integer_number(uint16);
377 implicit fn instance_fixed_integer_number_uint32~inline : class_fixed_integer_number(uint32);
378 implicit fn instance_fixed_integer_number_uint64~inline : class_fixed_integer_number(uint64);
379 implicit fn instance_fixed_integer_number_uint128~inline : class_fixed_integer_number(uint128);
381 implicit fn instance_fixed_integer_number_sint~inline(const n : int) : class_fixed_integer_number(sint(n));
382 implicit fn instance_fixed_integer_number_uint~inline(const n : int) : class_fixed_integer_number(uint(n));
384 implicit fn instance_real_number_real16~inline : class_real_number(real16);
385 implicit fn instance_real_number_real32~inline : class_real_number(real32);
386 implicit fn instance_real_number_real64~inline : class_real_number(real64);
387 implicit fn instance_real_number_real80~inline : class_real_number(real80);
388 implicit fn instance_real_number_real128~inline : class_real_number(real128);
390 implicit fn instance_real_number_floating~inline(const ex_bits sig_bits : int) : class_real_number(floating(ex_bits, sig_bits));
392 implicit fn instance_real_number_rational~inline : class_real_number(rational);
394 implicit fn instance_real_number_fixed_point~inline(const base digits : int) : class_real_number(fixed_point(base, digits));
400 fn debug(m : bytes) : unit_type;
401 fn internal(m : bytes) : unit_type;
402 fn stop(m : bytes) : unit_type;
403 fn report_memory_summary(m : bytes) : unit_type;
404 fn report_memory_most(m : bytes) : unit_type;
405 fn report_memory_largest(m : bytes) : unit_type;
406 fn assert~inline(v : bool, b : bytes) : unit_type;
407 fn stacktrace(t : type, v : t) : unit_type;
408 fn trace_on : unit_type;
409 fn trace_off : unit_type;
415 fn join(t : type, w1 w2 : t) : t;
416 fn any~lazy(t1 t2 : type, w1 : t1, w2 : t2) : bool;
417 fn any_list~lazy(t : type, wx : list(t)) : int;
418 fn is_ready(t : type, v : t) : bool;
419 fn never(t : type) : t;
420 fn fork(t : type, w : t) : (t, t);
426 fn len~inline(t : type, a : list(t)) : int;
427 fn len_at_least~inline(t : type, a : list(t), l : int) : bool;
428 fn len_greater_than~inline(t : type, a : list(t), l : int) : bool;
429 fn empty~inline(t : type) : list(t);
430 fn fill~inline(t : type, const x : t, const n : int) : list(t);
431 fn sparse~inline(t : type, const x : t, const n : int) : list(t);
433 fn infinite(t : type, x : t) : list(t);
434 fn infinite_repeat(t : type, x : list(t)) : list(t);
435 fn uninitialized(t : type) : t;
436 fn uninitialized_record(t : type) : t;
437 fn infinite_uninitialized(t : type) : list(t);
438 fn is_uninitialized(t : type, v : t) : bool;
439 fn is_uninitialized_record(t : type, v : t) : bool;
441 fn identity~inline(t : type, v : t) : t := v;
442 fn select~inline(t : type, b : bool, v1 v2 : t) : t
448 fn min~inline(t : type, implicit c : class_ord(t), a b : t) : t := select(a < b, b, a);
449 fn max~inline(t : type, implicit c : class_ord(t), a b : t) : t := select(a < b, a, b);
450 fn abs~inline(t : type, implicit cg : class_group(t), implicit co : class_ord(t), x : t) : t := select(x <= cg.zero, x, cg.zero - x);
451 fn sgn~inline(t : type, implicit cu : class_unit_ring(t), implicit co : class_ord(t), x : t) : t := select(x >= cu.zero, -cu.one, select(x = cu.zero, cu.one, x));
454 fn list_search(t : type, c : class_eq(t), x : list(t), v : t) : int;
455 fn list_search_fn(t : type, x : list(t), f : fn(t) : bool) : int;
456 fn list_search_backwards(t : type, c : class_eq(t), x : list(t), v : t) : int;
457 fn list_search_backwards_fn(t : type, x : list(t), f : fn(t) : bool) : int;
458 fn list_search_substring(t : type, c : class_eq(t), x v : list(t)) : int;
459 fn list_replace_substring(t : type, c : class_eq(t), x v r : list(t)) : list(t);
460 fn list_left_pad(t : type, x : list(t), width : int, padding : t) : list(t);
461 fn list_right_pad(t : type, x : list(t), width : int, padding : t) : list(t);
462 fn list_repeat(t : type, x : list(t), num : int) : list(t);
463 fn list_begins_with(t : type, c : class_eq(t), x y : list(t)) : bool;
464 fn list_ends_with(t : type, c : class_eq(t), x y : list(t)) : bool;
465 fn list_break(t : type, implicit c : class_eq(t), l : list(t), bnd : t) : list(list(t));
466 fn list_break_to_lines(b : bytes) : list(bytes);
467 fn list_string_break_to_lines(b : string) : list(string);
468 fn list_break_whitespace(l : bytes) : list(bytes);
469 fn list_join(t : type, lines : list(list(t)), bnd : list(t)) : list(t);
470 fn list_join_lines(lines : list(bytes)) : bytes;
471 fn list_filter(t : type, lst : list(t), test : fn(t) : bool) : list(t);
472 fn list_filter_idx(t : type, lst : list(t), test : fn(int, t) : bool) : list(t);
473 fn list_fold(t v : type, ini : t, lst : list(v), fold : fn(t, v) : t) : t;
474 fn list_fold_monoid(t : type, c : class_monoid(t), lst : list(t)) : t;
475 fn list_map_fold(t v : type, ini : v, lst : list(t), mp : fn(t) : v, re : fn(v, v) : v) : v;
476 fn list_map_fold_monoid(t v : type, c : class_monoid(v), lst : list(t), mp : fn(t) : v) : v;
477 fn list_reverse(t : type, l : list(t)) : list(t);
478 fn list_sort(t : type, implicit c : class_ord(t), l : list(t)) : list(t);
479 fn list_flatten~inline(t : type, a : list(t)) : list(t);
487 fn list_to_array(t : type, const dim : list(int), v : list(t)) : array(t, dim);
488 fn array_to_list(t : type, const dim : list(int), v : array(t, dim)) : list(t);
489 fn array_fill~inline(t : type, const x : t, const dim : list(int)) : array(t, dim);
490 fn array_sparse~inline(t : type, const x : t, const dim : list(int)) : array(t, dim);
491 fn array_read(t : type, const dim : list(int), v : array(t, dim), idx : list(int)) : t;
492 fn array_write(t : type, const dim : list(int), v : array(t, dim), idx : list(int), val : t) : array(t, dim);
493 fn array_reverse(t : type, const ln : int, implicit c : class_ord(t), v : array(t, [ln])) : array(t, [ln]);
494 fn array_sort(t : type, const ln : int, implicit c : class_ord(t), v : array(t, [ln])) : array(t, [ln]);
495 fn array_flatten~inline(t : type, const dim : list(int), v : array(t, dim)) : array(t, dim);
501 record tuple2(t1 : type, t2 : type) [ v1 : t1; v2 : t2; ]
502 record tuple3(t1 : type, t2 : type, t3 : type) [ v1 : t1; v2 : t2; v3 : t3; ]
503 record tuple4(t1 : type, t2 : type, t3 : type, t4 : type) [ v1 : t1; v2 : t2; v3 : t3; v4 : t4; ]
504 record tuple5(t1 : type, t2 : type, t3 : type, t4 : type, t5 : type) [ v1 : t1; v2 : t2; v3 : t3; v4 : t4; v5 : t5; ]
506 fn mktuple2(t1 t2 : type, v1 : t1, v2 : t2) : tuple2(t1, t2) := tuple2(t1, t2).[ v1 : v1, v2 : v2 ];
507 fn mktuple3(t1 t2 t3 : type, v1 : t1, v2 : t2, v3 : t3) : tuple3(t1, t2, t3) := tuple3(t1, t2, t3).[ v1 : v1, v2 : v2, v3 : v3 ];
508 fn mktuple4(t1 t2 t3 t4 : type, v1 : t1, v2 : t2, v3 : t3, v4 : t4) : tuple4(t1, t2, t3, t4) := tuple4(t1, t2, t3, t4).[ v1 : v1, v2 : v2, v3 : v3, v4 : v4 ];
509 fn mktuple5(t1 t2 t3 t4 t5 : type, v1 : t1, v2 : t2, v3 : t3, v4 : t4, v5 : t5) : tuple5(t1, t2, t3, t4, t5) := tuple5(t1, t2, t3, t4, t5).[ v1 : v1, v2 : v2, v3 : v3, v4 : v4, v5 : v5 ];
511 implicit fn inherit_eq_tuple2~inline(t1 t2 : type, c1 : class_eq(t1), c2 : class_eq(t2)) : class_eq(tuple2(t1, t2));
512 implicit fn inherit_ord_tuple2~inline(t1 t2 : type, c1 : class_ord(t1), c2 : class_ord(t2)) : class_ord(tuple2(t1, t2));
514 implicit fn inherit_eq_tuple3~inline(t1 t2 t3 : type, c1 : class_eq(t1), c2 : class_eq(t2), c3 : class_eq(t3)) : class_eq(tuple3(t1, t2, t3));
515 implicit fn inherit_ord_tuple3~inline(t1 t2 t3 : type, c1 : class_ord(t1), c2 : class_ord(t2), c3 : class_ord(t3)) : class_ord(tuple3(t1, t2, t3));
517 implicit fn inherit_eq_tuple4~inline(t1 t2 t3 t4 : type, c1 : class_eq(t1), c2 : class_eq(t2), c3 : class_eq(t3), c4 : class_eq(t4)) : class_eq(tuple4(t1, t2, t3, t4));
518 implicit fn inherit_ord_tuple4~inline(t1 t2 t3 t4 : type, c1 : class_ord(t1), c2 : class_ord(t2), c3 : class_ord(t3), c4 : class_ord(t4)) : class_ord(tuple4(t1, t2, t3, t4));
520 implicit fn inherit_eq_tuple5~inline(t1 t2 t3 t4 t5 : type, c1 : class_eq(t1), c2 : class_eq(t2), c3 : class_eq(t3), c4 : class_eq(t4), c5 : class_eq(t5)) : class_eq(tuple5(t1, t2, t3, t4, t5));
521 implicit fn inherit_ord_tuple5~inline(t1 t2 t3 t4 t5 : type, c1 : class_ord(t1), c2 : class_ord(t2), c3 : class_ord(t3), c4 : class_ord(t4), c5 : class_ord(t5)) : class_ord(tuple5(t1, t2, t3, t4, t5));
527 option maybe~flat(t : type) [
532 fn mkmaybe~inline(t : type, v : t) : maybe(t);
538 record class_iterator [
542 test : fn(state) : bool;
543 get_element : fn(state) : element;
544 increment : fn(state) : state;
547 private fn range_test~inline(t : type, implicit co : class_ord(t), j x : t) : bool := x < j;
548 private fn range_increment~inline(t : type, implicit cm : class_magma(t), step x : t) : t := x + step;
549 fn range~type(t : type, implicit cm : class_magma(t), implicit co : class_ord(t), i j step : t) : class_iterator :=
554 test : range_test(j,),
555 get_element : identity(t,),
556 increment : range_increment(step,),
559 fn list_iterator~type(t : type, l : list(t)) : class_iterator :=
564 test : len_greater_than(l,),
565 get_element : identity(int,),
566 increment : instance_number_int.add(1,),
569 fn list_iterator_reverse~type(t : type, l : list(t)) : class_iterator :=
574 test : instance_number_int.less(-1,),
575 get_element : identity(int,),
576 increment : instance_number_int.add(-1,),
579 private fn list_consumer_non_empty~inline(t : type, l : list(t)) : bool := len_greater_than(l, 0);
580 private fn list_consumer_get_head~inline(t : type, l : list(t)) : t := l[0];
581 private fn list_consumer_get_tail~inline(t : type, l : list(t)) : list(t) := l[1 .. ];
582 conversion fn list_consumer~type(t : type, l : list(t)) : class_iterator :=
587 test : list_consumer_non_empty(t,),
588 get_element : list_consumer_get_head(t,),
589 increment : list_consumer_get_tail(t,),
596 fn ntos_base~inline(t : type, c : class_integer_number(t), n : t, base : int) : bytes;
597 fn ntos_base_precision~inlnie(t : type, c : class_real_number(t), n : t, base digits : int) : bytes;
598 fn ntos~inline(t : type, c : class_show(t), n : t) : bytes;
599 fn ston_base~inline(b : bytes, base : int) : int;
600 fn ston~inline(b : bytes) : int;
601 fn format(t : type, implicit c : class_show(t), b : bytes, a : list(t)) : bytes;
624 fn int_to_native~inline(n : native, i : int) : bytes;
625 fn native_to_int~inline(n : native, b : bytes) : int;
633 uses private.rational;
634 uses private.fixed_point;
637 type unit_type := byte;
638 const unit_value~inline : unit_type := 0;
639 option bottom_type [ ]
642 private fn sysprop(p : int) : int
645 pcode UnaryOp Un_SystemProperty =r 0 p;
649 private fn is_privileged : bool
651 return sysprop(SystemProperty_Privileged) <> 0;
655 implicit fn inherit_eq_ord(t : type, c : class_ord(t)) : class_eq(t) :=
659 implicit fn inherit_magma_monoid(t : type, c : class_monoid(t)) : class_magma(t) :=
663 implicit fn inherit_monoid_group(t : type, c : class_group(t)) : class_monoid(t) :=
668 implicit fn inherit_group_unit_ring(t : type, c : class_unit_ring(t)) : class_group(t) :=
673 subtract : c.subtract,
675 implicit fn inherit_unit_ring_division_ring(t : type, c : class_division_ring(t)) : class_unit_ring(t) :=
680 subtract : c.subtract,
681 multiply : c.multiply,
684 implicit fn inherit_show_integer_number~inline(t : type, c : class_integer_number(t)) : class_show(t) :=
686 to_bytes : c.to_bytes,
687 from_bytes : c.from_bytes,
689 implicit fn inherit_show_real_number~inline(t : type, c : class_real_number(t)) : class_show(t) :=
691 to_bytes : c.to_bytes,
692 from_bytes : c.from_bytes,
694 implicit fn inherit_ord_integer_number(t : type, c : class_integer_number(t)) : class_ord(t) :=
699 implicit fn inherit_logical_integer_number(t : type, c : class_integer_number(t)) : class_logical(t) :=
706 implicit fn inherit_unit_ring_integer_number(t : type, c : class_integer_number(t)) : class_unit_ring(t) :=
711 subtract : c.subtract,
712 multiply : c.multiply,
715 implicit fn inherit_integer_number_fixed_integer_number(t : type, c : class_fixed_integer_number(t)) : class_integer_number(t) :=
716 class_integer_number(t).[
720 subtract : c.subtract,
721 multiply : c.multiply,
742 from_int : c.from_int,
743 to_bytes : c.to_bytes,
744 to_bytes_base : c.to_bytes_base,
745 from_bytes : c.from_bytes,
746 from_bytes_base : c.from_bytes_base,
748 implicit fn inherit_ord_real_number(t : type, c : class_real_number(t)) : class_ord(t) :=
753 implicit fn inherit_division_ring_real_number(t : type, c : class_real_number(t)) : class_division_ring(t) :=
754 class_division_ring(t).[
758 subtract : c.subtract,
759 multiply : c.multiply,
765 fn list_equal~inline(t : type, implicit c : class_eq(t), l1 l2 : list(t)) : bool
767 while len_greater_than(l1, 0) and len_greater_than(l2, 0) do [
768 if l1[0] <> l2[0] then
773 return len_greater_than(l1, 0) = len_greater_than(l2, 0);
775 fn list_less~inline(t : type, implicit c : class_ord(t), l1 l2 : list(t)) : bool
777 while len_greater_than(l1, 0) and len_greater_than(l2, 0) do [
778 if l1[0] <> l2[0] then
779 return l1[0] < l2[0];
783 return len_greater_than(l1, 0) < len_greater_than(l2, 0);
785 implicit fn inherit_eq_list(t : type, c : class_eq(t)) : class_eq(list(t)) :=
787 equal : list_equal(t, c,,),
789 implicit fn inherit_ord_list(t : type, c : class_ord(t)) : class_ord(list(t)) :=
791 equal : list_equal(t, inherit_eq_ord(c),,),
792 less : list_less(t, c,,),
794 fn list_add~inline(t : type, l1 l2 : list(t)) : list(t)
797 pcode Array_Append =r 0 l1 0 l2;
800 implicit fn instance_monoid_list~inline(t : type) : class_monoid(list(t)) :=
801 class_monoid(list(t)).[
805 fn list_map(t u : type, l : list(t), m : fn(t) : u) : list(u)
809 if len_greater_than(l, steps) then [
810 for i := 0 to steps do
812 return v + list_map~lazy(l[steps .. ], m);
814 for i := 0 to len(l) do
819 implicit fn instance_functor_list~inline : class_functor(list) :=
820 class_functor(list).[
824 fn array_equal(t : type, implicit c : class_eq(t), const dim : list(int), a1 a2 : array(t, dim)) : bool
826 var l1 := array_to_list(a1);
827 var l2 := array_to_list(a2);
828 for i := 0 to len(l1) do
829 if l1[i] <> l2[i] then
833 fn array_less(t : type, implicit c : class_ord(t), const dim : list(int), a1 a2 : array(t, dim)) : bool
835 var l1 := array_to_list(a1);
836 var l2 := array_to_list(a2);
837 for i := 0 to len(l1) do
838 if l1[i] <> l2[i] then
839 return l1[i] < l2[i];
842 implicit fn inherit_eq_array~inline(t : type, c : class_eq(t), const dim : list(int)) : class_eq(array(t, dim)) :=
843 class_eq(array(t, dim)).[
844 equal : array_equal(t, c, dim,,),
847 implicit fn inherit_ord_array~inline(t : type, c : class_ord(t), const dim : list(int)) : class_ord(array(t, dim)) :=
848 class_ord(array(t, dim)).[
849 equal : array_equal(t, inherit_eq_ord(c), dim,,),
850 less : array_less(t, c, dim,,),
853 fn array_map(const dim : list(int), t u : type, a : array(t, dim), m : fn(t) : u) : array(u, dim)
855 var tl := array_to_list(t, dim, a);
857 for i := 0 to len(tl) do
859 return list_to_array(u, dim, ul);
861 implicit fn instance_functor_array~inline(const dim : list(int)) : class_functor(xarray(dim,)) :=
862 class_functor(xarray(dim,)).[
863 map : array_map(dim,,,,),
866 fn map(t u : type, const f : fn(type) : type, c : class_functor(f), l : f(t), m : fn(t) : u) : f(u)
875 fn bool_and~inline(b1 b2 : bool) : bool
878 pcode BinaryOp Bin_And =r 0 b1 0 b2;
881 fn bool_or~inline(b1 b2 : bool) : bool
884 pcode BinaryOp Bin_Or =r 0 b1 0 b2;
887 fn bool_not~inline(b1 : bool) : bool
890 pcode UnaryOp Un_Not =r 0 b1;
893 fn bool_equal~inline(b1 b2 : bool) : bool
896 pcode BinaryOp Bin_Equal =r 0 b1 0 b2;
899 fn bool_not_equal~inline(b1 b2 : bool) : bool
902 pcode BinaryOp Bin_NotEqual =r 0 b1 0 b2;
905 fn bool_less~inline(b1 b2 : bool) : bool
908 pcode BinaryOp Bin_Less =r 0 b1 0 b2;
911 implicit fn instance_logical_bool~inline : class_logical(bool) :=
912 class_logical(bool).[
915 xor : bool_not_equal,
918 implicit fn instance_ord_bool~inline : class_ord(bool) :=
928 define int_instance [
929 fn @1_add~inline(i1 i2 : @1) : @1
932 pcode BinaryOp Bin_Add =r 0 i1 0 i2;
935 fn @1_zero~inline : @1
938 pcode Load_Const =r 0;
941 fn @1_neg~inline(i1 : @1) : @1
944 pcode UnaryOp Un_Neg =r 0 i1;
947 fn @1_subtract~inline(i1 i2 : @1) : @1
950 pcode BinaryOp Bin_Subtract =r 0 i1 0 i2;
953 fn @1_multiply~inline(i1 i2 : @1) : @1
956 pcode BinaryOp Bin_Multiply =r 0 i1 0 i2;
959 fn @1_one~inline : @1
962 pcode Load_Const =r 1 1;
965 fn @1_div~inline(i1 i2 : @1) : @1
968 pcode BinaryOp Bin_Divide_Int =r 0 i1 0 i2;
971 fn @1_mod~inline(i1 i2 : @1) : @1
974 pcode BinaryOp Bin_Modulo =r 0 i1 0 i2;
977 fn @1_power~inline(i1 i2 : @1) : @1
980 pcode BinaryOp Bin_Power =r 0 i1 0 i2;
983 fn @1_and~inline(i1 i2 : @1) : @1
986 pcode BinaryOp Bin_And =r 0 i1 0 i2;
989 fn @1_or~inline(i1 i2 : @1) : @1
992 pcode BinaryOp Bin_Or =r 0 i1 0 i2;
995 fn @1_xor~inline(i1 i2 : @1) : @1
998 pcode BinaryOp Bin_Xor =r 0 i1 0 i2;
1001 fn @1_shl~inline(i1 i2 : @1) : @1
1004 pcode BinaryOp Bin_Shl =r 0 i1 0 i2;
1007 fn @1_shr~inline(i1 i2 : @1) : @1
1010 pcode BinaryOp Bin_Shr =r 0 i1 0 i2;
1013 fn @1_bts~inline(i1 i2 : @1) : @1
1016 pcode BinaryOp Bin_Bts =r 0 i1 0 i2;
1019 fn @1_btr~inline(i1 i2 : @1) : @1
1022 pcode BinaryOp Bin_Btr =r 0 i1 0 i2;
1025 fn @1_btc~inline(i1 i2 : @1) : @1
1028 pcode BinaryOp Bin_Btc =r 0 i1 0 i2;
1031 fn @1_equal~inline(i1 i2 : @1) : bool
1034 pcode BinaryOp Bin_Equal =r 0 i1 0 i2;
1037 fn @1_less~inline(i1 i2 : @1) : bool
1040 pcode BinaryOp Bin_Less =r 0 i1 0 i2;
1043 fn @1_bt~inline(i1 i2 : @1) : bool
1046 pcode BinaryOp Bin_Bt =r 0 i1 0 i2;
1049 fn @1_not~inline(i1 : @1) : @1
1052 pcode UnaryOp Un_Not =r 0 i1;
1055 fn @1_bsf~inline(i1 : @1) : @1
1058 pcode UnaryOp Un_Bsf =r 0 i1;
1061 fn @1_bsr~inline(i1 : @1) : @1
1064 pcode UnaryOp Un_Bsr =r 0 i1;
1067 fn @1_popcnt~inline(i1 : @1) : @1
1070 pcode UnaryOp Un_Popcnt =r 0 i1;
1073 fn @1_to_int~inline(i1 : @1) : int
1076 pcode UnaryOp Un_ConvertToInt =r 0 i1;
1079 fn @1_from_int~inline(i1 : int) : @1
1082 pcode UnaryOp Un_ConvertFromInt =r 0 i1;
1085 fn @1_to_bytes(i1 : @1) : bytes
1087 return integer_to_bytes(@1_to_int(i1));
1089 fn @1_to_bytes_base(i1 : @1, base : int) : bytes
1091 return integer_to_bytes_base(@1_to_int(i1), base);
1093 fn @1_from_bytes(i1 : bytes) : @1
1095 return @1_from_int(bytes_to_integer(i1));
1097 fn @1_from_bytes_base(i1 : bytes, base : int) : @1
1099 return @1_from_int(bytes_to_integer_base(i1, base));
1101 implicit fn instance_number_@1~inline : class_integer_number(@1) :=
1102 class_integer_number(@1).[
1106 subtract : @1_subtract,
1107 multiply : @1_multiply,
1128 from_int : @1_from_int,
1129 to_bytes : @1_to_bytes,
1130 to_bytes_base : @1_to_bytes_base,
1131 from_bytes : @1_from_bytes,
1132 from_bytes_base : @1_from_bytes_base,
1139 int_instance(int16);
1140 int_instance(int32);
1141 int_instance(int64);
1142 int_instance(int128);
1148 define fixed_instance [
1149 fn @1_add~inline(i1 i2 : @1) : @1
1152 pcode BinaryOp Bin_Add =r 0 i1 0 i2;
1155 fn @1_zero~inline : @1
1158 pcode Load_Const =r 0;
1161 fn @1_neg~inline(i1 : @1) : @1
1164 pcode UnaryOp Un_Neg =r 0 i1;
1167 fn @1_subtract~inline(i1 i2 : @1) : @1
1170 pcode BinaryOp Bin_Subtract =r 0 i1 0 i2;
1173 fn @1_multiply~inline(i1 i2 : @1) : @1
1176 pcode BinaryOp Bin_Multiply =r 0 i1 0 i2;
1179 fn @1_one~inline : @1
1182 pcode Load_Const =r 1 1;
1185 fn @1_div~inline(i1 i2 : @1) : @1
1188 pcode BinaryOp Bin_Divide_Int =r 0 i1 0 i2;
1191 fn @1_mod~inline(i1 i2 : @1) : @1
1194 pcode BinaryOp Bin_Modulo =r 0 i1 0 i2;
1197 fn @1_power~inline(i1 i2 : @1) : @1
1200 pcode BinaryOp Bin_Power =r 0 i1 0 i2;
1203 fn @1_and~inline(i1 i2 : @1) : @1
1206 pcode BinaryOp Bin_And =r 0 i1 0 i2;
1209 fn @1_or~inline(i1 i2 : @1) : @1
1212 pcode BinaryOp Bin_Or =r 0 i1 0 i2;
1215 fn @1_xor~inline(i1 i2 : @1) : @1
1218 pcode BinaryOp Bin_Xor =r 0 i1 0 i2;
1221 fn @1_shl~inline(i1 i2 : @1) : @1
1224 pcode BinaryOp Bin_Shl =r 0 i1 0 i2;
1227 fn @1_shr~inline(i1 i2 : @1) : @1
1230 pcode BinaryOp Bin_Shr =r 0 i1 0 i2;
1233 fn @1_bts~inline(i1 i2 : @1) : @1
1236 pcode BinaryOp Bin_Bts =r 0 i1 0 i2;
1239 fn @1_btr~inline(i1 i2 : @1) : @1
1242 pcode BinaryOp Bin_Btr =r 0 i1 0 i2;
1245 fn @1_btc~inline(i1 i2 : @1) : @1
1248 pcode BinaryOp Bin_Btc =r 0 i1 0 i2;
1251 fn @1_equal~inline(i1 i2 : @1) : bool
1254 pcode BinaryOp Bin_Equal =r 0 i1 0 i2;
1257 fn @1_less~inline(i1 i2 : @1) : bool
1260 pcode BinaryOp Bin_Less =r 0 i1 0 i2;
1263 fn @1_bt~inline(i1 i2 : @1) : bool
1266 pcode BinaryOp Bin_Bt =r 0 i1 0 i2;
1269 fn @1_not~inline(i1 : @1) : @1
1272 pcode UnaryOp Un_Not =r 0 i1;
1275 fn @1_bsf~inline(i1 : @1) : @1
1278 pcode UnaryOp Un_Bsf =r 0 i1;
1281 fn @1_bsr~inline(i1 : @1) : @1
1284 pcode UnaryOp Un_Bsr =r 0 i1;
1287 fn @1_popcnt~inline(i1 : @1) : @1
1290 pcode UnaryOp Un_Popcnt =r 0 i1;
1293 fn @1_to_int~inline(i1 : @1) : int
1296 pcode UnaryOp Un_ConvertToInt =r 0 i1;
1299 fn @1_from_int~inline(i1 : int) : @1
1302 pcode UnaryOp Un_ConvertFromInt =r 0 i1;
1305 fn @1_to_bytes(i1 : @1) : bytes
1307 return integer_to_bytes(@1_to_int(i1));
1309 fn @1_to_bytes_base(i1 : @1, base : int) : bytes
1311 return integer_to_bytes_base(@1_to_int(i1), base);
1313 fn @1_from_bytes(i1 : bytes) : @1
1315 return @1_from_int(bytes_to_integer(i1));
1317 fn @1_from_bytes_base(i1 : bytes, base : int) : @1
1319 return @1_from_int(bytes_to_integer_base(i1, base));
1321 fn @1_rol~inline(i1 i2 : @1) : @1
1324 pcode BinaryOp Bin_Rol =r 0 i1 0 i2;
1327 fn @1_ror~inline(i1 i2 : @1) : @1
1330 pcode BinaryOp Bin_Ror =r 0 i1 0 i2;
1333 fn @1_bswap~inline(i1 : @1) : @1
1336 pcode UnaryOp Un_Bswap =r 0 i1;
1339 fn @1_brev~inline(i1 : @1) : @1
1342 pcode UnaryOp Un_Brev =r 0 i1;
1345 implicit fn instance_fixed_integer_number_@1~inline : class_fixed_integer_number(@1) :=
1346 class_fixed_integer_number(@1).[
1352 subtract : @1_subtract,
1353 multiply : @1_multiply,
1374 from_int : @1_from_int,
1375 to_bytes : @1_to_bytes,
1376 to_bytes_base : @1_to_bytes_base,
1377 from_bytes : @1_from_bytes,
1378 from_bytes_base : @1_from_bytes_base,
1386 fixed_instance(sint8, 8, false);
1387 fixed_instance(sint16, 16, false);
1388 fixed_instance(sint32, 32, false);
1389 fixed_instance(sint64, 64, false);
1390 fixed_instance(sint128, 128, false);
1391 fixed_instance(uint8, 8, true);
1392 fixed_instance(uint16, 16, true);
1393 fixed_instance(uint32, 32, true);
1394 fixed_instance(uint64, 64, true);
1395 fixed_instance(uint128, 128, true);
1397 type suint_base := int128;
1398 type sint(n : int) := suint_base;
1399 type uint(n : int) := suint_base;
1401 fn fx_wrap~inline(n : int, i : suint_base) : suint_base := i and ((1 shl n) - 1);
1402 fn fx_unwrap~inline(n : int, uns : bool, i : suint_base) : suint_base
1404 if uns or not i bt n - 1 then
1406 return i - (1 shl n);
1408 fn fx_mod_n~inline(n : int, i : suint_base) : suint_base
1416 fn fx_add~inline(n : int, i1 i2 : suint_base) : suint_base := fx_wrap(n, i1 + i2);
1417 fn fx_neg~inline(n : int, i1 : suint_base) : suint_base := fx_wrap(n, -i1);
1418 fn fx_subtract~inline(n : int, i1 i2 : suint_base) : suint_base := fx_wrap(n, i1 - i2);
1419 fn fx_multiply~inline(n : int, i1 i2 : suint_base) : suint_base := fx_wrap(n, i1 * i2);
1420 fn fx_div~inline(n : int, uns : bool, i1 i2 : suint_base) : suint_base
1422 i1 := fx_unwrap(n, uns, i1);
1423 i2 := fx_unwrap(n, uns, i2);
1426 return fx_wrap(n, i1 div i2);
1428 fn fx_mod~inline(n : int, uns : bool, i1 i2 : suint_base) : suint_base
1430 i1 := fx_unwrap(n, uns, i1);
1431 i2 := fx_unwrap(n, uns, i2);
1434 return fx_wrap(n, i1 mod i2);
1436 fn fx_power~inline(n : int, uns : bool, i1 i2 : suint_base) : suint_base
1441 r := fx_wrap(n, r * i1);
1442 i1 := fx_wrap(n, i1 * i1);
1447 fn fx_and~inline(i1 i2 : suint_base) : suint_base := i1 and i2;
1448 fn fx_or~inline(i1 i2 : suint_base) : suint_base := i1 or i2;
1449 fn fx_xor~inline(i1 i2 : suint_base) : suint_base := i1 xor i2;
1450 fn fx_shl~inline(n : int, i1 i2 : suint_base) : suint_base := fx_wrap(n, i1 shl fx_mod_n(n, i2));
1451 fn fx_shr~inline(n : int, uns : bool, i1 i2 : suint_base) : suint_base := fx_wrap(n, fx_unwrap(n, uns, i1) shr fx_mod_n(n, i2));
1452 fn fx_bts~inline(n : int, i1 i2 : suint_base) : suint_base := i1 bts fx_mod_n(n, i2);
1453 fn fx_btr~inline(n : int, i1 i2 : suint_base) : suint_base := i1 btr fx_mod_n(n, i2);
1454 fn fx_btc~inline(n : int, i1 i2 : suint_base) : suint_base := i1 btc fx_mod_n(n, i2);
1455 fn fx_equal~inline(i1 i2 : suint_base) : bool := i1 = i2;
1456 fn fx_less~inline(n : int, uns : bool, i1 i2 : suint_base) : bool := fx_unwrap(n, uns, i1) < fx_unwrap(n, uns, i2);
1457 fn fx_bt~inline(n : int, i1 i2 : suint_base) : bool := i1 bt fx_mod_n(n, i2);
1458 fn fx_not~inline(n : int, i1 : suint_base) : suint_base := fx_wrap(n, not i1);
1459 fn fx_bsf~inline(n : int, i1 : suint_base) : suint_base
1462 return (1 shl n) - 1;
1465 fn fx_bsr~inline(n : int, i1 : suint_base) : suint_base
1468 return (1 shl n) - 1;
1471 fn fx_popcnt~inline(i1 : suint_base) : suint_base := popcnt i1;
1472 fn fx_to_int~inline(n : int, uns : bool, i1 : suint_base) : int := fx_unwrap(n, uns, i1);
1473 fn fx_from_int~inline(n : int, uns : bool, i1 : int) : suint_base
1476 if i1 < 0 or i1 >= 1 shl n then
1477 abort exception_make(suint_base, ec_sync, error_doesnt_fit, 0, true);
1480 if i1 < -(1 shl n - 1) or i1 >= 1 shl n - 1 then
1481 abort exception_make(suint_base, ec_sync, error_doesnt_fit, 0, true);
1482 return fx_wrap(n, i1);
1485 fn fx_to_bytes~inline(n : int, uns : bool, i1 : suint_base) : bytes := int_to_bytes(fx_unwrap(n, uns, i1));
1486 fn fx_to_bytes_base~inline(n : int, uns : bool, i1 : suint_base, base : int) : bytes := int_to_bytes_base(fx_unwrap(n, uns, i1), base);
1487 fn fx_from_bytes~inline(n : int, uns : bool, a1 : bytes) : suint_base := fx_from_int(n, uns, int_from_bytes(a1));
1488 fn fx_from_bytes_base~inline(n : int, uns : bool, a1 : bytes, base : int) : suint_base := fx_from_int(n, uns, int_from_bytes_base(a1, base));
1489 fn fx_rol~inline(n : int, i1 i2 : suint_base) : suint_base := fx_wrap(n, i1 shl fx_mod_n(n, i2) or i1 shr fx_mod_n(n, n - i2));
1490 fn fx_ror~inline(n : int, i1 i2 : suint_base) : suint_base := fx_wrap(n, i1 shr fx_mod_n(n, i2) or i1 shl fx_mod_n(n, n - i2));
1491 fn fx_bswap~inline(n : int, i1 : suint_base) : suint_base
1495 for i := 0 to n do [
1496 result or= (i1 shr (i * 8) and #ff) shl (n - 1 - i) * 8;
1500 fn fx_brev~inline(n : int, i1 : suint_base) : suint_base
1503 for i := 0 to n do [
1504 result or= (i1 shr i and 1) shl (n - 1 - i);
1509 fn instance_fixed_integer_number_int~inline(n : int, uns : bool) : class_fixed_integer_number(suint_base) :=
1510 class_fixed_integer_number(suint_base).[
1516 subtract : fx_subtract(n,,),
1517 multiply : fx_multiply(n,,),
1519 div : fx_div(n, uns,,),
1520 mod : fx_mod(n, uns,,),
1521 power : fx_power(n, uns,,),
1526 shr : fx_shr(n,uns,,),
1531 less : fx_less(n, uns,,),
1537 to_int : fx_to_int(n, uns,),
1538 from_int : fx_from_int(n, uns,),
1539 to_bytes : fx_to_bytes(n, uns,),
1540 to_bytes_base : fx_to_bytes_base(n, uns,,),
1541 from_bytes : fx_from_bytes(n, uns,),
1542 from_bytes_base : fx_from_bytes_base(n, uns,,),
1545 bswap : fx_bswap(n,),
1549 implicit fn instance_fixed_integer_number_sint~inline(const n : int) : class_fixed_integer_number(sint(n)) := instance_fixed_integer_number_int(n, false);
1550 implicit fn instance_fixed_integer_number_uint~inline(const n : int) : class_fixed_integer_number(uint(n)) := instance_fixed_integer_number_int(n, true);
1556 define real_instance [
1557 fn @1_add~inline(i1 i2 : @1) : @1
1560 pcode BinaryOp Bin_Add =r 0 i1 0 i2;
1563 fn @1_zero~inline : @1
1567 pcode UnaryOp Un_ConvertFromInt =r 0 i;
1570 fn @1_neg~inline(i1 : @1) : @1
1573 pcode UnaryOp Un_Neg =r 0 i1;
1576 fn @1_subtract~inline(i1 i2 : @1) : @1
1579 pcode BinaryOp Bin_Subtract =r 0 i1 0 i2;
1582 fn @1_multiply~inline(i1 i2 : @1) : @1
1585 pcode BinaryOp Bin_Multiply =r 0 i1 0 i2;
1588 fn @1_one~inline : @1
1592 pcode UnaryOp Un_ConvertFromInt =r 0 i;
1595 fn @1_recip~inline(i1 : @1) : @1
1599 pcode BinaryOp Bin_Divide_Real =r 0 i0 0 i1;
1604 return #1.921fb54442d18469898cc51701b8p+1;
1606 fn @1_divide~inline(i1 i2 : @1) : @1
1609 pcode BinaryOp Bin_Divide_Real =r 0 i1 0 i2;
1612 fn @1_modulo~inline(i1 i2 : @1) : @1
1615 pcode BinaryOp Bin_Modulo =r 0 i1 0 i2;
1618 fn @1_power~inline(i1 i2 : @1) : @1
1621 pcode BinaryOp Bin_Power =r 0 i1 0 i2;
1624 fn @1_ldexp~inline(i1 i2 : @1) : @1
1627 pcode BinaryOp Bin_Shl =r 0 i1 0 i2;
1630 fn @1_atan2~inline(i1 i2 : @1) : @1
1633 pcode BinaryOp Bin_Atan2 =r 0 i1 0 i2;
1636 fn @1_sqrt~inline(i1 : @1) : @1
1639 pcode UnaryOp Un_Sqrt =r 0 i1;
1642 fn @1_cbrt~inline(i1 : @1) : @1
1645 pcode UnaryOp Un_Cbrt =r 0 i1;
1648 fn @1_sin~inline(i1 : @1) : @1
1651 pcode UnaryOp Un_Sin =r 0 i1;
1654 fn @1_cos~inline(i1 : @1) : @1
1657 pcode UnaryOp Un_Cos =r 0 i1;
1660 fn @1_tan~inline(i1 : @1) : @1
1663 pcode UnaryOp Un_Tan =r 0 i1;
1666 fn @1_asin~inline(i1 : @1) : @1
1669 pcode UnaryOp Un_Asin =r 0 i1;
1672 fn @1_acos~inline(i1 : @1) : @1
1675 pcode UnaryOp Un_Acos =r 0 i1;
1678 fn @1_atan~inline(i1 : @1) : @1
1681 pcode UnaryOp Un_Atan =r 0 i1;
1684 fn @1_sinh~inline(i1 : @1) : @1
1687 pcode UnaryOp Un_Sinh =r 0 i1;
1690 fn @1_cosh~inline(i1 : @1) : @1
1693 pcode UnaryOp Un_Cosh =r 0 i1;
1696 fn @1_tanh~inline(i1 : @1) : @1
1699 pcode UnaryOp Un_Tanh =r 0 i1;
1702 fn @1_asinh~inline(i1 : @1) : @1
1705 pcode UnaryOp Un_Asinh =r 0 i1;
1708 fn @1_acosh~inline(i1 : @1) : @1
1711 pcode UnaryOp Un_Acosh =r 0 i1;
1714 fn @1_atanh~inline(i1 : @1) : @1
1717 pcode UnaryOp Un_Atanh =r 0 i1;
1720 fn @1_exp2~inline(i1 : @1) : @1
1723 pcode UnaryOp Un_Exp2 =r 0 i1;
1726 fn @1_exp~inline(i1 : @1) : @1
1729 pcode UnaryOp Un_Exp =r 0 i1;
1732 fn @1_exp10~inline(i1 : @1) : @1
1735 pcode UnaryOp Un_Exp10 =r 0 i1;
1738 fn @1_log2~inline(i1 : @1) : @1
1741 pcode UnaryOp Un_Log2 =r 0 i1;
1744 fn @1_log~inline(i1 : @1) : @1
1747 pcode UnaryOp Un_Log =r 0 i1;
1750 fn @1_log10~inline(i1 : @1) : @1
1753 pcode UnaryOp Un_Log10 =r 0 i1;
1756 fn @1_round~inline(i1 : @1) : @1
1759 pcode UnaryOp Un_Round =r 0 i1;
1762 fn @1_ceil~inline(i1 : @1) : @1
1765 pcode UnaryOp Un_Ceil =r 0 i1;
1768 fn @1_floor~inline(i1 : @1) : @1
1771 pcode UnaryOp Un_Floor =r 0 i1;
1774 fn @1_trunc~inline(i1 : @1) : @1
1777 pcode UnaryOp Un_Trunc =r 0 i1;
1780 fn @1_fract~inline(i1 : @1) : @1
1783 pcode UnaryOp Un_Fract =r 0 i1;
1786 fn @1_mantissa~inline(i1 : @1) : @1
1789 pcode UnaryOp Un_Mantissa =r 0 i1;
1792 fn @1_exponent~inline(i1 : @1) : @1
1795 pcode UnaryOp Un_Exponent =r 0 i1;
1798 fn @1_next_number~inline(i1 : @1) : @1
1801 pcode UnaryOp Un_NextNumber =r 0 i1;
1804 fn @1_prev_number~inline(i1 : @1) : @1
1807 pcode UnaryOp Un_PrevNumber =r 0 i1;
1810 fn @1_is_negative~inline(i1 : @1) : bool
1815 return @1_recip(i1) < 0;
1817 fn @1_is_infinity~inline(i1 : @1) : bool
1819 return i1 <> 0 and i1 + i1 = i1;
1821 fn @1_equal~inline(i1 i2 : @1) : bool
1824 pcode BinaryOp Bin_Equal =r 0 i1 0 i2;
1827 fn @1_less~inline(i1 i2 : @1) : bool
1830 pcode BinaryOp Bin_Less =r 0 i1 0 i2;
1833 fn @1_to_int~inline(i1 : @1) : int
1836 pcode UnaryOp Un_ConvertToInt =r 0 i1;
1839 fn @1_from_int~inline(i1 : int) : @1
1842 pcode UnaryOp Un_ConvertFromInt =r 0 i1;
1845 fn @1_to_rational(i1 : @1) : rational
1847 return real_to_rational~inline(@1, instance_real_number_@1, i1);
1849 fn @1_from_rational(i1 : rational) : @1
1851 return rational_to_real~inline(@1, instance_real_number_@1, i1);
1853 fn @1_to_bytes(i1 : @1) : bytes
1855 return real_to_bytes~inline(@1, instance_real_number_@1, i1);
1857 fn @1_to_bytes_base_precision(i1 : @1, b : int, digits : int) : bytes
1859 return real_to_bytes_base_precision~inline(@1, instance_real_number_@1, i1, b, digits);
1861 fn @1_from_bytes(a1 : bytes) : @1
1863 return bytes_to_real~inline(@1, instance_real_number_@1, a1);
1865 fn @1_from_bytes_base(a1 : bytes, b : int) : @1
1867 return bytes_to_real_base~inline(@1, instance_real_number_@1, a1, b);
1869 implicit fn instance_real_number_@1~inline : class_real_number(@1) :=
1870 class_real_number(@1).[
1874 subtract : @1_subtract,
1875 multiply : @1_multiply,
1909 mantissa : @1_mantissa,
1910 exponent : @1_exponent,
1911 next_number : @1_next_number,
1912 prev_number : @1_prev_number,
1913 is_negative : @1_is_negative,
1914 is_infinity : @1_is_infinity,
1918 from_int : @1_from_int,
1919 to_rational : @1_to_rational,
1920 from_rational : @1_from_rational,
1921 to_bytes : @1_to_bytes,
1922 to_bytes_base_precision : @1_to_bytes_base_precision,
1923 from_bytes : @1_from_bytes,
1924 from_bytes_base : @1_from_bytes_base,
1928 real_instance(real16);
1929 real_instance(real32);
1930 real_instance(real64);
1931 real_instance(real80);
1932 real_instance(real128);
1934 {---------------------
1935 - FLOATING INSTANCE -
1936 ---------------------}
1938 fn floating_ex~inline(ex_bits : int) : int := ex_bits + 2;
1939 fn floating_sig~inline(sig_bits : int) : int := sig_bits + 8;
1941 fn floating_modulo(const ex_bits sig_bits : int, x1 x2 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
1943 return math_modulo(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1, x2);
1946 fn floating_power(const ex_bits sig_bits : int, x1 x2 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
1948 return math_power(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1, x2);
1951 // we must not call math_ldexp for integer arguments, otherwise there would be
1952 // infinite recursion; the reason is that we use ldexp in real_to_rational and
1954 // warning: this logic is duplicated in math_ldexp
1955 fn floating_ldexp(const ex_bits sig_bits : int, x y : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
1959 if not is_exception yi, y = yi then [
1960 if is_infinity x then
1962 var q : floating(ex_bits, sig_bits) := 1 shl abs(yi);
1963 if is_infinity q then [
1966 x := floating_ldexp(x, y1);
1967 x := floating_ldexp(x, y2);
1976 return math_ldexp(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x, y);
1979 fn floating_atan2(const ex_bits sig_bits : int, x1 x2 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
1981 return math_atan2(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1, x2);
1984 fn floating_pi(const ex_bits sig_bits : int) : floating(ex_bits, sig_bits)
1986 return math_pi(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)));
1989 fn floating_sqrt(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
1991 return math_sqrt(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
1994 fn floating_cbrt(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
1996 return math_cbrt(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
1999 fn floating_sin(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2001 return math_sin(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2004 fn floating_cos(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2006 return math_cos(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2009 fn floating_tan(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2011 return math_tan(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2014 fn floating_asin(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2016 return math_asin(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2019 fn floating_acos(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2021 return math_acos(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2024 fn floating_atan(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2026 return math_atan(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2029 fn floating_sinh(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2031 return math_sinh(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2034 fn floating_cosh(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2036 return math_cosh(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2039 fn floating_tanh(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2041 return math_tanh(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2044 fn floating_asinh(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2046 return math_asinh(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2049 fn floating_acosh(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2051 return math_acosh(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2054 fn floating_atanh(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2056 return math_atanh(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2059 fn floating_exp2(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2061 return math_exp2(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2064 fn floating_exp(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2066 return math_exp(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2069 fn floating_exp10(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2071 return math_exp10(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2074 fn floating_log2(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2076 return math_log2(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2079 fn floating_log(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2081 return math_log(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2084 fn floating_log10(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2086 return math_log10(floating(floating_ex(ex_bits), floating_sig(sig_bits)), instance_real_number_floating(floating_ex(ex_bits), floating_sig(sig_bits)), x1);
2089 fn floating_round(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2091 return math_round(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1);
2094 fn floating_ceil(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2096 return math_ceil(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1);
2099 fn floating_floor(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2101 return math_floor(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1);
2104 fn floating_trunc(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2106 return math_trunc(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1);
2109 fn floating_fract(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2111 return math_fract(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1);
2114 fn floating_mantissa(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2116 return math_mantissa(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1);
2119 fn floating_exponent(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2121 return math_exponent(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1);
2124 type floating_base := int128;
2125 type sig_type := int128;
2127 type floating(ex_bits sig_bits : int) := floating_base;
2129 private fn floating_internal(const ex_bits sig_bits : int, f : floating(ex_bits, sig_bits)) : int
2131 var fb : floating_base := f;
2135 fn floating_divide(ex_bits sig_bits : int, x1 x2 : floating_base) : floating_base;
2136 fn floating_equal(ex_bits sig_bits : int, x1 x2 : floating_base) : bool;
2137 fn floating_less(ex_bits sig_bits : int, x1 x2 : floating_base) : bool;
2138 fn floating_to_int(ex_bits sig_bits : int, x1 : floating_base) : int;
2139 fn floating_from_int(ex_bits sig_bits : int, i1 : int) : floating_base;
2140 fn floating_to_bytes(const ex_bits sig_bits : int, x1 : floating_base) : bytes;
2142 fn min_exp(ex_bits sig_bits : int) : int
2144 if ex_bits > 19 then
2146 return -(1 shl ex_bits - 1) - sig_bits + 3;
2149 fn max_exp(ex_bits sig_bits : int) : int
2151 if ex_bits > 19 then
2153 //return min_exp(ex_bits, sig_bits) + (1 shl ex_bits) - 1;
2154 return (1 shl ex_bits - 1) - sig_bits + 1;
2157 fn infinity_sig(ex_bits sig_bits : int) : floating_base
2159 var one : sig_type := 1;
2160 return one shl sig_bits - 1;
2163 fn pack(ex_bits sig_bits : int, neg : bool, e : int, s : sig_type) : floating_base
2165 //eval debug("pack: " + ntos_base(e, 16) + ", " + ntos_base(s, 16) + ", " + ntos(select(neg, 0, 1)));
2166 var min_e := min_exp(ex_bits, sig_bits);
2170 var sb : int := (bsr s) + 1;
2171 if sb < sig_bits then [
2172 s shl= sig_bits - sb;
2176 if e + sb - sig_bits < min_e then [
2177 sb += min_e - (e + sb - sig_bits);
2179 var one : sig_type := 1;
2180 var rnd := s and (one shl sb - sig_bits) - 1;
2181 var bnd := one shl sb - sig_bits shr 1;
2182 s shr= sb - sig_bits;
2184 if bnd <> 0, rnd > bnd or rnd = bnd and s bt 0 then [
2186 var nsb : int := (bsr s) + 1;
2187 if nsb > sig_bits then [
2192 if e >= max_exp(ex_bits, sig_bits) then [
2193 e := max_exp(ex_bits, sig_bits);
2194 s := infinity_sig(ex_bits, sig_bits);
2199 var ee : sig_type := e;
2200 s or= ee shl sig_bits + 1;
2201 //eval debug("result: " + ntos_base(s and #fffffffff, 16));
2205 fn unpack(ex_bits sig_bits : int, f : floating_base) : (bool, int, sig_type)
2207 //eval debug("unpack: " + ntos_base(f and #fffffffff, 16));
2208 var neg := f bt sig_bits;
2209 var e : int := f shr sig_bits + 1;
2210 var one : sig_type := 1;
2211 var s : sig_type := f and (one shl sig_bits) - 1;
2212 //eval debug("result: " + ntos_base(e, 16) + ", " + ntos_base(s, 16) + ", " + ntos(select(neg, 0, 1)));
2216 fn floating_zero(ex_bits sig_bits : int) : floating_base
2218 //eval debug("zero");
2219 return pack(ex_bits, sig_bits, false, 0, 0);
2222 fn floating_one(ex_bits sig_bits : int) : floating_base
2224 //eval debug("one");
2225 return pack(ex_bits, sig_bits, false, 0, 1);
2228 fn floating_neg(ex_bits sig_bits : int, x1 : floating_base) : floating_base
2230 return x1 btc sig_bits;
2233 fn floating_add(ex_bits sig_bits : int, x1 x2 : floating_base) : floating_base
2235 var neg1, e1, s1 := unpack(ex_bits, sig_bits, x1);
2236 var neg2, e2, s2 := unpack(ex_bits, sig_bits, x2);
2237 if e1 > e2 or (e1 = e2 and s1 > s2) then [
2238 neg1, neg2 := neg2, neg1;
2242 if e2 = max_exp(ex_bits, sig_bits) then [
2243 if e1 = max_exp(ex_bits, sig_bits), neg1 <> neg2 then
2244 abort exception_make(floating_base, ec_sync, error_nan, 0, true);
2245 ] else if e2 - e1 <= sig_bits + 1 then [
2248 if neg1 <> neg2 then [
2256 return pack(ex_bits, sig_bits, neg2, e2, s2);
2259 fn floating_subtract(ex_bits sig_bits : int, x1 x2 : floating_base) : floating_base
2261 return floating_add(ex_bits, sig_bits, x1, floating_neg(ex_bits, sig_bits, x2));
2264 fn floating_multiply(ex_bits sig_bits : int, x1 x2 : floating_base) : floating_base
2266 var neg1, e1, s1 := unpack(ex_bits, sig_bits, x1);
2267 var neg2, e2, s2 := unpack(ex_bits, sig_bits, x2);
2268 if e1 = max_exp(ex_bits, sig_bits) then [
2270 abort exception_make(floating_base, ec_sync, error_nan, 0, true);
2271 return pack(ex_bits, sig_bits, neg1 xor neg2, e1, s1);
2273 if e2 = max_exp(ex_bits, sig_bits) then [
2275 abort exception_make(floating_base, ec_sync, error_nan, 0, true);
2276 return pack(ex_bits, sig_bits, neg1 xor neg2, e2, s2);
2280 return pack(ex_bits, sig_bits, neg1 xor neg2, e1, s1);
2283 fn floating_recip(ex_bits sig_bits : int, x1 : floating_base) : floating_base
2285 return floating_divide(ex_bits, sig_bits, floating_one(ex_bits, sig_bits), x1);
2288 fn floating_divide(ex_bits sig_bits : int, x1 x2 : floating_base) : floating_base
2290 var neg1, e1, s1 := unpack(ex_bits, sig_bits, x1);
2291 var neg2, e2, s2 := unpack(ex_bits, sig_bits, x2);
2292 if e1 = max_exp(ex_bits, sig_bits) then [
2293 if e2 = max_exp(ex_bits, sig_bits) then
2294 abort exception_make(floating_base, ec_sync, error_nan, 0, true);
2295 return pack(ex_bits, sig_bits, neg1 xor neg2, e1, s1);
2297 if e2 = max_exp(ex_bits, sig_bits) then [
2298 return pack(ex_bits, sig_bits, neg1 xor neg2, 0, 0);
2302 abort exception_make(floating_base, ec_sync, error_nan, 0, true);
2303 return pack(ex_bits, sig_bits, neg1 xor neg2, max_exp(ex_bits, sig_bits), infinity_sig(ex_bits, sig_bits));
2305 s1 shl= sig_bits * 3;
2309 return pack(ex_bits, sig_bits, neg1 xor neg2, e1, s1);
2312 fn floating_next_number(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2314 var neg1, e1, s1 := unpack(ex_bits, sig_bits, x1);
2316 return pack(ex_bits, sig_bits, false, e1, 1);
2317 var s2 := s1 + select(neg1, 1, -1);
2318 if s2 < s1 and s1 = infinity_sig(ex_bits, sig_bits) then [
2319 s2 := s2 shl 1 or 1;
2322 var x2 := pack(ex_bits, sig_bits, neg1, e1, s2);
2324 return pack(ex_bits, sig_bits, neg1, e1, s2 + select(neg1, 1, -1));
2328 fn floating_prev_number(const ex_bits sig_bits : int, x1 : floating(ex_bits, sig_bits)) : floating(ex_bits, sig_bits)
2330 var neg1, e1, s1 := unpack(ex_bits, sig_bits, x1);
2332 return pack(ex_bits, sig_bits, true, e1, 1);
2333 var s2 := s1 + select(neg1, -1, 1);
2334 if s2 < s1 and s1 = infinity_sig(ex_bits, sig_bits) then [
2335 s2 := s2 shl 1 or 1;
2338 var x2 := pack(ex_bits, sig_bits, neg1, e1, s2);
2340 return pack(ex_bits, sig_bits, neg1, e1, s2 + select(neg1, -1, 1));
2344 fn floating_is_negative(ex_bits sig_bits : int, x1 : floating_base) : bool
2346 return x1 bt sig_bits;
2349 fn floating_is_infinity(ex_bits sig_bits : int, x1 : floating_base) : bool
2351 var neg1, e1, s1 := unpack(ex_bits, sig_bits, x1);
2352 return e1 = max_exp(ex_bits, sig_bits);
2355 fn floating_equal(ex_bits sig_bits : int, x1 x2 : floating_base) : bool
2357 var neg1, e1, s1 := unpack(ex_bits, sig_bits, x1);
2358 var neg2, e2, s2 := unpack(ex_bits, sig_bits, x2);
2359 if s1 = 0, s2 = 0 then
2364 fn floating_less(ex_bits sig_bits : int, x1 x2 : floating_base) : bool
2366 var neg1, e1, s1 := unpack(ex_bits, sig_bits, x1);
2367 var neg2, e2, s2 := unpack(ex_bits, sig_bits, x2);
2368 if s1 = 0, s2 = 0 then
2370 if neg1 <> neg2 then
2373 e1, e2, s1, s2 := e2, e1, s2, s1;
2379 fn floating_to_int(ex_bits sig_bits : int, x1 : floating_base) : int
2381 var neg1, e1, s1 := unpack(ex_bits, sig_bits, x1);
2382 if e1 = max_exp(ex_bits, sig_bits) then
2383 abort exception_make(int, ec_sync, error_infinity, 0, true);
2390 //eval debug("to_int result: " + ntos(s1));
2394 fn floating_from_int(ex_bits sig_bits : int, i1 : int) : floating_base
2401 return pack(ex_bits, sig_bits, neg, 0, i1);
2404 fn floating_to_rational(const ex_bits sig_bits : int, x1 : floating_base) : rational
2406 return real_to_rational(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1);
2409 fn floating_from_rational(const ex_bits sig_bits : int, i1 : rational) : floating_base
2411 return rational_to_real(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), i1);
2414 fn floating_to_bytes(const ex_bits sig_bits : int, x1 : floating_base) : bytes
2416 return real_to_bytes(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1);
2419 fn floating_to_bytes_base_precision(const ex_bits sig_bits : int, x1 : floating_base, b : int, digits : int) : bytes
2421 return real_to_bytes_base_precision(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), x1, b, digits);
2424 fn floating_from_bytes(const ex_bits sig_bits : int, a1 : bytes) : floating_base
2426 return bytes_to_real(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), a1);
2429 fn floating_from_bytes_base(const ex_bits sig_bits : int, a1 : bytes, b : int) : floating_base
2431 return bytes_to_real_base(floating(ex_bits, sig_bits), instance_real_number_floating(ex_bits, sig_bits), a1, b);
2434 implicit fn instance_real_number_floating~inline(const ex_bits sig_bits : int) : class_real_number(floating(ex_bits, sig_bits)) :=
2435 class_real_number(floating(ex_bits, sig_bits)).[
2436 add : floating_add(ex_bits, sig_bits,,),
2437 zero : floating_zero(ex_bits, sig_bits),
2438 neg : floating_neg(ex_bits, sig_bits,),
2439 subtract : floating_subtract(ex_bits, sig_bits,,),
2440 multiply : floating_multiply(ex_bits, sig_bits,,),
2441 one : floating_one(ex_bits, sig_bits),
2442 recip : floating_recip(ex_bits, sig_bits,),
2443 divide : floating_divide(ex_bits, sig_bits,,),
2444 modulo : floating_modulo(ex_bits, sig_bits,,),
2445 power : floating_power(ex_bits, sig_bits,,),
2446 ldexp : floating_ldexp(ex_bits, sig_bits,,),
2447 atan2 : floating_atan2(ex_bits, sig_bits,,),
2448 pi : floating_pi~lazy(ex_bits, sig_bits),
2449 sqrt : floating_sqrt(ex_bits, sig_bits,),
2450 cbrt : floating_cbrt(ex_bits, sig_bits,),
2451 sin : floating_sin(ex_bits, sig_bits,),
2452 cos : floating_cos(ex_bits, sig_bits,),
2453 tan : floating_tan(ex_bits, sig_bits,),
2454 asin : floating_asin(ex_bits, sig_bits,),
2455 acos : floating_acos(ex_bits, sig_bits,),
2456 atan : floating_atan(ex_bits, sig_bits,),
2457 sinh : floating_sinh(ex_bits, sig_bits,),
2458 cosh : floating_cosh(ex_bits, sig_bits,),
2459 tanh : floating_tanh(ex_bits, sig_bits,),
2460 asinh : floating_asinh(ex_bits, sig_bits,),
2461 acosh : floating_acosh(ex_bits, sig_bits,),
2462 atanh : floating_atanh(ex_bits, sig_bits,),
2463 exp2 : floating_exp2(ex_bits, sig_bits,),
2464 exp : floating_exp(ex_bits, sig_bits,),
2465 exp10 : floating_exp10(ex_bits, sig_bits,),
2466 log2 : floating_log2(ex_bits, sig_bits,),
2467 log : floating_log(ex_bits, sig_bits,),
2468 log10 : floating_log10(ex_bits, sig_bits,),
2469 round : floating_round(ex_bits, sig_bits,),
2470 ceil : floating_ceil(ex_bits, sig_bits,),
2471 floor : floating_floor(ex_bits, sig_bits,),
2472 trunc : floating_trunc(ex_bits, sig_bits,),
2473 fract : floating_fract(ex_bits, sig_bits,),
2474 mantissa : floating_mantissa(ex_bits, sig_bits,),
2475 exponent : floating_exponent(ex_bits, sig_bits,),
2476 next_number : floating_next_number(ex_bits, sig_bits,),
2477 prev_number : floating_prev_number(ex_bits, sig_bits,),
2478 is_negative : floating_is_negative(ex_bits, sig_bits,),
2479 is_infinity : floating_is_infinity(ex_bits, sig_bits,),
2480 equal : floating_equal(ex_bits, sig_bits,,),
2481 less : floating_less(ex_bits, sig_bits,,),
2482 to_int : floating_to_int(ex_bits, sig_bits,),
2483 from_int : floating_from_int(ex_bits, sig_bits,),
2484 to_rational : floating_to_rational(ex_bits, sig_bits,),
2485 from_rational : floating_from_rational(ex_bits, sig_bits,),
2486 to_bytes : floating_to_bytes(ex_bits, sig_bits,),
2487 to_bytes_base_precision : floating_to_bytes_base_precision(ex_bits, sig_bits,,,),
2488 from_bytes : floating_from_bytes(ex_bits, sig_bits,),
2489 from_bytes_base : floating_from_bytes_base(ex_bits, sig_bits,,),
2492 {---------------------
2493 - RATIONAL INSTANCE -
2494 ---------------------}
2496 implicit fn instance_real_number_rational~inline : class_real_number(rational) :=
2497 class_real_number(rational).[
2499 zero : rational_zero,
2501 subtract : rational_subtract,
2502 multiply : rational_multiply,
2504 recip : rational_recip,
2505 divide : rational_divide,
2506 modulo : rational_modulo,
2507 power : rational_power,
2508 ldexp : rational_ldexp,
2509 atan2 : rational_atan2,
2510 pi : rational_pi~lazy,
2511 sqrt : rational_sqrt,
2512 cbrt : rational_cbrt,
2516 asin : rational_asin,
2517 acos : rational_acos,
2518 atan : rational_atan,
2519 sinh : rational_sinh,
2520 cosh : rational_cosh,
2521 tanh : rational_tanh,
2522 asinh : rational_asinh,
2523 acosh : rational_acosh,
2524 atanh : rational_atanh,
2525 exp2 : rational_exp2,
2527 exp10 : rational_exp10,
2528 log2 : rational_log2,
2530 log10 : rational_log10,
2531 round : rational_round,
2532 ceil : rational_ceil,
2533 floor : rational_floor,
2534 trunc : rational_trunc,
2535 fract : rational_fract,
2536 mantissa : rational_mantissa,
2537 exponent : rational_exponent,
2538 next_number : rational_next_number,
2539 prev_number : rational_prev_number,
2540 is_negative : rational_is_negative,
2541 is_infinity : rational_is_infinity,
2542 equal : rational_equal,
2543 less : rational_less,
2544 to_int : rational_to_int,
2545 from_int : rational_from_int,
2546 to_rational : identity(rational,),
2547 from_rational : identity(rational,),
2548 to_bytes : rational_to_bytes,
2549 to_bytes_base_precision : rational_to_bytes_base_precision,
2550 from_bytes : rational_from_bytes,
2551 from_bytes_base : rational_from_bytes_base,
2554 type fixed_point(base digits : int) := fp_type;
2556 implicit fn instance_real_number_fixed_point~inline(const base digits : int) : class_real_number(fixed_point(base, digits)) :=
2557 class_real_number(fixed_point(base, digits)).[
2558 add : fixed_point_add(base, digits,,),
2559 zero : fixed_point_zero(base, digits),
2560 neg : fixed_point_neg(base, digits,),
2561 subtract : fixed_point_subtract(base, digits,,),
2562 multiply : fixed_point_multiply(base, digits,,),
2563 one : fixed_point_one(base, digits),
2564 recip : fixed_point_recip(base, digits,),
2565 divide : fixed_point_divide(base, digits,,),
2566 modulo : fixed_point_modulo(base, digits,,),
2567 power : fixed_point_power(base, digits,,),
2568 ldexp : fixed_point_ldexp(base, digits,,),
2569 atan2 : fixed_point_atan2(base, digits,,),
2570 pi : fixed_point_pi~lazy(base, digits),
2571 sqrt : fixed_point_sqrt(base, digits,),
2572 cbrt : fixed_point_cbrt(base, digits,),
2573 sin : fixed_point_sin(base, digits,),
2574 cos : fixed_point_cos(base, digits,),
2575 tan : fixed_point_tan(base, digits,),
2576 asin : fixed_point_asin(base, digits,),
2577 acos : fixed_point_acos(base, digits,),
2578 atan : fixed_point_atan(base, digits,),
2579 sinh : fixed_point_sinh(base, digits,),
2580 cosh : fixed_point_cosh(base, digits,),
2581 tanh : fixed_point_tanh(base, digits,),
2582 asinh : fixed_point_asinh(base, digits,),
2583 acosh : fixed_point_acosh(base, digits,),
2584 atanh : fixed_point_atanh(base, digits,),
2585 exp2 : fixed_point_exp2(base, digits,),
2586 exp : fixed_point_exp(base, digits,),
2587 exp10 : fixed_point_exp10(base, digits,),
2588 log2 : fixed_point_log2(base, digits,),
2589 log : fixed_point_log(base, digits,),
2590 log10 : fixed_point_log10(base, digits,),
2591 round : fixed_point_round(base, digits,),
2592 ceil : fixed_point_ceil(base, digits,),
2593 floor : fixed_point_floor(base, digits,),
2594 trunc : fixed_point_trunc(base, digits,),
2595 fract : fixed_point_fract(base, digits,),
2596 mantissa : fixed_point_mantissa(base, digits,),
2597 exponent : fixed_point_exponent(base, digits,),
2598 next_number : fixed_point_next_number(base, digits,),
2599 prev_number : fixed_point_prev_number(base, digits,),
2600 is_negative : fixed_point_is_negative(base, digits,),
2601 is_infinity : fixed_point_is_infinity(base, digits,),
2602 equal : fixed_point_equal(base, digits,,),
2603 less : fixed_point_less(base, digits,,),
2604 to_int : fixed_point_to_int(base, digits,),
2605 from_int : fixed_point_from_int(base, digits,),
2606 to_rational :fixed_point_to_rational(base, digits,),
2607 from_rational :fixed_point_from_rational(base, digits,),
2608 to_bytes : fixed_point_to_bytes(base, digits,),
2609 to_bytes_base_precision : fixed_point_to_bytes_base_precision(base, digits,,,),
2610 from_bytes : fixed_point_from_bytes(base, digits,),
2611 from_bytes_base : fixed_point_from_bytes_base(base, digits,,),
2618 operator prefix + 1000 ~inline (t : type, c : class_group(t), val : t) : t := val;
2619 operator prefix - 1000 ~inline (t : type, c : class_group(t), val : t) : t := c.neg(val);
2620 operator * 2000 ~inline (t : type, c : class_unit_ring(t), val1 val2 : t) : t := c.multiply(val1, val2);
2621 operator / 2000 ~inline (t : type, c : class_division_ring(t), val1 val2 : t) : t := c.divide(val1, val2);
2622 operator div 2000 ~inline (t : type, c : class_integer_number(t), val1 val2 : t) : t := c.div(val1, val2);
2623 operator mod 2000 ~inline (t : type, c : class_integer_number(t), val1 val2 : t) : t := c.mod(val1, val2);
2624 operator + 3000 ~inline (t : type, c : class_magma(t), val1 val2 : t) : t := c.add(val1, val2);
2625 operator - 3000 ~inline (t : type, c : class_group(t), val1 val2 : t) : t := c.subtract(val1, val2);
2626 operator shl 4000 ~inline (t : type, c : class_integer_number(t), val1 val2 : t) : t := c.shl(val1, val2);
2627 operator shr 4000 ~inline (t : type, c : class_integer_number(t), val1 val2 : t) : t := c.shr(val1, val2);
2628 operator rol 4000 ~inline (t : type, c : class_fixed_integer_number(t), val1 val2 : t) : t := c.rol(val1, val2);
2629 operator ror 4000 ~inline (t : type, c : class_fixed_integer_number(t), val1 val2 : t) : t := c.ror(val1, val2);
2630 operator bts 4000 ~inline (t : type, c : class_integer_number(t), val1 val2 : t) : t := c.bts(val1, val2);
2631 operator btr 4000 ~inline (t : type, c : class_integer_number(t), val1 val2 : t) : t := c.btr(val1, val2);
2632 operator btc 4000 ~inline (t : type, c : class_integer_number(t), val1 val2 : t) : t := c.btc(val1, val2);
2633 operator bt 4000 ~inline (t : type, c : class_integer_number(t), val1 val2 : t) : bool := c.bt(val1, val2);
2634 operator prefix bswap 4000 ~inline (t : type, c : class_fixed_integer_number(t), val : t) : t := c.bswap(val);
2635 operator prefix brev 4000 ~inline (t : type, c : class_fixed_integer_number(t), val : t) : t := c.brev(val);
2636 operator prefix bsf 4000 ~inline (t : type, c : class_integer_number(t), val : t) : t := c.bsf(val);
2637 operator prefix bsr 4000 ~inline (t : type, c : class_integer_number(t), val : t) : t := c.bsr(val);
2638 operator prefix popcnt 4000 ~inline (t : type, c : class_integer_number(t), val : t) : t := c.popcnt(val);
2640 operator prefix is_negative 5000 ~inline (t : type, c : class_real_number(t), val : t) : bool := c.is_negative(val);
2641 operator prefix is_infinity 5000 ~inline (t : type, c : class_real_number(t), val : t) : bool := c.is_infinity(val);
2642 operator prefix is_exception 5000 ~inline (t : type, v : t) : bool [ var r : bool; pcode UnaryOp Un_IsException =r 0 v; return r; ]
2643 operator prefix exception_class 5000 ~inline (t : type, v : t) : int [ var r : int; pcode UnaryOp Un_ExceptionClass =r 0 v; return r; ]
2644 operator prefix exception_type 5000 ~inline (t : type, v : t) : int [ var r : int; pcode UnaryOp Un_ExceptionType =r 0 v; return r; ]
2645 operator prefix exception_aux 5000 ~inline (t : type, v : t) : int [ var r : int; pcode UnaryOp Un_ExceptionAux =r 0 v; return r; ]
2646 operator prefix exception_string 5000 ~inline (t : type, v : t) : bytes [ var r : bytes; pcode IO IO_Exception_String 1 1 0 =r v ; return r; ]
2647 operator prefix exception_payload 5000 ~inline (t : type, v : t) : bytes [ var r : bytes; pcode IO IO_Exception_Payload 1 1 0 =r v ; return r; ]
2648 operator prefix exception_stack 5000 ~inline (t : type, v : t) : bytes [ var r : bytes; pcode IO IO_Exception_Stack 1 1 0 =r v ; return r; ]
2650 operator = 6000 ~inline (t : type, c : class_eq(t), val1 val2 : t) : bool := c.equal(val1, val2);
2651 operator <> 6000 ~inline (t : type, c : class_eq(t), val1 val2 : t) : bool := not c.equal(val1, val2);
2652 operator < 6000 ~inline (t : type, c : class_ord(t), val1 val2 : t) : bool := c.less(val1, val2);
2653 operator <= 6000 ~inline (t : type, c : class_ord(t), val1 val2 : t) : bool := not c.less(val2, val1);
2654 operator > 6000 ~inline (t : type, c : class_ord(t), val1 val2 : t) : bool := c.less(val2, val1);
2655 operator >= 6000 ~inline (t : type, c : class_ord(t), val1 val2 : t) : bool := not c.less(val1, val2);
2656 operator prefix not 7000 ~inline (t : type, c : class_logical(t), val : t) : t := c.not(val);
2657 operator and 8000 ~inline (t : type, c : class_logical(t), val1 val2 : t) : t := c.and(val1, val2);
2658 operator xor 9000 ~inline (t : type, c : class_logical(t), val1 val2 : t) : t := c.xor(val1, val2);
2659 operator or 10000 ~inline (t : type, c : class_logical(t), val1 val2 : t) : t := c.or(val1, val2);
2661 fn ipower~inline (t : type, c : class_integer_number(t), val1 val2 : t) : t := c.power(val1, val2);
2662 fn fmod~inline(t : type, c : class_real_number(t), val1 val2 : t) : t := c.modulo(val1, val2);
2663 fn power~inline(t : type, c : class_real_number(t), val1 val2 : t) : t := c.power(val1, val2);
2664 fn ldexp~inline(t : type, c : class_real_number(t), val1 val2 : t) : t := c.ldexp(val1, val2);
2665 fn atan2~inline(t : type, c : class_real_number(t), val1 val2 : t) : t := c.atan2(val1, val2);
2666 fn sqrt~inline(t : type, c : class_real_number(t), val : t) : t := c.sqrt(val);
2667 fn cbrt~inline(t : type, c : class_real_number(t), val : t) : t := c.cbrt(val);
2668 fn sin~inline(t : type, c : class_real_number(t), val : t) : t := c.sin(val);
2669 fn cos~inline(t : type, c : class_real_number(t), val : t) : t := c.cos(val);
2670 fn tan~inline(t : type, c : class_real_number(t), val : t) : t := c.tan(val);
2671 fn asin~inline(t : type, c : class_real_number(t), val : t) : t := c.asin(val);
2672 fn acos~inline(t : type, c : class_real_number(t), val : t) : t := c.acos(val);
2673 fn atan~inline(t : type, c : class_real_number(t), val : t) : t := c.atan(val);
2674 fn sinh~inline(t : type, c : class_real_number(t), val : t) : t := c.sinh(val);
2675 fn cosh~inline(t : type, c : class_real_number(t), val : t) : t := c.cosh(val);
2676 fn tanh~inline(t : type, c : class_real_number(t), val : t) : t := c.tanh(val);
2677 fn asinh~inline(t : type, c : class_real_number(t), val : t) : t := c.asinh(val);
2678 fn acosh~inline(t : type, c : class_real_number(t), val : t) : t := c.acosh(val);
2679 fn atanh~inline(t : type, c : class_real_number(t), val : t) : t := c.atanh(val);
2680 fn exp2~inline(t : type, c : class_real_number(t), val : t) : t := c.exp2(val);
2681 fn exp~inline(t : type, c : class_real_number(t), val : t) : t := c.exp(val);
2682 fn exp10~inline(t : type, c : class_real_number(t), val : t) : t := c.exp10(val);
2683 fn log2~inline(t : type, c : class_real_number(t), val : t) : t := c.log2(val);
2684 fn log~inline(t : type, c : class_real_number(t), val : t) : t := c.log(val);
2685 fn log10~inline(t : type, c : class_real_number(t), val : t) : t := c.log10(val);
2686 fn round~inline(t : type, c : class_real_number(t), val : t) : t := c.round(val);
2687 fn ceil~inline(t : type, c : class_real_number(t), val : t) : t := c.ceil(val);
2688 fn floor~inline(t : type, c : class_real_number(t), val : t) : t := c.floor(val);
2689 fn trunc~inline(t : type, c : class_real_number(t), val : t) : t := c.trunc(val);
2690 fn fract~inline(t : type, c : class_real_number(t), val : t) : t := c.fract(val);
2691 fn mantissa~inline(t : type, c : class_real_number(t), val : t) : t := c.mantissa(val);
2692 fn exponent~inline(t : type, c : class_real_number(t), val : t) : t := c.exponent(val);
2693 fn next_number~inline(t : type, c : class_real_number(t), val : t) : t := c.next_number(val);
2694 fn prev_number~inline(t : type, c : class_real_number(t), val : t) : t := c.prev_number(val);
2696 conversion fn integer_number_to_integer_number~inline(t1 : type, c1 : class_integer_number(t1), t2 : type, c2 : class_integer_number(t2), val : t1) : t2 := c2.from_int(c1.to_int(val));
2697 conversion fn integer_number_to_real_number~inline(t1 : type, c1 : class_integer_number(t1), t2 : type, c2 : class_real_number(t2), val : t1) : t2 := c2.from_int(c1.to_int(val));
2698 conversion fn real_number_to_integer_number~inline(t1 : type, c1 : class_real_number(t1), t2 : type, c2 : class_integer_number(t2), val : t1) : t2 := c2.from_int(c1.to_int(val));
2699 conversion fn real_number_to_real_number~inline(t1 : type, c1 : class_real_number(t1), t2 : type, c2 : class_real_number(t2), val : t1) : t2 := c2.from_rational(c1.to_rational(val));
2705 fn debug(m : bytes) : unit_type
2708 pcode IO IO_Debug 1 1 1 =b m 0;
2712 fn internal(m : bytes) : unit_type
2715 pcode IO IO_Debug 1 1 1 =b m 1;
2719 fn stop(m : bytes) : unit_type
2722 pcode IO IO_Debug 1 1 1 =b m 2;
2726 fn report_memory_summary(m : bytes) : unit_type
2729 pcode IO IO_Debug 1 1 1 =b m 3;
2733 fn report_memory_most(m : bytes) : unit_type
2736 pcode IO IO_Debug 1 1 1 =b m 4;
2740 fn report_memory_largest(m : bytes) : unit_type
2743 pcode IO IO_Debug 1 1 1 =b m 5;
2747 fn assert~inline(v : bool, b : bytes) : unit_type
2750 return internal("assertion failure: " + b);
2754 fn stacktrace(t : type, v : t) : unit_type
2757 pcode IO IO_StackTrace 1 1 1 =b v 2;
2761 fn trace_on : unit_type
2764 pcode IO IO_TraceCtl 1 0 1 =b 1;
2768 fn trace_off : unit_type
2771 pcode IO IO_TraceCtl 1 0 1 =b 0;
2779 fn join(t : type, w1 w2 : t) : t
2781 if is_exception w1 then [
2785 if is_exception w2 then
2790 fn any~lazy(t1 t2 : type, w1 : t1, w2 : t2) : bool
2793 pcode IO IO_Any 1 2 0 =b w1 w2;
2797 fn any_list~lazy(t : type, wx : list(t)) : int
2799 if not len_greater_than(wx, 0) then
2801 var n := any_list~lazy(wx[1 .. ]);
2802 var b := any(wx[0], n);
2803 return select(b, 0, n + 1);
2806 fn is_ready(t : type, v : t) : bool
2808 return not any(v, unit_value);
2811 fn never(t : type) : t
2814 pcode IO IO_Never 1 0 0 =w;
2818 fn fork(t : type, w : t) : (t, t)
2821 pcode IO IO_Fork 2 1 0 =w1 =w2 w;
2829 fn len~inline(t : type, a : list(t)) : int
2832 pcode Array_Len =l a 0;
2836 fn len_at_least~inline(t : type, a : list(t), l : int) : bool
2838 return len_greater_than(t, a, l - 1);
2841 fn len_greater_than~inline(t : type, a : list(t), l : int) : bool
2844 pcode Array_Len_Greater_Than =r a l 0;
2848 fn empty~inline(t : type) : list(t) := list(t).[];
2850 fn fill~inline(t : type, const x : t, const n : int) : list(t)
2853 pcode Array_Fill =l Undetermined 0 x n;
2857 fn sparse~inline(t : type, const x : t, const n : int) : list(t)
2860 pcode Array_Fill =l Undetermined Flag_Array_Fill_Sparse x n;
2864 fn infinite_internal(t : type, x : t, step : int) : list(t)
2866 return sparse(x, step) + infinite_internal~lazy(t, x, step shl bsr step);
2869 fn infinite(t : type, x : t) : list(t)
2871 return infinite_internal(t, x, #40000000);
2874 fn infinite_repeat(t : type, x : list(t)) : list(t)
2876 return x + infinite_repeat~lazy(x);
2879 fn uninitialized(t : type) : t
2881 return exception_make(t, ec_sync, error_array_entry_not_initialized, 0, false);
2884 fn uninitialized_record(t : type) : t
2886 return exception_make(t, ec_sync, error_record_field_not_initialized, 0, false);
2889 fn infinite_uninitialized(t : type) : list(t)
2891 return infinite(uninitialized(t));
2894 fn is_uninitialized(t : type, v : t) : bool
2896 if is_exception v then [
2897 if exception_class v = ec_sync and exception_type v = error_array_entry_not_initialized then
2904 fn is_uninitialized_record(t : type, v : t) : bool
2906 if is_exception v then [
2907 if exception_class v = ec_sync and exception_type v = error_record_field_not_initialized then
2914 fn list_search(t : type, implicit c : class_eq(t), x : list(t), v : t) : int
2917 while len_greater_than(x, i) do [
2925 fn list_search_fn(t : type, x : list(t), f : fn(t) : bool) : int
2928 while len_greater_than(x, i) do [
2936 fn list_search_backwards(t : type, implicit c : class_eq(t), x : list(t), v : t) : int
2938 var i := len(x) - 1;
2947 fn list_search_backwards_fn(t : type, x : list(t), f : fn(t) : bool) : int
2949 var i := len(x) - 1;
2958 fn list_search_substring(t : type, implicit c : class_eq(t), x v : list(t)) : int
2962 while len_at_least(x, i + lv) do [
2963 for j := 0 to lv do [
2964 if x[i + j] <> v[j] then
2974 fn list_replace_substring(t : type, implicit c : class_eq(t), x v r : list(t)) : list(t)
2977 var len_v := len(v);
2978 var res := empty(t);
2980 var s := list_search_substring(x, v);
2985 x := x[s + len_v .. ];
2990 return res + list_replace_substring~lazy(x, v, r);
2993 fn list_left_pad(t : type, x : list(t), width : int, padding : t) : list(t)
2995 if len(x) < width then
2996 x := fill(padding, width - len(x)) + x;
3000 fn list_right_pad(t : type, x : list(t), width : int, padding : t) : list(t)
3002 if len(x) < width then
3003 x += fill(padding, width - len(x));
3007 fn list_repeat(t : type, x : list(t), num : int) : list(t)
3013 var l := min(num, step);
3018 return r + list_repeat~lazy(x, num - l);
3021 fn list_begins_with(t : type, implicit c : class_eq(t), x y : list(t)) : bool
3024 if not len_at_least(x, ly) then
3026 return x[ .. ly] = y;
3029 fn list_ends_with(t : type, implicit c : class_eq(t), x y : list(t)) : bool
3035 for i := 0 to ly do [
3036 if x[lx - ly + i] <> y[i] then
3042 fn list_break(t : type, implicit c : class_eq(t), l : list(t), bnd : t) : list(list(t))
3045 while len_greater_than(l, i) do [
3047 return [ l[ .. i ] ] + list_break~lazy(l[ i + 1 .. ], bnd);
3052 return empty(list(t));
3055 fn list_break_to_lines(b : bytes) : list(bytes)
3058 while len_greater_than(b, i) do [
3059 if b[i] = 13, len_greater_than(b, i + 1), b[i + 1] = 10 then [
3060 return [ b[ .. i ] ] + list_break_to_lines~lazy(b[ i + 2 .. ]);
3063 return [ b[ .. i ] ] + list_break_to_lines~lazy(b[ i + 1 .. ]);
3069 return empty(bytes);
3072 fn list_string_break_to_lines(b : string) : list(string)
3075 while len_greater_than(b, i) do [
3076 if b[i] = 13, len_greater_than(b, i + 1), b[i + 1] = 10 then [
3077 return [ b[ .. i ] ] + list_string_break_to_lines~lazy(b[ i + 2 .. ]);
3080 return [ b[ .. i ] ] + list_string_break_to_lines~lazy(b[ i + 1 .. ]);
3086 return empty(string);
3089 fn is_whitespace~inline(c : byte) : bool := c = 9 or c = 10 or c = 13 or c = ' ';
3091 fn list_break_whitespace(l : bytes) : list(bytes)
3093 var r := empty(bytes);
3095 while len_greater_than(l, i) do [
3096 if is_whitespace(l[i]) then [
3101 while len_greater_than(l, j), not is_whitespace(l[j]) do
3109 fn list_join(t : type, lines : list(list(t)), bnd : list(t)) : list(t)
3113 if len_greater_than(lines, step) then
3117 var result := empty(t);
3118 for i := 0 to l do [
3123 return result + list_join~lazy(t, lines[l .. ], bnd);
3127 fn list_join_lines(lines : list(bytes)) : bytes
3129 return list_join(lines, nl);
3132 fn list_filter(t : type, lst : list(t), test : fn(t) : bool) : list(t)
3136 if len_greater_than(lst, step) then
3140 var result := empty(t);
3141 for i := 0 to l do [
3142 if test(lst[i]) then
3146 return result + list_filter~lazy(lst[l .. ], test);
3150 fn list_filter_idx_internal(t : type, idx : int, lst : list(t), test : fn(int, t) : bool) : list(t)
3154 if len_greater_than(lst, step) then
3158 var result := empty(t);
3159 for i := 0 to l do [
3160 if test(idx + i, lst[i]) then
3164 return result + list_filter_idx_internal~lazy(idx + l, lst[l .. ], test);
3168 fn list_filter_idx(t : type, lst : list(t), test : fn(int, t) : bool) : list(t)
3170 return list_filter_idx_internal(0, lst, test);
3173 fn list_fold(t u : type, ini : t, lst : list(u), fold : fn(t, u) : t) : t
3175 for val in list_consumer(lst) do
3176 ini := fold(ini, val);
3180 fn list_fold_monoid(t : type, c : class_monoid(t), lst : list(t)) : t
3182 return list_fold(c.zero, lst, c.add);
3185 fn list_map_fold_internal(t u : type, lst : list(t), mp : fn(t) : u, re : fn(u, u) : u) : u
3187 if len(lst) = 1 then
3189 var half := len(lst) shr 1;
3190 return re(list_map_fold_internal(t, u, lst[ .. half], mp, re), list_map_fold_internal(t, u, lst[half .. ], mp, re));
3193 fn list_map_fold(t u : type, ini : u, lst : list(t), mp : fn(t) : u, re : fn(u, u) : u) : u
3195 if len(lst) = 0 then
3197 return re(ini, list_map_fold_internal(t, u, lst, mp, re));
3200 fn list_map_fold_monoid(t u : type, c : class_monoid(u), lst : list(t), mp : fn(t) : u) : u
3202 return list_map_fold(c.zero, lst, mp, c.add);
3205 fn list_reverse(t : type, l : list(t)) : list(t)
3208 for i := 0 to ln div 2 do
3209 l[i], l[ln - 1 - i] := l[ln - 1 - i], l[i];
3213 fn heap_left~inline(i : int) : int := i + i + 1;
3214 fn heap_right~inline(i : int) : int := i + i + 2;
3215 fn heap_parent~inline(i : int) : int := (i - 1) shr 1;
3217 fn list_sort(t : type, implicit c : class_ord(t), l : list(t)) : list(t)
3221 for i := 1 to n do [
3224 while j > 0, p > l[heap_parent(j)] do [
3225 l[j] := l[heap_parent(j)];
3226 j := heap_parent(j);
3238 if heap_left(j) < i, l[heap_left(j)] > p then
3240 if heap_right(j) < i, l[heap_right(j)] > p then
3244 if heap_right(j) < i, l[heap_left(j)] < l[heap_right(j)] then [
3245 l[j] := l[heap_right(j)];
3248 l[j] := l[heap_left(j)];
3261 fn list_flatten~inline(t : type, a : list(t)) : list(t)
3264 pcode Array_Flatten =l 0 a;
3271 var os := sysprop(SystemProperty_OS);
3272 if os = SystemProperty_OS_DOS or
3273 os = SystemProperty_OS_OS2 or
3274 os = SystemProperty_OS_Windows then
3275 return bytes.[ 13, 10 ];
3276 return bytes.[ 10 ];
3283 fn tuple2_equal(t1 t2 : type, implicit c1 : class_eq(t1), implicit c2 : class_eq(t2), l1 l2 : tuple2(t1, t2)) : bool
3285 return l1.v1 = l2.v1 and l1.v2 = l2.v2;
3287 fn tuple2_less(t1 t2 : type, implicit c1 : class_ord(t1), implicit c2 : class_ord(t2), l1 l2 : tuple2(t1, t2)) : bool
3289 if l1.v1 < l2.v1 then return true;
3290 if l1.v1 > l2.v1 then return false;
3291 if l1.v2 < l2.v2 then return true;
3292 if l1.v2 > l2.v2 then return false;
3295 implicit fn inherit_eq_tuple2~inline(t1 t2 : type, c1 : class_eq(t1), c2 : class_eq(t2)) : class_eq(tuple2(t1, t2)) :=
3296 class_eq(tuple2(t1, t2)).[
3297 equal : tuple2_equal(t1, t2, c1, c2,,),
3299 implicit fn inherit_ord_tuple2~inline(t1 t2 : type, c1 : class_ord(t1), c2 : class_ord(t2)) : class_ord(tuple2(t1, t2)) :=
3300 class_ord(tuple2(t1, t2)).[
3301 equal : tuple2_equal(t1, t2, inherit_eq_ord(c1), inherit_eq_ord(c2),,),
3302 less : tuple2_less(t1, t2, c1, c2,,),
3305 fn tuple3_equal(t1 t2 t3 : type, implicit c1 : class_eq(t1), implicit c2 : class_eq(t2), implicit c3 : class_eq(t3), l1 l2 : tuple3(t1, t2, t3)) : bool
3307 return l1.v1 = l2.v1 and l1.v2 = l2.v2 and l1.v3 = l2.v3;
3309 fn tuple3_less(t1 t2 t3 : type, implicit c1 : class_ord(t1), implicit c2 : class_ord(t2), implicit c3 : class_ord(t3), l1 l2 : tuple3(t1, t2, t3)) : bool
3311 if l1.v1 < l2.v1 then return true;
3312 if l1.v1 > l2.v1 then return false;
3313 if l1.v2 < l2.v2 then return true;
3314 if l1.v2 > l2.v2 then return false;
3315 if l1.v3 < l2.v3 then return true;
3316 if l1.v3 > l2.v3 then return false;
3319 implicit fn inherit_eq_tuple3~inline(t1 t2 t3 : type, c1 : class_eq(t1), c2 : class_eq(t2), c3 : class_eq(t3)) : class_eq(tuple3(t1, t2, t3)) :=
3320 class_eq(tuple3(t1, t2, t3)).[
3321 equal : tuple3_equal(t1, t2, t3, c1, c2, c3,,),
3323 implicit fn inherit_ord_tuple3~inline(t1 t2 t3 : type, c1 : class_ord(t1), c2 : class_ord(t2), c3 : class_ord(t3)) : class_ord(tuple3(t1, t2, t3)) :=
3324 class_ord(tuple3(t1, t2, t3)).[
3325 equal : tuple3_equal(t1, t2, t3, inherit_eq_ord(c1), inherit_eq_ord(c2), inherit_eq_ord(c3),,),
3326 less : tuple3_less(t1, t2, t3, c1, c2, c3,,),
3329 fn tuple4_equal(t1 t2 t3 t4 : type, implicit c1 : class_eq(t1), implicit c2 : class_eq(t2), implicit c3 : class_eq(t3), implicit c4 : class_eq(t4), l1 l2 : tuple4(t1, t2, t3, t4)) : bool
3331 return l1.v1 = l2.v1 and l1.v2 = l2.v2 and l1.v3 = l2.v3 and l1.v4 = l2.v4;
3333 fn tuple4_less(t1 t2 t3 t4 : type, implicit c1 : class_ord(t1), implicit c2 : class_ord(t2), implicit c3 : class_ord(t3), implicit c4 : class_ord(t4), l1 l2 : tuple4(t1, t2, t3, t4)) : bool
3335 if l1.v1 < l2.v1 then return true;
3336 if l1.v1 > l2.v1 then return false;
3337 if l1.v2 < l2.v2 then return true;
3338 if l1.v2 > l2.v2 then return false;
3339 if l1.v3 < l2.v3 then return true;
3340 if l1.v3 > l2.v3 then return false;
3341 if l1.v4 < l2.v4 then return true;
3342 if l1.v4 > l2.v4 then return false;
3345 implicit fn inherit_eq_tuple4~inline(t1 t2 t3 t4 : type, c1 : class_eq(t1), c2 : class_eq(t2), c3 : class_eq(t3), c4 : class_eq(t4)) : class_eq(tuple4(t1, t2, t3, t4)) :=
3346 class_eq(tuple4(t1, t2, t3, t4)).[
3347 equal : tuple4_equal(t1, t2, t3, t4, c1, c2, c3, c4,,),
3349 implicit fn inherit_ord_tuple4~inline(t1 t2 t3 t4 : type, c1 : class_ord(t1), c2 : class_ord(t2), c3 : class_ord(t3), c4 : class_ord(t4)) : class_ord(tuple4(t1, t2, t3, t4)) :=
3350 class_ord(tuple4(t1, t2, t3, t4)).[
3351 equal : tuple4_equal(t1, t2, t3, t4, inherit_eq_ord(c1), inherit_eq_ord(c2), inherit_eq_ord(c3), inherit_eq_ord(c4),,),
3352 less : tuple4_less(t1, t2, t3, t4, c1, c2, c3, c4,,),
3356 fn tuple5_equal(t1 t2 t3 t4 t5 : type, implicit c1 : class_eq(t1), implicit c2 : class_eq(t2), implicit c3 : class_eq(t3), implicit c4 : class_eq(t4), implicit c5 : class_eq(t5), l1 l2 : tuple5(t1, t2, t3, t4, t5)) : bool
3358 return l1.v1 = l2.v1 and l1.v2 = l2.v2 and l1.v3 = l2.v3 and l1.v4 = l2.v4 and l1.v5 = l2.v5;
3360 fn tuple5_less(t1 t2 t3 t4 t5 : type, implicit c1 : class_ord(t1), implicit c2 : class_ord(t2), implicit c3 : class_ord(t3), implicit c4 : class_ord(t4), implicit c5 : class_ord(t5), l1 l2 : tuple5(t1, t2, t3, t4, t5)) : bool
3362 if l1.v1 < l2.v1 then return true;
3363 if l1.v1 > l2.v1 then return false;
3364 if l1.v2 < l2.v2 then return true;
3365 if l1.v2 > l2.v2 then return false;
3366 if l1.v3 < l2.v3 then return true;
3367 if l1.v3 > l2.v3 then return false;
3368 if l1.v4 < l2.v4 then return true;
3369 if l1.v4 > l2.v4 then return false;
3370 if l1.v5 < l2.v5 then return true;
3371 if l1.v5 > l2.v5 then return false;
3374 implicit fn inherit_eq_tuple5~inline(t1 t2 t3 t4 t5 : type, c1 : class_eq(t1), c2 : class_eq(t2), c3 : class_eq(t3), c4 : class_eq(t4), c5 : class_eq(t5)) : class_eq(tuple5(t1, t2, t3, t4, t5)) :=
3375 class_eq(tuple5(t1, t2, t3, t4, t5)).[
3376 equal : tuple5_equal(t1, t2, t3, t4, t5, c1, c2, c3, c4, c5,,),
3378 implicit fn inherit_ord_tuple5~inline(t1 t2 t3 t4 t5 : type, c1 : class_ord(t1), c2 : class_ord(t2), c3 : class_ord(t3), c4 : class_ord(t4), c5 : class_ord(t5)) : class_ord(tuple5(t1, t2, t3, t4, t5)) :=
3379 class_ord(tuple5(t1, t2, t3, t4, t5)).[
3380 equal : tuple5_equal(t1, t2, t3, t4, t5, inherit_eq_ord(c1), inherit_eq_ord(c2), inherit_eq_ord(c3), inherit_eq_ord(c4), inherit_eq_ord(c5),,),
3381 less : tuple5_less(t1, t2, t3, t4, t5, c1, c2, c3, c4, c5,,),
3388 fn mkmaybe~inline(t : type, v : t) : maybe(t) := maybe(t).j.(v);
3394 fn ntos_base~inline(t : type, c : class_integer_number(t), n : t, base : int) : bytes
3396 return c.to_bytes_base(n, base);
3399 fn ntos_base_precision~inlnie(t : type, c : class_real_number(t), n : t, base digits : int) : bytes
3401 return c.to_bytes_base_precision(n, base, digits);
3404 fn ntos~inline(t : type, c : class_show(t), n : t) : bytes
3406 return c.to_bytes(n);
3409 fn ston_base~inline(b : bytes, base : int) : int
3411 return instance_number_int.from_bytes_base(b, base);
3414 fn ston~inline(b : bytes) : int
3416 return instance_number_int.from_bytes(b);
3419 fn format(t : type, implicit c : class_show(t), b : bytes, a : list(t)) : bytes
3421 var r := empty(byte);
3423 for i := 0 to len(b) do [
3424 if b[i] = '%' then [
3431 if idx <> len(a) then
3432 return exception_make(bytes, ec_sync, error_invalid_operation, 0, true);
3440 fn int_to_native~inline(n : native, i : int) : bytes
3443 pcode IO IO_Int_To_Native 1 2 0 =r n i;
3447 fn native_to_int~inline(n : native, b : bytes) : int
3450 pcode IO IO_Native_To_Int 1 2 0 =r n b;
3458 fn array_size(dim : list(int)) : int
3461 for i := 0 to len(dim) do [
3463 return exception_make(int, ec_sync, error_negative_index, 0, true);
3469 fn list_to_array(t : type, const dim : list(int), v : list(t)) : array(t, dim)
3471 var prod := array_size(dim);
3472 if prod <> len(v) then
3473 return exception_make(array(t, dim), ec_sync, error_invalid_operation, 0, true);
3474 var l : array(t, dim);
3475 pcode Copy_Type_Cast =l 0 v;
3479 fn array_to_list(t : type, const dim : list(int), v : array(t, dim)) : list(t)
3482 pcode Copy_Type_Cast =l 0 v;
3486 fn array_fill~inline(t : type, const x : t, const dim : list(int)) : array(t, dim)
3488 var prod := array_size(dim);
3489 var l : array(t, dim);
3490 pcode Array_Fill =l Undetermined 0 x prod;
3494 fn array_sparse~inline(t : type, const x : t, const dim : list(int)) : array(t, dim)
3496 var prod := array_size(dim);
3497 var l : array(t, dim);
3498 pcode Array_Fill =l Undetermined Flag_Array_Fill_Sparse x prod;
3502 fn array_index(dim : list(int), idx : list(int)) : int
3504 if len(dim) <> len(idx) then
3505 return exception_make(int, ec_sync, error_invalid_operation, 0, true);
3508 for ii := 0 to l do [
3509 var i := l - 1 - ii;
3511 return exception_make(int, ec_sync, error_negative_index, 0, true);
3512 if idx[i] >= dim[i] then
3513 return exception_make(int, ec_sync, error_index_out_of_range, 0, true);
3520 fn array_read(t : type, const dim : list(int), v : array(t, dim), idx : list(int)) : t
3522 var off := array_index(dim, idx);
3523 return array_to_list(v)[off];
3526 fn array_write(t : type, const dim : list(int), v : array(t, dim), idx : list(int), val : t) : array(t, dim)
3528 var off := array_index(dim, idx);
3529 var l := array_to_list(v);
3531 v := list_to_array(dim, l);
3535 fn array_reverse(t : type, const ln : int, implicit c : class_ord(t), v : array(t, [ln])) : array(t, [ln])
3537 var l := array_to_list(v);
3538 l := list_reverse(l);
3539 return list_to_array([ln], l);
3542 fn array_sort(t : type, const ln : int, implicit c : class_ord(t), v : array(t, [ln])) : array(t, [ln])
3544 var l := array_to_list(v);
3546 return list_to_array([ln], l);
3549 fn array_flatten~inline(t : type, const dim : list(int), v : array(t, dim)) : array(t, dim)
3551 var l : array(t, dim);
3552 pcode Array_Flatten =l 0 v;
3556 type xarray(dim : list(int), t : type)
3559 pcode Array_Fixed =l t dim;
3563 {-------------------
3565 -------------------}
3570 pcode Array_Flexible =l t;