porffor 0.59.8 → 0.59.9

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/compiler/2c.js CHANGED
@@ -534,8 +534,9 @@ export default ({ funcs, globals, data, pages }) => {
534
534
  case Opcodes.if: {
535
535
  let cond = removeBrackets(vals.pop());
536
536
  if (!lastCond) {
537
- if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} != 0e+0`;
538
- else cond = `(${cond}) != 0`;
537
+ // if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} != 0e+0`;
538
+ // else cond = `(${cond}) != 0`;
539
+ cond = `(${cond}) != 0`;
539
540
  }
540
541
 
541
542
  line(`// if ${invValtype[i[1]] ?? ''}`, false);
@@ -600,7 +601,7 @@ export default ({ funcs, globals, data, pages }) => {
600
601
  const importFunc = importFuncs[i[1]];
601
602
  switch (importFunc.name) {
602
603
  case 'print':
603
- line(`printf("${valtype === 'f64' ? '%g' : '%i'}", ${vals.pop()})`);
604
+ line(`printf("${valtype === 'f64' ? '%.15g' : '%i'}", ${vals.pop()})`);
604
605
  includes.set('stdio.h', true);
605
606
  break;
606
607
  case 'printChar':
@@ -772,8 +773,9 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
772
773
 
773
774
  let cond = removeBrackets(vals.pop());
774
775
  if (!lastCond) {
775
- if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} != 0e+0`;
776
- else cond = `(${cond}) != 0`;
776
+ // if (cond.startsWith(`(i32)`)) cond = `${cond.slice(5)} != 0e+0`;
777
+ // else cond = `(${cond}) != 0`;
778
+ cond = `(${cond}) != 0`;
777
779
  }
778
780
 
779
781
  line(`if (${cond}) {`, false);
@@ -29,62 +29,6 @@ export const __Porffor_printHexDigit = (arg: number) => {
29
29
  }
30
30
  };
31
31
 
32
- export const __Porffor_numberLog = (arg: number) => {
33
- print(arg);
34
- Porffor.printStatic('\n');
35
- };
36
-
37
- export const __Porffor_miniLog = (arg: any) => {
38
- switch (Porffor.type(arg)) {
39
- case Porffor.TYPES.number:
40
- print(arg);
41
- break;
42
-
43
- case Porffor.TYPES.boolean:
44
- if (arg) {
45
- Porffor.printStatic('true');
46
- } else {
47
- Porffor.printStatic('false');
48
- }
49
- break;
50
-
51
- case Porffor.TYPES.bytestring:
52
- case Porffor.TYPES.string:
53
- Porffor.printStatic("'");
54
- __Porffor_printString(arg);
55
- Porffor.printStatic("'");
56
- break;
57
-
58
- case Porffor.TYPES.array:
59
- const arrLen: i32 = arg.length - 1;
60
- if (arrLen == -1) {
61
- Porffor.printStatic('[]');
62
- } else {
63
- Porffor.printStatic('[ ');
64
- for (let i: i32 = 0; i <= arrLen; i++) {
65
- __Porffor_miniLog(arg[i]);
66
- if (i != arrLen) Porffor.printStatic(', ');
67
- }
68
- Porffor.printStatic(' ]');
69
- }
70
- break;
71
-
72
- case Porffor.TYPES.undefined:
73
- Porffor.printStatic('undefined');
74
- break;
75
-
76
- case Porffor.TYPES.object:
77
- if (arg) {
78
- Porffor.printStatic('[Object]');
79
- } else {
80
- Porffor.printStatic('null');
81
- }
82
- break;
83
- }
84
-
85
- Porffor.printStatic('\n');
86
- };
87
-
88
32
  export const __Porffor_print = (arg: any, colors: boolean = true, depth: number = 0) => {
89
33
  const __Porffor_printArray = (arg: any[]|Uint8Array|Int8Array|Uint8ClampedArray|Uint16Array|Int16Array|Uint32Array|Int32Array|Float32Array|Float64Array, colors: boolean, length: boolean = false) => {
90
34
  const arrLen: i32 = arg.length;
@@ -46,8 +46,10 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
46
46
  Porffor.bytestring.append2Char(out, 92, 117); // \u
47
47
  Porffor.bytestring.append2Char(out, 48, 48); // 00
48
48
 
49
- Porffor.printHexDigit((c & 0xf0) / 0x10);
50
- Porffor.printHexDigit(c & 0x0f);
49
+ const h1: i32 = (c & 0xf0) / 0x10;
50
+ const h2: i32 = c & 0x0f;
51
+ Porffor.bytestring.appendChar(out, h1 < 10 ? h1 + 48 : h1 + 55); // 0-9 or A-F
52
+ Porffor.bytestring.appendChar(out, h2 < 10 ? h2 + 48 : h2 + 55); // 0-9 or A-F
51
53
  continue;
52
54
  }
53
55
 
@@ -73,7 +75,7 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
73
75
  Porffor.type(value) == Porffor.TYPES.number,
74
76
  Porffor.type(value) == Porffor.TYPES.numberobject
75
77
  )) { // number
76
- if (Number.isFinite(value)) return __Number_prototype_toString(value, 10);
78
+ if (Number.isFinite(value)) return value + '';
77
79
  return 'null';
78
80
  }
79
81
 
@@ -87,7 +89,7 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
87
89
  for (const x of (value as any[])) {
88
90
  if (hasSpace) {
89
91
  Porffor.bytestring.appendChar(out, 10); // \n
90
- for (let i: i32 = 0; i < depth; i++) Porffor.bytestring.appendStr(out, space);
92
+ for (let i: i32 = 0; i < depth; i++) Porffor.bytestring.appendStr(out, space as bytestring);
91
93
  }
92
94
 
93
95
  Porffor.bytestring.appendStr(out, __Porffor_json_serialize(x, depth, space) ?? 'null');
@@ -100,10 +102,9 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
100
102
  // swap trailing , with ] (or append if empty)
101
103
  if (out.length > 1) {
102
104
  if (hasSpace) {
103
- Porffor.wasm.i32.store8(Porffor.wasm`local.get ${out}` + out.length, 10, 0, 3); // \n
104
- for (let i: i32 = 0; i < depth; i++) Porffor.bytestring.appendStr(out, space);
105
- Porffor.wasm.i32.store8(Porffor.wasm`local.get ${out}` + out.length, 93, 0, 4); // ]
106
- out.length += 1;
105
+ Porffor.bytestring.appendChar(out, 10); // \n
106
+ for (let i: i32 = 0; i < depth; i++) Porffor.bytestring.appendStr(out, space as bytestring);
107
+ Porffor.bytestring.appendChar(out, 93); // ]
107
108
  } else {
108
109
  Porffor.wasm.i32.store8(Porffor.wasm`local.get ${out}` + out.length, 93, 0, 3); // ]
109
110
  }
@@ -132,7 +133,7 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
132
133
 
133
134
  if (hasSpace) {
134
135
  Porffor.bytestring.appendChar(out, 10); // \n
135
- for (let i: i32 = 0; i < depth; i++) Porffor.bytestring.appendStr(out, space);
136
+ for (let i: i32 = 0; i < depth; i++) Porffor.bytestring.appendStr(out, space as bytestring);
136
137
  }
137
138
 
138
139
  Porffor.bytestring.appendChar(out, 34); // "
@@ -152,10 +153,9 @@ export const __Porffor_json_serialize = (value: any, depth: i32, space: bytestri
152
153
  // swap trailing , with } (or append if empty)
153
154
  if (out.length > 1) {
154
155
  if (hasSpace) {
155
- Porffor.wasm.i32.store8(Porffor.wasm`local.get ${out}` + out.length, 10, 0, 3); // \n
156
- for (let i: i32 = 0; i < depth; i++) Porffor.bytestring.appendStr(out, space);
157
- Porffor.wasm.i32.store8(Porffor.wasm`local.get ${out}` + out.length, 125, 0, 4); // }
158
- out.length += 1;
156
+ Porffor.bytestring.appendChar(out, 10); // \n
157
+ for (let i: i32 = 0; i < depth; i++) Porffor.bytestring.appendStr(out, space as bytestring);
158
+ Porffor.bytestring.appendChar(out, 125); // }
159
159
  } else {
160
160
  Porffor.wasm.i32.store8(Porffor.wasm`local.get ${out}` + out.length, 125, 0, 3); // }
161
161
  }
@@ -183,7 +183,6 @@ export const __JSON_stringify = (value: any, replacer: any, space: any) => {
183
183
  Porffor.type(space) == Porffor.TYPES.numberobject
184
184
  )) {
185
185
  space = Math.min(Math.trunc(space), 10);
186
- Porffor.print(space); Porffor.printStatic('\n');
187
186
 
188
187
  if (space < 1) {
189
188
  space = undefined;
@@ -211,4 +210,197 @@ export const __JSON_stringify = (value: any, replacer: any, space: any) => {
211
210
  }
212
211
 
213
212
  return __Porffor_json_serialize(value, 0, space);
213
+ };
214
+
215
+
216
+ // todo: not globals when closures work well
217
+ let text: bytestring, pos: i32, len: i32;
218
+ export const __JSON_parse = (_: bytestring) => {
219
+ text = _;
220
+ pos = 0;
221
+ len = text.length;
222
+
223
+ const skipWhitespace = () => {
224
+ while (pos < len) {
225
+ const c: i32 = text.charCodeAt(pos);
226
+ if (c > 32) break; // fast path
227
+
228
+ if (c == 32 || c == 9 || c == 10 || c == 13) pos++;
229
+ else break;
230
+ }
231
+ };
232
+
233
+ const parseValue = (): any => {
234
+ skipWhitespace();
235
+ if (pos >= len) throw new SyntaxError('Unexpected end of JSON input');
236
+
237
+ const c: i32 = text.charCodeAt(pos);
238
+ if (c == 110) { // 'n' - null
239
+ if (pos + 4 <= len &&
240
+ text.charCodeAt(pos + 1) == 117 && // 'u'
241
+ text.charCodeAt(pos + 2) == 108 && // 'l'
242
+ text.charCodeAt(pos + 3) == 108) { // 'l'
243
+ pos += 4;
244
+ return null;
245
+ }
246
+ throw new SyntaxError('Unexpected token');
247
+ }
248
+
249
+ if (c == 116) { // 't' - true
250
+ if (pos + 4 <= len &&
251
+ text.charCodeAt(pos + 1) == 114 && // 'r'
252
+ text.charCodeAt(pos + 2) == 117 && // 'u'
253
+ text.charCodeAt(pos + 3) == 101) { // 'e'
254
+ pos += 4;
255
+ return true;
256
+ }
257
+ throw new SyntaxError('Unexpected token');
258
+ }
259
+
260
+ if (c == 102) { // 'f' - false
261
+ if (pos + 5 <= len &&
262
+ text.charCodeAt(pos + 1) == 97 && // 'a'
263
+ text.charCodeAt(pos + 2) == 108 && // 'l'
264
+ text.charCodeAt(pos + 3) == 115 && // 's'
265
+ text.charCodeAt(pos + 4) == 101) { // 'e'
266
+ pos += 5;
267
+ return false;
268
+ }
269
+ throw new SyntaxError('Unexpected token');
270
+ }
271
+
272
+ if (c == 34) { // '"' - string
273
+ pos++;
274
+ const out: bytestring = Porffor.allocate();
275
+
276
+ while (pos < len) {
277
+ const ch: i32 = text.charCodeAt(pos);
278
+ if (ch == 34) { // closing "
279
+ pos++;
280
+ return out;
281
+ }
282
+ if (ch == 92) { // backslash
283
+ pos++;
284
+ if (pos >= len) throw new SyntaxError('Unterminated string');
285
+
286
+ const esc: i32 = text.charCodeAt(pos++);
287
+ if (esc == 34) Porffor.bytestring.appendChar(out, 34); // \"
288
+ else if (esc == 92) Porffor.bytestring.appendChar(out, 92); // \\
289
+ else if (esc == 47) Porffor.bytestring.appendChar(out, 47); // \/
290
+ else if (esc == 98) Porffor.bytestring.appendChar(out, 8); // \b
291
+ else if (esc == 102) Porffor.bytestring.appendChar(out, 12); // \f
292
+ else if (esc == 110) Porffor.bytestring.appendChar(out, 10); // \n
293
+ else if (esc == 114) Porffor.bytestring.appendChar(out, 13); // \r
294
+ else if (esc == 116) Porffor.bytestring.appendChar(out, 9); // \t
295
+ else if (esc == 117) { // \u
296
+ if (pos + 4 >= len) throw new SyntaxError('Invalid unicode escape');
297
+ let unicode: i32 = 0;
298
+ for (let i: i32 = 0; i < 4; i++) {
299
+ const hex: i32 = text.charCodeAt(pos + i);
300
+ unicode <<= 4;
301
+ if (hex >= 48 && hex <= 57) unicode |= hex - 48; // 0-9
302
+ else if (hex >= 65 && hex <= 70) unicode |= hex - 55; // A-F
303
+ else if (hex >= 97 && hex <= 102) unicode |= hex - 87; // a-f
304
+ else throw new SyntaxError('Invalid unicode escape');
305
+ }
306
+ pos += 4;
307
+ Porffor.bytestring.appendChar(out, unicode);
308
+ } else throw new SyntaxError('Invalid escape sequence');
309
+ } else {
310
+ if (ch >= 0x00 && ch <= 0x1f) throw new SyntaxError('Unescaped control character');
311
+ Porffor.bytestring.appendChar(out, ch);
312
+ pos++;
313
+ }
314
+ }3
315
+ throw new SyntaxError('Unterminated string');
316
+ }
317
+
318
+ if (c == 91) { // '[' - array
319
+ pos++;
320
+ const arr: any[] = Porffor.allocate();
321
+ skipWhitespace();
322
+
323
+ if (pos < len && text.charCodeAt(pos) == 93) { // empty array
324
+ pos++;
325
+ return arr;
326
+ }
327
+
328
+ while (true) {
329
+ arr.push(parseValue());
330
+ skipWhitespace();
331
+ if (pos >= len) throw new SyntaxError('Unterminated array');
332
+
333
+ const next: i32 = text.charCodeAt(pos);
334
+ if (next == 93) { // ]
335
+ pos++;
336
+ break;
337
+ }
338
+ if (next == 44) { // ,
339
+ pos++;
340
+ continue;
341
+ }
342
+ throw new SyntaxError('Expected , or ]');
343
+ }
344
+ return arr;
345
+ }
346
+
347
+ if (c == 123) { // '{' - object
348
+ pos++;
349
+ const obj: any = {};
350
+ skipWhitespace();
351
+
352
+ if (pos < len && text.charCodeAt(pos) == 125) { // empty object
353
+ pos++;
354
+ return obj;
355
+ }
356
+
357
+ while (true) {
358
+ skipWhitespace();
359
+ if (pos >= len || text.charCodeAt(pos) != 34) throw new SyntaxError('Expected string key');
360
+
361
+ const key: any = parseValue();
362
+ skipWhitespace();
363
+ if (pos >= len || text.charCodeAt(pos) != 58) throw new SyntaxError('Expected :');
364
+ pos++;
365
+
366
+ const value: any = parseValue();
367
+ obj[key] = value;
368
+
369
+ skipWhitespace();
370
+ if (pos >= len) throw new SyntaxError('Unterminated object');
371
+
372
+ const next: i32 = text.charCodeAt(pos);
373
+ if (next == 125) { // }
374
+ pos++;
375
+ break;
376
+ }
377
+ if (next == 44) { // ,
378
+ pos++;
379
+ continue;
380
+ }
381
+ throw new SyntaxError('Expected , or }');
382
+ }
383
+ return obj;
384
+ }
385
+
386
+ // number
387
+ if ((c >= 48 && c <= 57) || c == 45) { // 0-9 or -
388
+ const start: i32 = pos;
389
+ if (c == 45) pos++; // skip -
390
+
391
+ while (pos < len) {
392
+ const ch: i32 = text.charCodeAt(pos);
393
+ if (ch >= 48 && ch <= 57) pos++; // 0-9
394
+ else if (ch == 46 || ch == 101 || ch == 69) pos++; // . e E
395
+ else if ((ch == 43 || ch == 45) && pos > start + 1) pos++; // + - (not at start)
396
+ else break;
397
+ }
398
+
399
+ return +ecma262.StringToNumber(__ByteString_prototype_slice(text, start, pos));
400
+ }
401
+
402
+ throw new SyntaxError('Unexpected token');
403
+ };
404
+
405
+ return parseValue();
214
406
  };