papagaio 0.7.1 → 0.7.3
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/package.json +1 -1
- package/src/louro.js +235 -0
- package/src/papagaio.js +81 -128
- package/examples/simple.html +0 -15
- package/examples/wasm.papagaio +0 -70
- package/src/papagaio-bootstrap.mjs +0 -23
package/package.json
CHANGED
package/src/louro.js
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// louro - https://github.com/jardimdanificado/papagaio
|
|
2
|
+
function parsePattern(symbols, pat) {
|
|
3
|
+
const t = [], S = symbols.sigil, O = symbols.open, C = symbols.close;
|
|
4
|
+
let i = 0;
|
|
5
|
+
while (i < pat.length) {
|
|
6
|
+
if (pat[i] === S) {
|
|
7
|
+
let j = i + S.length;
|
|
8
|
+
const isDouble = pat[j] === S;
|
|
9
|
+
if (isDouble) j++;
|
|
10
|
+
if (pat[j] === O) {
|
|
11
|
+
const [od, e1] = extractBlock(symbols, pat, j);
|
|
12
|
+
if (pat[e1] === O) {
|
|
13
|
+
const [cd, e2] = extractBlock(symbols, pat, e1);
|
|
14
|
+
let v = '', k = e2;
|
|
15
|
+
while (k < pat.length && /[A-Za-z0-9_]/.test(pat[k])) v += pat[k++];
|
|
16
|
+
if (v) {
|
|
17
|
+
let optional = pat[k] === '?';
|
|
18
|
+
if (optional) k++;
|
|
19
|
+
|
|
20
|
+
t.push({
|
|
21
|
+
type: isDouble ? 'blockseq' : 'block',
|
|
22
|
+
varName: v,
|
|
23
|
+
open: unescapeDelim(od.trim()) || O,
|
|
24
|
+
close: unescapeDelim(cd.trim()) || C,
|
|
25
|
+
optional
|
|
26
|
+
});
|
|
27
|
+
i = k; continue;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
j = i + S.length;
|
|
32
|
+
let v = '';
|
|
33
|
+
while (j < pat.length && /[A-Za-z0-9_]/.test(pat[j])) v += pat[j++];
|
|
34
|
+
if (v) {
|
|
35
|
+
const optional = pat[j] === '?';
|
|
36
|
+
if (optional) j++;
|
|
37
|
+
t.push({ type: 'var', varName: v, optional });
|
|
38
|
+
i = j; continue;
|
|
39
|
+
}
|
|
40
|
+
t.push({ type: 'lit', value: S }); i += S.length; continue;
|
|
41
|
+
}
|
|
42
|
+
if (/\s/.test(pat[i])) {
|
|
43
|
+
while (i < pat.length && /\s/.test(pat[i])) i++;
|
|
44
|
+
t.push({ type: 'ws' }); continue;
|
|
45
|
+
}
|
|
46
|
+
let lit = '';
|
|
47
|
+
while (i < pat.length && pat[i] !== S && !/\s/.test(pat[i])) lit += pat[i++];
|
|
48
|
+
if (lit) t.push({ type: 'lit', value: lit });
|
|
49
|
+
}
|
|
50
|
+
return t;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function matchPattern(symbols, src, tok, pos = 0) {
|
|
54
|
+
let cap = {};
|
|
55
|
+
const startPos = pos;
|
|
56
|
+
|
|
57
|
+
for (let ti = 0; ti < tok.length; ti++) {
|
|
58
|
+
const t = tok[ti];
|
|
59
|
+
if (t.type === 'ws') { while (pos < src.length && /\s/.test(src[pos])) pos++; continue; }
|
|
60
|
+
if (t.type === 'lit') { if (!src.startsWith(t.value, pos)) return null; pos += t.value.length; continue; }
|
|
61
|
+
if (t.type === 'var') {
|
|
62
|
+
while (pos < src.length && /\s/.test(src[pos])) pos++;
|
|
63
|
+
const nx = findNext(tok, ti);
|
|
64
|
+
let v = '';
|
|
65
|
+
if (nx && (nx.type === 'block' || nx.type === 'lit')) {
|
|
66
|
+
const stop = nx.type === 'block' ? nx.open : nx.value;
|
|
67
|
+
while (pos < src.length && !src.startsWith(stop, pos) && src[pos] !== '\n') v += src[pos++];
|
|
68
|
+
v = v.trimEnd();
|
|
69
|
+
} else {
|
|
70
|
+
while (pos < src.length && !/\s/.test(src[pos])) v += src[pos++];
|
|
71
|
+
}
|
|
72
|
+
if (!v && !t.optional) return null;
|
|
73
|
+
cap[t.varName] = v;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (t.type === 'blockseq') {
|
|
77
|
+
let blocks = [];
|
|
78
|
+
while (pos < src.length && src.startsWith(t.open, pos)) {
|
|
79
|
+
const [c, e] = extractBlock(symbols, src, pos, t.open, t.close);
|
|
80
|
+
blocks.push(c);
|
|
81
|
+
pos = e;
|
|
82
|
+
while (pos < src.length && /\s/.test(src[pos])) pos++;
|
|
83
|
+
}
|
|
84
|
+
if (!blocks.length && !t.optional) return null;
|
|
85
|
+
cap[t.varName] = blocks;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (t.type === 'block') {
|
|
89
|
+
if (!src.startsWith(t.open, pos)) {
|
|
90
|
+
if (t.optional) {
|
|
91
|
+
cap[t.varName] = '';
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const [c, e] = extractBlock(symbols, src, pos, t.open, t.close);
|
|
98
|
+
cap[t.varName] = c; pos = e; continue;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return { captures: cap, startPos, endPos: pos, matched: src.slice(startPos, pos) };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function findNext(t, i) {
|
|
105
|
+
for (let k = i + 1; k < t.length; k++)
|
|
106
|
+
if (t[k].type !== 'ws') return t[k];
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function extractBlock(symbols, src, i, od = symbols.open, cd = symbols.close) {
|
|
111
|
+
if (od.length > 1 || cd.length > 1) {
|
|
112
|
+
if (src.substring(i, i + od.length) === od) {
|
|
113
|
+
i += od.length; const s = i; let d = 0;
|
|
114
|
+
while (i < src.length) {
|
|
115
|
+
if (src.substring(i, i + od.length) === od) { d++; i += od.length; }
|
|
116
|
+
else if (src.substring(i, i + cd.length) === cd) {
|
|
117
|
+
if (!d) return [src.substring(s, i), i + cd.length];
|
|
118
|
+
d--; i += cd.length;
|
|
119
|
+
} else i++;
|
|
120
|
+
}
|
|
121
|
+
return [src.substring(s), src.length];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (src[i] === od) {
|
|
125
|
+
i++; const s = i;
|
|
126
|
+
if (od === cd) { while (i < src.length && src[i] !== cd) i++; return [src.substring(s, i), i + 1]; }
|
|
127
|
+
let d = 1;
|
|
128
|
+
while (i < src.length && d > 0) { if (src[i] === od) d++; else if (src[i] === cd) d--; if (d > 0) i++; }
|
|
129
|
+
return [src.substring(s, i), i + 1];
|
|
130
|
+
}
|
|
131
|
+
return ['', i];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function esc(s) { return s.replace(/[.*+?^${}()|[\]\\""']/g, '\\$&'); }
|
|
135
|
+
function unescapeDelim(s) {
|
|
136
|
+
let r = '';
|
|
137
|
+
for (let i = 0; i < s.length; i++) {
|
|
138
|
+
if (s[i] === '\\' && i + 1 < s.length && (s[i + 1] === '"' || s[i + 1] === "'" || s[i + 1] === '\\')) { r += s[i + 1]; i++; }
|
|
139
|
+
else r += s[i];
|
|
140
|
+
}
|
|
141
|
+
return r;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function capture(content, pattern, symbols = { sigil: '$', open: '{', close: '}' }) {
|
|
145
|
+
const tokens = parsePattern(symbols, pattern);
|
|
146
|
+
const matches = [];
|
|
147
|
+
|
|
148
|
+
let pos = 0;
|
|
149
|
+
while (pos < content.length) {
|
|
150
|
+
const m = matchPattern(symbols, content, tokens, pos);
|
|
151
|
+
if (m) {
|
|
152
|
+
matches.push({
|
|
153
|
+
matched: m.matched,
|
|
154
|
+
captures: m.captures,
|
|
155
|
+
start: m.startPos,
|
|
156
|
+
end: m.endPos,
|
|
157
|
+
index: matches.length
|
|
158
|
+
});
|
|
159
|
+
pos = m.endPos;
|
|
160
|
+
} else {
|
|
161
|
+
pos++;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
content,
|
|
167
|
+
pattern,
|
|
168
|
+
matches,
|
|
169
|
+
count: matches.length,
|
|
170
|
+
|
|
171
|
+
replace(replacement) {
|
|
172
|
+
if (matches.length === 0) return { content, matches: [], count: 0 };
|
|
173
|
+
|
|
174
|
+
let result = '';
|
|
175
|
+
let lastPos = 0;
|
|
176
|
+
|
|
177
|
+
for (const match of matches) {
|
|
178
|
+
result += content.slice(lastPos, match.start);
|
|
179
|
+
|
|
180
|
+
let rep = typeof replacement === 'function'
|
|
181
|
+
? replacement(match)
|
|
182
|
+
: replacement;
|
|
183
|
+
|
|
184
|
+
for (const [key, value] of Object.entries(match.captures)) {
|
|
185
|
+
const varPattern = new RegExp(esc(symbols.sigil + key) + '(?![A-Za-z0-9_])', 'g');
|
|
186
|
+
rep = rep.replace(varPattern, value);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
result += rep;
|
|
190
|
+
lastPos = match.end;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
result += content.slice(lastPos);
|
|
194
|
+
|
|
195
|
+
return result;
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
filter(predicate) {
|
|
199
|
+
const filtered = matches.filter(predicate);
|
|
200
|
+
return {
|
|
201
|
+
content,
|
|
202
|
+
pattern,
|
|
203
|
+
matches: filtered,
|
|
204
|
+
count: filtered.length,
|
|
205
|
+
replace: this.replace.bind({ ...this, matches: filtered }),
|
|
206
|
+
filter: this.filter,
|
|
207
|
+
only: this.only
|
|
208
|
+
};
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
only(n) {
|
|
212
|
+
const len = this.matches.length;
|
|
213
|
+
let idx = n >= 0 ? n : len + n;
|
|
214
|
+
if (idx < 0 || idx >= len) {
|
|
215
|
+
return {
|
|
216
|
+
...this,
|
|
217
|
+
matches: []
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
return {
|
|
221
|
+
...this,
|
|
222
|
+
matches: [this.matches[idx]]
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
Object.defineProperty(String.prototype, "capture", {
|
|
229
|
+
value: function (pattern, symbols) {
|
|
230
|
+
return capture(this.toString(), pattern, symbols);
|
|
231
|
+
},
|
|
232
|
+
writable: true,
|
|
233
|
+
configurable: true,
|
|
234
|
+
enumerable: false
|
|
235
|
+
});
|
package/src/papagaio.js
CHANGED
|
@@ -1,112 +1,5 @@
|
|
|
1
1
|
// papagaio - https://github.com/jardimdanificado/papagaio
|
|
2
|
-
|
|
3
|
-
const t = [], S = p.symbols.sigil, O = p.symbols.open, C = p.symbols.close;
|
|
4
|
-
let i = 0;
|
|
5
|
-
while (i < pat.length) {
|
|
6
|
-
if (pat.startsWith(S + p.symbols.regex, i)) {
|
|
7
|
-
let j = i + S.length + p.symbols.regex.length;
|
|
8
|
-
while (j < pat.length && /\s/.test(pat[j])) j++;
|
|
9
|
-
let v = '';
|
|
10
|
-
while (j < pat.length && /[A-Za-z0-9_]/.test(pat[j])) v += pat[j++];
|
|
11
|
-
if (v) {
|
|
12
|
-
while (j < pat.length && /\s/.test(pat[j])) j++;
|
|
13
|
-
if (pat[j] === O) {
|
|
14
|
-
const [rx, e] = extractBlock(p, pat, j);
|
|
15
|
-
t.push({ type: 'regex', varName: v, regex: rx.trim() });
|
|
16
|
-
i = e; continue;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
if (pat[i] === S) {
|
|
21
|
-
let j = i + S.length;
|
|
22
|
-
const isDouble = pat[j] === S;
|
|
23
|
-
if (isDouble) j++;
|
|
24
|
-
if (pat[j] === O) {
|
|
25
|
-
const [od, e1] = extractBlock(p, pat, j);
|
|
26
|
-
if (pat[e1] === O) {
|
|
27
|
-
const [cd, e2] = extractBlock(p, pat, e1);
|
|
28
|
-
let v = '', k = e2;
|
|
29
|
-
while (k < pat.length && /[A-Za-z0-9_]/.test(pat[k])) v += pat[k++];
|
|
30
|
-
if (v) {
|
|
31
|
-
t.push({ type: isDouble ? 'blockseq' : 'block', varName: v, open: unescapeDelim(od.trim()) || O, close: unescapeDelim(cd.trim()) || C });
|
|
32
|
-
i = k; continue;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
j = i + S.length;
|
|
37
|
-
let v = '';
|
|
38
|
-
while (j < pat.length && /[A-Za-z0-9_]/.test(pat[j])) v += pat[j++];
|
|
39
|
-
if (v) {
|
|
40
|
-
const optional = pat[j] === '?';
|
|
41
|
-
if (optional) j++;
|
|
42
|
-
t.push({ type: 'var', varName: v, optional });
|
|
43
|
-
i = j; continue;
|
|
44
|
-
}
|
|
45
|
-
t.push({ type: 'lit', value: S }); i += S.length; continue;
|
|
46
|
-
}
|
|
47
|
-
if (/\s/.test(pat[i])) {
|
|
48
|
-
while (i < pat.length && /\s/.test(pat[i])) i++;
|
|
49
|
-
t.push({ type: 'ws' }); continue;
|
|
50
|
-
}
|
|
51
|
-
let lit = '';
|
|
52
|
-
while (i < pat.length && pat[i] !== S && !/\s/.test(pat[i])) lit += pat[i++];
|
|
53
|
-
if (lit) t.push({ type: 'lit', value: lit });
|
|
54
|
-
}
|
|
55
|
-
return t;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function matchPattern(p, src, tok, pos = 0) {
|
|
59
|
-
let cap = {};
|
|
60
|
-
for (let ti = 0; ti < tok.length; ti++) {
|
|
61
|
-
const t = tok[ti];
|
|
62
|
-
if (t.type === 'ws') { while (pos < src.length && /\s/.test(src[pos])) pos++; continue; }
|
|
63
|
-
if (t.type === 'lit') { if (!src.startsWith(t.value, pos)) return null; pos += t.value.length; continue; }
|
|
64
|
-
if (t.type === 'regex') {
|
|
65
|
-
try {
|
|
66
|
-
const rx = new RegExp(t.regex), m = src.slice(pos).match(rx);
|
|
67
|
-
if (!m || m.index !== 0) return null;
|
|
68
|
-
cap[p.symbols.sigil + t.varName] = m[0];
|
|
69
|
-
pos += m[0].length;
|
|
70
|
-
} catch (e) { return null; }
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (t.type === 'var') {
|
|
74
|
-
while (pos < src.length && /\s/.test(src[pos])) pos++;
|
|
75
|
-
const nx = findNext(tok, ti);
|
|
76
|
-
let v = '';
|
|
77
|
-
if (nx && (nx.type === 'block' || nx.type === 'lit')) {
|
|
78
|
-
const stop = nx.type === 'block' ? nx.open : nx.value;
|
|
79
|
-
while (pos < src.length && !src.startsWith(stop, pos) && src[pos] !== '\n') v += src[pos++];
|
|
80
|
-
v = v.trimEnd();
|
|
81
|
-
} else {
|
|
82
|
-
while (pos < src.length && !/\s/.test(src[pos])) v += src[pos++];
|
|
83
|
-
}
|
|
84
|
-
if (!v && !t.optional) return null;
|
|
85
|
-
cap[p.symbols.sigil + t.varName] = v;
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
if (t.type === 'blockseq') {
|
|
89
|
-
let blocks = [];
|
|
90
|
-
while (pos < src.length && src.startsWith(t.open, pos)) {
|
|
91
|
-
const [c, e] = extractBlock(p, src, pos, t.open, t.close);
|
|
92
|
-
blocks.push(c);
|
|
93
|
-
pos = e;
|
|
94
|
-
while (pos < src.length && /\s/.test(src[pos])) pos++;
|
|
95
|
-
}
|
|
96
|
-
if (!blocks.length) return null;
|
|
97
|
-
cap[p.symbols.sigil + t.varName] = blocks.join(' ');
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
if (t.type === 'block') {
|
|
101
|
-
if (!src.startsWith(t.open, pos)) return null;
|
|
102
|
-
const [c, e] = extractBlock(p, src, pos, t.open, t.close);
|
|
103
|
-
cap[p.symbols.sigil + t.varName] = c; pos = e; continue;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return { captures: cap, endPos: pos };
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function findNext(t, i) { for (let k = i + 1; k < t.length; k++) if (t[k].type !== 'ws') return t[k]; return null; }
|
|
2
|
+
import { capture } from './louro.js';
|
|
110
3
|
|
|
111
4
|
function extractBlock(p, src, i, od = p.symbols.open, cd = p.symbols.close) {
|
|
112
5
|
if (od.length > 1 || cd.length > 1) {
|
|
@@ -185,41 +78,101 @@ function applyEvals(p, txt, ev) {
|
|
|
185
78
|
return r;
|
|
186
79
|
}
|
|
187
80
|
|
|
81
|
+
function processRegexPatterns(p, src, pattern) {
|
|
82
|
+
// Processa padrões regex que o louro não suporta nativamente
|
|
83
|
+
const S = p.symbols.sigil, O = p.symbols.open;
|
|
84
|
+
const regexMatch = pattern.match(new RegExp(`${esc(S)}${esc(p.symbols.regex)}\\s+([A-Za-z0-9_]+)\\s*${esc(O)}([^${esc(p.symbols.close)}]*)${esc(p.symbols.close)}`));
|
|
85
|
+
|
|
86
|
+
if (!regexMatch) return null;
|
|
87
|
+
|
|
88
|
+
const varName = regexMatch[1];
|
|
89
|
+
const regexStr = regexMatch[2].trim();
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const rx = new RegExp(regexStr);
|
|
93
|
+
const matches = [];
|
|
94
|
+
let pos = 0;
|
|
95
|
+
|
|
96
|
+
while (pos < src.length) {
|
|
97
|
+
const m = src.slice(pos).match(rx);
|
|
98
|
+
if (m && m.index === 0) {
|
|
99
|
+
matches.push({
|
|
100
|
+
matched: m[0],
|
|
101
|
+
captures: { [varName]: m[0] },
|
|
102
|
+
start: pos,
|
|
103
|
+
end: pos + m[0].length
|
|
104
|
+
});
|
|
105
|
+
pos += m[0].length;
|
|
106
|
+
} else {
|
|
107
|
+
pos++;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return matches;
|
|
112
|
+
} catch (e) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
188
117
|
function applyPats(p, src, pats) {
|
|
189
118
|
for (const pat of pats) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
119
|
+
// Verifica se é um padrão regex
|
|
120
|
+
const regexMatches = processRegexPatterns(p, src, pat.m);
|
|
121
|
+
|
|
122
|
+
if (regexMatches) {
|
|
123
|
+
// Processa como padrão regex
|
|
124
|
+
let n = '', lastPos = 0;
|
|
125
|
+
|
|
126
|
+
for (const match of regexMatches) {
|
|
127
|
+
n += src.slice(lastPos, match.start);
|
|
128
|
+
|
|
196
129
|
let r = pat.r;
|
|
197
130
|
const [loc, cln] = extractNested(p, r);
|
|
198
131
|
r = cln;
|
|
199
|
-
|
|
200
|
-
|
|
132
|
+
|
|
133
|
+
Object.keys(match.captures).forEach(k => {
|
|
134
|
+
r = r.replace(new RegExp(esc(p.symbols.sigil + k) + '(?![A-Za-z0-9_])', 'g'), match.captures[k]);
|
|
201
135
|
});
|
|
136
|
+
|
|
202
137
|
if (loc.length) r = applyPats(p, r, loc);
|
|
203
|
-
p.match =
|
|
138
|
+
p.match = match.matched;
|
|
204
139
|
const [ev, ct] = extractEvals(p, r);
|
|
205
140
|
if (ev.length) r = applyEvals(p, ct, ev);
|
|
206
|
-
|
|
207
|
-
|
|
141
|
+
|
|
142
|
+
n += r;
|
|
143
|
+
lastPos = match.end;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
n += src.slice(lastPos);
|
|
147
|
+
if (regexMatches.length > 0) src = n;
|
|
148
|
+
} else {
|
|
149
|
+
// Usa louro para padrões normais
|
|
150
|
+
const result = capture(src, pat.m, p.symbols);
|
|
151
|
+
|
|
152
|
+
if (result.count > 0) {
|
|
153
|
+
src = result.replace((match) => {
|
|
154
|
+
let r = pat.r;
|
|
155
|
+
const [loc, cln] = extractNested(p, r);
|
|
156
|
+
r = cln;
|
|
157
|
+
|
|
158
|
+
Object.keys(match.captures).forEach(k => {
|
|
159
|
+
r = r.replace(new RegExp(esc(p.symbols.sigil + k) + '(?![A-Za-z0-9_])', 'g'), match.captures[k]);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
if (loc.length) r = applyPats(p, r, loc);
|
|
163
|
+
p.match = match.matched;
|
|
164
|
+
const [ev, ct] = extractEvals(p, r);
|
|
165
|
+
if (ev.length) r = applyEvals(p, ct, ev);
|
|
166
|
+
|
|
167
|
+
return r;
|
|
168
|
+
});
|
|
169
|
+
}
|
|
208
170
|
}
|
|
209
|
-
if (ok) src = n;
|
|
210
171
|
}
|
|
211
172
|
return src;
|
|
212
173
|
}
|
|
213
174
|
|
|
214
175
|
function esc(s) { return s.replace(/[.*+?^${}()|[\]\\""']/g, '\\$&'); }
|
|
215
|
-
function unescapeDelim(s) {
|
|
216
|
-
let r = '';
|
|
217
|
-
for (let i = 0; i < s.length; i++) {
|
|
218
|
-
if (s[i] === '\\' && i + 1 < s.length && (s[i+1] === '"' || s[i+1] === "'" || s[i+1] === '\\')) { r += s[i+1]; i++; }
|
|
219
|
-
else r += s[i];
|
|
220
|
-
}
|
|
221
|
-
return r;
|
|
222
|
-
}
|
|
223
176
|
|
|
224
177
|
export class Papagaio {
|
|
225
178
|
constructor(sigil = '$', open = '{', close = '}', pattern = 'pattern', evalKw = 'eval', blockKw = 'recursive', regexKw = 'regex', blockseqKw = 'sequential') {
|
package/examples/simple.html
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>papagaio test</title>
|
|
7
|
-
</head>
|
|
8
|
-
<script src="../src/papagaio-bootstrap.mjs" type="module"></script>
|
|
9
|
-
<script type="papagaio">
|
|
10
|
-
$pattern {abc} {$eval{console.log(this)} aaaaaaaaaaaaaaaaaaaaaaaaaaaa}
|
|
11
|
-
abc
|
|
12
|
-
</script>
|
|
13
|
-
<body>
|
|
14
|
-
</body>
|
|
15
|
-
</html>
|
package/examples/wasm.papagaio
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
// generic ts-like to wasm compiler
|
|
2
|
-
|
|
3
|
-
// util patterns
|
|
4
|
-
$pattern {// $comment $regex newline{[^\n]*}} {}
|
|
5
|
-
$pattern {$regex spaces{\s\s}}{ }
|
|
6
|
-
|
|
7
|
-
$eval{
|
|
8
|
-
papagaio.exit = function()
|
|
9
|
-
{
|
|
10
|
-
papagaio.content = "(module\n" + papagaio.content + "\n)";
|
|
11
|
-
papagaio.exit = null;
|
|
12
|
-
};
|
|
13
|
-
return ""
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
$pattern {export function $name ${(}{)}params:$rets ${}{}content} {
|
|
17
|
-
$pattern {parametrize}
|
|
18
|
-
{
|
|
19
|
-
$eval {
|
|
20
|
-
let str = "$params".replace("(", "").replace(")", "");
|
|
21
|
-
let params = str.split(",").map(p => p.trim()).filter(p => p);
|
|
22
|
-
let new_stuff = "";
|
|
23
|
-
for (const param of params) {
|
|
24
|
-
if (!param.includes(":")) continue; // Pula se não tem ':'
|
|
25
|
-
const [name, type] = param.split(":");
|
|
26
|
-
if (name && type) { // Verifica se ambos existem
|
|
27
|
-
new_stuff += ` (param $${name.trim()} ${type.trim()}) `;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return new_stuff;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
(func (export "$name") parametrize (result $rets)
|
|
35
|
-
$content
|
|
36
|
-
)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
$pattern {function $name ${}{}params{(}{)}:$rets ${}{}content} {
|
|
40
|
-
$pattern {parametrize}
|
|
41
|
-
{
|
|
42
|
-
$eval {
|
|
43
|
-
let str = "$params".replace("(", "").replace(")", "");
|
|
44
|
-
let params = str.split(",").map(p => p.trim()).filter(p => p);
|
|
45
|
-
let new_stuff = "";
|
|
46
|
-
for (const param of params) {
|
|
47
|
-
if (!param.includes(":")) continue; // Pula se não tem ':'
|
|
48
|
-
const [name, type] = param.split(":");
|
|
49
|
-
if (name && type) { // Verifica se ambos existem
|
|
50
|
-
new_stuff += ` (param $${name.trim()} ${type.trim()}) `;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return new_stuff;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
(func $$name parametrize (result $rets)
|
|
58
|
-
$content
|
|
59
|
-
)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function name(a:i32, b:i32):i64 i64
|
|
63
|
-
{
|
|
64
|
-
contentnans
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export function funcao_exportada(a:f32, b:f32, c:f32):i64 i64 i64 i64
|
|
68
|
-
{
|
|
69
|
-
fução expoortada1
|
|
70
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// papagaio-bootstrap.js
|
|
2
|
-
// only needed if using <script type="papagaio"> in browser
|
|
3
|
-
import { Papagaio } from "./papagaio.js";
|
|
4
|
-
|
|
5
|
-
(async () => {
|
|
6
|
-
const p = new Papagaio();
|
|
7
|
-
|
|
8
|
-
const nodes = [...document.querySelectorAll('script[type="papagaio"]')];
|
|
9
|
-
|
|
10
|
-
for (const el of nodes) {
|
|
11
|
-
let src = el.textContent;
|
|
12
|
-
|
|
13
|
-
if (el.src) {
|
|
14
|
-
src = await fetch(el.src).then(r => r.text());
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const out = p.process(src);
|
|
18
|
-
|
|
19
|
-
const s = document.createElement("div");
|
|
20
|
-
s.textContent = out;
|
|
21
|
-
window.document.body.appendChild(s);
|
|
22
|
-
}
|
|
23
|
-
})();
|