-
Notifications
You must be signed in to change notification settings - Fork 152
/
Copy pathtmp.js
124 lines (121 loc) · 3.6 KB
/
tmp.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const e = (m) => { throw new Error(m); };
const toStr = (s) => typeof s === "symbol" ? s.toString() : "" + s;
const num = (v) => typeof v[0] === "number" ? v.shift() : e("not a number: " + toStr(v[0]));
const str = (s) => toStr(s.shift());
const truthyString = (v) => {
let s = v.shift();
if (!s && s !== 0)
return;
return s.toString();
};
const bool = (v) => !!v.shift();
function classnames(stack) {
stack = stack.slice(0);
let sources = [];
let classes = [];
let nSources = num(stack);
let nOutputs = num(stack);
let canSetSource = true;
let abort = () => canSetSource = false;
let isSourceSet = (n) => sources[n];
let setSource = (n) => { if (canSetSource)
sources[n] = true; };
while (nSources-- > 0) {
sourceExpr(stack, isSourceSet, setSource, abort);
canSetSource = true;
}
while (nOutputs-- > 0) {
let c = str(stack);
if (boolExpr(stack, isSourceSet))
classes.push(c);
}
return classes.join(" ");
}
function sourceExpr(stack, isSourceSet, setSource, abort) {
let enforceSwitch = true;
let type = num(stack);
if (type & 1 /* dependency */) {
let numDeps = num(stack);
while (numDeps-- > 0) {
let depIndex = num(stack);
if (!isSourceSet(depIndex))
enforceSwitch = abort();
}
}
if (type & 2 /* boolean */) {
if (!bool(stack))
abort();
}
if (type & 4 /* switch */) {
let nValues = num(stack);
let ifFalsy = num(stack);
let value = truthyString(stack);
if (value === undefined) {
switch (ifFalsy) {
case 2 /* default */:
value = str(stack);
break;
case 0 /* error */:
if (enforceSwitch)
e("string expected"); // TODO: error message
break;
case 1 /* unset */:
abort();
break;
default:
e("wtf");
}
}
while (nValues-- > 0) {
let matchValue = str(stack);
let nSources = num(stack);
while (nSources-- > 0) {
value === matchValue ? setSource(num(stack)) : num(stack);
}
}
}
else if (type === 0 /* ternary */) {
let condition = bool(stack);
let nTrue = num(stack);
while (nTrue-- > 0) {
condition ? setSource(num(stack)) : num(stack);
}
let nFalse = num(stack);
while (nFalse-- > 0) {
condition ? num(stack) : setSource(num(stack));
}
}
else {
let nSources = num(stack);
while (nSources-- > 0) {
setSource(num(stack));
}
}
}
function boolExpr(stack, isSourceSet) {
let result;
let type = num(stack);
switch (type) {
case -1 /* not */:
return !boolExpr(stack, isSourceSet);
case -3 /* and */:
let nAnds = num(stack);
result = true;
while (nAnds-- > 0) {
let nextResult = boolExpr(stack, isSourceSet);
result = result && nextResult;
}
return result;
case -2 /* or */:
let nOrs = num(stack);
result = false;
while (nOrs-- > 0) {
let nextResult = boolExpr(stack, isSourceSet);
result = result || nextResult;
}
return result;
default:
return isSourceSet(type);
}
}
export { classnames };