@forthic/interp 0.8.2 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,17 @@
1
1
  import { Module, Word } from "./module";
2
+ import { Temporal } from "temporal-polyfill";
2
3
  import { type Interpreter } from "./interpreter";
3
4
  export declare class GlobalModule extends Module {
4
5
  literal_handlers: Array<(value: any) => any>;
5
6
  constructor(interp: Interpreter);
7
+ set_interp(_interp: Interpreter): void;
6
8
  find_word(name: string): Word | null;
7
9
  find_literal_word(string: string): Word | null;
8
10
  to_bool(str_val: string): boolean | null;
9
11
  to_int(str_val: string): number | null;
10
12
  to_float(str_val: string): number | null;
11
- to_literal_date(str_val: string): Date | null;
12
- to_time(str_val: string): Date | null;
13
+ to_literal_date(str_val: string): Temporal.PlainDate | null;
14
+ to_time(str_val: string): Temporal.PlainTime | null;
13
15
  make_element_word(element_name: string): (interp: Interpreter) => Promise<void>;
14
16
  add_element_word(element_name: string): void;
15
17
  word_VARIABLES(interp: Interpreter): void;
@@ -93,7 +95,7 @@ export declare class GlobalModule extends Module {
93
95
  word_FRIDAY(interp: Interpreter): void;
94
96
  word_SATURDAY(interp: Interpreter): void;
95
97
  word_SUNDAY(interp: Interpreter): void;
96
- static get_day_this_week(day_of_week: any): Date;
98
+ static get_day_this_week(day_of_week: number, timezone: Temporal.TimeZoneLike): Temporal.PlainDate;
97
99
  word_ADD_DAYS(interp: Interpreter): void;
98
100
  word_SUBTRACT_DATES(interp: Interpreter): void;
99
101
  word_DATE_to_STR(interp: Interpreter): void;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GlobalModule = void 0;
4
4
  const module_1 = require("./module");
5
5
  const utils_1 = require("./utils");
6
+ const temporal_polyfill_1 = require("temporal-polyfill");
6
7
  const map_word_1 = require("./global_module/map_word");
7
8
  const tokenizer_1 = require("./tokenizer");
8
9
  const errors_1 = require("./errors");
@@ -210,6 +211,9 @@ class GlobalModule extends module_1.Module {
210
211
  this.add_module_word("PROFILE-END", this.word_PROFILE_END);
211
212
  this.add_module_word("PROFILE-DATA", this.word_PROFILE_DATA);
212
213
  }
214
+ set_interp(_interp) {
215
+ throw new Error("Attempt to overwrite interpreter of global module");
216
+ }
213
217
  find_word(name) {
214
218
  let result = super.find_word(name);
215
219
  if (!result)
@@ -258,9 +262,11 @@ class GlobalModule extends module_1.Module {
258
262
  const year = Number(match[1]);
259
263
  const month = Number(match[2]);
260
264
  const day = Number(match[3]);
261
- const result = new Date();
262
- result.setUTCFullYear(year, month - 1, day);
263
- result.setUTCHours(0, 0, 0, 0);
265
+ const result = temporal_polyfill_1.Temporal.PlainDate.from({
266
+ year,
267
+ month,
268
+ day,
269
+ });
264
270
  return result;
265
271
  }
266
272
  to_time(str_val) {
@@ -273,8 +279,10 @@ class GlobalModule extends module_1.Module {
273
279
  return null;
274
280
  if (minutes >= 60)
275
281
  return null;
276
- const result = new Date();
277
- result.setHours(hours, minutes, 0, 0);
282
+ const result = temporal_polyfill_1.Temporal.PlainTime.from({
283
+ hour: hours,
284
+ minute: minutes,
285
+ });
278
286
  return result;
279
287
  }
280
288
  // Convenience function to create element word handlers
@@ -1578,45 +1586,54 @@ class GlobalModule extends module_1.Module {
1578
1586
  // ( time -- time )
1579
1587
  word_AM(interp) {
1580
1588
  const time = interp.stack_pop();
1581
- if (!(time instanceof Date))
1589
+ if (!(time instanceof temporal_polyfill_1.Temporal.PlainTime))
1582
1590
  throw "AM expecting a time";
1583
1591
  let result = time;
1584
- if (time.getHours() >= 12) {
1585
- result = new Date();
1586
- result.setHours(time.getHours() - 12);
1587
- result.setMinutes(time.getMinutes());
1592
+ if (time.hour >= 12) {
1593
+ result = temporal_polyfill_1.Temporal.PlainTime.from({
1594
+ hour: time.hour - 12,
1595
+ minute: time.minute,
1596
+ });
1588
1597
  }
1589
1598
  interp.stack_push(result);
1590
1599
  }
1591
1600
  // ( time -- time )
1592
1601
  word_PM(interp) {
1593
1602
  const time = interp.stack_pop();
1594
- if (!(time instanceof Date))
1603
+ if (!(time instanceof temporal_polyfill_1.Temporal.PlainTime))
1595
1604
  throw "PM expecting a time";
1596
1605
  let result = time;
1597
- if (time.getHours() < 12) {
1598
- result = new Date();
1599
- result.setHours(time.getHours() + 12);
1600
- result.setMinutes(time.getMinutes());
1606
+ if (time.hour < 12) {
1607
+ result = temporal_polyfill_1.Temporal.PlainTime.from({
1608
+ hour: time.hour + 12,
1609
+ minute: time.minute,
1610
+ });
1601
1611
  }
1602
1612
  interp.stack_push(result);
1603
1613
  }
1604
1614
  // ( -- time )
1605
1615
  word_NOW(interp) {
1606
- const result = new Date();
1616
+ const result = temporal_polyfill_1.Temporal.Now.plainDateTimeISO(interp.get_timezone());
1607
1617
  interp.stack_push(result);
1608
1618
  }
1609
1619
  // ( item -- time )
1610
1620
  word_to_TIME(interp) {
1611
1621
  const item = interp.stack_pop();
1612
1622
  let result;
1613
- if (item instanceof Date) {
1623
+ if (item instanceof temporal_polyfill_1.Temporal.PlainTime) {
1614
1624
  result = item;
1615
1625
  }
1626
+ else if (item instanceof temporal_polyfill_1.Temporal.PlainDateTime) {
1627
+ result = temporal_polyfill_1.Temporal.PlainTime.from(item);
1628
+ }
1616
1629
  else {
1617
1630
  // NB: We need a date in order for Date.parse to succeed. Also assuming str is a time
1618
1631
  const date_string = "Jan 1, 2000 " + item;
1619
- result = new Date(Date.parse(date_string));
1632
+ const date = new Date(Date.parse(date_string));
1633
+ result = temporal_polyfill_1.Temporal.PlainTime.from({
1634
+ hour: date.getHours(),
1635
+ minute: date.getMinutes(),
1636
+ });
1620
1637
  }
1621
1638
  interp.stack_push(result);
1622
1639
  }
@@ -1634,64 +1651,57 @@ class GlobalModule extends module_1.Module {
1634
1651
  }
1635
1652
  // ( -- date )
1636
1653
  word_TODAY(interp) {
1637
- const result = new Date();
1638
- result.setHours(0, 0, 0, 0);
1654
+ const result = temporal_polyfill_1.Temporal.Now.plainDateISO(interp.get_timezone());
1639
1655
  interp.stack_push(result);
1640
1656
  }
1641
1657
  // ( -- date )
1642
1658
  word_MONDAY(interp) {
1643
- interp.stack_push(GlobalModule.get_day_this_week(0));
1659
+ interp.stack_push(GlobalModule.get_day_this_week(0, interp.get_timezone()));
1644
1660
  }
1645
1661
  // ( -- date )
1646
1662
  word_TUESDAY(interp) {
1647
- interp.stack_push(GlobalModule.get_day_this_week(1));
1663
+ interp.stack_push(GlobalModule.get_day_this_week(1, interp.get_timezone()));
1648
1664
  }
1649
1665
  // ( -- date )
1650
1666
  word_WEDNESDAY(interp) {
1651
- interp.stack_push(GlobalModule.get_day_this_week(2));
1667
+ interp.stack_push(GlobalModule.get_day_this_week(2, interp.get_timezone()));
1652
1668
  }
1653
1669
  // ( -- date )
1654
1670
  word_THURSDAY(interp) {
1655
- interp.stack_push(GlobalModule.get_day_this_week(3));
1671
+ interp.stack_push(GlobalModule.get_day_this_week(3, interp.get_timezone()));
1656
1672
  }
1657
1673
  // ( -- date )
1658
1674
  word_FRIDAY(interp) {
1659
- interp.stack_push(GlobalModule.get_day_this_week(4));
1675
+ interp.stack_push(GlobalModule.get_day_this_week(4, interp.get_timezone()));
1660
1676
  }
1661
1677
  // ( -- date )
1662
1678
  word_SATURDAY(interp) {
1663
- interp.stack_push(GlobalModule.get_day_this_week(5));
1679
+ interp.stack_push(GlobalModule.get_day_this_week(5, interp.get_timezone()));
1664
1680
  }
1665
1681
  // ( -- date )
1666
1682
  word_SUNDAY(interp) {
1667
- interp.stack_push(GlobalModule.get_day_this_week(6));
1668
- }
1669
- static get_day_this_week(day_of_week) {
1670
- // NOTE: Monday is start of week
1671
- function normalize_day(day) {
1672
- return day;
1673
- }
1674
- const today = new Date();
1675
- today.setHours(0, 0, 0, 0);
1676
- const delta_days = (day_of_week - normalize_day(today.getDay())) % 7;
1677
- const result = today;
1678
- result.setDate(result.getDate() + delta_days + 1);
1683
+ interp.stack_push(GlobalModule.get_day_this_week(6, interp.get_timezone()));
1684
+ }
1685
+ static get_day_this_week(day_of_week, timezone) {
1686
+ // Get plain date for day of week
1687
+ const today = temporal_polyfill_1.Temporal.Now.plainDateISO(timezone);
1688
+ const delta_days = (day_of_week - today.dayOfWeek) % 7;
1689
+ const result = today.add({ days: delta_days });
1679
1690
  return result;
1680
1691
  }
1681
1692
  // ( date num-days -- date )
1682
1693
  word_ADD_DAYS(interp) {
1683
1694
  const num_days = interp.stack_pop();
1684
1695
  const date = interp.stack_pop();
1685
- const result = new Date(date);
1686
- result.setDate(result.getDate() + num_days);
1696
+ const result = temporal_polyfill_1.Temporal.PlainDate.from(date).add({ days: num_days });
1687
1697
  interp.stack_push(result);
1688
1698
  }
1689
1699
  // ( l_date r_date -- num_days )
1690
1700
  word_SUBTRACT_DATES(interp) {
1691
- const r_date = interp.stack_pop();
1692
- const l_date = interp.stack_pop();
1693
- const ms_per_day = 1000 * 60 * 60 * 24;
1694
- const result = Math.round((l_date.getTime() - r_date.getTime()) / ms_per_day);
1701
+ const r_date = temporal_polyfill_1.Temporal.PlainDate.from(interp.stack_pop());
1702
+ const l_date = temporal_polyfill_1.Temporal.PlainDate.from(interp.stack_pop());
1703
+ // Subtract the dates and get the difference in days
1704
+ const result = r_date.until(l_date).total({ unit: "days" });
1695
1705
  interp.stack_push(result);
1696
1706
  }
1697
1707
  // ( date -- str )
@@ -1709,28 +1719,36 @@ class GlobalModule extends module_1.Module {
1709
1719
  }
1710
1720
  // ( date time -- datetime )
1711
1721
  word_DATE_TIME_to_DATETIME(interp) {
1712
- const time = interp.stack_pop();
1713
- const date = interp.stack_pop();
1714
- const dt_string = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${time.getHours()}:${time.getMinutes()}`;
1715
- const result = new Date(dt_string);
1722
+ const time = temporal_polyfill_1.Temporal.PlainTime.from(interp.stack_pop());
1723
+ const date = temporal_polyfill_1.Temporal.PlainDate.from(interp.stack_pop());
1724
+ const result = temporal_polyfill_1.Temporal.PlainDateTime.from({
1725
+ year: date.year,
1726
+ month: date.month,
1727
+ day: date.day,
1728
+ hour: time.hour,
1729
+ minute: time.minute,
1730
+ });
1716
1731
  interp.stack_push(result);
1717
1732
  }
1718
1733
  // ( datetime -- timestamp )
1719
1734
  word_DATETIME_to_TIMESTAMP(interp) {
1720
1735
  const datetime = interp.stack_pop();
1721
- const result = Math.round(datetime.getTime() / 1000);
1736
+ // Convert to ZonedDateTime
1737
+ const zonedDateTime = datetime.toZonedDateTime(interp.get_timezone());
1738
+ const result = zonedDateTime.toInstant().epochSeconds;
1722
1739
  interp.stack_push(result);
1723
1740
  }
1724
1741
  // ( timestamp -- datetime )
1725
1742
  word_TIMESTAMP_to_DATETIME(interp) {
1726
1743
  const timestamp = interp.stack_pop();
1727
- const result = new Date(timestamp * 1000);
1744
+ const result = temporal_polyfill_1.Temporal.Instant.fromEpochSeconds(timestamp).toZonedDateTime({ timeZone: interp.get_timezone(), calendar: "iso8601" });
1728
1745
  interp.stack_push(result);
1729
1746
  }
1730
1747
  // ( str -- datetime )
1731
1748
  word_STR_to_DATETIME(interp) {
1732
1749
  const s = interp.stack_pop();
1733
- const result = new Date(s);
1750
+ const date = new Date(s);
1751
+ const result = temporal_polyfill_1.Temporal.Instant.fromEpochMilliseconds(date.getTime()).toZonedDateTime({ timeZone: interp.get_timezone(), calendar: "iso8601" });
1734
1752
  interp.stack_push(result);
1735
1753
  }
1736
1754
  // ( str -- timestamp )