hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

arithmetic.ha (3224B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use time;
      5 
      6 // Returns true if two [[moment]]s represent the same time in the same locality,
      7 // which is to say that their [[locality]] and [[time::instant]] are both equal.
      8 // Their observed values and representations in a chronology should be the same
      9 // in all cases.
     10 //
     11 // See [[simultaneous]] to determine if two moments represent the same moment in
     12 // time regardless of locality.
     13 export fn coincident(a: *moment, b: *moment) bool = {
     14 	return a.loc == b.loc && a.sec == b.sec && a.nsec == b.nsec;
     15 };
     16 
     17 // Returns true if two [[moment]]s represent the same moment in time, regardless
     18 // of locality.
     19 //
     20 // The moments are compared as [[time::instant]]s; their observed chronological
     21 // values and representations are ignored.
     22 //
     23 // If the moments' associated [[timescale]]s are different, they will be
     24 // converted to [[tai]] instants first. Any [[discontinuity]] occurence will be
     25 // returned. If a discontinuity against TAI amongst the two timescales exist,
     26 // consider converting such instants manually.
     27 //
     28 // See [[coincident]] to determine if two [[moment]]s are equal with respect to
     29 // both time and locality.
     30 export fn simultaneous(a: *moment, b: *moment) (bool | discontinuity) = {
     31 	return 0 == compare(a, b)?;
     32 };
     33 
     34 // Compares two [[moment]]s. Returns -1 if a precedes b, 0 if a and b are
     35 // simultaneous, or +1 if b precedes a.
     36 //
     37 // The moments are compared as [[time::instant]]s; their observed chronological
     38 // values are ignored.
     39 //
     40 // If the moments' associated [[timescale]]s are different, they will be
     41 // converted to [[tai]] instants first. Any [[discontinuity]] occurence will be
     42 // returned. If a discontinuity against TAI amongst the two timescales exist,
     43 // consider converting such instants manually.
     44 export fn compare(a: *moment, b: *moment) (i8 | discontinuity) = {
     45 	const (ia, ib) = convertpair(a, b)?;
     46 	return time::compare(ia, ib);
     47 };
     48 
     49 // Returns the [[time::duration]] between two [[moment]]s, from a to b.
     50 //
     51 // The moments are compared as [[time::instant]]s; their observed chronological
     52 // values are ignored.
     53 //
     54 // If the moments' associated [[timescale]]s are different, they will be
     55 // converted to [[tai]] instants first. Any [[discontinuity]] occurence will be
     56 // returned. If a discontinuity against TAI amongst the two timescales exist,
     57 // consider converting such instants manually.
     58 export fn diff(a: *moment, b: *moment) (time::duration | discontinuity) = {
     59 	const (ia, ib) = convertpair(a, b)?;
     60 	return time::diff(ia, ib);
     61 };
     62 
     63 // Adds a [[time::duration]] to a [[moment]] with [[time::add]].
     64 export fn add(m: *moment, x: time::duration) moment = {
     65 	return new(m.loc, time::add(*(m: *time::instant), x));
     66 };
     67 
     68 fn convertpair(
     69 	a: *moment,
     70 	b: *moment,
     71 ) ((time::instant, time::instant) | discontinuity) = {
     72 	let ia = *(a: *time::instant);
     73 	let ib = *(b: *time::instant);
     74 
     75 	if (a.loc.timescale != b.loc.timescale) {
     76 		match (convert(ia, a.loc.timescale, &tai)) {
     77 		case let i: time::instant =>
     78 			ia = i;
     79 		case =>
     80 			return discontinuity;
     81 		};
     82 
     83 		match (convert(ib, b.loc.timescale, &tai)) {
     84 		case let i: time::instant =>
     85 			ib = i;
     86 		case =>
     87 			return discontinuity;
     88 		};
     89 	};
     90 
     91 	return (ia, ib);
     92 };