sval 0.4.8 → 0.5.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.
@@ -0,0 +1,21 @@
1
+ name: Coverage
2
+ on:
3
+ push:
4
+ branches:
5
+ - master
6
+ jobs:
7
+ coverage:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - name: Check out repository code
11
+ uses: actions/checkout@v3
12
+ - name: Setup node environment
13
+ uses: actions/setup-node@v3.4.1
14
+ - name: Install node modules
15
+ run: npm install
16
+ - name: Test code
17
+ run: npm test
18
+ - name: Send coverage info to Coveralls
19
+ uses: coverallsapp/github-action@1.1.3
20
+ with:
21
+ github-token: ${{ secrets.GITHUB_TOKEN }}
package/README.md CHANGED
@@ -1,8 +1,4 @@
1
- # Sval
2
-
3
- [![npm](https://img.shields.io/npm/v/sval.svg?style=flat-square)](https://www.npmjs.com/package/sval)
4
- [![travis-ci](https://img.shields.io/travis/Siubaak/sval.svg?style=flat-square)](https://travis-ci.org/Siubaak/sval)
5
- [![coveralls](https://img.shields.io/coveralls/github/Siubaak/sval.svg?style=flat-square)](https://coveralls.io/github/Siubaak/sval)
1
+ # Sval · [![npm](https://img.shields.io/npm/v/sval.svg?style=flat-square)](https://www.npmjs.com/package/sval) [![github-actions](https://img.shields.io/github/workflow/status/Siubaak/sval/Coverage.svg?style=flat-square)](https://github.com/Siubaak/sval/actions/workflows/coverage.yml) [![coveralls](https://img.shields.io/coveralls/github/Siubaak/sval.svg?style=flat-square)](https://coveralls.io/github/Siubaak/sval)
6
2
 
7
3
  A JavaScript interpreter writen in JavaScript, based on parser [Acorn](https://github.com/acornjs/acorn).
8
4
 
@@ -38,8 +34,11 @@ import Sval from 'sval'
38
34
 
39
35
  // Sval options
40
36
  const options = {
41
- // ECMA Version of the code (5 | 6 | 7 | 8 | 9 | 10 | 2015 | 2016 | 2017 | 2018 | 2019)
42
- ecmaVer: 9,
37
+ // ECMA Version of the code
38
+ // 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15
39
+ // or 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024
40
+ // or "latest"
41
+ ecmaVer: 'latest',
43
42
  // Whether the code runs in a sandbox
44
43
  sandBox: true,
45
44
  }
@@ -68,11 +67,11 @@ console.log(interpreter.exports.mod) // Get 'AllKindsOfStuffs'
68
67
 
69
68
  Sval constructor has options with two fields, **ecmaVer** and **sandBox**.
70
69
 
71
- - **ecmaVer** is the ECMAScript edition of the code. Currently, 5, 6(2015), 7(2016), 8(2017), 9(2018) and 10(2019) are supported, and the default edition is 9.
70
+ - **ecmaVer** is the ECMAScript edition of the code. Currently, 3, 5, 6(2015), 7(2016), 8(2017), 9(2018), 10(2019), 11(2020), 12(2021), 13(2022), 14(2023), 15(2024) and "latest" are supported, and the default edition is "latest".
72
71
 
73
72
  - **sandBox** is true for sandbox mode or false for invasived mode. Sandbox mode will run code in an isolated sandbox and won't pollute your global scope. Invasived mode allows you run code in the same global scope of your current environment. The default setting is true.
74
73
 
75
- Sval instance has two methods, **import** and **run**.
74
+ Sval instance has three methods, **import**, **parse** and **run**.
76
75
 
77
76
  - **import** is to import modules into your Sval instance scope, expecting a name and a module as arguments like `import(name: string, mod: any)`, or an object which contains the modules as argument like `import({ [name: string]: any })`. The modules will be automatically declared as global variables. This method is more likely to be used in sandbox mode.
78
77
 
package/dist/sval.es6.js CHANGED
@@ -383,7 +383,7 @@
383
383
  }
384
384
  }
385
385
 
386
- var version = "0.4.8";
386
+ var version = "0.5.0";
387
387
 
388
388
  const AWAIT = { RES: undefined };
389
389
  const RETURN = { RES: undefined };
@@ -733,7 +733,7 @@
733
733
  }
734
734
  }
735
735
  function AssignmentExpression(node, scope) {
736
- const value = evaluate(node.right, scope);
736
+ var _a;
737
737
  const left = node.left;
738
738
  let variable;
739
739
  if (left.type === 'Identifier') {
@@ -747,8 +747,10 @@
747
747
  variable = MemberExpression(left, scope, { getVar: true });
748
748
  }
749
749
  else {
750
+ const value = evaluate(node.right, scope);
750
751
  return pattern$3(left, scope, { feed: value });
751
752
  }
753
+ const value = evaluate(node.right, scope);
752
754
  switch (node.operator) {
753
755
  case '=':
754
756
  variable.set(value);
@@ -789,15 +791,27 @@
789
791
  case '&=':
790
792
  variable.set(variable.get() & value);
791
793
  return variable.get();
794
+ case '??=':
795
+ variable.set((_a = variable.get()) !== null && _a !== void 0 ? _a : value);
796
+ return variable.get();
797
+ case '&&=':
798
+ variable.set(variable.get() && value);
799
+ return variable.get();
800
+ case '||=':
801
+ variable.set(variable.get() || value);
802
+ return variable.get();
792
803
  default: throw new SyntaxError(`Unexpected token ${node.operator}`);
793
804
  }
794
805
  }
795
806
  function LogicalExpression(node, scope) {
807
+ var _a;
796
808
  switch (node.operator) {
797
809
  case '||':
798
810
  return (evaluate(node.left, scope)) || (evaluate(node.right, scope));
799
811
  case '&&':
800
812
  return (evaluate(node.left, scope)) && (evaluate(node.right, scope));
813
+ case '??':
814
+ return (_a = (evaluate(node.left, scope))) !== null && _a !== void 0 ? _a : (evaluate(node.right, scope));
801
815
  default:
802
816
  throw new SyntaxError(`Unexpected token ${node.operator}`);
803
817
  }
@@ -836,9 +850,15 @@
836
850
  const getter = getGetter(object, key);
837
851
  if (node.object.type === 'Super' && getter) {
838
852
  const thisObject = scope.find('this').get();
853
+ if (node.optional && thisObject == null) {
854
+ return undefined;
855
+ }
839
856
  return getter.call(thisObject);
840
857
  }
841
858
  else {
859
+ if (node.optional && object == null) {
860
+ return undefined;
861
+ }
842
862
  return object[key];
843
863
  }
844
864
  }
@@ -853,6 +873,9 @@
853
873
  let object;
854
874
  if (node.callee.type === 'MemberExpression') {
855
875
  object = MemberExpression(node.callee, scope, { getObj: true });
876
+ if (node.callee.optional && object == null) {
877
+ return undefined;
878
+ }
856
879
  let key;
857
880
  if (node.callee.computed) {
858
881
  key = evaluate(node.callee.property, scope);
@@ -867,6 +890,9 @@
867
890
  else {
868
891
  func = object[key];
869
892
  }
893
+ if (node.optional && func == null) {
894
+ return undefined;
895
+ }
870
896
  if (typeof func !== 'function') {
871
897
  throw new TypeError(`${key} is not a function`);
872
898
  }
@@ -877,6 +903,9 @@
877
903
  else {
878
904
  object = scope.find('this').get();
879
905
  func = evaluate(node.callee, scope);
906
+ if (node.optional && func == null) {
907
+ return undefined;
908
+ }
880
909
  if (typeof func !== 'function' || node.callee.type !== 'Super' && func[CLSCTOR]) {
881
910
  let name;
882
911
  if (node.callee.type === 'Identifier') {
@@ -1020,6 +1049,9 @@
1020
1049
  }
1021
1050
  function SpreadElement(node, scope) {
1022
1051
  return evaluate(node.argument, scope);
1052
+ }
1053
+ function ChainExpression(node, scope) {
1054
+ return evaluate(node.expression, scope);
1023
1055
  }
1024
1056
 
1025
1057
  var expression = /*#__PURE__*/Object.freeze({
@@ -1045,7 +1077,8 @@
1045
1077
  TemplateElement: TemplateElement,
1046
1078
  ClassExpression: ClassExpression,
1047
1079
  Super: Super,
1048
- SpreadElement: SpreadElement
1080
+ SpreadElement: SpreadElement,
1081
+ ChainExpression: ChainExpression
1049
1082
  });
1050
1083
 
1051
1084
  function ExpressionStatement(node, scope) {
@@ -1474,7 +1507,10 @@
1474
1507
  function ClassBody(node, scope, options = {}) {
1475
1508
  const { klass, superClass } = options;
1476
1509
  for (let i = 0; i < node.body.length; i++) {
1477
- MethodDefinition(node.body[i], scope, { klass, superClass });
1510
+ const def = node.body[i];
1511
+ if (def.type === 'MethodDefinition') {
1512
+ MethodDefinition(def, scope, { klass, superClass });
1513
+ }
1478
1514
  }
1479
1515
  }
1480
1516
  function MethodDefinition(node, scope, options = {}) {
@@ -1733,7 +1769,7 @@
1733
1769
  }
1734
1770
  }
1735
1771
  function* AssignmentExpression$1(node, scope) {
1736
- const value = yield* evaluate$1(node.right, scope);
1772
+ var _a;
1737
1773
  const left = node.left;
1738
1774
  let variable;
1739
1775
  if (left.type === 'Identifier') {
@@ -1747,8 +1783,10 @@
1747
1783
  variable = yield* MemberExpression$1(left, scope, { getVar: true });
1748
1784
  }
1749
1785
  else {
1786
+ const value = yield* evaluate$1(node.right, scope);
1750
1787
  return yield* pattern$2(left, scope, { feed: value });
1751
1788
  }
1789
+ const value = yield* evaluate$1(node.right, scope);
1752
1790
  switch (node.operator) {
1753
1791
  case '=':
1754
1792
  variable.set(value);
@@ -1789,15 +1827,27 @@
1789
1827
  case '&=':
1790
1828
  variable.set(variable.get() & value);
1791
1829
  return variable.get();
1830
+ case '??=':
1831
+ variable.set((_a = variable.get()) !== null && _a !== void 0 ? _a : value);
1832
+ return variable.get();
1833
+ case '&&=':
1834
+ variable.set(variable.get() && value);
1835
+ return variable.get();
1836
+ case '||=':
1837
+ variable.set(variable.get() || value);
1838
+ return variable.get();
1792
1839
  default: throw new SyntaxError(`Unexpected token ${node.operator}`);
1793
1840
  }
1794
1841
  }
1795
1842
  function* LogicalExpression$1(node, scope) {
1843
+ var _a;
1796
1844
  switch (node.operator) {
1797
1845
  case '||':
1798
1846
  return (yield* evaluate$1(node.left, scope)) || (yield* evaluate$1(node.right, scope));
1799
1847
  case '&&':
1800
1848
  return (yield* evaluate$1(node.left, scope)) && (yield* evaluate$1(node.right, scope));
1849
+ case '??':
1850
+ return (_a = (yield* evaluate$1(node.left, scope))) !== null && _a !== void 0 ? _a : (yield* evaluate$1(node.right, scope));
1801
1851
  default:
1802
1852
  throw new SyntaxError(`Unexpected token ${node.operator}`);
1803
1853
  }
@@ -1836,9 +1886,15 @@
1836
1886
  const getter = getGetter(object, key);
1837
1887
  if (node.object.type === 'Super' && getter) {
1838
1888
  const thisObject = scope.find('this').get();
1889
+ if (node.optional && thisObject == null) {
1890
+ return undefined;
1891
+ }
1839
1892
  return getter.call(thisObject);
1840
1893
  }
1841
1894
  else {
1895
+ if (node.optional && object == null) {
1896
+ return undefined;
1897
+ }
1842
1898
  return object[key];
1843
1899
  }
1844
1900
  }
@@ -1853,6 +1909,9 @@
1853
1909
  let object;
1854
1910
  if (node.callee.type === 'MemberExpression') {
1855
1911
  object = yield* MemberExpression$1(node.callee, scope, { getObj: true });
1912
+ if (node.callee.optional && object == null) {
1913
+ return undefined;
1914
+ }
1856
1915
  let key;
1857
1916
  if (node.callee.computed) {
1858
1917
  key = yield* evaluate$1(node.callee.property, scope);
@@ -1867,6 +1926,9 @@
1867
1926
  else {
1868
1927
  func = object[key];
1869
1928
  }
1929
+ if (node.optional && func == null) {
1930
+ return undefined;
1931
+ }
1870
1932
  if (typeof func !== 'function') {
1871
1933
  throw new TypeError(`${key} is not a function`);
1872
1934
  }
@@ -1877,6 +1939,9 @@
1877
1939
  else {
1878
1940
  object = scope.find('this').get();
1879
1941
  func = yield* evaluate$1(node.callee, scope);
1942
+ if (node.optional && func == null) {
1943
+ return undefined;
1944
+ }
1880
1945
  if (typeof func !== 'function' || node.callee.type !== 'Super' && func[CLSCTOR]) {
1881
1946
  let name;
1882
1947
  if (node.callee.type === 'Identifier') {
@@ -2021,6 +2086,9 @@
2021
2086
  function* SpreadElement$1(node, scope) {
2022
2087
  return yield* evaluate$1(node.argument, scope);
2023
2088
  }
2089
+ function* ChainExpression$1(node, scope) {
2090
+ return yield* evaluate$1(node.expression, scope);
2091
+ }
2024
2092
  function* YieldExpression(node, scope) {
2025
2093
  const res = yield* evaluate$1(node.argument, scope);
2026
2094
  return node.delegate ? yield* res : yield res;
@@ -2054,6 +2122,7 @@
2054
2122
  ClassExpression: ClassExpression$1,
2055
2123
  Super: Super$1,
2056
2124
  SpreadElement: SpreadElement$1,
2125
+ ChainExpression: ChainExpression$1,
2057
2126
  YieldExpression: YieldExpression,
2058
2127
  AwaitExpression: AwaitExpression
2059
2128
  });
@@ -2491,7 +2560,10 @@
2491
2560
  function* ClassBody$1(node, scope, options = {}) {
2492
2561
  const { klass, superClass } = options;
2493
2562
  for (let i = 0; i < node.body.length; i++) {
2494
- yield* MethodDefinition$1(node.body[i], scope, { klass, superClass });
2563
+ const def = node.body[i];
2564
+ if (def.type === 'MethodDefinition') {
2565
+ yield* MethodDefinition$1(def, scope, { klass, superClass });
2566
+ }
2495
2567
  }
2496
2568
  }
2497
2569
  function* MethodDefinition$1(node, scope, options = {}) {
@@ -2710,7 +2782,7 @@
2710
2782
  yield* RestElement$1(param, subScope, { kind: 'var', feed: args.slice(i) });
2711
2783
  }
2712
2784
  else {
2713
- yield* pattern$2(param, subScope, { feed: args[i] });
2785
+ yield* pattern$2(param, subScope, { kind: 'var', feed: args[i] });
2714
2786
  }
2715
2787
  }
2716
2788
  let result;
@@ -2786,7 +2858,7 @@
2786
2858
  const methodBody = node.body.body;
2787
2859
  for (let i = 0; i < methodBody.length; i++) {
2788
2860
  const method = methodBody[i];
2789
- if (method.kind === 'constructor') {
2861
+ if (method.type === 'MethodDefinition' && method.kind === 'constructor') {
2790
2862
  klass = createFunc(method.value, scope, { superClass, isCtor: true });
2791
2863
  break;
2792
2864
  }
@@ -2949,7 +3021,7 @@
2949
3021
  RestElement(param, subScope, { kind: 'var', feed: args.slice(i) });
2950
3022
  }
2951
3023
  else {
2952
- pattern$3(param, subScope, { feed: args[i] });
3024
+ pattern$3(param, subScope, { kind: 'var', feed: args[i] });
2953
3025
  }
2954
3026
  }
2955
3027
  let result;
@@ -2997,7 +3069,7 @@
2997
3069
  const methodBody = node.body.body;
2998
3070
  for (let i = 0; i < methodBody.length; i++) {
2999
3071
  const method = methodBody[i];
3000
- if (method.kind === 'constructor') {
3072
+ if (method.type === 'MethodDefinition' && method.kind === 'constructor') {
3001
3073
  klass = createFunc$1(method.value, scope, { superClass, isCtor: true });
3002
3074
  break;
3003
3075
  }
@@ -3037,14 +3109,17 @@
3037
3109
  return result;
3038
3110
  }
3039
3111
 
3112
+ const latestVer = 15;
3040
3113
  class Sval {
3041
3114
  constructor(options = {}) {
3042
- this.options = {};
3115
+ this.options = { ecmaVersion: 'latest' };
3043
3116
  this.scope = new Scope(null, true);
3044
3117
  this.exports = {};
3045
- let { ecmaVer = 9, sandBox = true } = options;
3046
- ecmaVer -= ecmaVer < 2015 ? 0 : 2009;
3047
- if ([3, 5, 6, 7, 8, 9, 10].indexOf(ecmaVer) === -1) {
3118
+ let { ecmaVer = 'latest', sandBox = true } = options;
3119
+ if (typeof ecmaVer === 'number') {
3120
+ ecmaVer -= ecmaVer < 2015 ? 0 : 2009;
3121
+ }
3122
+ if (ecmaVer !== 'latest' && ecmaVer !== 3 && (ecmaVer < 5 || ecmaVer > latestVer)) {
3048
3123
  throw new Error(`unsupported ecmaVer`);
3049
3124
  }
3050
3125
  this.options.ecmaVersion = ecmaVer;