papagaio 0.32.9 → 0.38.2
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 +160 -91
- package/dist/wasm/papagaio.js +30 -59
- package/dist/wasm/papagaio_wasm.js +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
# Papagaio
|
|
2
2
|
|
|
3
|
-
Papagaio is
|
|
3
|
+
Papagaio is an embeddable text processing engine.
|
|
4
4
|
|
|
5
5
|
## Key Features
|
|
6
6
|
|
|
7
7
|
- **Lightweight Core**: Efficient C engine for pattern matching and transformation.
|
|
8
8
|
- **Pattern-Matching**: Powerful capture system with built-in and custom modifiers.
|
|
9
|
-
- **WebAssembly Plugins**: Highly secure, zero-dependency plugin architecture via an embedded `wasm3` runtime.
|
|
10
9
|
- **Configurable Delimiters**: Redefine sigils, delimiters, and markers at runtime.
|
|
11
10
|
- **Language Bindings**: Native usage in C and Node.js/WebAssembly.
|
|
12
11
|
|
|
@@ -28,17 +27,6 @@ free(out);
|
|
|
28
27
|
papagaio_close(ctx);
|
|
29
28
|
```
|
|
30
29
|
|
|
31
|
-
### JavaScript / WASM (Node.js)
|
|
32
|
-
```javascript
|
|
33
|
-
import Papagaio from './papagaio.js';
|
|
34
|
-
|
|
35
|
-
const p = new Papagaio();
|
|
36
|
-
await p.init();
|
|
37
|
-
p.registerCommand("mycmd", (name, ...args) => `Result: ${args[0]}`);
|
|
38
|
-
|
|
39
|
-
console.log(p.process('$mycmd{Hello}')); // Output: Result: Hello
|
|
40
|
-
```
|
|
41
|
-
|
|
42
30
|
---
|
|
43
31
|
|
|
44
32
|
## Pattern Syntax
|
|
@@ -55,7 +43,6 @@ Modifiers specify the data type or constraints of a match:
|
|
|
55
43
|
- **Numbers**: `$var$int`, `$var$float`, `$var$number`
|
|
56
44
|
- **Casing**: `$var$upper`, `$var$lower`, `$var$capitalized`
|
|
57
45
|
- **Formats**: `$var$word`, `$var$identifier`, `$var$hex`, `$var$path`, `$var$binary`, `$var$percent`
|
|
58
|
-
- **Regex**: `$id$regex{[0-9]+}`
|
|
59
46
|
- **Block**: `$item$block{[}{]}` (captures everything between delimiters)
|
|
60
47
|
- **Aliases**: `$kind$aliases{cat}{dog}{bird}` (multi-block syntax).
|
|
61
48
|
- **Substrings**: `$var$starts{foo}`, `$var$ends{bar}`, `$var$prefix{p}`, `$var$suffix{s}`, `$var$infix{i}`, `$var$includes{x}`
|
|
@@ -94,17 +81,11 @@ $pattern {$n$aliases{$x$int}{abc}} {VALUE: $n}
|
|
|
94
81
|
|
|
95
82
|
---
|
|
96
83
|
|
|
97
|
-
## Extensibility (Wasm Plugins)
|
|
98
|
-
|
|
99
|
-
Papagaio follows a Wasm-first plugin architecture. Core features are limited to pattern matching and transformation, while custom text processing capabilities are provided by WebAssembly plugins.
|
|
100
|
-
|
|
101
84
|
### Built-in Operators
|
|
102
85
|
- **`$document`**: Injects the current state of the document (alias for `$document$current`).
|
|
103
86
|
- **`$document$original`**: Injects the initial, unprocessed input text. Useful for referencing the source even after multiple transformations.
|
|
104
87
|
- **`$document$current`**: Injects the current state of the document during the pre-processing pass.
|
|
105
|
-
-
|
|
106
|
-
- **$file{path}**: Injects the content of a file from the file system (CLI only).
|
|
107
|
-
- **`$wat{source}`**: Compiles a WebAssembly Text Format (WAT) source string inline and registers all exported `papagaio_*` functions as commands. Useful for embedding lightweight plugins without an external `.wasm` file.
|
|
88
|
+
- **$file{path}**: Injects the content of a file from the file system.
|
|
108
89
|
- **`$NAME$from{value}`**: Dynamically assigns a processed `value` to `$NAME`. The assignment itself is suppressed from the output, and the variable becomes available for exact-match replacement in the remaining document.
|
|
109
90
|
|
|
110
91
|
```text
|
|
@@ -113,15 +94,6 @@ Papagaio follows a Wasm-first plugin architecture. Core features are limited to
|
|
|
113
94
|
```
|
|
114
95
|
*Output: `Hello, Alice!`*
|
|
115
96
|
|
|
116
|
-
```text
|
|
117
|
-
$wat{
|
|
118
|
-
(module
|
|
119
|
-
(func (export "papagaio_hello") (result i32)
|
|
120
|
-
i32.const 42))
|
|
121
|
-
}
|
|
122
|
-
$hello
|
|
123
|
-
```
|
|
124
|
-
|
|
125
97
|
---
|
|
126
98
|
|
|
127
99
|
## CLI Argument Expansion
|
|
@@ -145,11 +117,11 @@ Arguments in the format `key=value` are automatically parsed and can be accessed
|
|
|
145
117
|
1. **Explicit**: `$args$key`
|
|
146
118
|
2. **Direct**: `$key` (shorthand for `$args$key`)
|
|
147
119
|
|
|
148
|
-
Direct access (`$key`) will only resolve if `key` does not conflict with a registered command
|
|
120
|
+
Direct access (`$key`) will only resolve if `key` does not conflict with a registered command or a built-in directive.
|
|
149
121
|
|
|
150
122
|
#### Example:
|
|
151
123
|
```sh
|
|
152
|
-
|
|
124
|
+
# Then compile ready.c with clang
|
|
153
125
|
```
|
|
154
126
|
Inside `input.c`:
|
|
155
127
|
```c
|
|
@@ -177,7 +149,7 @@ This changes the sigil to `@`, delimiters to `< >`, and the optional marker to `
|
|
|
177
149
|
|
|
178
150
|
## Recursive Priority System
|
|
179
151
|
|
|
180
|
-
Papagaio allows you to control the order of execution and side-effects (such as pattern definitions
|
|
152
|
+
Papagaio allows you to control the order of execution and side-effects (such as pattern definitions) using the **`$priority$N`** directive.
|
|
181
153
|
|
|
182
154
|
- **`$priority$0{...}`**: Maximum priority.
|
|
183
155
|
- **`$priority$max{...}`**: Alias for `INT_MIN + 1` (Absolute highest priority).
|
|
@@ -202,7 +174,7 @@ The **`$from`** operator allows you to capture processed content and assign it t
|
|
|
202
174
|
### Syntax
|
|
203
175
|
`$NAME$from{...content...}`
|
|
204
176
|
|
|
205
|
-
1. **Recursive Processing**: The `content` is fully processed (patterns,
|
|
177
|
+
1. **Recursive Processing**: The `content` is fully processed (patterns, other assignments) before being stored.
|
|
206
178
|
2. **Immediate Registration**: The variable is registered as an exact-match rule as soon as it is parsed. This allows for **chained assignments**.
|
|
207
179
|
3. **Output Suppression**: The entire `$from` directive is removed from the output text.
|
|
208
180
|
|
|
@@ -239,69 +211,160 @@ Result: FOO
|
|
|
239
211
|
|
|
240
212
|
---
|
|
241
213
|
|
|
242
|
-
##
|
|
214
|
+
## List Operations (`$list`)
|
|
243
215
|
|
|
244
|
-
|
|
216
|
+
Any variable can be treated as a list by accessing it through the `$list` modifier chain. The **separator** can be any string (single character or multi-character) and is itself **processed** before use, allowing dynamic separators.
|
|
217
|
+
|
|
218
|
+
### Syntax
|
|
245
219
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
```c
|
|
249
|
-
// Functions starting with 'papagaio_' are automatically registered as commands
|
|
250
|
-
char* papagaio_greet(int argc, char **argv)
|
|
251
|
-
{
|
|
252
|
-
if (argc < 1) return "Hello, Stranger!";
|
|
253
|
-
return argv[0]; // return first argument
|
|
254
|
-
}
|
|
220
|
+
```
|
|
221
|
+
$VARNAME$list{separator}$OPERATION{...arguments}
|
|
255
222
|
```
|
|
256
223
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
{
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
}
|
|
224
|
+
### Operations
|
|
225
|
+
|
|
226
|
+
| Operation | Signature | Emits | Mutates |
|
|
227
|
+
|---|---|---|---|
|
|
228
|
+
| `get` | `$V$list{sep}$get{idx}` | Element at index | No |
|
|
229
|
+
| `set` | `$V$list{sep}$set{idx}{content}` | Nothing | Yes |
|
|
230
|
+
| `push` | `$V$list{sep}$push{content}` | Nothing | Yes |
|
|
231
|
+
| `pop` | `$V$list{sep}$pop` | Last element | Yes |
|
|
232
|
+
| `shift` | `$V$list{sep}$shift` | First element | Yes |
|
|
233
|
+
| `unshift` | `$V$list{sep}$unshift{content}` | Nothing | Yes |
|
|
234
|
+
| `insert` | `$V$list{sep}$insert{idx}{content}` | Nothing | Yes |
|
|
235
|
+
| `remove` | `$V$list{sep}$remove{idx}` | Nothing | Yes |
|
|
236
|
+
| `swap` | `$V$list{sep}$swap{idx_a}{idx_b}` | Nothing | Yes |
|
|
237
|
+
| `reverse` | `$V$list{sep}$reverse` | Nothing | Yes |
|
|
238
|
+
| `count` | `$V$list{sep}$count` | Number of elements | No |
|
|
239
|
+
| `join` | `$V$list{sep_orig}$join{sep_new}` | List with new separator | No |
|
|
240
|
+
| `slice` | `$V$list{sep}$slice{start}{end}` | Sub-list from start to end | No |
|
|
241
|
+
| `find` | `$V$list{sep}$find{pat}` | First **whole element** matching `pat` | No |
|
|
242
|
+
| `contains` | `$V$list{sep}$contains{pat}` | Index of `pat` **within** matching element | No |
|
|
243
|
+
| `replace` | `$V$list{sep}$replace{pat}{rep}` | First match found; updates the **whole element** | Yes |
|
|
244
|
+
|
|
245
|
+
**Index rules**: zero-based; negative indices count from the end (`-1` = last); out-of-range access emits `""` silently.
|
|
246
|
+
|
|
247
|
+
### Examples
|
|
248
|
+
|
|
249
|
+
```text
|
|
250
|
+
$FRUITS$from{apple,banana,orange}
|
|
251
|
+
|
|
252
|
+
$FRUITS$list{,}$get{0} → apple
|
|
253
|
+
$FRUITS$list{,}$get{-1} → orange
|
|
254
|
+
$FRUITS$list{,}$count → 3
|
|
271
255
|
```
|
|
272
256
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
257
|
+
```text
|
|
258
|
+
$L$from{a,b,c}
|
|
259
|
+
$L$list{,}$push{d}
|
|
260
|
+
$L$list{,}$set{1}{B}
|
|
261
|
+
$L → a,B,c,d
|
|
277
262
|
```
|
|
278
|
-
This generates `greet.wasm`.
|
|
279
263
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
264
|
+
```text
|
|
265
|
+
$STACK$from{x,y,z}
|
|
266
|
+
Popped: $STACK$list{,}$pop
|
|
267
|
+
Rest: $STACK → Popped: z / Rest: x,y
|
|
283
268
|
```
|
|
284
|
-
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
./papagaiocc greet.c
|
|
269
|
+
|
|
270
|
+
```text
|
|
271
|
+
$CSV$from{one,two,three}
|
|
272
|
+
$CSV$list{,}$join{ | } → one | two | three
|
|
289
273
|
```
|
|
290
274
|
|
|
291
|
-
### 3. Use in Papagaio
|
|
292
|
-
Loading the Wasm file automatically registers all exported commands.
|
|
293
275
|
```text
|
|
294
|
-
$
|
|
295
|
-
$
|
|
276
|
+
$PATH$from{/usr/local/bin}
|
|
277
|
+
$PATH$list{/}$get{-1} → bin
|
|
296
278
|
```
|
|
297
|
-
*Output: Hello, Papagaio!*
|
|
298
279
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
280
|
+
```text
|
|
281
|
+
/* Dynamic separator from variable */
|
|
282
|
+
$SEP$from{,}
|
|
283
|
+
$L$from{x,y,z}
|
|
284
|
+
$L$list{$SEP}$get{2} → z
|
|
285
|
+
|
|
286
|
+
$L$from{a,b,c,d,e}
|
|
287
|
+
$L$list{,}$slice{1}{4} → b,c,d
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Flow Control Operators
|
|
293
|
+
|
|
294
|
+
Papagaio provides operators for conditional logic and value chaining. These are treated as **suffix modifiers** that can be appended to any variable, list operation, or expression.
|
|
295
|
+
|
|
296
|
+
### Syntax
|
|
297
|
+
|
|
298
|
+
```
|
|
299
|
+
$VAL$compare{target}
|
|
300
|
+
$VAL$find{pattern}
|
|
301
|
+
$VAL$contains{pattern}
|
|
302
|
+
$VAL$replace{pattern}{replacement}
|
|
303
|
+
$VAL$slice{start}{end}
|
|
304
|
+
$VAL$then{content}
|
|
305
|
+
$VAL$else{content}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
| Operator | Behavior |
|
|
309
|
+
|---|---|
|
|
310
|
+
| **`compare`** | If `$VAL` matches `target`, emits `$VAL`. Otherwise, emits `""`. |
|
|
311
|
+
| **`find`** | Performs a non-anchored search for `pattern` in `$VAL`. Emits the matched substring. |
|
|
312
|
+
| **`contains`** | Performs a non-anchored search. Emits the character index of the first match (or `""`). |
|
|
313
|
+
| **`replace`** | Replaces the first match of `pattern` with `replacement`. Emits the OLD match. |
|
|
314
|
+
| **`slice`** | Returns a substring from `start` to `end`. Supports negative indices. |
|
|
315
|
+
| **`then`** | If `$VAL` is **not empty**, processes and emits `content`. Otherwise, emits `""`. |
|
|
316
|
+
| **`else`** | If `$VAL` **is empty**, processes and emits `content`. Otherwise, passes `$VAL` through. |
|
|
317
|
+
| **`repeat`** | `$repeat{N}{code}` | Executes `code` N times. Emits nothing; used for side effects. |
|
|
318
|
+
| **`while`** | `$while{pat}{code}` | Executes `code` while its result matches `pat`. Emits the last successful result. |
|
|
319
|
+
| **`until`** | `$until{pat}{code}` | Executes `code` until its result matches `pat`. Emits the match that caused the break. |
|
|
320
|
+
| **`byte`** | `$byte{code}` | Appends a byte (0-255) to the variable or current stream. |
|
|
321
|
+
|
|
322
|
+
### Chaining (If-Then-Else)
|
|
323
|
+
|
|
324
|
+
Operators can be chained to create complex conditional logic. The output of one operator becomes the input for the next.
|
|
325
|
+
|
|
326
|
+
#### Basic If-Then:
|
|
327
|
+
```text
|
|
328
|
+
$A$from{hello}
|
|
329
|
+
$A$compare{hello}$then{Matched!} → Matched!
|
|
330
|
+
$A$compare{world}$then{Matched!} → (empty)
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
#### If-Then-Else Pattern:
|
|
334
|
+
```text
|
|
335
|
+
$A$from{abc}
|
|
336
|
+
$A$compare{abc}$then{YES}$else{NO} → YES
|
|
337
|
+
$A$compare{xyz}$then{YES}$else{NO} → NO
|
|
338
|
+
|
|
339
|
+
#### Search and Extract:
|
|
340
|
+
```text
|
|
341
|
+
$A$from{user_id: 12345}
|
|
342
|
+
$A$find{$d+}$ → 12345
|
|
343
|
+
$A$contains{id} → 5
|
|
344
|
+
$A$replace{$d+}{HIDDEN} $A → 12345 user_id: HIDDEN
|
|
345
|
+
|
|
346
|
+
#### Slicing:
|
|
347
|
+
```text
|
|
348
|
+
$A$from{hello world}
|
|
349
|
+
$A$slice{0}{5} → hello
|
|
350
|
+
$A$slice{-5} → world
|
|
351
|
+
```
|
|
352
|
+
```
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Standalone and Braced Usage
|
|
356
|
+
|
|
357
|
+
- **Standalone**: If used without a preceding variable (e.g., `$else{default}`), the input is assumed to be an empty string.
|
|
358
|
+
- **Braced**: You can pipe arbitrary braced expressions into flow operators: `${some content}$then{has content!}`.
|
|
359
|
+
|
|
360
|
+
#### Example:
|
|
361
|
+
```text
|
|
362
|
+
$L$from{a,b,c}
|
|
363
|
+
$R$from{$L$list{,}$get{0}}
|
|
364
|
+
$R$compare{a}$then{Is A}$else{Not A} → Is A
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
---
|
|
305
368
|
|
|
306
369
|
---
|
|
307
370
|
|
|
@@ -309,17 +372,23 @@ The Wasm SDK lives at `examples/lib.c` inside the repository. It is **not** auto
|
|
|
309
372
|
|
|
310
373
|
```sh
|
|
311
374
|
make # Core & CLI
|
|
312
|
-
make
|
|
313
|
-
make wasm # WebAssembly build (Papagaio in the browser/node)
|
|
375
|
+
make wasm # WebAssembly build (via Emscripten)
|
|
314
376
|
make test # Run comprehensive test suite
|
|
315
377
|
```
|
|
316
378
|
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## System Limits
|
|
382
|
+
|
|
383
|
+
| Feature | Limit | Rationale / Detail |
|
|
384
|
+
|---|---|---|
|
|
385
|
+
| **Symbol Length** | 15 characters | Sigils, delimiters (`{`, `}`), and markers are stored in fixed 16-byte buffers. |
|
|
386
|
+
| **String Size** | Unlimited | All internal buffers (`StrBuf`) use dynamic `realloc`. Limited only by available RAM. |
|
|
387
|
+
| **Pattern Count** | Unlimited | Registered rules are stored in a dynamic array. |
|
|
388
|
+
| **Priority Range** | `INT_MIN` to `INT_MAX` | Priorities are handled as standard signed integers. |
|
|
389
|
+
| **Recursion Depth** | Stack-limited | Deeply nested patterns or priority blocks are processed recursively. |
|
|
390
|
+
|
|
317
391
|
## References
|
|
318
392
|
|
|
319
393
|
- [cpp](https://en.wikipedia.org/wiki/C_preprocessor)
|
|
320
|
-
- [m4](https://www.gnu.org/software/m4/)
|
|
321
|
-
- [libregexp](https://bellard.org/quickjs/)
|
|
322
|
-
- [quickjs](https://bellard.org/quickjs/)
|
|
323
|
-
- [tcc](https://bellard.org/tcc/)
|
|
324
|
-
- [wasm3](https://github.com/wasm3/wasm3)
|
|
325
|
-
- [watr](https://github.com/dy/watr)
|
|
394
|
+
- [m4](https://www.gnu.org/software/m4/)
|
package/dist/wasm/papagaio.js
CHANGED
|
@@ -1,89 +1,60 @@
|
|
|
1
|
-
import
|
|
1
|
+
import ModuleFactory from './papagaio_wasm.js';
|
|
2
2
|
|
|
3
3
|
class Papagaio {
|
|
4
4
|
constructor() {
|
|
5
5
|
this._module = null;
|
|
6
|
+
this._ctx = null;
|
|
6
7
|
this._initialized = false;
|
|
7
|
-
this.
|
|
8
|
+
this._args = [];
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
async init() {
|
|
11
|
-
if (this._initialized) return;
|
|
12
|
-
|
|
12
|
+
if (this._initialized) return this;
|
|
13
|
+
|
|
14
|
+
// Load WASM module
|
|
15
|
+
this._module = await ModuleFactory();
|
|
13
16
|
this._ctx = this._module._papagaio_open();
|
|
14
17
|
this._initialized = true;
|
|
15
18
|
return this;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
registerCommand(name, handler) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// name=i, argc=ii, argv=iii, argl=iiii, userdata=iiiii
|
|
22
|
-
const wrapper = (ctx, namePtr, argc, argvPtr, arglPtr, userdata) => {
|
|
23
|
-
const cmdName = this._module.UTF8ToString(namePtr);
|
|
24
|
-
const args = [];
|
|
25
|
-
for (let i = 0; i < argc; i++) {
|
|
26
|
-
const ptr = this._module.getValue(argvPtr + (i * 4), "i32");
|
|
27
|
-
const len = this._module.getValue(arglPtr + (i * 4), "i32");
|
|
28
|
-
args.push(this._module.UTF8ToString(ptr, len));
|
|
29
|
-
}
|
|
30
|
-
const result = handler(cmdName, ...args);
|
|
31
|
-
|
|
32
|
-
if (result === null || result === undefined) return 0;
|
|
33
|
-
const resStr = String(result);
|
|
34
|
-
const resLen = this._module.lengthBytesUTF8(resStr) + 1;
|
|
35
|
-
const resPtr = this._module._malloc(resLen);
|
|
36
|
-
this._module.stringToUTF8(resStr, resPtr, resLen);
|
|
37
|
-
return resPtr;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const funcPtr = this._module.addFunction(wrapper, 'iiiiiii');
|
|
41
|
-
this._module.ccall(
|
|
42
|
-
"papagaio_register_command",
|
|
43
|
-
null,
|
|
44
|
-
["number", "string", "number", "number"],
|
|
45
|
-
[this._ctx, name, funcPtr, 0]
|
|
46
|
-
);
|
|
22
|
+
// Note: Implementing JS->C callbacks requires addFunction and extra glue.
|
|
47
23
|
}
|
|
48
24
|
|
|
49
25
|
setArgs(argv) {
|
|
50
|
-
if (!this._initialized) throw new Error("
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
/* Create a null-terminated array of string pointers in Wasm memory */
|
|
54
|
-
const ptrs = argv.map(str => {
|
|
55
|
-
const len = this._module.lengthBytesUTF8(str) + 1;
|
|
56
|
-
const ptr = this._module._malloc(len);
|
|
57
|
-
this._module.stringToUTF8(str, ptr, len);
|
|
58
|
-
return ptr;
|
|
59
|
-
});
|
|
26
|
+
if (!this._initialized) throw new Error("Papagaio not initialized. Call init() first.");
|
|
27
|
+
this._args = argv;
|
|
60
28
|
|
|
61
29
|
const argc = argv.length;
|
|
62
|
-
const argvPtr = this._module._malloc(argc * 4);
|
|
30
|
+
const argvPtr = this._module._malloc(argc * 4);
|
|
63
31
|
for (let i = 0; i < argc; i++) {
|
|
64
|
-
|
|
32
|
+
const str = argv[i];
|
|
33
|
+
const strLen = this._module.lengthBytesUTF8(str) + 1;
|
|
34
|
+
const strPtr = this._module._malloc(strLen);
|
|
35
|
+
this._module.stringToUTF8(str, strPtr, strLen);
|
|
36
|
+
this._module.setValue(argvPtr + (i * 4), strPtr, 'i32');
|
|
65
37
|
}
|
|
66
38
|
|
|
67
39
|
this._module._papagaio_set_args(this._ctx, argc, argvPtr);
|
|
68
|
-
|
|
69
|
-
|
|
40
|
+
// We don't free argvPtr/strPtr here as Papagaio context might use them.
|
|
41
|
+
// They will be "leaked" until destroy(), which is fine for a processing session.
|
|
70
42
|
}
|
|
71
43
|
|
|
72
44
|
process(text) {
|
|
73
|
-
if (!this._initialized)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
45
|
+
if (!this._initialized) throw new Error("Papagaio not initialized. Call init() first.");
|
|
46
|
+
|
|
47
|
+
const textLen = this._module.lengthBytesUTF8(text);
|
|
48
|
+
const textPtr = this._module._malloc(textLen + 1);
|
|
49
|
+
this._module.stringToUTF8(text, textPtr, textLen + 1);
|
|
50
|
+
|
|
51
|
+
const outPtr = this._module._papagaio_process_text(this._ctx, textPtr, textLen);
|
|
52
|
+
const output = this._module.UTF8ToString(outPtr);
|
|
53
|
+
|
|
54
|
+
this._module._free(textPtr);
|
|
55
|
+
this._module._free(outPtr);
|
|
82
56
|
|
|
83
|
-
|
|
84
|
-
const result = this._module.UTF8ToString(ptr);
|
|
85
|
-
this._module._free(ptr);
|
|
86
|
-
return result;
|
|
57
|
+
return output;
|
|
87
58
|
}
|
|
88
59
|
|
|
89
60
|
destroy() {
|
|
Binary file
|