subscript 5.2.0 → 5.2.1
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.
- package/README.md +10 -5
- package/justin.js +22 -28
- package/justin.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
# <img alt="subscript" src="/subscript2.svg" height=42/> <!--sub͘<em>script</em>--> <!--<sub>SUB͘<em>SCRIPT</em></sub>-->
|
|
1
|
+
# <img alt="subscript" src="/subscript2.svg" height=42/> <!--sub͘<em>script</em>--> <!--<sub>SUB͘<em>SCRIPT</em></sub>-->
|
|
2
|
+
<a href="https://github.com/spectjs/subscript/actions/workflows/node.js.yml"><img src="https://github.com/spectjs/subscript/actions/workflows/node.js.yml/badge.svg"/></a>
|
|
3
|
+
<a href="http://npmjs.org/subscript"><img src="https://img.shields.io/npm/v/subscript?color=orangered"/></a>
|
|
4
|
+
<a href="http://microjs.com/#subscript"><img src="https://img.shields.io/badge/microjs-subscript-blue?color=darkslateblue"/></a>
|
|
2
5
|
|
|
3
6
|
_Subscript_ is micro-language with common syntax subset of C++, JS, Java, Python, Go, Rust, Swift, Objective C, Kotlin etc.<br/>
|
|
4
7
|
|
|
@@ -27,7 +30,7 @@ _Subscript_ is designed to be useful for:
|
|
|
27
30
|
* custom DSL
|
|
28
31
|
|
|
29
32
|
[_Jsep_](https://github.com/EricSmekens/jsep) is generally fine for the listed tasks, unless you need dependencies as small as possible.
|
|
30
|
-
_Subscript_ has [2.5kb](https://npmfs.com/package/subscript/5.
|
|
33
|
+
_Subscript_ has [2.5kb](https://npmfs.com/package/subscript/5.2.0/subscript.min.js) footprint vs [11.4kb](https://npmfs.com/package/jsep/1.2.0/dist/jsep.min.js) _jsep_, with _jsep_ and more test coverage and better performance.
|
|
31
34
|
|
|
32
35
|
|
|
33
36
|
## Evaluation
|
|
@@ -49,6 +52,8 @@ evaluate(['+', ['*', 'min', 60], '"sec"'], { min: 5 }) // min*60 + "sec" == "300
|
|
|
49
52
|
|
|
50
53
|
## Extending
|
|
51
54
|
|
|
55
|
+
### Operators
|
|
56
|
+
|
|
52
57
|
Default operators include common operators for the listed languages in the following precedence:
|
|
53
58
|
|
|
54
59
|
* `++ --` unary postfix
|
|
@@ -83,13 +88,13 @@ let tree = parse(`
|
|
|
83
88
|
evaluate(tree, { Math, map, take, interval, gaussian })
|
|
84
89
|
```
|
|
85
90
|
|
|
86
|
-
|
|
91
|
+
### Tokens
|
|
87
92
|
|
|
88
93
|
Default tokens include:
|
|
89
94
|
|
|
90
95
|
* `"abc"` strings
|
|
91
96
|
* `1.2e+3` floats
|
|
92
|
-
* identifiers
|
|
97
|
+
* `name` identifiers
|
|
93
98
|
|
|
94
99
|
Tokens are extensible via `parse.token` list, can be added support of _literals_, _regexes_, _strings_, _numbers_ and others.
|
|
95
100
|
|
|
@@ -102,7 +107,7 @@ parse.token.unshift(c => char(4) === 'this' ? ctx : null)
|
|
|
102
107
|
evaluate(parse(`this.x`)) // 1
|
|
103
108
|
```
|
|
104
109
|
|
|
105
|
-
|
|
110
|
+
### Spaces/comments
|
|
106
111
|
|
|
107
112
|
Comments can be added via extending `parse.space`. See [justin.js](./justin.js) for more examples.
|
|
108
113
|
|
package/justin.js
CHANGED
|
@@ -4,14 +4,14 @@ import {parse, code, char, skip, expr, err} from './parse.js'
|
|
|
4
4
|
|
|
5
5
|
const PERIOD=46, OPAREN=40, CPAREN=41, CBRACK=93, SPACE=32,
|
|
6
6
|
|
|
7
|
-
PREC_SEQ=1, PREC_SOME=4, PREC_EVERY=5, PREC_OR=6, PREC_XOR=7, PREC_AND=8,
|
|
8
|
-
PREC_EQ=9, PREC_COMP=10, PREC_SHIFT=11, PREC_SUM=12, PREC_MULT=13, PREC_UNARY=15, PREC_POSTFIX=16, PREC_CALL=18, PREC_GROUP=19
|
|
7
|
+
PREC_SEQ=1, PREC_TERN=3, PREC_SOME=4, PREC_EVERY=5, PREC_OR=6, PREC_XOR=7, PREC_AND=8,
|
|
8
|
+
PREC_EQ=9, PREC_COMP=10, PREC_SHIFT=11, PREC_SUM=12, PREC_MULT=13, PREC_UNARY=15, PREC_POSTFIX=16, PREC_CALL=18, PREC_GROUP=19,
|
|
9
|
+
PREC_EXP=14, PREC_TOKEN=20
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
// tokens
|
|
12
13
|
const v = v => ({valueOf:()=>v})
|
|
13
14
|
parse.token.push(
|
|
14
|
-
// TODO: better parser
|
|
15
15
|
// 1.2e+3, .5 - fast & small version, but consumes corrupted nums as well
|
|
16
16
|
(number) => (
|
|
17
17
|
(number = skip(c => (c > 47 && c < 58) || c == PERIOD)) && (
|
|
@@ -31,11 +31,6 @@ parse.token.push(
|
|
|
31
31
|
return skip(), qc + str + qc
|
|
32
32
|
},
|
|
33
33
|
|
|
34
|
-
// {}
|
|
35
|
-
(cc, node) => (
|
|
36
|
-
cc === 123 && (skip(), node = mapObj(['{', expr(0,125)]), skip(), node)
|
|
37
|
-
),
|
|
38
|
-
|
|
39
34
|
// literal
|
|
40
35
|
c =>
|
|
41
36
|
c === 116 && char(4) === 'true' && skip(4) ? v(true) :
|
|
@@ -56,14 +51,6 @@ parse.token.push(
|
|
|
56
51
|
|
|
57
52
|
const escape = {n:'\n', r:'\r', t:'\t', b:'\b', f:'\f', v:'\v'}
|
|
58
53
|
|
|
59
|
-
// {}
|
|
60
|
-
const mapObj = (n, args) => (
|
|
61
|
-
args = !n[1] ? [] :
|
|
62
|
-
(n[1][0]==':') ? [n[1]] :
|
|
63
|
-
(n[1][0]==',') ? n[1].slice(1) : args,
|
|
64
|
-
['{', ...args]
|
|
65
|
-
)
|
|
66
|
-
|
|
67
54
|
|
|
68
55
|
// /**/, //
|
|
69
56
|
parse.space = cc => {
|
|
@@ -86,7 +73,7 @@ const addOps = (add, stride=2, list) => {
|
|
|
86
73
|
|
|
87
74
|
addOps(parse.operator, 3, [
|
|
88
75
|
// subscript ones
|
|
89
|
-
// TODO: add ,, as node here
|
|
76
|
+
// TODO: add ,, as node here?
|
|
90
77
|
',', PREC_SEQ,,
|
|
91
78
|
|
|
92
79
|
'|', PREC_OR,,
|
|
@@ -144,12 +131,12 @@ addOps(parse.operator, 3, [
|
|
|
144
131
|
')',,,
|
|
145
132
|
|
|
146
133
|
// justin extension
|
|
147
|
-
';',
|
|
148
|
-
'===',
|
|
149
|
-
'!==',
|
|
150
|
-
'**',
|
|
151
|
-
'~',
|
|
152
|
-
'?',
|
|
134
|
+
';', PREC_SEQ,,
|
|
135
|
+
'===', PREC_EQ,,
|
|
136
|
+
'!==', PREC_EQ,,
|
|
137
|
+
'**', PREC_EXP,,
|
|
138
|
+
'~', PREC_UNARY, -1,
|
|
139
|
+
'?', PREC_TERN, (node) => {
|
|
153
140
|
if (!node) err('Expected expression')
|
|
154
141
|
let a, b
|
|
155
142
|
skip(), parse.space(), a = expr()
|
|
@@ -158,12 +145,19 @@ addOps(parse.operator, 3, [
|
|
|
158
145
|
return ['?:', node, a, b]
|
|
159
146
|
},
|
|
160
147
|
'}',,,
|
|
161
|
-
':'
|
|
162
|
-
'in',
|
|
163
|
-
|
|
148
|
+
':',,,
|
|
149
|
+
'in', PREC_COMP, (node) => code(2) <= 32 && [skip(2), '"'+node+'"', expr(PREC_COMP)],
|
|
150
|
+
|
|
151
|
+
// [a,b,c]
|
|
152
|
+
'[', PREC_TOKEN, (node,arg) => !node && (
|
|
164
153
|
skip(), arg=expr(0,93), skip(),
|
|
165
|
-
!arg ? ['['] : arg[0]
|
|
166
|
-
)
|
|
154
|
+
!arg ? ['['] : arg[0] == ',' ? (arg[0]='[',arg) : ['[',arg]
|
|
155
|
+
),
|
|
156
|
+
|
|
157
|
+
// {a:0, b:1}
|
|
158
|
+
'{', PREC_TOKEN, (node,arg) => !node && (skip(), arg=expr(0,125), skip(),
|
|
159
|
+
!arg ? ['{'] : arg[0] == ':' ? ['{',arg] : arg[0] == ',' ? (arg[0]='{',arg) : ['[',arg])
|
|
160
|
+
,
|
|
167
161
|
])
|
|
168
162
|
|
|
169
163
|
addOps(evaluate.operator, 2, [
|
package/justin.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,r,t=e=>Array.isArray(e)&&("string"==typeof e[0]||t(e[0])),a=(e,r={},o,l)=>t(e)?("string"==typeof(o=e[0])&&(l=n[o]),"function"!=typeof(o=l||a(o,r))?o:o.call(...e.map((e=>a(e,r))))):e&&"string"==typeof e?'"'===e[0]?e.slice(1,-1):"@"===e[0]?e.slice(1):e in r?r[e]:e:e,n={},o=(a.operator=(e,r)=>n[e]=2==r.length?(...e)=>e.reduce(r):r,(t,a)=>(r=t,e=0,a=p(),e<r.length?l():a.valueOf())),l=(t="Bad syntax")=>{throw Error(t+" `"+r[e]+"` at "+e)},s=(t=1,a=e)=>{if("number"==typeof t)e+=t;else for(;t(u());)e++;return r.slice(a,e)},u=(t=0)=>r.charCodeAt(e+t),f=(t=1)=>r.substr(e,t),p=(e=0,r,t,a,n=0,s,u)=>{for(;(t=o.space())&&(u=v[t]?.(a,e)||!a&&c(t));)a=u;return r&&t!==r&&l("Unclosed paren"),a},i=(o.space=r=>{for(;(r=u())<=32;)e++;return r},o.token=[]),c=(e,r=0,t)=>{for(;r<i.length;)if(t=i[r++](e))return t},v=[],d=(o.operator=(r,t=0,a=0,n,i=r.charCodeAt(0),c=r.length,d=v[i],h=r.toUpperCase()!==r,y)=>(y=c<2?h?e=>u(1)<=32:e=>1:h?e=>f(c)==r&&u(c)<=32:e=>f(c)==r,n=a?a>0?e=>e&&[s(c),e]:a<0?e=>!e&&[s(c),(p(t-1)||l()).valueOf()]:a:a=>{a=[r,a||l()];do{e+=c,a.push((p(t)||l()).valueOf())}while(o.space()==i&&y());return a},v[i]=(e,r)=>r<t&&y()&&n(e)||d&&d(e,r)),
|
|
1
|
+
var e,r,t=e=>Array.isArray(e)&&("string"==typeof e[0]||t(e[0])),a=(e,r={},o,l)=>t(e)?("string"==typeof(o=e[0])&&(l=n[o]),"function"!=typeof(o=l||a(o,r))?o:o.call(...e.map((e=>a(e,r))))):e&&"string"==typeof e?'"'===e[0]?e.slice(1,-1):"@"===e[0]?e.slice(1):e in r?r[e]:e:e,n={},o=(a.operator=(e,r)=>n[e]=2==r.length?(...e)=>e.reduce(r):r,(t,a)=>(r=t,e=0,a=p(),e<r.length?l():a.valueOf())),l=(t="Bad syntax")=>{throw Error(t+" `"+r[e]+"` at "+e)},s=(t=1,a=e)=>{if("number"==typeof t)e+=t;else for(;t(u());)e++;return r.slice(a,e)},u=(t=0)=>r.charCodeAt(e+t),f=(t=1)=>r.substr(e,t),p=(e=0,r,t,a,n=0,s,u)=>{for(;(t=o.space())&&(u=v[t]?.(a,e)||!a&&c(t));)a=u;return r&&t!==r&&l("Unclosed paren"),a},i=(o.space=r=>{for(;(r=u())<=32;)e++;return r},o.token=[]),c=(e,r=0,t)=>{for(;r<i.length;)if(t=i[r++](e))return t},v=[],d=(o.operator=(r,t=0,a=0,n,i=r.charCodeAt(0),c=r.length,d=v[i],h=r.toUpperCase()!==r,y)=>(y=c<2?h?e=>u(1)<=32:e=>1:h?e=>f(c)==r&&u(c)<=32:e=>f(c)==r,n=a?a>0?e=>e&&[s(c),e]:a<0?e=>!e&&[s(c),(p(t-1)||l()).valueOf()]:a:a=>{a=[r,a||l()];do{e+=c,a.push((p(t)||l()).valueOf())}while(o.space()==i&&y());return a},v[i]=(e,r)=>r<t&&y()&&n(e)||d&&d(e,r)),10),h=15,y=e=>({valueOf:()=>e});o.token.push((e=>(e=s((e=>e>47&&e<58||46==e)))&&((69==u()||101==u())&&(e+=s(2)+s((e=>e>=48&&e<=57))),isNaN(e=new Number(e))?l("Bad number"):e)),((e,r,t,a)=>{if(34===e||39===e){for(r=f(),s(),a="";(t=u())-e;)92===t?(s(),a+=g[f()]||f()):a+=f(),s();return s(),r+a+r}}),(e=>116===e&&"true"===f(4)&&s(4)?y(!0):102===e&&"false"===f(5)&&s(5)?y(!1):110===e&&"null"===f(4)&&s(4)?y(null):117===e&&"undefined"===f(9)&&s(9)?y(void 0):null),(e=>s((e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e))));var g={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"};o.space=e=>{for(;(e=u())<=32;)s(),47===u()&&(42===u(1)?(s(2),s((e=>42!==e&&47!==u(1))),s(2)):47===u(1)&&(s(2),s((e=>e>=32))));return e};var O=(e,r=2,t)=>{for(let a=0;a<t.length;a+=r)e(t[a],t[a+1],t[a+2])};O(o.operator,3,[",",1,,"|",6,,"||",4,,"&",8,,"&&",5,,"^",7,,"==",9,,"!=",9,,">",d,,">=",d,,">>",11,,">>>",11,,"<",d,,"<=",d,,"<<",11,,"+",12,,"+",h,-1,"++",h,-1,"++",h,1,"-",12,,"-",h,-1,"--",h,-1,"--",h,1,"!",h,-1,"*",13,,"/",13,,"%",13,,".",18,(e,r)=>e&&[s(),e,"string"==typeof(r=p(18))?'"'+r+'"':r.valueOf()],"[",18,e=>(s(),e=[".",e,p(0,93).valueOf()],s(),e),"]",,,"(",18,(e,r)=>(s(),r=p(0,41),s(),Array.isArray(r)&&","===r[0]?(r[0]=e,r):r?[e,r.valueOf()]:[e]),"(",19,(e,r)=>!e&&(s(),r=p(0,41)||l(),s(),r),")",,,";",1,,"===",9,,"!==",9,,"**",14,,"~",h,-1,"?",3,e=>{let r,t;return e||l("Expected expression"),s(),o.space(),r=p(),58!==u()&&l("Expected :"),s(),o.space(),t=p(),["?:",e,r,t]},"}",,,":",,,"in",d,e=>u(2)<=32&&[s(2),'"'+e+'"',p(d)],"[",20,(e,r)=>!e&&(s(),r=p(0,93),s(),r?","==r[0]?(r[0]="[",r):["[",r]:["["]),"{",20,(e,r)=>!e&&(s(),r=p(0,125),s(),r?":"==r[0]?["{",r]:","==r[0]?(r[0]="{",r):["[",r]:["{"])]),O(a.operator,2,["!",e=>!e,"++",e=>++e,"--",e=>--e,".",(e,r)=>e&&e[r],"%",(e,r)=>e%r,"/",(e,r)=>e/r,"*",(e,r)=>e*r,"+",(e,r)=>e+r,"-",(...e)=>e.length<2?-e:e.reduce(((e,r)=>e-r)),">>>",(e,r)=>e>>>r,">>",(e,r)=>e>>r,"<<",(e,r)=>e<<r,">=",(e,r)=>e>=r,">",(e,r)=>e>r,"<=",(e,r)=>e<=r,"<",(e,r)=>e<r,"!=",(e,r)=>e!=r,"==",(e,r)=>e==r,"&",(e,r)=>e&r,"^",(e,r)=>e^r,"|",(e,r)=>e|r,"&&",(...e)=>e.every(Boolean),"||",(...e)=>e.some(Boolean),",",(e,r)=>r,"**",(...e)=>e.reduceRight(((e,r)=>Math.pow(r,e))),"~",e=>~e,"?:",(e,r,t)=>e?r:t,"in",(e,r)=>e in r,"[",(...e)=>Array(...e),"{",(...e)=>Object.fromEntries(e),":",(e,r)=>[e,r]]);var b=e=>(e="string"==typeof e?o(e):e,r=>a(e,r));export{b as default,a as evaluate,o as parse};
|