- SPEC - review - 3 rounds
-
package.jsonwithnode --testas test runner (no dependencies) - Test harness: run
.gpjfiles, assert stdout/stderr/exit code - GitHub Actions CI: run tests on push
-
let/valdeclarations with primitives (Number, String, Boolean, None) -
Arithmetic and string concatenation with type checking
-
if/else,while,for -
Functions (declaration and arrow)
-
==/!=on primitives (emits===/!==),??(emits??) -
Arrays and
for...of -
Objects and structural types
-
__gpj_eqruntime (deep equality, seen-pair registry for circular refs) -
Modules (
import/export) -
Error handling (
try/catch/finally,throw) -
do/whileloops -
switch/case -
Spread operator (
...) and rest parameters -
Type aliases (
type Foo = ...) - parse and skip -
Destructuring (object, array, nested, rest, rename)
-
Compound assignment (
+=,-=,*=,/=,%=,**=) -
for...ofwith destructuring -
C-style
forloops -
F-strings (string interpolation) - see also INTRO
-
Ternary operator,
typeofoperator (foundational;typeofis prereq for type narrowing) -
Whitespace enforcement — spaces around binary operators required by parser (§1 of SPEC)
-
Type representation — parse type annotations into real AST nodes instead of discarding them (prerequisite for all type-checking steps)
-
Basic type inference and checking — variable declarations, literals, simple mismatches
-
Function types — check param/return annotations, infer return type from
returnstatements -
Union/nullable assignment checking — enable
UnionType/NullableTypeincheckCompat;T | Saccepts any matching member;T?accepts T or None; no narrowing yet -
typeofnarrowing — recognisetypeof x == "TypeName"inif/switchconditions; thread narrowed env into branch; narrow remainder into else; prerequisite for practical union use -
Typed catch —
catch (e: SomeType)generates a runtime structural guard; multiple catch blocks in order; re-throw if none match; union types in catch annotations -
Map and Set —
Map.of(...)/Set.of(...)factory transpilation;for...ofiteration; method pass-through -
Private properties —
_-prefixed property access only viathisinside the defining object literal; external access is a type error; tracked via parser object-literal context stack -
Method-call enforcement — MemberExpression with FunctionType property must be in call position;
v.methodwithout()is a type error; zero runtime cost -
Unknowntype — operations onUnknownare a type error; narrow withtypeoffirst;??on a non-nullable left operand is a type error
-
Stringbuilt-in methods — runtime preamble:at(n)→String | None;indexOf(s)→Number | None;split(sep)requires separator arg;String.compare(a, b)static method (spec §8);trim,slice,includes,startsWith,endsWith,toLowerCase,toUpperCase,replacepass through unchanged -
Arraybuilt-in methods — runtime preamble:pop()/shift()/find(fn)→T | None;findIndex(fn)/indexOf(v)→Number | None(indexOf uses__gpj_eq);sort(cmp)enforces comparator;map,filter,reduce,forEach,some,every,join,slice,concat,reverse,flat,flatMappass through -
JSON.decycle/JSON.encycle— add to runtime preamble per stdlib-notes.md;JSON.parse/JSON.stringifyare already JS globals, no work needed -
Stdlib import infrastructure — codegen rewrites bare-name imports (no
./prefix) to absolute paths pointing tosrc/stdlib/<name>.js; CLI refactored to write temp file + spawn Node when generated code contains top-levelimportstatements (prerequisite for 36-38) -
httpmodule —src/stdlib/http.js; sync HTTP via subprocess:get(url, options?)→{ok, status, text(), json()}; drives Node's built-infetchin a child process -
processmodule —src/stdlib/process.js; re-exportsprocess.env(object),process.argvasargs(Array),process.exit(code) -
fsmodule —src/stdlib/fs.js; sync wrappers:readFile(path),writeFile(path, data),exists(path),readDir(path),makeDir(path),removeFile(path)
Milestone: example/gh-ci-stat.gpj — synchronous GPJ equivalent of the promise-chained JS version;
uses http.get, f-strings, try/catch, array indexing, object access
TODO