porffor 0.16.0-c6061294e โ 0.16.0-c86dc1d57
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/CONTRIBUTING.md +2 -3
- package/compiler/2c.js +23 -25
- package/compiler/builtins/console.ts +2 -4
- package/compiler/builtins/porffor.d.ts +0 -11
- package/compiler/builtins/set.ts +2 -3
- package/compiler/builtins/symbol.ts +6 -6
- package/compiler/builtins.js +2 -2
- package/compiler/codegen.js +1 -1
- package/compiler/parse.js +1 -1
- package/package.json +1 -1
package/CONTRIBUTING.md
CHANGED
@@ -206,7 +206,6 @@ Store the character code into the `out` pointer variable, and increment it.
|
|
206
206
|
- You cannot use other functions in the file not exported, or variables not inside the current function.
|
207
207
|
- `if (...)` uses a fast truthy implementation which is not spec-compliant as most conditions should be strictly checked. To use spec-compliant behavior, use `if (Boolean(...))`.
|
208
208
|
- For object (string/array/etc) literals, you must use a variable eg `const out: bytestring = 'foobar'; console.log(out);` instead of `console.log('foobar')` due to precompile's allocator constraints.
|
209
|
-
- Generally prefer/use non-strict equality ops (`==`/`!=`).
|
210
209
|
|
211
210
|
<br>
|
212
211
|
|
@@ -233,7 +232,7 @@ builtins/tostring_number: impl radix
|
|
233
232
|
|
234
233
|
## Test262
|
235
234
|
|
236
|
-
|
235
|
+
Make sure you have Test262 cloned already **inside of `test262/`** (`git clone https://github.com/tc39/test262.git test262/test262`) and run `npm install` inside `test262/` too.
|
237
236
|
|
238
237
|
Run `node test262` to run all the tests and get an output of total overall test results.
|
239
238
|
|
@@ -247,7 +246,7 @@ The main thing you want to pay attention to is the emoji summary (lol):
|
|
247
246
|
To break this down:
|
248
247
|
๐งช total ๐ค pass โ fail ๐ runtime error ๐ todo (error) โฐ timeout ๐๏ธ wasm compile error ๐ฅ compile error
|
249
248
|
|
250
|
-
The diff compared to the last commit (with test262 data) is shown in brackets. Basically, you
|
249
|
+
The diff compared to the last commit (with test262 data) is shown in brackets. Basically, you can passes ๐ค up, and errors ๐๐๐๐ฅ down. It is fine if some errors change balance/etc, as long as they are not new failures.
|
251
250
|
|
252
251
|
It will also log new passes/fails. Be careful as sometimes the overall passes can increase, but other files have also regressed into failures which you might miss. Also keep in mind some tests may have been false positives before, but we can investigate the diff together :)
|
253
252
|
|
package/compiler/2c.js
CHANGED
@@ -156,7 +156,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
156
156
|
}
|
157
157
|
|
158
158
|
if (data.length > 0) {
|
159
|
-
prependMain.set('_data', data.map(x => `memcpy(_memory + ${x.offset}, (unsigned char[]){${x.bytes.join(',')}}, ${x.bytes.length});`).join('\n
|
159
|
+
prependMain.set('_data', data.map(x => `memcpy(_memory + ${x.offset}, (unsigned char[]){${x.bytes.join(',')}}, ${x.bytes.length});`).join('\n'));
|
160
160
|
}
|
161
161
|
|
162
162
|
if (importFuncs.find(x => x.name === '__Porffor_readArgv')) {
|
@@ -168,10 +168,10 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
168
168
|
|
169
169
|
let depth = 1;
|
170
170
|
let brDepth = 0;
|
171
|
-
const line = (str, semi = true) => out += `${' '.repeat(
|
171
|
+
const line = (str, semi = true) => out += `${' '.repeat(depth * 2 + brDepth * 2)}${str}${semi ? ';' : ''}\n`;
|
172
172
|
const lines = lines => {
|
173
173
|
for (const x of lines) {
|
174
|
-
out += `${' '.repeat(
|
174
|
+
out += `${' '.repeat(depth * 2)}${x}\n`;
|
175
175
|
}
|
176
176
|
};
|
177
177
|
|
@@ -222,7 +222,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
222
222
|
else out += `${f.internal ? (returns ? CValtype.f64 : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')}) {\n`;
|
223
223
|
|
224
224
|
if (f.name === 'main') {
|
225
|
-
out +=
|
225
|
+
out += [...prependMain.values()].join('\n');
|
226
226
|
if (prependMain.size > 0) out += '\n\n';
|
227
227
|
}
|
228
228
|
|
@@ -439,7 +439,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
|
|
439
439
|
includes.set('stdio.h', true);
|
440
440
|
break;
|
441
441
|
case 'printChar':
|
442
|
-
line(`
|
442
|
+
line(`printf("%c", (int)(${vals.pop()}))`);
|
443
443
|
includes.set('stdio.h', true);
|
444
444
|
break;
|
445
445
|
|
@@ -470,11 +470,14 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
470
470
|
winIncludes.set('windows.h', true);
|
471
471
|
break;
|
472
472
|
|
473
|
-
case '__Porffor_readArgv':
|
473
|
+
case '__Porffor_readArgv':
|
474
|
+
includes.set('stdlib.h', true);
|
475
|
+
|
474
476
|
prepend.set('__Porffor_readArgv',
|
475
|
-
`
|
477
|
+
`void __Porffor_readArgv(u32 index, u32 outPtr) {
|
476
478
|
if (index >= _argc) {
|
477
|
-
|
479
|
+
printf("expected %d arguments\\n", index);
|
480
|
+
exit(1);
|
478
481
|
}
|
479
482
|
|
480
483
|
char* arg = _argv[index];
|
@@ -487,24 +490,23 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
487
490
|
}
|
488
491
|
|
489
492
|
memcpy(_memory + outPtr, &read, sizeof(read));
|
490
|
-
return read;
|
491
493
|
}`);
|
492
494
|
|
493
|
-
|
494
|
-
|
495
|
-
vals.push(`(f64)__Porffor_readArgv((u32)(${index}), (u32)(${outPtr}))`);
|
495
|
+
line(`__Porffor_readArgv((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
|
496
|
+
vals.pop();
|
496
497
|
break;
|
497
|
-
}
|
498
498
|
|
499
|
-
case '__Porffor_readFile':
|
499
|
+
case '__Porffor_readFile':
|
500
500
|
includes.set('stdio.h', true);
|
501
|
+
includes.set('stdlib.h', true);
|
501
502
|
|
502
503
|
prepend.set('__Porffor_readFile',
|
503
|
-
`
|
504
|
+
`void __Porffor_readFile(u32 pathPtr, u32 outPtr) {
|
504
505
|
char* path = _memory + pathPtr + 4;
|
505
506
|
FILE* fp = fopen(path, "r");
|
506
507
|
if (fp == NULL) {
|
507
|
-
|
508
|
+
printf("failed to open file: %s\\n", path);
|
509
|
+
exit(1);
|
508
510
|
}
|
509
511
|
|
510
512
|
u32 read = 0;
|
@@ -517,13 +519,10 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
517
519
|
fclose(fp);
|
518
520
|
|
519
521
|
memcpy(_memory + outPtr, &read, sizeof(read));
|
520
|
-
return read;
|
521
522
|
}`);
|
522
|
-
|
523
|
-
|
524
|
-
vals.push(`(f64)__Porffor_readFile((u32)(${pathPtr}), (u32)(${outPtr}))`);
|
523
|
+
line(`__Porffor_readFile((u32)(${vals.at(-2)}), (u32)(${vals.pop()}))`);
|
524
|
+
vals.pop();
|
525
525
|
break;
|
526
|
-
}
|
527
526
|
|
528
527
|
default:
|
529
528
|
log.warning('2c', `unimplemented import: ${importFunc.name}`);
|
@@ -540,10 +539,9 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
|
|
540
539
|
if (func.internal) {
|
541
540
|
vals.push(`${sanitize(func.name)}(${args.join(', ')})`);
|
542
541
|
} else {
|
543
|
-
const
|
544
|
-
|
545
|
-
vals.push(`_
|
546
|
-
vals.push(`_${id}.type`);
|
542
|
+
line(`const struct ReturnValue _${retTmpId++} = ${sanitize(func.name)}(${args.join(', ')})`);
|
543
|
+
vals.push(`_.value`);
|
544
|
+
vals.push(`_.type`);
|
547
545
|
}
|
548
546
|
} else line(`${sanitize(func.name)}(${args.join(', ')})`);
|
549
547
|
|
@@ -22,14 +22,6 @@ type PorfforGlobal = {
|
|
22
22
|
}
|
23
23
|
}
|
24
24
|
|
25
|
-
allocate(): any;
|
26
|
-
set: {
|
27
|
-
read(_this: any, index: number): i32;
|
28
|
-
write(_this: any, index: number, value: any): boolean;
|
29
|
-
}
|
30
|
-
|
31
|
-
print(x: any): i32;
|
32
|
-
|
33
25
|
randomByte(): i32;
|
34
26
|
|
35
27
|
type(x: any): bytestring;
|
@@ -56,9 +48,6 @@ type PorfforGlobal = {
|
|
56
48
|
|
57
49
|
s(...args: any): string;
|
58
50
|
bs(...args: any): bytestring;
|
59
|
-
|
60
|
-
readArgv(index: i32, out: bytestring): i32;
|
61
|
-
readFile(path: bytestring, out: bytestring): i32;
|
62
51
|
};
|
63
52
|
|
64
53
|
declare global {
|
package/compiler/builtins/set.ts
CHANGED
@@ -189,10 +189,9 @@ export const Set$constructor = (iterable: any): Set => {
|
|
189
189
|
|
190
190
|
export const __Set_prototype_union = (_this: Set, other: any) => {
|
191
191
|
if (Porffor.rawType(other) != Porffor.TYPES.set) {
|
192
|
-
throw new TypeError("Set.
|
192
|
+
throw new TypeError("Set.union requires 'Set'");
|
193
193
|
}
|
194
|
-
|
195
|
-
const out: Set = Set$constructor(_this);
|
194
|
+
const out: Set = new Set(_this);
|
196
195
|
for (const x of other) {
|
197
196
|
out.add(x);
|
198
197
|
}
|
@@ -8,10 +8,10 @@ export const __Porffor_symbol_descStore = (op: boolean, value: any): any => {
|
|
8
8
|
Porffor.wasm.i32.store(ptr, size + 1, 0, 0)
|
9
9
|
|
10
10
|
// reuse set internals to store description
|
11
|
-
|
11
|
+
__Porffor_set_write(ptr, size, value);
|
12
12
|
return size;
|
13
13
|
} else { // read
|
14
|
-
return
|
14
|
+
return __Porffor_set_read(ptr, value);
|
15
15
|
}
|
16
16
|
};
|
17
17
|
|
@@ -21,8 +21,8 @@ export const Symbol = (description: any): Symbol => {
|
|
21
21
|
};
|
22
22
|
|
23
23
|
export const __Symbol_prototype_description$get = (_this: Symbol) => {
|
24
|
-
const description: bytestring =
|
25
|
-
|
24
|
+
const description: bytestring = __Porffor_symbol_descStore(false,
|
25
|
+
Porffor.wasm`local.get ${_this}` - 1);
|
26
26
|
return description;
|
27
27
|
};
|
28
28
|
|
@@ -38,8 +38,8 @@ export const __Symbol_prototype_toString = (_this: Symbol) => {
|
|
38
38
|
Porffor.wasm.i32.store8(out, 108, 0, 9);
|
39
39
|
Porffor.wasm.i32.store8(out, 40, 0, 10);
|
40
40
|
|
41
|
-
const description: bytestring =
|
42
|
-
|
41
|
+
const description: bytestring = __Porffor_symbol_descStore(false,
|
42
|
+
Porffor.wasm`local.get ${_this}` - 1);
|
43
43
|
|
44
44
|
const descLen: i32 = description.length;
|
45
45
|
let outPtr: i32 = Porffor.wasm`local.get ${out}` + 7;
|
package/compiler/builtins.js
CHANGED
package/compiler/codegen.js
CHANGED
@@ -2582,7 +2582,7 @@ const generateUnary = (scope, decl) => {
|
|
2582
2582
|
|
2583
2583
|
case '!':
|
2584
2584
|
const arg = decl.argument;
|
2585
|
-
if (arg.type ===
|
2585
|
+
if (arg.type === "UnaryExpression" && arg.operator === "!") {
|
2586
2586
|
// !!x -> is x truthy
|
2587
2587
|
return truthy(scope, generate(scope, arg.argument), getNodeType(scope, arg.argument), false, false);
|
2588
2588
|
}
|
package/compiler/parse.js
CHANGED
@@ -10,7 +10,7 @@ if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
|
|
10
10
|
const file = process.argv.slice(2).find(x => x[0] !== '-' && !['run', 'wasm', 'native', 'c', 'profile', 'debug', 'debug-wasm'].includes(x));
|
11
11
|
|
12
12
|
// should we try to support types (while parsing)
|
13
|
-
const types = Prefs.parseTypes ||
|
13
|
+
const types = Prefs.parseTypes || file?.endsWith('.ts');
|
14
14
|
globalThis.typedInput = types && Prefs.optTypes;
|
15
15
|
|
16
16
|
// todo: review which to use by default
|
package/package.json
CHANGED