From b78b8e1141e83538d94da92abcaa2dec4dfa00bd Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 13:12:55 +0300 Subject: [PATCH 01/35] preexpand_body converted --- src/data.ts | 23 +++++++++++++ src/expander.ts | 72 +++++++++++++++++++++++---------------- src/preexpand-handlers.ts | 51 ++++++++++++++++++--------- tsconfig.tsbuildinfo | 2 +- 4 files changed, 101 insertions(+), 47 deletions(-) create mode 100644 src/data.ts diff --git a/src/data.ts b/src/data.ts new file mode 100644 index 0000000..d36eb40 --- /dev/null +++ b/src/data.ts @@ -0,0 +1,23 @@ +import { preexpand_helpers } from "./preexpand-helpers"; +import { import_req, lexical_extension, modular_extension } from "./stx"; +import { CompilationUnit, Context, Loc } from "./syntax-structures"; + +export type goodies = { + loc: Loc; + lexical: lexical_extension; + context: Context; + counter: number; + unit: CompilationUnit; + helpers: preexpand_helpers; +}; + +//export type data = { +// imp: import_req; +// modular: modular_extension; +//}; + +export type walker = (data: goodies) => Promise; + +export type walkerplus = (data: goodies & T) => Promise; + +export type swalker = (data: goodies) => goodies; diff --git a/src/expander.ts b/src/expander.ts index eb41bb4..8d39fd0 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -25,8 +25,9 @@ import { import { apply_syntax_rules, core_handlers } from "./syntax-core-patterns"; import { debug, in_isolation, syntax_error } from "./stx-error"; import { array_to_ll, join_separated, llappend } from "./llhelpers"; -import { gen_binding, goodies, preexpand_list_handlers } from "./preexpand-handlers"; +import { gen_binding, preexpand_list_handlers } from "./preexpand-handlers"; import { preexpand_helpers } from "./preexpand-helpers"; +import { goodies, walkerplus } from "./data"; export function initial_step( ast: AST, @@ -146,7 +147,7 @@ async function expand_program( imp: import_req; }> { async function expand(loc: Loc) { - return preexpand_body(loc, lexical, unit, context, counter, "value", helpers).then( + return preexpand_body({ loc, lexical, unit, context, counter, sort: "value", helpers }).then( ({ loc, lexical, counter, context, unit }) => { // rib is filled // context is filled also @@ -193,26 +194,25 @@ async function expand_program( return go_down(loc, expand, expand_empty_program); } -async function preexpand_body( - loc: Loc, - lexical: lexical_extension, - unit: CompilationUnit, - context: Context, - counter: number, - sort: "type" | "value", - helpers: preexpand_helpers, -): Promise { - return in_isolation( +const preexpand_body: walkerplus<{ sort: "type" | "value" }> = async ({ + loc, + lexical, + unit, + context, + counter, + sort, + ...data +}) => + in_isolation( loc, - (loc) => preexpand_forms(loc, lexical, counter, unit, context, sort, helpers), - (loc, { lexical, context, counter, unit }) => + (loc) => preexpand_forms(loc, lexical, counter, unit, context, sort, data.helpers), + (loc, data) => go_next( loc, - (loc) => preexpand_body(loc, lexical, unit, context, counter, sort, helpers), - (loc) => Promise.resolve({ loc, lexical, context, counter, unit }), + (loc) => preexpand_body({ loc, sort, ...data }), + (loc) => Promise.resolve({ loc, ...data }), ), ); -} async function preexpand_body_curly( loc: Loc, @@ -231,6 +231,7 @@ async function preexpand_body_curly( counter, lexical, unit, + helpers, }), ); } @@ -406,6 +407,7 @@ async function preexpand_forms( context, counter, unit, + helpers, }); } function next(loc: Loc): Promise { @@ -476,12 +478,12 @@ async function preexpand_forms( assert(loc.t.type === "list"); const h = preexpand_list_handlers[loc.t.tag]; if (h) { - return h({ loc, lexical, counter, unit, context }, helpers).then( + return h({ loc, lexical, counter, unit, context, helpers }, helpers).then( ({ loc, lexical, counter, unit, context }) => go_next( loc, (loc) => preexpand_forms(loc, lexical, counter, unit, context, sort, helpers), - (loc) => Promise.resolve({ loc, lexical, counter, unit, context }), + (loc) => Promise.resolve({ loc, lexical, counter, unit, context, helpers }), ), ); } @@ -682,7 +684,7 @@ function expand_arrow_function( rib_id, rib: { type: "rib", normal_env: {}, types_env: {} }, }; - const pgs = extract_parameters({ loc, lexical, counter, context, unit }); + const pgs = extract_parameters({ loc, lexical, counter, context, unit, helpers }); const arr = go_right(pgs.loc, itself, invalid_form); check_punct(arr, "=>"); const body = go_right(arr, itself, invalid_form); @@ -737,13 +739,13 @@ function expand_type_parameters( assert(loc.t.content === ","); return go_right( loc, - (loc) => post_var({ loc, lexical, counter, unit, context, imp }), + (loc) => post_var({ loc, lexical, counter, unit, context, imp, helpers }), (loc) => { debug(loc, "cant go past commma2?"); }, ); }, - (loc) => end({ loc: go_up(loc), lexical, unit, counter, context, imp }), + (loc) => end({ loc: go_up(loc), lexical, unit, counter, context, imp, helpers }), ); } @@ -757,7 +759,7 @@ function expand_type_parameters( }: goodies & { imp: import_req }): T { switch (loc.t.tag) { case "identifier": - return post_after_var({ loc, lexical, counter, unit, context, imp }); + return post_after_var({ loc, lexical, counter, unit, context, imp, helpers }); case "type_parameter": return go_down(loc, (loc) => { assert(loc.t.tag === "identifier"); @@ -779,7 +781,15 @@ function expand_type_parameters( helpers, ).then(({ loc, counter, unit, context, imp }) => go_right(loc, syntax_error, () => - post_after_var({ loc: go_up(loc), lexical, counter, unit, context, imp }), + post_after_var({ + loc: go_up(loc), + lexical, + counter, + unit, + context, + imp, + helpers, + }), ), ), ); @@ -805,7 +815,7 @@ function expand_type_parameters( if (loc.t.content !== ",") syntax_error(loc, "expected a comma ','"); return go_right( loc, - (loc) => pre_var({ loc, lexical, counter, unit, context, imp }), + (loc) => pre_var({ loc, lexical, counter, unit, context, imp, helpers }), (loc) => debug(loc, "cant go past commma?"), ); }, @@ -818,6 +828,7 @@ function expand_type_parameters( unit: extend_unit(unit, lexical), context, imp, + helpers, }), ), ); @@ -840,6 +851,7 @@ function expand_type_parameters( context, unit, sort: "type", + helpers, }); return pre_after_var({ ...gs, loc: rename(loc, name), imp }); case "type_parameter": @@ -852,6 +864,7 @@ function expand_type_parameters( context, unit, sort: "type", + helpers, }); return pre_after_var({ ...gs, loc: go_up(rename(loc, name)), imp }); }); @@ -868,8 +881,8 @@ function expand_type_parameters( const lexical: lexical_extension = { extensible: true, rib_id, rib }; return go_down( loc, - (loc) => pre_var({ loc, lexical, unit, counter, context, imp }), - (loc) => end({ loc, unit, lexical, context, counter, imp }), + (loc) => pre_var({ loc, lexical, unit, counter, context, imp, helpers }), + (loc) => end({ loc, unit, lexical, context, counter, imp, helpers }), ); } @@ -885,7 +898,7 @@ function expand_type_parameters( loc, (loc) => { assert(loc.t.content === ">"); - return { loc, lexical, unit, counter, context, imp }; + return { loc, lexical, unit, counter, context, imp, helpers }; }, syntax_error, ); @@ -931,10 +944,11 @@ function expand_expr( counter, context, imp, + helpers, })), ); }, - (loc, { unit, counter, context, imp }) => ({ loc, unit, counter, context, imp }), + (loc, { unit, counter, context, imp }) => ({ loc, unit, counter, context, imp, helpers }), ); } diff --git a/src/preexpand-handlers.ts b/src/preexpand-handlers.ts index afbfd31..02179f2 100644 --- a/src/preexpand-handlers.ts +++ b/src/preexpand-handlers.ts @@ -1,26 +1,18 @@ import { assert } from "./assert"; +import { goodies } from "./data"; import { imported_module, preexpand_helpers } from "./preexpand-helpers"; import { extend_context_lexical, extend_rib, extend_unit, - import_req, lexical_extension, rib_push, } from "./stx"; import { syntax_error } from "./stx-error"; -import { CompilationUnit, Context, Loc, STX } from "./syntax-structures"; +import { Context, Loc, STX } from "./syntax-structures"; import { list_tag } from "./tags"; import { change, go_down, go_right, go_up, mkzipper } from "./zipper"; -export type goodies = { - loc: Loc; - lexical: lexical_extension; - context: Context; - counter: number; - unit: CompilationUnit; -}; - function skip_optional(loc: Loc, kwd: string): Loc { if (loc.t.content === kwd) { return go_right(loc, (loc) => loc, syntax_error); @@ -44,6 +36,7 @@ export function gen_binding({ context, unit, sort, + helpers, }: goodies & { sort: "type" | "value" }): Omit & { name: string } { const stx = loc.t; assert(stx.type === "atom" && stx.tag === "identifier", stx); @@ -71,21 +64,36 @@ export function gen_binding({ counter, name, unit, + helpers, }), ), (reason) => syntax_error(loc, reason), ); } -function lexical_declaration({ loc, lexical, context, counter, unit }: goodies): Promise { - async function after_vars({ loc, lexical, context, counter, unit }: goodies): Promise { +function lexical_declaration({ + loc, + lexical, + context, + counter, + unit, + ...data +}: goodies): Promise { + async function after_vars({ + loc, + lexical, + context, + counter, + unit, + ...data + }: goodies): Promise { if (loc.t.type === "atom" && loc.t.tag === "other") { switch (loc.t.content) { case ";": return go_right( loc, (loc) => syntax_error(loc, "expected nothing after semicolon"), - (loc) => ({ loc, lexical, context, counter, unit }), + (loc) => ({ loc, lexical, context, counter, unit, ...data }), ); case ",": return go_right( @@ -102,7 +110,15 @@ function lexical_declaration({ loc, lexical, context, counter, unit }: goodies): return go_down( ls, (loc) => { - const goodies = gen_binding({ loc, lexical, counter, context, unit, sort: "value" }); + const goodies = gen_binding({ + loc, + lexical, + counter, + context, + unit, + sort: "value", + ...data, + }); return go_right( ls, (loc) => after_vars({ ...goodies, loc }), @@ -134,10 +150,11 @@ function type_alias_declaration({ context, counter, unit, + ...data }: goodies): Promise { async function after_type(loc: Loc) { assert(loc.t.type === "atom" && loc.t.tag === "identifier", "expected an identifier"); - const gs = gen_binding({ loc, lexical, counter, context, unit, sort: "type" }); + const gs = gen_binding({ loc, lexical, counter, context, unit, sort: "type", ...data }); return { ...gs, loc: go_up(loc) }; } return go_down( @@ -147,7 +164,7 @@ function type_alias_declaration({ ); } -const import_declaration: preexpand_list_handler = ({ loc, ...goodies }, helpers) => { +const import_declaration: preexpand_list_handler = async ({ loc, ...goodies }, helpers) => { async function handle_import_from_file(loc: Loc) { if (loc.t.tag !== "string") syntax_error(loc, "expected a string literal for import"); const mod = await helpers.manager.resolve_import(loc); @@ -189,7 +206,7 @@ const import_declaration: preexpand_list_handler = ({ loc, ...goodies }, helpers }, rib); const new_lexical: lexical_extension = { extensible: true, rib: new_rib, rib_id }; const new_unit = extend_unit(unit, new_lexical); - return { loc, counter, unit: new_unit, context, lexical: new_lexical }; + return { loc, counter, unit: new_unit, context, lexical: new_lexical, helpers }; } default: syntax_error(loc, `unexpected ${loc.t.tag} in import context`); diff --git a/tsconfig.tsbuildinfo b/tsconfig.tsbuildinfo index aed54ea..a85d85e 100644 --- a/tsconfig.tsbuildinfo +++ b/tsconfig.tsbuildinfo @@ -1 +1 @@ -{"root":["./files.test.ts","./generate-stdlibs.test.ts","./vite.config.ts","./vitest.config.ts","./rtsc/testing-file-extensions.rts.ts","./rtsc/watch.ts","./src/assert.ts","./src/ast.ts","./src/expander.ts","./src/fs-helpers.ts","./src/generate-stdlibs.ts","./src/generated-stdlibs.ts","./src/global-module.ts","./src/library-manager.ts","./src/llhelpers.ts","./src/parse.ts","./src/pprint.ts","./src/preexpand-handlers.ts","./src/preexpand-helpers.ts","./src/proxy-code.ts","./src/serialize.ts","./src/stx-error.ts","./src/stx.ts","./src/syntax-core-patterns.ts","./src/syntax-structures.ts","./src/tags.ts","./src/zipper.ts","./test-project/index.ts","./test-project/main.rts.ts","./test-project/mod.rts.ts","./ui/astvis.tsx","./ui/app.tsx","./ui/editor.tsx","./ui/main.tsx","./ui/vite-env.d.ts"],"version":"5.7.2"} \ No newline at end of file +{"root":["./files.test.ts","./generate-stdlibs.test.ts","./vite.config.ts","./vitest.config.ts","./rtsc/testing-file-extensions.rts.ts","./rtsc/watch.ts","./src/assert.ts","./src/ast.ts","./src/data.ts","./src/expander.ts","./src/fs-helpers.ts","./src/generate-stdlibs.ts","./src/generated-stdlibs.ts","./src/global-module.ts","./src/library-manager.ts","./src/llhelpers.ts","./src/parse.ts","./src/pprint.ts","./src/preexpand-handlers.ts","./src/preexpand-helpers.ts","./src/proxy-code.ts","./src/serialize.ts","./src/stx-error.ts","./src/stx.ts","./src/syntax-core-patterns.ts","./src/syntax-structures.ts","./src/tags.ts","./src/zipper.ts","./test-project/index.ts","./test-project/main.rts.ts","./test-project/mod.rts.ts","./ui/astvis.tsx","./ui/app.tsx","./ui/editor.tsx","./ui/main.tsx","./ui/vite-env.d.ts"],"version":"5.7.2"} \ No newline at end of file From ec05361b520b6fad6fd38c55cd30d2072c4cf222 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 13:25:19 +0300 Subject: [PATCH 02/35] preexpand_forms --- src/expander.ts | 104 ++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 8d39fd0..7abb5c1 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -194,18 +194,10 @@ async function expand_program( return go_down(loc, expand, expand_empty_program); } -const preexpand_body: walkerplus<{ sort: "type" | "value" }> = async ({ - loc, - lexical, - unit, - context, - counter, - sort, - ...data -}) => +const preexpand_body: walkerplus<{ sort: "type" | "value" }> = async ({ loc, sort, ...data }) => in_isolation( loc, - (loc) => preexpand_forms(loc, lexical, counter, unit, context, sort, data.helpers), + (loc) => preexpand_forms({ loc, sort, ...data }), (loc, data) => go_next( loc, @@ -237,7 +229,7 @@ async function preexpand_body_curly( } return in_isolation( loc, - (loc) => preexpand_forms(loc, lexical, counter, unit, context, sort, helpers), + (loc) => preexpand_forms({ loc, lexical, counter, unit, context, sort, helpers }), (loc, { lexical, context, counter, unit }) => { return go_right( loc, @@ -369,7 +361,7 @@ async function expand_concise_body( (loc) => debug(loc, "???"), ), ) - : preexpand_forms(loc, lexical, counter, unit, context, sort, helpers)); + : preexpand_forms({ loc, lexical, counter, unit, context, sort, helpers })); const new_unit = extend_unit(gs.unit, gs.lexical); return postexpand_body( gs.loc, @@ -391,24 +383,9 @@ function rewrap(loc: Loc, rib_id: string, cu_id: string): Loc { }; } -async function preexpand_forms( - loc: Loc, - lexical: lexical_extension, - counter: number, - unit: CompilationUnit, - context: Context, - sort: "type" | "value", - helpers: preexpand_helpers, -): Promise { +const preexpand_forms: walkerplus<{ sort: "type" | "value" }> = async ({ loc, sort, ...data }) => { function done(loc: Loc): Promise { - return Promise.resolve({ - loc, - lexical, - context, - counter, - unit, - helpers, - }); + return Promise.resolve({ loc, ...data }); } function next(loc: Loc): Promise { return go_next(loc, (loc) => h(find_form(loc)), done); @@ -424,7 +401,14 @@ async function preexpand_forms( case "identifier": { assert(loc.t.type === "atom" && loc.t.tag === "identifier", loc.t); const { content, wrap } = loc.t; - const resolution = await resolve(content, wrap, context, unit, sort_env[sort], helpers); + const resolution = await resolve( + content, + wrap, + data.context, + data.unit, + sort_env[sort], + data.helpers, + ); switch (resolution.type) { case "unbound": return next(loc); @@ -438,25 +422,40 @@ async function preexpand_forms( return next(loc); case "core_syntax": { const { name } = binding; - return helpers.inspect(loc, "core form", () => - handle_core_syntax(loc, name, context, unit, counter, lexical, helpers).then( - ({ loc, counter, unit, context, lexical }) => - helpers.inspect(loc, `core output`, () => - preexpand_forms(loc, lexical, counter, unit, context, sort, helpers), - ), + return data.helpers.inspect(loc, "core form", () => + handle_core_syntax( + loc, + name, + data.context, + data.unit, + data.counter, + data.lexical, + data.helpers, + ).then(({ loc, counter, unit, context, lexical }) => + data.helpers.inspect(loc, `core output`, () => + preexpand_forms({ + loc, + lexical, + counter, + unit, + context, + sort, + helpers: data.helpers, + }), + ), ), ); } case "syntax_rules_transformer": { const { clauses } = binding; - return helpers.inspect(loc, `transformer form`, () => - apply_syntax_rules(loc, clauses, unit, counter, helpers).then( + return data.helpers.inspect(loc, `transformer form`, () => + apply_syntax_rules(loc, clauses, data.unit, data.counter, data.helpers).then( ({ loc, counter }) => { - const rewrapped = lexical.extensible - ? rewrap(loc, lexical.rib_id, unit.cu_id) + const rewrapped = data.lexical.extensible + ? rewrap(loc, data.lexical.rib_id, data.unit.cu_id) : loc; - return helpers.inspect(rewrapped, `transformer output`, () => - preexpand_forms(rewrapped, lexical, counter, unit, context, sort, helpers), + return data.helpers.inspect(rewrapped, `transformer output`, () => + preexpand_forms({ loc: rewrapped, ...data, counter, sort }), ); }, ), @@ -478,13 +477,12 @@ async function preexpand_forms( assert(loc.t.type === "list"); const h = preexpand_list_handlers[loc.t.tag]; if (h) { - return h({ loc, lexical, counter, unit, context, helpers }, helpers).then( - ({ loc, lexical, counter, unit, context }) => - go_next( - loc, - (loc) => preexpand_forms(loc, lexical, counter, unit, context, sort, helpers), - (loc) => Promise.resolve({ loc, lexical, counter, unit, context, helpers }), - ), + return h({ loc, ...data }, data.helpers).then(({ loc, ...data }) => + go_next( + loc, + (loc) => preexpand_forms({ loc, sort, ...data }), + (loc) => Promise.resolve({ loc, ...data }), + ), ); } switch (loc.t.tag) { @@ -504,7 +502,7 @@ async function preexpand_forms( } } return h(find_form(loc)); -} +}; type ffrv = | { type: "done"; loc: Loc } @@ -920,15 +918,15 @@ function expand_expr( return in_isolation( loc, async (loc) => { - return preexpand_forms( + return preexpand_forms({ loc, - { extensible: false }, + lexical: { extensible: false }, counter, unit, context, sort, helpers, - ).then(({ loc, unit, counter, context }) => + }).then(({ loc, unit, counter, context }) => postexpand_body( loc, { extensible: false }, From cf48a58928229e870e061bac5515506b40a557ca Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 13:29:36 +0300 Subject: [PATCH 03/35] preexpand-body-curly --- src/expander.ts | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 7abb5c1..c93a346 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -27,7 +27,7 @@ import { debug, in_isolation, syntax_error } from "./stx-error"; import { array_to_ll, join_separated, llappend } from "./llhelpers"; import { gen_binding, preexpand_list_handlers } from "./preexpand-handlers"; import { preexpand_helpers } from "./preexpand-helpers"; -import { goodies, walkerplus } from "./data"; +import { goodies, walker, walkerplus } from "./data"; export function initial_step( ast: AST, @@ -206,39 +206,27 @@ const preexpand_body: walkerplus<{ sort: "type" | "value" }> = async ({ loc, sor ), ); -async function preexpand_body_curly( - loc: Loc, - lexical: lexical_extension, - unit: CompilationUnit, - context: Context, - counter: number, - sort: "type" | "value", - helpers: preexpand_helpers, -): Promise { +const preexpand_body_curly: walker = async ({ loc, ...data }) => { if (loc.t.type === "atom" && loc.t.tag === "other" && loc.t.content === "}") { return go_right(loc, syntax_error, () => Promise.resolve({ loc: go_up(loc), - context, - counter, - lexical, - unit, - helpers, + ...data, }), ); } return in_isolation( loc, - (loc) => preexpand_forms({ loc, lexical, counter, unit, context, sort, helpers }), - (loc, { lexical, context, counter, unit }) => { + (loc) => preexpand_forms({ loc, sort: "value", ...data }), + (loc, data) => { return go_right( loc, - (loc) => preexpand_body_curly(loc, lexical, unit, context, counter, sort, helpers), + (loc) => preexpand_body_curly({ loc, ...data }), (loc) => syntax_error(loc, "no right"), ); }, ); -} +}; async function handle_core_syntax( loc: Loc, @@ -323,22 +311,20 @@ async function preexpand_block( counter: number, unit: CompilationUnit, context: Context, - sort: "type" | "value", helpers: preexpand_helpers, ): Promise { assert(loc.t.type === "list" && loc.t.tag === "statement_block"); const bodies = go_down(loc, itself, (loc) => syntax_error(loc, "no bodies")); assert(bodies.t.type === "atom" && bodies.t.tag === "other" && bodies.t.content === "{"); const bodies_rest = go_right(bodies, itself, (loc) => syntax_error(loc, "no body rest")); - const gs = await preexpand_body_curly( - bodies_rest, + const gs = await preexpand_body_curly({ + loc: bodies_rest, lexical, unit, context, counter, - sort, helpers, - ); + }); assert(gs.loc.t.type === "list" && gs.loc.t.tag === "statement_block"); return gs; } @@ -354,7 +340,7 @@ async function expand_concise_body( helpers: preexpand_helpers, ): Promise<{ loc: Loc; imp: import_req; counter: number }> { const gs = await (loc.t.type === "list" && loc.t.tag === "statement_block" - ? preexpand_block(loc, lexical, counter, unit, context, sort, helpers).then(({ loc, ...gs }) => + ? preexpand_block(loc, lexical, counter, unit, context, helpers).then(({ loc, ...gs }) => go_down( loc, (loc) => ({ ...gs, loc }), From 63c03dfa1ac06e9eb43c304d0ac9f3fedf4df925 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 13:33:40 +0300 Subject: [PATCH 04/35] refactored preexpand_block --- src/data.ts | 2 ++ src/expander.ts | 53 +++++++++++++++---------------------------------- 2 files changed, 18 insertions(+), 37 deletions(-) diff --git a/src/data.ts b/src/data.ts index d36eb40..a1fcce5 100644 --- a/src/data.ts +++ b/src/data.ts @@ -11,6 +11,8 @@ export type goodies = { helpers: preexpand_helpers; }; +export type data = goodies; + //export type data = { // imp: import_req; // modular: modular_extension; diff --git a/src/expander.ts b/src/expander.ts index c93a346..3f96d0d 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -206,27 +206,20 @@ const preexpand_body: walkerplus<{ sort: "type" | "value" }> = async ({ loc, sor ), ); -const preexpand_body_curly: walker = async ({ loc, ...data }) => { - if (loc.t.type === "atom" && loc.t.tag === "other" && loc.t.content === "}") { - return go_right(loc, syntax_error, () => - Promise.resolve({ - loc: go_up(loc), - ...data, - }), - ); - } - return in_isolation( - loc, - (loc) => preexpand_forms({ loc, sort: "value", ...data }), - (loc, data) => { - return go_right( +const preexpand_body_curly: walker = async ({ loc, ...data }) => + loc.t.type === "atom" && loc.t.tag === "other" && loc.t.content === "}" + ? go_right(loc, syntax_error, () => ({ loc: go_up(loc), ...data })) + : in_isolation( loc, - (loc) => preexpand_body_curly({ loc, ...data }), - (loc) => syntax_error(loc, "no right"), + (loc) => preexpand_forms({ loc, sort: "value", ...data }), + (loc, data) => { + return go_right( + loc, + (loc) => preexpand_body_curly({ loc, ...data }), + (loc) => syntax_error(loc, "no right"), + ); + }, ); - }, - ); -}; async function handle_core_syntax( loc: Loc, @@ -305,29 +298,15 @@ const list_handlers_table: { [tag in list_tag]: "descend" | "stop" | "todo" } = syntax_list: "descend", }; -async function preexpand_block( - loc: Loc, - lexical: lexical_extension, - counter: number, - unit: CompilationUnit, - context: Context, - helpers: preexpand_helpers, -): Promise { +const preexpand_block: walker = async ({ loc, ...data }) => { assert(loc.t.type === "list" && loc.t.tag === "statement_block"); const bodies = go_down(loc, itself, (loc) => syntax_error(loc, "no bodies")); assert(bodies.t.type === "atom" && bodies.t.tag === "other" && bodies.t.content === "{"); const bodies_rest = go_right(bodies, itself, (loc) => syntax_error(loc, "no body rest")); - const gs = await preexpand_body_curly({ - loc: bodies_rest, - lexical, - unit, - context, - counter, - helpers, - }); + const gs = await preexpand_body_curly({ loc: bodies_rest, ...data }); assert(gs.loc.t.type === "list" && gs.loc.t.tag === "statement_block"); return gs; -} +}; async function expand_concise_body( loc: Loc, @@ -340,7 +319,7 @@ async function expand_concise_body( helpers: preexpand_helpers, ): Promise<{ loc: Loc; imp: import_req; counter: number }> { const gs = await (loc.t.type === "list" && loc.t.tag === "statement_block" - ? preexpand_block(loc, lexical, counter, unit, context, helpers).then(({ loc, ...gs }) => + ? preexpand_block({ loc, lexical, counter, unit, context, helpers }).then(({ loc, ...gs }) => go_down( loc, (loc) => ({ ...gs, loc }), From ebf5934d3b161c2648de5866705b231650969545 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 13:41:22 +0300 Subject: [PATCH 05/35] refactored extract parameters --- src/expander.ts | 64 ++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 3f96d0d..b9a7ad9 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -27,7 +27,7 @@ import { debug, in_isolation, syntax_error } from "./stx-error"; import { array_to_ll, join_separated, llappend } from "./llhelpers"; import { gen_binding, preexpand_list_handlers } from "./preexpand-handlers"; import { preexpand_helpers } from "./preexpand-helpers"; -import { goodies, walker, walkerplus } from "./data"; +import { data, goodies, swalker, walker, walkerplus } from "./data"; export function initial_step( ast: AST, @@ -349,16 +349,16 @@ function rewrap(loc: Loc, rib_id: string, cu_id: string): Loc { } const preexpand_forms: walkerplus<{ sort: "type" | "value" }> = async ({ loc, sort, ...data }) => { - function done(loc: Loc): Promise { + function done(loc: Loc): Promise { return Promise.resolve({ loc, ...data }); } - function next(loc: Loc): Promise { + function next(loc: Loc): Promise { return go_next(loc, (loc) => h(find_form(loc)), done); } - function descend(loc: Loc): Promise { + function descend(loc: Loc): Promise { return go_down(loc, (loc) => h(find_form(loc)), syntax_error); } - async function h(ffrv: ffrv): Promise { + async function h(ffrv: ffrv): Promise { const loc = ffrv.loc; switch (ffrv.type) { case "done": @@ -549,34 +549,32 @@ function itself(loc: Loc): Loc { return loc; } -function extract_parameters(goodies: goodies): goodies { +const extract_parameters: swalker = (data) => { // - function tail(goodies: goodies): goodies { - const loc = goodies.loc; + const tail: swalker = ({ loc, ...data }) => { switch (loc.t.type) { case "atom": { switch (loc.t.tag) { case "other": { switch (loc.t.content) { case ",": - return go_right(loc, (loc) => head({ ...goodies, loc }), invalid_form); + return go_right(loc, (loc) => head({ ...data, loc }), invalid_form); case ")": - return go_right(loc, invalid_form, (loc) => ({ ...goodies, loc: go_up(loc) })); + return go_right(loc, invalid_form, (loc) => ({ ...data, loc: go_up(loc) })); } } } } } syntax_error(loc); - } + }; - function head(goodies: goodies): goodies { - const loc = goodies.loc; + const head: swalker = ({ loc, ...data }) => { switch (loc.t.type) { case "atom": { switch (loc.t.tag) { case "identifier": { - const gs = identifier(goodies); + const gs = identifier({ loc, ...data }); return go_right(gs.loc, (loc) => tail({ ...gs, loc }), invalid_form); } case "other": { @@ -584,45 +582,45 @@ function extract_parameters(goodies: goodies): goodies { case ",": return invalid_form(loc); case ")": - return go_right(loc, invalid_form, (loc) => ({ ...goodies, loc: go_up(loc) })); + return go_right(loc, invalid_form, (loc) => ({ ...data, loc: go_up(loc) })); } } } } } syntax_error(loc); - } + }; - function identifier(goodies: goodies): goodies { - const id = goodies.loc.t; + const identifier: swalker = (data) => { + const id = data.loc.t; assert(id.type === "atom" && id.tag === "identifier"); - const { name, ...gs } = gen_binding({ ...goodies, sort: "value" }); - return { ...gs, loc: rename(goodies.loc, name) }; - } + const { name, ...gs } = gen_binding({ ...data, sort: "value" }); + return { ...gs, loc: rename(data.loc, name) }; + }; - function first_param(goodies: goodies): goodies { - switch (goodies.loc.t.type) { + const first_param: swalker = (data) => { + switch (data.loc.t.type) { case "atom": { - switch (goodies.loc.t.tag) { + switch (data.loc.t.tag) { case "identifier": - const gs = identifier(goodies); + const gs = identifier(data); return go_right(gs.loc, invalid_form, (loc) => ({ ...gs, loc: go_up(loc) })); case "other": { - if (goodies.loc.t.content === "(") { - return go_right(goodies.loc, (loc) => head({ ...goodies, loc }), invalid_form); + if (data.loc.t.content === "(") { + return go_right(data.loc, (loc) => head({ ...data, loc }), invalid_form); } } } - return syntax_error(goodies.loc); + return syntax_error(data.loc); } } - debug(goodies.loc, "non atom first_param"); - } + debug(data.loc, "non atom first_param"); + }; { - assert(goodies.loc.t.type === "list" && goodies.loc.t.tag === "formal_parameters"); - return go_down(goodies.loc, (loc) => first_param({ ...goodies, loc }), invalid_form); + assert(data.loc.t.type === "list" && data.loc.t.tag === "formal_parameters"); + return go_down(data.loc, (loc) => first_param({ ...data, loc }), invalid_form); } -} +}; function check_punct(loc: Loc, content: string) { if (loc.t.type !== "atom" || loc.t.tag !== "other" || loc.t.content !== content) { From 58f0543ba1f2e036d66458edf77ea71ba8821ffd Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 13:57:10 +0300 Subject: [PATCH 06/35] added imp to data --- src/data.ts | 2 +- src/expander.ts | 123 +++++++++++++++----------------------- src/preexpand-handlers.ts | 28 ++++----- 3 files changed, 63 insertions(+), 90 deletions(-) diff --git a/src/data.ts b/src/data.ts index a1fcce5..43159a9 100644 --- a/src/data.ts +++ b/src/data.ts @@ -9,12 +9,12 @@ export type goodies = { counter: number; unit: CompilationUnit; helpers: preexpand_helpers; + imp: import_req; }; export type data = goodies; //export type data = { -// imp: import_req; // modular: modular_extension; //}; diff --git a/src/expander.ts b/src/expander.ts index b9a7ad9..3d07881 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -147,25 +147,32 @@ async function expand_program( imp: import_req; }> { async function expand(loc: Loc) { - return preexpand_body({ loc, lexical, unit, context, counter, sort: "value", helpers }).then( - ({ loc, lexical, counter, context, unit }) => { - // rib is filled - // context is filled also - const new_unit = extend_unit(unit, lexical); - const modular: modular_extension = { - extensible: true, - explicit: { type: "rib", normal_env: {}, types_env: {} }, - implicit: { type: "rib", normal_env: {}, types_env: {} }, - }; - return helpers.inspect(loc, "After preexpanding the program", () => - postexpand_program(loc, modular, new_unit, counter, context, imp, helpers).then( - ({ loc, modular, imp, counter }) => { - return { loc, unit: new_unit, context, modular, imp, counter }; - }, - ), - ); - }, - ); + return preexpand_body({ + loc, + lexical, + unit, + context, + counter, + sort: "value", + helpers, + imp, + }).then(({ loc, lexical, counter, context, unit }) => { + // rib is filled + // context is filled also + const new_unit = extend_unit(unit, lexical); + const modular: modular_extension = { + extensible: true, + explicit: { type: "rib", normal_env: {}, types_env: {} }, + implicit: { type: "rib", normal_env: {}, types_env: {} }, + }; + return helpers.inspect(loc, "After preexpanding the program", () => + postexpand_program(loc, modular, new_unit, counter, context, imp, helpers).then( + ({ loc, modular, imp, counter }) => { + return { loc, unit: new_unit, context, modular, imp, counter }; + }, + ), + ); + }); } async function expand_empty_program() { const empty_rib: Rib = { type: "rib", normal_env: {}, types_env: {} }; @@ -319,14 +326,15 @@ async function expand_concise_body( helpers: preexpand_helpers, ): Promise<{ loc: Loc; imp: import_req; counter: number }> { const gs = await (loc.t.type === "list" && loc.t.tag === "statement_block" - ? preexpand_block({ loc, lexical, counter, unit, context, helpers }).then(({ loc, ...gs }) => - go_down( - loc, - (loc) => ({ ...gs, loc }), - (loc) => debug(loc, "???"), - ), + ? preexpand_block({ loc, lexical, counter, unit, context, helpers, imp }).then( + ({ loc, ...gs }) => + go_down( + loc, + (loc) => ({ ...gs, loc }), + (loc) => debug(loc, "???"), + ), ) - : preexpand_forms({ loc, lexical, counter, unit, context, sort, helpers })); + : preexpand_forms({ loc, lexical, counter, unit, context, sort, helpers, imp })); const new_unit = extend_unit(gs.unit, gs.lexical); return postexpand_body( gs.loc, @@ -406,6 +414,7 @@ const preexpand_forms: walkerplus<{ sort: "type" | "value" }> = async ({ loc, so context, sort, helpers: data.helpers, + imp: data.imp, }), ), ), @@ -442,7 +451,7 @@ const preexpand_forms: walkerplus<{ sort: "type" | "value" }> = async ({ loc, so assert(loc.t.type === "list"); const h = preexpand_list_handlers[loc.t.tag]; if (h) { - return h({ loc, ...data }, data.helpers).then(({ loc, ...data }) => + return h({ loc, ...data }).then(({ loc, ...data }) => go_next( loc, (loc) => preexpand_forms({ loc, sort, ...data }), @@ -645,7 +654,7 @@ function expand_arrow_function( rib_id, rib: { type: "rib", normal_env: {}, types_env: {} }, }; - const pgs = extract_parameters({ loc, lexical, counter, context, unit, helpers }); + const pgs = extract_parameters({ loc, lexical, counter, context, unit, helpers, imp }); const arr = go_right(pgs.loc, itself, invalid_form); check_punct(arr, "=>"); const body = go_right(arr, itself, invalid_form); @@ -684,16 +693,9 @@ function expand_type_parameters( context: Context, imp: import_req, helpers: preexpand_helpers, -): Promise { - type T = Promise; - function post_after_var({ - loc, - lexical, - counter, - unit, - context, - imp, - }: goodies & { imp: import_req }): T { +): Promise { + type T = Promise; + function post_after_var({ loc, lexical, counter, unit, context, imp }: goodies): T { return go_right( loc, (loc) => { @@ -710,14 +712,7 @@ function expand_type_parameters( ); } - function post_var({ - loc, - lexical, - counter, - unit, - context, - imp, - }: goodies & { imp: import_req }): T { + function post_var({ loc, lexical, counter, unit, context, imp }: goodies): T { switch (loc.t.tag) { case "identifier": return post_after_var({ loc, lexical, counter, unit, context, imp, helpers }); @@ -761,14 +756,7 @@ function expand_type_parameters( } } - function pre_after_var({ - loc, - lexical, - counter, - unit, - context, - imp, - }: goodies & { imp: import_req }): T { + function pre_after_var({ loc, lexical, counter, unit, context, imp }: goodies): T { assert(lexical.extensible); return go_right( loc, @@ -795,14 +783,7 @@ function expand_type_parameters( ); } - function pre_var({ - loc, - lexical, - counter, - unit, - context, - imp, - }: goodies & { imp: import_req }): T { + function pre_var({ loc, lexical, counter, unit, context, ...data }: goodies): T { switch (loc.t.tag) { case "identifier": const { name, ...gs } = gen_binding({ @@ -812,7 +793,7 @@ function expand_type_parameters( context, unit, sort: "type", - helpers, + ...data, }); return pre_after_var({ ...gs, loc: rename(loc, name), imp }); case "type_parameter": @@ -825,7 +806,7 @@ function expand_type_parameters( context, unit, sort: "type", - helpers, + ...data, }); return pre_after_var({ ...gs, loc: go_up(rename(loc, name)), imp }); }); @@ -847,19 +828,12 @@ function expand_type_parameters( ); } - async function end({ - loc, - lexical, - unit, - context, - counter, - imp, - }: goodies & { imp: import_req }): T { + async function end({ loc, ...data }: goodies): T { return go_right( loc, (loc) => { assert(loc.t.content === ">"); - return { loc, lexical, unit, counter, context, imp, helpers }; + return { loc, ...data }; }, syntax_error, ); @@ -877,7 +851,7 @@ function expand_expr( imp: import_req, sort: "type" | "value", helpers: preexpand_helpers, -): Promise & { imp: import_req }> { +): Promise> { return in_isolation( loc, async (loc) => { @@ -889,6 +863,7 @@ function expand_expr( context, sort, helpers, + imp, }).then(({ loc, unit, counter, context }) => postexpand_body( loc, diff --git a/src/preexpand-handlers.ts b/src/preexpand-handlers.ts index 02179f2..1efef66 100644 --- a/src/preexpand-handlers.ts +++ b/src/preexpand-handlers.ts @@ -1,6 +1,6 @@ import { assert } from "./assert"; -import { goodies } from "./data"; -import { imported_module, preexpand_helpers } from "./preexpand-helpers"; +import { data, goodies, walker } from "./data"; +import { imported_module } from "./preexpand-helpers"; import { extend_context_lexical, extend_rib, @@ -36,7 +36,7 @@ export function gen_binding({ context, unit, sort, - helpers, + ...data }: goodies & { sort: "type" | "value" }): Omit & { name: string } { const stx = loc.t; assert(stx.type === "atom" && stx.tag === "identifier", stx); @@ -64,7 +64,7 @@ export function gen_binding({ counter, name, unit, - helpers, + ...data, }), ), (reason) => syntax_error(loc, reason), @@ -164,23 +164,23 @@ function type_alias_declaration({ ); } -const import_declaration: preexpand_list_handler = async ({ loc, ...goodies }, helpers) => { +const import_declaration: walker = async ({ loc, helpers, ...data }) => { async function handle_import_from_file(loc: Loc) { if (loc.t.tag !== "string") syntax_error(loc, "expected a string literal for import"); const mod = await helpers.manager.resolve_import(loc); return mod; } - async function after_var(loc: Loc, mod: imported_module): Promise { + async function after_var(loc: Loc, mod: imported_module): Promise { switch (loc.t.content) { case "}": - return { loc: go_up(loc), ...goodies }; + return { loc: go_up(loc), helpers, ...data }; case ",": return go_right(loc, (loc) => handle_named_import(loc, mod), syntax_error); default: syntax_error(loc); } } - async function handle_named_import(loc0: Loc, mod: imported_module): Promise { + async function handle_named_import(loc0: Loc, mod: imported_module): Promise { switch (loc0.t.tag) { case "identifier": { const name = loc0.t.content; @@ -206,17 +206,17 @@ const import_declaration: preexpand_list_handler = async ({ loc, ...goodies }, h }, rib); const new_lexical: lexical_extension = { extensible: true, rib: new_rib, rib_id }; const new_unit = extend_unit(unit, new_lexical); - return { loc, counter, unit: new_unit, context, lexical: new_lexical, helpers }; + return { loc, ...data, counter, unit: new_unit, context, lexical: new_lexical, helpers }; } default: syntax_error(loc, `unexpected ${loc.t.tag} in import context`); } } - async function handle_named_imports(loc: Loc, mod: imported_module): Promise { + async function handle_named_imports(loc: Loc, mod: imported_module): Promise { if (loc.t.content !== "{") syntax_error(loc); return go_right(loc, (loc) => handle_named_import(loc, mod), syntax_error); } - async function handle_imports(loc: Loc, mod: imported_module): Promise { + async function handle_imports(loc: Loc, mod: imported_module): Promise { switch (loc.t.tag) { case "named_imports": return go_down(loc, (loc) => handle_named_imports(loc, mod), syntax_error); @@ -224,7 +224,7 @@ const import_declaration: preexpand_list_handler = async ({ loc, ...goodies }, h syntax_error(loc, `unexpected ${loc.t.tag} in import`); } } - async function handle_import_clause(loc: Loc): Promise { + async function handle_import_clause(loc: Loc): Promise { if (loc.t.tag === "import_clause") { const mod = await handle_import_from_file( skip_required( @@ -251,9 +251,7 @@ const import_declaration: preexpand_list_handler = async ({ loc, ...goodies }, h ).then(({ ...gs }) => ({ ...gs, loc: change(loc, mkzipper(empty_slice)) })); }; -type preexpand_list_handler = (goodies: goodies, helpers: preexpand_helpers) => Promise; - -export const preexpand_list_handlers: { [k in list_tag]?: preexpand_list_handler } = { +export const preexpand_list_handlers: { [k in list_tag]?: walker } = { lexical_declaration, type_alias_declaration, import_declaration, From 61998a61e4fe2ea9c721211f2b7d1ac7356a2197 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 14:29:21 +0300 Subject: [PATCH 07/35] expand_type_parameters --- src/expander.ts | 111 +++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 3d07881..8e3e098 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -166,7 +166,7 @@ async function expand_program( implicit: { type: "rib", normal_env: {}, types_env: {} }, }; return helpers.inspect(loc, "After preexpanding the program", () => - postexpand_program(loc, modular, new_unit, counter, context, imp, helpers).then( + postexpand_program(loc, modular, new_unit, counter, context, imp, helpers, lexical).then( ({ loc, modular, imp, counter }) => { return { loc, unit: new_unit, context, modular, imp, counter }; }, @@ -345,6 +345,7 @@ async function expand_concise_body( imp, sort, helpers, + lexical, ); } @@ -543,10 +544,11 @@ function postexpand_program( context: Context, imp: import_req, helpers: preexpand_helpers, + lexical: lexical_extension, ): Promise<{ loc: Loc; modular: modular_extension; counter: number; imp: import_req }> { assert(loc.t.tag === "program"); return go_down(loc, (loc) => - postexpand_body(loc, modular, unit, counter, context, imp, "value", helpers), + postexpand_body(loc, modular, unit, counter, context, imp, "value", helpers, lexical), ); } @@ -686,36 +688,29 @@ function expand_arrow_function( ); } -function expand_type_parameters( - loc: Loc, - unit: CompilationUnit, - orig_counter: number, - context: Context, - imp: import_req, - helpers: preexpand_helpers, -): Promise { - type T = Promise; - function post_after_var({ loc, lexical, counter, unit, context, imp }: goodies): T { +const expand_type_parameters: walker = ({ loc, ...data }) => { + // + const post_after_var: walker = ({ loc, ...data }) => { return go_right( loc, (loc) => { assert(loc.t.content === ","); return go_right( loc, - (loc) => post_var({ loc, lexical, counter, unit, context, imp, helpers }), + (loc) => post_var({ loc, ...data }), (loc) => { debug(loc, "cant go past commma2?"); }, ); }, - (loc) => end({ loc: go_up(loc), lexical, unit, counter, context, imp, helpers }), + (loc) => end({ loc: go_up(loc), ...data }), ); - } + }; - function post_var({ loc, lexical, counter, unit, context, imp }: goodies): T { + const post_var: walker = ({ loc, lexical, ...data }) => { switch (loc.t.tag) { case "identifier": - return post_after_var({ loc, lexical, counter, unit, context, imp, helpers }); + return post_after_var({ loc, lexical, ...data }); case "type_parameter": return go_down(loc, (loc) => { assert(loc.t.tag === "identifier"); @@ -726,25 +721,25 @@ function expand_type_parameters( expand_expr( wrap_loc(loc, { marks: null, - subst: [{ rib_id: lexical.rib_id, cu_id: unit.cu_id }, null], + subst: [{ rib_id: lexical.rib_id, cu_id: data.unit.cu_id }, null], aes: null, }), - counter, - unit, - context, - imp, + data.counter, + data.unit, + data.context, + data.imp, "type", - helpers, - ).then(({ loc, counter, unit, context, imp }) => + data.helpers, + lexical, + ).then(({ loc, counter, unit, context, imp, ...data }) => go_right(loc, syntax_error, () => post_after_var({ loc: go_up(loc), - lexical, counter, unit, context, imp, - helpers, + ...data, }), ), ), @@ -754,9 +749,9 @@ function expand_type_parameters( default: syntax_error(loc); } - } + }; - function pre_after_var({ loc, lexical, counter, unit, context, imp }: goodies): T { + const pre_after_var: walker = ({ loc, lexical, counter, unit, context, imp, ...data }) => { assert(lexical.extensible); return go_right( loc, @@ -764,7 +759,7 @@ function expand_type_parameters( if (loc.t.content !== ",") syntax_error(loc, "expected a comma ','"); return go_right( loc, - (loc) => pre_var({ loc, lexical, counter, unit, context, imp, helpers }), + (loc) => pre_var({ loc, lexical, counter, unit, context, imp, ...data }), (loc) => debug(loc, "cant go past commma?"), ); }, @@ -777,13 +772,13 @@ function expand_type_parameters( unit: extend_unit(unit, lexical), context, imp, - helpers, + ...data, }), ), ); - } + }; - function pre_var({ loc, lexical, counter, unit, context, ...data }: goodies): T { + const pre_var: walker = ({ loc, lexical, counter, unit, context, ...data }) => { switch (loc.t.tag) { case "identifier": const { name, ...gs } = gen_binding({ @@ -795,7 +790,7 @@ function expand_type_parameters( sort: "type", ...data, }); - return pre_after_var({ ...gs, loc: rename(loc, name), imp }); + return pre_after_var({ ...gs, loc: rename(loc, name) }); case "type_parameter": return go_down(loc, (loc) => { if (loc.t.tag !== "identifier") syntax_error(loc, "expected an identifier"); @@ -808,27 +803,26 @@ function expand_type_parameters( sort: "type", ...data, }); - return pre_after_var({ ...gs, loc: go_up(rename(loc, name)), imp }); + return pre_after_var({ ...gs, loc: go_up(rename(loc, name)) }); }); default: syntax_error(loc); } - } + }; - function start(loc: Loc): T { + const start: walker = ({ loc, counter, ...data }) => { assert(loc.t.tag === "syntax_list"); - - const [rib_id, counter] = new_rib_id(orig_counter); + const [rib_id, new_counter] = new_rib_id(counter); const rib: Rib = { type: "rib", normal_env: {}, types_env: {} }; const lexical: lexical_extension = { extensible: true, rib_id, rib }; return go_down( loc, - (loc) => pre_var({ loc, lexical, unit, counter, context, imp, helpers }), - (loc) => end({ loc, unit, lexical, context, counter, imp, helpers }), + (loc) => pre_var({ loc, ...data, lexical, counter: new_counter }), + (loc) => end({ loc, ...data, lexical, counter: new_counter }), ); - } + }; - async function end({ loc, ...data }: goodies): T { + const end: walker = async ({ loc, ...data }) => { return go_right( loc, (loc) => { @@ -837,11 +831,11 @@ function expand_type_parameters( }, syntax_error, ); - } + }; assert(loc.t.content === "<"); - return go_right(loc, start, syntax_error); -} + return go_right(loc, (loc) => start({ loc, ...data }), syntax_error); +}; function expand_expr( loc: Loc, @@ -851,20 +845,21 @@ function expand_expr( imp: import_req, sort: "type" | "value", helpers: preexpand_helpers, -): Promise> { + lexical: lexical_extension, +): Promise> { return in_isolation( loc, async (loc) => { return preexpand_forms({ loc, - lexical: { extensible: false }, + lexical, counter, unit, context, sort, helpers, imp, - }).then(({ loc, unit, counter, context }) => + }).then(({ loc, unit, counter, context, lexical, imp, helpers }) => postexpand_body( loc, { extensible: false }, @@ -874,17 +869,19 @@ function expand_expr( imp, sort, helpers, - ).then(({ loc, imp, counter }) => ({ + lexical, + ).then(({ loc, imp, counter, modular: _ignored_modular }) => ({ loc, unit, counter, context, imp, helpers, + lexical, })), ); }, - (loc, { unit, counter, context, imp }) => ({ loc, unit, counter, context, imp, helpers }), + (loc, data) => ({ loc, ...data }), ); } @@ -1003,6 +1000,7 @@ async function postexpand_type_alias_declaration( context: Context, imp: import_req, helpers: preexpand_helpers, + lexical: lexical_extension, ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { async function do_after_equal( loc: Loc, @@ -1011,7 +1009,7 @@ async function postexpand_type_alias_declaration( context: Context, imp: import_req, ): Promise<{ loc: Loc; imp: import_req; counter: number }> { - return expand_expr(loc, counter, unit, context, imp, "type", helpers).then( + return expand_expr(loc, counter, unit, context, imp, "type", helpers, lexical).then( ({ loc, unit: _unit, counter, context: _context, imp }) => { function done(loc: Loc) { return { loc: go_up(loc), imp, counter }; @@ -1038,7 +1036,7 @@ async function postexpand_type_alias_declaration( case "=": return go_right(loc, (loc) => do_after_equal(loc, counter, unit, context, imp)); case "<": - return expand_type_parameters(loc, unit, counter, context, imp, helpers).then( + return expand_type_parameters({ loc, unit, counter, context, imp, helpers, lexical }).then( ({ loc, counter, unit, context, lexical, imp }) => { assert(loc.t.content === ">"); assert(lexical.extensible); @@ -1120,6 +1118,7 @@ async function postexpand_lexical_declaration( context: Context, imp: import_req, helpers: preexpand_helpers, + lexical: lexical_extension, ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { async function handle_value_initializer( loc: Loc, @@ -1127,7 +1126,7 @@ async function postexpand_lexical_declaration( assert(loc.t.content === "="); return go_right( loc, - (loc) => expand_expr(loc, counter, unit, context, imp, "value", helpers), + (loc) => expand_expr(loc, counter, unit, context, imp, "value", helpers, lexical), (loc) => syntax_error(loc, "expected an expression following the '=' sign"), ); } @@ -1138,7 +1137,7 @@ async function postexpand_lexical_declaration( return go_right( loc, (loc) => - expand_expr(loc, counter, unit, context, imp, "type", helpers).then( + expand_expr(loc, counter, unit, context, imp, "type", helpers, lexical).then( ({ loc, counter, unit: _ignored_unit, context: _ignored_context, imp }) => go_right(loc, handle_value_initializer, (loc) => Promise.resolve({ loc, imp, counter }), @@ -1298,6 +1297,7 @@ async function postexpand_body( imp: import_req, sort: "type" | "value", helpers: preexpand_helpers, + lexical: lexical_extension, ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { type T = Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }>; async function done(loc: Loc, modular: modular_extension, imp: import_req, counter: number): T { @@ -1376,6 +1376,7 @@ async function postexpand_body( context, imp, helpers, + lexical, ).then(({ loc, modular, imp, counter }) => cont(loc, modular, imp, counter)); case "arrow_function": { return in_isolation( @@ -1396,6 +1397,7 @@ async function postexpand_body( context, imp, helpers, + lexical, ).then(({ loc, modular, imp, counter }) => cont(loc, modular, imp, counter)); } case "member_expression": { @@ -1412,6 +1414,7 @@ async function postexpand_body( imp, sort, helpers, + lexical, ), (loc, { modular: _ignored_modular, imp, counter }) => go_right(loc, (loc) => { From 6c162ca7468a05b805df59aa598bcfe3907be75e Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 14:55:39 +0300 Subject: [PATCH 08/35] core syntax takes data --- src/expander.ts | 4 +++- src/syntax-core-patterns.ts | 45 ++++++++++++++++++------------------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 8e3e098..c3414df 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -236,6 +236,7 @@ async function handle_core_syntax( counter: number, lexical: lexical_extension, helpers: preexpand_helpers, + imp: import_req, ): Promise<{ loc: Loc; counter: number; @@ -245,7 +246,7 @@ async function handle_core_syntax( }> { const handler = core_handlers[name]; assert(handler !== undefined); - return handler(loc, context, unit, counter, lexical, helpers); + return handler({ loc, context, unit, counter, lexical, helpers, imp }); } const atom_handlers_table: { [tag in atom_tag]: "next" | "stop" } = { @@ -405,6 +406,7 @@ const preexpand_forms: walkerplus<{ sort: "type" | "value" }> = async ({ loc, so data.counter, data.lexical, data.helpers, + data.imp, ).then(({ loc, counter, unit, context, lexical }) => data.helpers.inspect(loc, `core output`, () => preexpand_forms({ diff --git a/src/syntax-core-patterns.ts b/src/syntax-core-patterns.ts index 9323a4d..782f365 100644 --- a/src/syntax-core-patterns.ts +++ b/src/syntax-core-patterns.ts @@ -24,15 +24,9 @@ import { } from "./syntax-structures"; import { go_next, go_down, mkzipper, stx_list_content, go_up, change } from "./zipper"; import { preexpand_helpers } from "./preexpand-helpers"; +import { data } from "./data"; -type handler = ( - loc: Loc, - context: Context, - unit: CompilationUnit, - counter: number, - lexical: lexical_extension, - helpers: preexpand_helpers, -) => Promise<{ +type handler = (data: data) => Promise<{ loc: Loc; counter: number; unit: CompilationUnit; @@ -266,7 +260,7 @@ export const core_pattern_match: ( return unification; }; -const splice: handler = async (loc, context, unit, counter, lexical, helpers) => { +const splice: handler = async ({ loc, context, unit, counter, lexical, helpers, ...data }) => { const unification = await core_pattern_match(loc, unit, "splice", helpers); assert(unification !== null); const { subst } = unification; @@ -286,6 +280,7 @@ const splice: handler = async (loc, context, unit, counter, lexical, helpers) => unit, context, lexical, + ...data, }; }; @@ -356,14 +351,15 @@ function group_by(ls: [K, V][], eq: (a: K, b: K) => boolean): [K, V[]][] { return ac; } -const using_rewrite_rules: handler = async ( - orig_loc, - orig_context, - orig_unit, - orig_counter, - orig_lexical, +const using_rewrite_rules: handler = async ({ + loc: orig_loc, + context: orig_context, + unit: orig_unit, + counter: orig_counter, + lexical: orig_lexical, helpers, -) => { + ...data +}) => { const unification = await core_pattern_match(orig_loc, orig_unit, "using_rewrite_rules", helpers); if (!unification) syntax_error(orig_loc); const { subst, loc } = unification; @@ -426,6 +422,7 @@ const using_rewrite_rules: handler = async ( unit: final_unit, context: final_context, lexical: orig_lexical, + ...data, }; }; @@ -498,14 +495,15 @@ export async function apply_syntax_rules( return { loc: new_loc, counter: new_counter }; } -const define_rewrite_rules: handler = async ( - orig_loc, - orig_context, - orig_unit, - orig_counter, - orig_lexical, +const define_rewrite_rules: handler = async ({ + loc: orig_loc, + context: orig_context, + unit: orig_unit, + counter: orig_counter, + lexical: orig_lexical, helpers, -) => { + ...data +}) => { if (orig_lexical.extensible === false) syntax_error(orig_loc, "cannot define rules in nondefinition context"); const unification = await core_pattern_match( @@ -570,6 +568,7 @@ const define_rewrite_rules: handler = async ( unit: final_unit, context: final_context, lexical, + ...data, }; }; From dd215068e36738eb9c7bfbb3e51c12ddeb07fa03 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 14:58:23 +0300 Subject: [PATCH 09/35] core syntax handlers are now walkers --- src/syntax-core-patterns.ts | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/syntax-core-patterns.ts b/src/syntax-core-patterns.ts index 782f365..69cb207 100644 --- a/src/syntax-core-patterns.ts +++ b/src/syntax-core-patterns.ts @@ -24,15 +24,7 @@ import { } from "./syntax-structures"; import { go_next, go_down, mkzipper, stx_list_content, go_up, change } from "./zipper"; import { preexpand_helpers } from "./preexpand-helpers"; -import { data } from "./data"; - -type handler = (data: data) => Promise<{ - loc: Loc; - counter: number; - unit: CompilationUnit; - context: Context; - lexical: lexical_extension; -}>; +import { walker } from "./data"; const zipper_find: (loc: Loc, pred: (x: STX) => boolean) => Loc | null = (loc, pred) => { const t = loc.t; @@ -260,7 +252,7 @@ export const core_pattern_match: ( return unification; }; -const splice: handler = async ({ loc, context, unit, counter, lexical, helpers, ...data }) => { +const splice: walker = async ({ loc, context, unit, counter, lexical, helpers, ...data }) => { const unification = await core_pattern_match(loc, unit, "splice", helpers); assert(unification !== null); const { subst } = unification; @@ -280,6 +272,7 @@ const splice: handler = async ({ loc, context, unit, counter, lexical, helpers, unit, context, lexical, + helpers, ...data, }; }; @@ -351,7 +344,7 @@ function group_by(ls: [K, V][], eq: (a: K, b: K) => boolean): [K, V[]][] { return ac; } -const using_rewrite_rules: handler = async ({ +const using_rewrite_rules: walker = async ({ loc: orig_loc, context: orig_context, unit: orig_unit, @@ -422,6 +415,7 @@ const using_rewrite_rules: handler = async ({ unit: final_unit, context: final_context, lexical: orig_lexical, + helpers, ...data, }; }; @@ -495,7 +489,7 @@ export async function apply_syntax_rules( return { loc: new_loc, counter: new_counter }; } -const define_rewrite_rules: handler = async ({ +const define_rewrite_rules: walker = async ({ loc: orig_loc, context: orig_context, unit: orig_unit, @@ -568,6 +562,7 @@ const define_rewrite_rules: handler = async ({ unit: final_unit, context: final_context, lexical, + helpers, ...data, }; }; @@ -592,7 +587,7 @@ const define_rewrite_rules: handler = async ({ // } //}; -export const core_handlers: { [k: string]: handler } = { +export const core_handlers: { [k: string]: walker } = { splice, using_rewrite_rules, define_rewrite_rules, From c495b9b1e883082838593116d3ffd28f22d6233a Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 15:06:45 +0300 Subject: [PATCH 10/35] minor refactor --- src/preexpand-handlers.ts | 37 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) diff --git a/src/preexpand-handlers.ts b/src/preexpand-handlers.ts index 1efef66..4f42b5c 100644 --- a/src/preexpand-handlers.ts +++ b/src/preexpand-handlers.ts @@ -71,22 +71,8 @@ export function gen_binding({ ); } -function lexical_declaration({ - loc, - lexical, - context, - counter, - unit, - ...data -}: goodies): Promise { - async function after_vars({ - loc, - lexical, - context, - counter, - unit, - ...data - }: goodies): Promise { +const lexical_declaration: walker = ({ loc, lexical, context, counter, unit, ...data }) => { + const after_vars: walker = async ({ loc, lexical, context, counter, unit, ...data }) => { if (loc.t.type === "atom" && loc.t.tag === "other") { switch (loc.t.content) { case ";": @@ -104,8 +90,8 @@ function lexical_declaration({ } } syntax_error(loc, "expected a ',' or a ';'"); - } - async function get_vars(ls: Loc, lexical: lexical_extension, context: Context, counter: number) { + }; + function get_vars(ls: Loc, lexical: lexical_extension, context: Context, counter: number) { if (ls.t.type === "list" && ls.t.tag === "variable_declarator") { return go_down( ls, @@ -142,19 +128,12 @@ function lexical_declaration({ ), syntax_error, ); -} +}; -function type_alias_declaration({ - loc, - lexical, - context, - counter, - unit, - ...data -}: goodies): Promise { +const type_alias_declaration: walker = ({ loc, ...data }) => { async function after_type(loc: Loc) { assert(loc.t.type === "atom" && loc.t.tag === "identifier", "expected an identifier"); - const gs = gen_binding({ loc, lexical, counter, context, unit, sort: "type", ...data }); + const gs = gen_binding({ loc, sort: "type", ...data }); return { ...gs, loc: go_up(loc) }; } return go_down( @@ -162,7 +141,7 @@ function type_alias_declaration({ (loc) => after_type(skip_required(skip_optional(loc, "export"), ["type"])), syntax_error, ); -} +}; const import_declaration: walker = async ({ loc, helpers, ...data }) => { async function handle_import_from_file(loc: Loc) { From 65aeadeb29d4dd93d8b6cc363d499a5464ff67ee Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 15:14:51 +0300 Subject: [PATCH 11/35] gen_bindings is now more conservative in what it takes and returns --- src/expander.ts | 28 ++++++---------------------- src/preexpand-handlers.ts | 26 ++++++++++++++++++-------- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index c3414df..6bbf664 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -608,7 +608,7 @@ const extract_parameters: swalker = (data) => { const id = data.loc.t; assert(id.type === "atom" && id.tag === "identifier"); const { name, ...gs } = gen_binding({ ...data, sort: "value" }); - return { ...gs, loc: rename(data.loc, name) }; + return { ...data, ...gs, loc: rename(data.loc, name) }; }; const first_param: swalker = (data) => { @@ -780,32 +780,16 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { ); }; - const pre_var: walker = ({ loc, lexical, counter, unit, context, ...data }) => { + const pre_var: walker = ({ loc, ...data }) => { switch (loc.t.tag) { case "identifier": - const { name, ...gs } = gen_binding({ - loc, - lexical, - counter, - context, - unit, - sort: "type", - ...data, - }); - return pre_after_var({ ...gs, loc: rename(loc, name) }); + const { name, ...gs } = gen_binding({ loc, ...data, sort: "type" }); + return pre_after_var({ ...data, ...gs, loc: rename(loc, name) }); case "type_parameter": return go_down(loc, (loc) => { if (loc.t.tag !== "identifier") syntax_error(loc, "expected an identifier"); - const { name, ...gs } = gen_binding({ - loc, - lexical, - counter, - context, - unit, - sort: "type", - ...data, - }); - return pre_after_var({ ...gs, loc: go_up(rename(loc, name)) }); + const { name, ...gs } = gen_binding({ loc, ...data, sort: "type" }); + return pre_after_var({ ...data, ...gs, loc: go_up(rename(loc, name)) }); }); default: syntax_error(loc); diff --git a/src/preexpand-handlers.ts b/src/preexpand-handlers.ts index 4f42b5c..07e973d 100644 --- a/src/preexpand-handlers.ts +++ b/src/preexpand-handlers.ts @@ -9,7 +9,7 @@ import { rib_push, } from "./stx"; import { syntax_error } from "./stx-error"; -import { Context, Loc, STX } from "./syntax-structures"; +import { CompilationUnit, Context, Loc, STX } from "./syntax-structures"; import { list_tag } from "./tags"; import { change, go_down, go_right, go_up, mkzipper } from "./zipper"; @@ -36,8 +36,20 @@ export function gen_binding({ context, unit, sort, - ...data -}: goodies & { sort: "type" | "value" }): Omit & { name: string } { +}: { + loc: Loc; + lexical: lexical_extension; + counter: number; + context: Context; + unit: CompilationUnit; + sort: "type" | "value"; +}): { + name: string; + lexical: lexical_extension; + counter: number; + context: Context; + unit: CompilationUnit; +} { const stx = loc.t; assert(stx.type === "atom" && stx.tag === "identifier", stx); assert(lexical.extensible); @@ -64,7 +76,6 @@ export function gen_binding({ counter, name, unit, - ...data, }), ), (reason) => syntax_error(loc, reason), @@ -103,12 +114,11 @@ const lexical_declaration: walker = ({ loc, lexical, context, counter, unit, ... context, unit, sort: "value", - ...data, }); return go_right( ls, - (loc) => after_vars({ ...goodies, loc }), - (loc) => Promise.resolve({ ...goodies, loc }), + (loc) => after_vars({ ...data, ...goodies, loc }), + (loc) => Promise.resolve({ ...data, ...goodies, loc }), ); }, syntax_error, @@ -134,7 +144,7 @@ const type_alias_declaration: walker = ({ loc, ...data }) => { async function after_type(loc: Loc) { assert(loc.t.type === "atom" && loc.t.tag === "identifier", "expected an identifier"); const gs = gen_binding({ loc, sort: "type", ...data }); - return { ...gs, loc: go_up(loc) }; + return { ...data, ...gs, loc: go_up(loc) }; } return go_down( loc, From 88f05dbe0d53df908019efc0c359f9ed052979d9 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 15:24:48 +0300 Subject: [PATCH 12/35] more simplifications --- src/data.ts | 10 ++++---- src/expander.ts | 61 +++++++++++++++++++------------------------------ 2 files changed, 28 insertions(+), 43 deletions(-) diff --git a/src/data.ts b/src/data.ts index 43159a9..b9246a2 100644 --- a/src/data.ts +++ b/src/data.ts @@ -2,7 +2,7 @@ import { preexpand_helpers } from "./preexpand-helpers"; import { import_req, lexical_extension, modular_extension } from "./stx"; import { CompilationUnit, Context, Loc } from "./syntax-structures"; -export type goodies = { +export type data = { loc: Loc; lexical: lexical_extension; context: Context; @@ -12,14 +12,14 @@ export type goodies = { imp: import_req; }; -export type data = goodies; +export type goodies = data; //export type data = { // modular: modular_extension; //}; -export type walker = (data: goodies) => Promise; +export type walker = (data: data) => Promise; -export type walkerplus = (data: goodies & T) => Promise; +export type walkerplus = (data: data & T) => Promise; -export type swalker = (data: goodies) => goodies; +export type swalker = (data: data) => data; diff --git a/src/expander.ts b/src/expander.ts index 6bbf664..27fd0fa 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -27,7 +27,7 @@ import { debug, in_isolation, syntax_error } from "./stx-error"; import { array_to_ll, join_separated, llappend } from "./llhelpers"; import { gen_binding, preexpand_list_handlers } from "./preexpand-handlers"; import { preexpand_helpers } from "./preexpand-helpers"; -import { data, goodies, swalker, walker, walkerplus } from "./data"; +import { data, swalker, walker, walkerplus } from "./data"; export function initial_step( ast: AST, @@ -720,30 +720,17 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { if (loc.t.content !== "extends") syntax_error(loc, "expected 'extends'"); assert(lexical.extensible); return go_right(loc, (loc) => - expand_expr( - wrap_loc(loc, { + expand_expr({ + loc: wrap_loc(loc, { marks: null, subst: [{ rib_id: lexical.rib_id, cu_id: data.unit.cu_id }, null], aes: null, }), - data.counter, - data.unit, - data.context, - data.imp, - "type", - data.helpers, + sort: "type", lexical, - ).then(({ loc, counter, unit, context, imp, ...data }) => - go_right(loc, syntax_error, () => - post_after_var({ - loc: go_up(loc), - counter, - unit, - context, - imp, - ...data, - }), - ), + ...data, + }).then(({ loc, ...data }) => + go_right(loc, syntax_error, () => post_after_var({ loc: go_up(loc), ...data })), ), ); }); @@ -753,7 +740,7 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { } }; - const pre_after_var: walker = ({ loc, lexical, counter, unit, context, imp, ...data }) => { + const pre_after_var: walker = ({ loc, lexical, counter, unit, ...data }) => { assert(lexical.extensible); return go_right( loc, @@ -761,7 +748,7 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { if (loc.t.content !== ",") syntax_error(loc, "expected a comma ','"); return go_right( loc, - (loc) => pre_var({ loc, lexical, counter, unit, context, imp, ...data }), + (loc) => pre_var({ loc, lexical, counter, unit, ...data }), (loc) => debug(loc, "cant go past commma?"), ); }, @@ -772,8 +759,6 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { lexical, counter, unit: extend_unit(unit, lexical), - context, - imp, ...data, }), ), @@ -823,16 +808,16 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { return go_right(loc, (loc) => start({ loc, ...data }), syntax_error); }; -function expand_expr( - loc: Loc, - counter: number, - unit: CompilationUnit, - context: Context, - imp: import_req, - sort: "type" | "value", - helpers: preexpand_helpers, - lexical: lexical_extension, -): Promise> { +const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ + loc, + counter, + unit, + context, + imp, + sort, + helpers, + lexical, +}) => { return in_isolation( loc, async (loc) => { @@ -869,7 +854,7 @@ function expand_expr( }, (loc, data) => ({ loc, ...data }), ); -} +}; const empty_wrap: Wrap = { marks: null, subst: null, aes: null }; @@ -995,7 +980,7 @@ async function postexpand_type_alias_declaration( context: Context, imp: import_req, ): Promise<{ loc: Loc; imp: import_req; counter: number }> { - return expand_expr(loc, counter, unit, context, imp, "type", helpers, lexical).then( + return expand_expr({ loc, counter, unit, context, imp, sort: "type", helpers, lexical }).then( ({ loc, unit: _unit, counter, context: _context, imp }) => { function done(loc: Loc) { return { loc: go_up(loc), imp, counter }; @@ -1112,7 +1097,7 @@ async function postexpand_lexical_declaration( assert(loc.t.content === "="); return go_right( loc, - (loc) => expand_expr(loc, counter, unit, context, imp, "value", helpers, lexical), + (loc) => expand_expr({ loc, counter, unit, context, imp, sort: "value", helpers, lexical }), (loc) => syntax_error(loc, "expected an expression following the '=' sign"), ); } @@ -1123,7 +1108,7 @@ async function postexpand_lexical_declaration( return go_right( loc, (loc) => - expand_expr(loc, counter, unit, context, imp, "type", helpers, lexical).then( + expand_expr({ loc, counter, unit, context, imp, sort: "type", helpers, lexical }).then( ({ loc, counter, unit: _ignored_unit, context: _ignored_context, imp }) => go_right(loc, handle_value_initializer, (loc) => Promise.resolve({ loc, imp, counter }), From a7b5401c19f13bd8b60ebd27a15bae26e5f3d4c2 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 15:34:17 +0300 Subject: [PATCH 13/35] added modular to data --- src/data.ts | 2 +- src/expander.ts | 151 ++++++++++++++++++++++++++++++------------------ 2 files changed, 96 insertions(+), 57 deletions(-) diff --git a/src/data.ts b/src/data.ts index b9246a2..51a2fbb 100644 --- a/src/data.ts +++ b/src/data.ts @@ -10,12 +10,12 @@ export type data = { unit: CompilationUnit; helpers: preexpand_helpers; imp: import_req; + modular: modular_extension; }; export type goodies = data; //export type data = { -// modular: modular_extension; //}; export type walker = (data: data) => Promise; diff --git a/src/expander.ts b/src/expander.ts index 27fd0fa..e13a7fa 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -46,12 +46,14 @@ export function initial_step( const { stx, counter, unit, rib, rib_id } = init_top_level(ast, cu_id, globals, global_macros); const initial_loc: Loc = mkzipper(stx); const lexical: lexical_extension = { extensible: true, rib, rib_id }; + const empty_rib: Rib = { type: "rib", normal_env: {}, types_env: {} }; + const modular: modular_extension = { extensible: true, explicit: empty_rib, implicit: empty_rib }; const context: Context = {}; const imp: import_req = {}; return [ initial_loc, (helpers: preexpand_helpers) => - expand_program(initial_loc, unit, context, imp, counter, lexical, helpers).then( + expand_program(initial_loc, unit, context, imp, counter, lexical, helpers, modular).then( async ({ loc, unit, context, modular, imp }) => { const import_code = await generate_imports(imp, helpers); assert(loc.t.tag === "program"); @@ -139,6 +141,7 @@ async function expand_program( counter: number, lexical: lexical_extension, helpers: preexpand_helpers, + modular: modular_extension, ): Promise<{ loc: Loc; unit: CompilationUnit; @@ -156,6 +159,7 @@ async function expand_program( sort: "value", helpers, imp, + modular, }).then(({ loc, lexical, counter, context, unit }) => { // rib is filled // context is filled also @@ -175,12 +179,6 @@ async function expand_program( }); } async function expand_empty_program() { - const empty_rib: Rib = { type: "rib", normal_env: {}, types_env: {} }; - const modular: modular_extension = { - extensible: true, - implicit: empty_rib, - explicit: empty_rib, - }; const empty_export: STX = { type: "list", tag: "export_declaration", @@ -237,6 +235,7 @@ async function handle_core_syntax( lexical: lexical_extension, helpers: preexpand_helpers, imp: import_req, + modular: modular_extension, ): Promise<{ loc: Loc; counter: number; @@ -246,7 +245,7 @@ async function handle_core_syntax( }> { const handler = core_handlers[name]; assert(handler !== undefined); - return handler({ loc, context, unit, counter, lexical, helpers, imp }); + return handler({ loc, context, unit, counter, lexical, helpers, imp, modular }); } const atom_handlers_table: { [tag in atom_tag]: "next" | "stop" } = { @@ -325,9 +324,10 @@ async function expand_concise_body( imp: import_req, sort: "type" | "value", helpers: preexpand_helpers, + modular: modular_extension, ): Promise<{ loc: Loc; imp: import_req; counter: number }> { const gs = await (loc.t.type === "list" && loc.t.tag === "statement_block" - ? preexpand_block({ loc, lexical, counter, unit, context, helpers, imp }).then( + ? preexpand_block({ loc, lexical, counter, unit, context, helpers, imp, modular }).then( ({ loc, ...gs }) => go_down( loc, @@ -335,7 +335,7 @@ async function expand_concise_body( (loc) => debug(loc, "???"), ), ) - : preexpand_forms({ loc, lexical, counter, unit, context, sort, helpers, imp })); + : preexpand_forms({ loc, lexical, counter, unit, context, sort, helpers, imp, modular })); const new_unit = extend_unit(gs.unit, gs.lexical); return postexpand_body( gs.loc, @@ -407,6 +407,7 @@ const preexpand_forms: walkerplus<{ sort: "type" | "value" }> = async ({ loc, so data.lexical, data.helpers, data.imp, + data.modular, ).then(({ loc, counter, unit, context, lexical }) => data.helpers.inspect(loc, `core output`, () => preexpand_forms({ @@ -418,6 +419,7 @@ const preexpand_forms: walkerplus<{ sort: "type" | "value" }> = async ({ loc, so sort, helpers: data.helpers, imp: data.imp, + modular: data.modular, }), ), ), @@ -648,6 +650,7 @@ function expand_arrow_function( imp: import_req, unit: CompilationUnit, helpers: preexpand_helpers, + modular: modular_extension, ): Promise<{ loc: Loc; imp: import_req; counter: number }> { return go_down( loc, @@ -658,7 +661,16 @@ function expand_arrow_function( rib_id, rib: { type: "rib", normal_env: {}, types_env: {} }, }; - const pgs = extract_parameters({ loc, lexical, counter, context, unit, helpers, imp }); + const pgs = extract_parameters({ + loc, + lexical, + counter, + context, + unit, + helpers, + imp, + modular, + }); const arr = go_right(pgs.loc, itself, invalid_form); check_punct(arr, "=>"); const body = go_right(arr, itself, invalid_form); @@ -681,6 +693,7 @@ function expand_arrow_function( imp, "value", helpers, + modular, ); }, (loc, { imp, counter }) => ({ loc, imp, counter }), @@ -817,6 +830,7 @@ const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ sort, helpers, lexical, + ...data }) => { return in_isolation( loc, @@ -830,6 +844,7 @@ const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ sort, helpers, imp, + ...data, }).then(({ loc, unit, counter, context, lexical, imp, helpers }) => postexpand_body( loc, @@ -841,7 +856,7 @@ const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ sort, helpers, lexical, - ).then(({ loc, imp, counter, modular: _ignored_modular }) => ({ + ).then(({ loc, imp, counter, modular }) => ({ loc, unit, counter, @@ -849,6 +864,7 @@ const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ imp, helpers, lexical, + modular, })), ); }, @@ -980,21 +996,29 @@ async function postexpand_type_alias_declaration( context: Context, imp: import_req, ): Promise<{ loc: Loc; imp: import_req; counter: number }> { - return expand_expr({ loc, counter, unit, context, imp, sort: "type", helpers, lexical }).then( - ({ loc, unit: _unit, counter, context: _context, imp }) => { - function done(loc: Loc) { - return { loc: go_up(loc), imp, counter }; - } - return go_right( - loc, - (loc) => { - assert(loc.t.content === ";"); - return go_right(loc, syntax_error, done); - }, - done, - ); - }, - ); + return expand_expr({ + loc, + counter, + unit, + context, + imp, + sort: "type", + helpers, + lexical, + modular, + }).then(({ loc, unit: _unit, counter, context: _context, imp }) => { + function done(loc: Loc) { + return { loc: go_up(loc), imp, counter }; + } + return go_right( + loc, + (loc) => { + assert(loc.t.content === ";"); + return go_right(loc, syntax_error, done); + }, + done, + ); + }); } async function do_after_identifier( loc: Loc, @@ -1007,28 +1031,35 @@ async function postexpand_type_alias_declaration( case "=": return go_right(loc, (loc) => do_after_equal(loc, counter, unit, context, imp)); case "<": - return expand_type_parameters({ loc, unit, counter, context, imp, helpers, lexical }).then( - ({ loc, counter, unit, context, lexical, imp }) => { - assert(loc.t.content === ">"); - assert(lexical.extensible); - return go_right(loc, (loc) => { - if (loc.t.content !== "=") syntax_error(loc, "expected '='"); - return go_right(loc, (loc) => - do_after_equal( - wrap_loc(loc, { - marks: null, - subst: [{ rib_id: lexical.rib_id, cu_id: unit.cu_id }, null], - aes: null, - }), - counter, - unit, - context, - imp, - ), - ); - }); - }, - ); + return expand_type_parameters({ + loc, + unit, + counter, + context, + imp, + helpers, + lexical, + modular, + }).then(({ loc, counter, unit, context, lexical, imp }) => { + assert(loc.t.content === ">"); + assert(lexical.extensible); + return go_right(loc, (loc) => { + if (loc.t.content !== "=") syntax_error(loc, "expected '='"); + return go_right(loc, (loc) => + do_after_equal( + wrap_loc(loc, { + marks: null, + subst: [{ rib_id: lexical.rib_id, cu_id: unit.cu_id }, null], + aes: null, + }), + counter, + unit, + context, + imp, + ), + ); + }); + }); default: return syntax_error(loc); } @@ -1097,7 +1128,8 @@ async function postexpand_lexical_declaration( assert(loc.t.content === "="); return go_right( loc, - (loc) => expand_expr({ loc, counter, unit, context, imp, sort: "value", helpers, lexical }), + (loc) => + expand_expr({ loc, counter, unit, context, imp, sort: "value", helpers, lexical, modular }), (loc) => syntax_error(loc, "expected an expression following the '=' sign"), ); } @@ -1108,11 +1140,18 @@ async function postexpand_lexical_declaration( return go_right( loc, (loc) => - expand_expr({ loc, counter, unit, context, imp, sort: "type", helpers, lexical }).then( - ({ loc, counter, unit: _ignored_unit, context: _ignored_context, imp }) => - go_right(loc, handle_value_initializer, (loc) => - Promise.resolve({ loc, imp, counter }), - ), + expand_expr({ + loc, + counter, + unit, + context, + imp, + sort: "type", + helpers, + lexical, + modular, + }).then(({ loc, counter, unit: _ignored_unit, context: _ignored_context, imp }) => + go_right(loc, handle_value_initializer, (loc) => Promise.resolve({ loc, imp, counter })), ), (loc) => syntax_error(loc, "expected an expression following the '=' sign"), ); @@ -1352,7 +1391,7 @@ async function postexpand_body( case "arrow_function": { return in_isolation( loc, - (loc) => expand_arrow_function(loc, counter, context, imp, unit, helpers), + (loc) => expand_arrow_function(loc, counter, context, imp, unit, helpers, modular), (loc, gs) => ({ ...gs, loc }), ).then(({ loc, imp, counter }) => cont(loc, modular, imp, counter)); } From 66f8b69945fe0aa8d1c9173a492b9bb9ab9e6a77 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 15:53:12 +0300 Subject: [PATCH 14/35] simplified handle_core_syntax --- src/expander.ts | 38 ++++---------------------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index e13a7fa..747497c 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -226,17 +226,7 @@ const preexpand_body_curly: walker = async ({ loc, ...data }) => }, ); -async function handle_core_syntax( - loc: Loc, - name: string, - context: Context, - unit: CompilationUnit, - counter: number, - lexical: lexical_extension, - helpers: preexpand_helpers, - imp: import_req, - modular: modular_extension, -): Promise<{ +async function handle_core_syntax({ name, ...data }: data & { name: string }): Promise<{ loc: Loc; counter: number; unit: CompilationUnit; @@ -245,7 +235,7 @@ async function handle_core_syntax( }> { const handler = core_handlers[name]; assert(handler !== undefined); - return handler({ loc, context, unit, counter, lexical, helpers, imp, modular }); + return handler(data); } const atom_handlers_table: { [tag in atom_tag]: "next" | "stop" } = { @@ -398,29 +388,9 @@ const preexpand_forms: walkerplus<{ sort: "type" | "value" }> = async ({ loc, so case "core_syntax": { const { name } = binding; return data.helpers.inspect(loc, "core form", () => - handle_core_syntax( - loc, - name, - data.context, - data.unit, - data.counter, - data.lexical, - data.helpers, - data.imp, - data.modular, - ).then(({ loc, counter, unit, context, lexical }) => + handle_core_syntax({ ...data, loc, name }).then(({ loc, ...new_data }) => data.helpers.inspect(loc, `core output`, () => - preexpand_forms({ - loc, - lexical, - counter, - unit, - context, - sort, - helpers: data.helpers, - imp: data.imp, - modular: data.modular, - }), + preexpand_forms({ loc, sort, ...data, ...new_data }), ), ), ); From 80d9820ed218c52781d7547b7700da7de50a5d94 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Mon, 16 Dec 2024 16:27:46 +0300 Subject: [PATCH 15/35] simplified postexpand_program --- deno.lock | 4 +- rtsc/.rts/testing-file-extensions.rts.json | 2 +- src/expander.ts | 81 ++++++++-------------- src/library-manager.ts | 2 +- test-project/.rts/main.rts.json | 2 +- test-project/.rts/mod.rts.json | 2 +- 6 files changed, 36 insertions(+), 57 deletions(-) diff --git a/deno.lock b/deno.lock index 5393f70..e3496b3 100644 --- a/deno.lock +++ b/deno.lock @@ -1496,8 +1496,8 @@ "npm:@eslint/js@^9.11.1", "npm:@types/babel__code-frame@^7.0.6", "npm:@types/json-stable-stringify@^1.1.0", - "npm:@types/node@^22.10.1", - "npm:@types/react-dom@^19.0.1", + "npm:@types/node@^22.10.2", + "npm:@types/react-dom@^19.0.2", "npm:@types/react@^19.0.1", "npm:@uiw/codemirror-theme-abcdef@^4.23.6", "npm:@uiw/react-codemirror@^4.23.6", diff --git a/rtsc/.rts/testing-file-extensions.rts.json b/rtsc/.rts/testing-file-extensions.rts.json index cda34e9..bc881a2 100644 --- a/rtsc/.rts/testing-file-extensions.rts.json +++ b/rtsc/.rts/testing-file-extensions.rts.json @@ -1,6 +1,6 @@ { "cid": "rtsc/testing-file-extensions.rts rewrite-ts-visualized 0.0.0", - "cookie": "rewrite-ts-007", + "cookie": "rewrite-ts-008", "exported_identifiers": { "x": [ { diff --git a/src/expander.ts b/src/expander.ts index 747497c..32e571e 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -50,22 +50,21 @@ export function initial_step( const modular: modular_extension = { extensible: true, explicit: empty_rib, implicit: empty_rib }; const context: Context = {}; const imp: import_req = {}; + const data = { loc: initial_loc, unit, context, imp, counter, lexical, modular }; return [ initial_loc, (helpers: preexpand_helpers) => - expand_program(initial_loc, unit, context, imp, counter, lexical, helpers, modular).then( - async ({ loc, unit, context, modular, imp }) => { - const import_code = await generate_imports(imp, helpers); - assert(loc.t.tag === "program"); - assert(loc.p.type === "top"); - const new_program: STX = { - ...loc.t, - wrap: empty_wrap, - content: llappend(array_to_ll(import_code), loc.t.content), - }; - return { loc: mkzipper(new_program), unit, context, modular }; - }, - ), + expand_program({ ...data, helpers }).then(async ({ loc, imp, ...data }) => { + const import_code = await generate_imports(imp, helpers); + assert(loc.t.tag === "program"); + assert(loc.p.type === "top"); + const new_program: STX = { + ...loc.t, + wrap: empty_wrap, + content: llappend(array_to_ll(import_code), loc.t.content), + }; + return { loc: mkzipper(new_program), ...data }; + }), ]; } @@ -133,16 +132,7 @@ async function generate_imports(imp: import_req, helpers: preexpand_helpers): Pr return Promise.all(Object.entries(imp).map(([cuid, bindings]) => generate(cuid, bindings))); } -async function expand_program( - loc: Loc, - unit: CompilationUnit, - context: Context, - imp: import_req, - counter: number, - lexical: lexical_extension, - helpers: preexpand_helpers, - modular: modular_extension, -): Promise<{ +async function expand_program({ loc, ...data }: data): Promise<{ loc: Loc; unit: CompilationUnit; context: Context; @@ -152,27 +142,16 @@ async function expand_program( async function expand(loc: Loc) { return preexpand_body({ loc, - lexical, - unit, - context, - counter, sort: "value", - helpers, - imp, - modular, - }).then(({ loc, lexical, counter, context, unit }) => { + ...data, + }).then(({ loc, lexical, unit, ...new_data }) => { // rib is filled // context is filled also const new_unit = extend_unit(unit, lexical); - const modular: modular_extension = { - extensible: true, - explicit: { type: "rib", normal_env: {}, types_env: {} }, - implicit: { type: "rib", normal_env: {}, types_env: {} }, - }; - return helpers.inspect(loc, "After preexpanding the program", () => - postexpand_program(loc, modular, new_unit, counter, context, imp, helpers, lexical).then( - ({ loc, modular, imp, counter }) => { - return { loc, unit: new_unit, context, modular, imp, counter }; + return data.helpers.inspect(loc, "After preexpanding the program", () => + postexpand_program({ loc, ...data, ...new_data, unit: new_unit, lexical }).then( + ({ loc, ...new_new_data }) => { + return { ...new_data, ...new_new_data, loc, unit: new_unit }; }, ), ); @@ -193,7 +172,7 @@ async function expand_program( content: array_to_ll([empty_export]), src: false, }; - return { loc: mkzipper(empty_program), unit, context, modular, imp, counter }; + return { loc: mkzipper(empty_program), ...data }; } if (loc.t.tag !== "program") syntax_error(loc, "expected a program"); return go_down(loc, expand, expand_empty_program); @@ -510,16 +489,16 @@ function find_form(loc: Loc): ffrv { return find_form(loc); } -function postexpand_program( - loc: Loc, - modular: modular_extension, - unit: CompilationUnit, - counter: number, - context: Context, - imp: import_req, - helpers: preexpand_helpers, - lexical: lexical_extension, -): Promise<{ loc: Loc; modular: modular_extension; counter: number; imp: import_req }> { +function postexpand_program({ + loc, + modular, + unit, + counter, + context, + imp, + helpers, + lexical, +}: data): Promise<{ loc: Loc; modular: modular_extension; counter: number; imp: import_req }> { assert(loc.t.tag === "program"); return go_down(loc, (loc) => postexpand_body(loc, modular, unit, counter, context, imp, "value", helpers, lexical), diff --git a/src/library-manager.ts b/src/library-manager.ts index b0365a3..d9a9847 100644 --- a/src/library-manager.ts +++ b/src/library-manager.ts @@ -19,7 +19,7 @@ import { Binding, CompilationUnit, Context, Loc } from "./syntax-structures"; import stringify from "json-stringify-pretty-compact"; import { init_global_context } from "./global-module"; -const cookie = "rewrite-ts-007"; +const cookie = "rewrite-ts-008"; type module_state = | { type: "initial" } diff --git a/test-project/.rts/main.rts.json b/test-project/.rts/main.rts.json index bba218c..a961edb 100644 --- a/test-project/.rts/main.rts.json +++ b/test-project/.rts/main.rts.json @@ -1,6 +1,6 @@ { "cid": "test-project/main.rts rewrite-ts-visualized 0.0.0", - "cookie": "rewrite-ts-007", + "cookie": "rewrite-ts-008", "exported_identifiers": {}, "context": {} } \ No newline at end of file diff --git a/test-project/.rts/mod.rts.json b/test-project/.rts/mod.rts.json index 03885d0..9ac5014 100644 --- a/test-project/.rts/mod.rts.json +++ b/test-project/.rts/mod.rts.json @@ -1,6 +1,6 @@ { "cid": "test-project/mod.rts rewrite-ts-visualized 0.0.0", - "cookie": "rewrite-ts-007", + "cookie": "rewrite-ts-008", "exported_identifiers": { "x": [ { From 441e3c1a97130ead8fbbc55a5c8d962de2cee075 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 03:07:27 +0300 Subject: [PATCH 16/35] refacrored postexpand_body --- src/expander.ts | 119 +++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 67 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 32e571e..5551bd0 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -306,17 +306,17 @@ async function expand_concise_body( ) : preexpand_forms({ loc, lexical, counter, unit, context, sort, helpers, imp, modular })); const new_unit = extend_unit(gs.unit, gs.lexical); - return postexpand_body( - gs.loc, - { extensible: false }, - new_unit, - gs.counter, - gs.context, + return postexpand_body({ + loc: gs.loc, + modular: { extensible: false }, + unit: new_unit, + counter: gs.counter, + context: gs.context, imp, sort, helpers, lexical, - ); + }); } function rewrap(loc: Loc, rib_id: string, cu_id: string): Loc { @@ -501,7 +501,7 @@ function postexpand_program({ }: data): Promise<{ loc: Loc; modular: modular_extension; counter: number; imp: import_req }> { assert(loc.t.tag === "program"); return go_down(loc, (loc) => - postexpand_body(loc, modular, unit, counter, context, imp, "value", helpers, lexical), + postexpand_body({ loc, modular, unit, counter, context, imp, sort: "value", helpers, lexical }), ); } @@ -770,53 +770,33 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { return go_right(loc, (loc) => start({ loc, ...data }), syntax_error); }; -const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ - loc, - counter, - unit, - context, - imp, - sort, - helpers, - lexical, - ...data -}) => { +const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ loc, sort, ...data }) => { return in_isolation( loc, - async (loc) => { - return preexpand_forms({ - loc, - lexical, - counter, - unit, - context, - sort, - helpers, - imp, - ...data, - }).then(({ loc, unit, counter, context, lexical, imp, helpers }) => - postexpand_body( - loc, - { extensible: false }, - unit, - counter, - context, - imp, - sort, - helpers, - lexical, - ).then(({ loc, imp, counter, modular }) => ({ - loc, - unit, - counter, - context, - imp, - helpers, - lexical, - modular, - })), - ); - }, + (loc) => + preexpand_forms({ loc, sort, ...data }).then( + ({ loc, unit, counter, context, lexical, imp, helpers }) => + postexpand_body({ + loc, + modular: { extensible: false }, + unit, + counter, + context, + imp, + sort, + helpers, + lexical, + }).then(({ loc, imp, counter, modular }) => ({ + unit, + context, + helpers, + lexical, + loc, + imp, + counter, + modular, + })), + ), (loc, data) => ({ loc, ...data }), ); }; @@ -1247,17 +1227,22 @@ function rename(loc: Loc, new_name: string): Loc { const sort_env = { type: "types_env" as const, value: "normal_env" as const }; -async function postexpand_body( - loc: Loc, - modular: modular_extension, - unit: CompilationUnit, - counter: number, - context: Context, - imp: import_req, - sort: "type" | "value", - helpers: preexpand_helpers, - lexical: lexical_extension, -): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { +async function postexpand_body({ + loc, + modular, + unit, + counter, + context, + imp, + sort, + helpers, + lexical, +}: data & { sort: "type" | "value" }): Promise<{ + loc: Loc; + modular: modular_extension; + imp: import_req; + counter: number; +}> { type T = Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }>; async function done(loc: Loc, modular: modular_extension, imp: import_req, counter: number): T { return { loc, modular, imp, counter }; @@ -1364,9 +1349,9 @@ async function postexpand_body( in_isolation( loc, (loc) => - postexpand_body( + postexpand_body({ loc, - { extensible: false }, + modular: { extensible: false }, unit, counter, context, @@ -1374,7 +1359,7 @@ async function postexpand_body( sort, helpers, lexical, - ), + }), (loc, { modular: _ignored_modular, imp, counter }) => go_right(loc, (loc) => { assert(loc.t.content === "."); From ab18f1bf978776f706ee0e4a99143523a29effba Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 03:15:53 +0300 Subject: [PATCH 17/35] progress --- src/expander.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 5551bd0..40c6771 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -1041,16 +1041,16 @@ async function postexpand_type_alias_declaration( }).then(({ loc, modular, imp, counter }) => insert_export_keyword(loc, counter, modular, imp)); } -async function postexpand_lexical_declaration( - loc: Loc, - modular: modular_extension, - unit: CompilationUnit, - counter: number, - context: Context, - imp: import_req, - helpers: preexpand_helpers, - lexical: lexical_extension, -): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { +async function postexpand_lexical_declaration({ + loc, + modular, + unit, + counter, + context, + imp, + helpers, + lexical, +}: data): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { async function handle_value_initializer( loc: Loc, ): Promise<{ loc: Loc; imp: import_req; counter: number }> { @@ -1312,7 +1312,7 @@ async function postexpand_body({ switch (loc.t.tag) { case "lexical_declaration": assert(sort === "value"); - return postexpand_lexical_declaration( + return postexpand_lexical_declaration({ loc, modular, unit, @@ -1321,7 +1321,7 @@ async function postexpand_body({ imp, helpers, lexical, - ).then(({ loc, modular, imp, counter }) => cont(loc, modular, imp, counter)); + }).then(({ loc, modular, imp, counter }) => cont(loc, modular, imp, counter)); case "arrow_function": { return in_isolation( loc, From b93868de70d89630702ce6d8273d0e43becb09de Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 03:18:13 +0300 Subject: [PATCH 18/35] progress --- src/expander.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 40c6771..80728d4 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -908,16 +908,16 @@ function insert_export_keyword( } } -async function postexpand_type_alias_declaration( - loc: Loc, - modular: modular_extension, - unit: CompilationUnit, - counter: number, - context: Context, - imp: import_req, - helpers: preexpand_helpers, - lexical: lexical_extension, -): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { +async function postexpand_type_alias_declaration({ + loc, + modular, + unit, + context, + counter, + imp, + helpers, + lexical, +}: data): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { async function do_after_equal( loc: Loc, counter: number, @@ -1333,7 +1333,7 @@ async function postexpand_body({ return syntax_error(loc, "invalid slice"); } case "type_alias_declaration": { - return postexpand_type_alias_declaration( + return postexpand_type_alias_declaration({ loc, modular, unit, @@ -1342,7 +1342,7 @@ async function postexpand_body({ imp, helpers, lexical, - ).then(({ loc, modular, imp, counter }) => cont(loc, modular, imp, counter)); + }).then(({ loc, modular, imp, counter }) => cont(loc, modular, imp, counter)); } case "member_expression": { return go_down(loc, (loc) => From 2a2f7b399168ffa904ec57ecba39386d8a7a7922 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 04:12:56 +0300 Subject: [PATCH 19/35] more refactoring --- src/expander.ts | 156 +++++++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 82 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 80728d4..143ff84 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -600,7 +600,7 @@ function expand_arrow_function( unit: CompilationUnit, helpers: preexpand_helpers, modular: modular_extension, -): Promise<{ loc: Loc; imp: import_req; counter: number }> { +): Promise<{ loc: Loc; imp: import_req; counter: number; modular: modular_extension }> { return go_down( loc, (loc) => { @@ -645,7 +645,7 @@ function expand_arrow_function( modular, ); }, - (loc, { imp, counter }) => ({ loc, imp, counter }), + (loc, { imp, counter }) => ({ loc, imp, counter, modular }), ); }, invalid_form, @@ -770,34 +770,21 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { return go_right(loc, (loc) => start({ loc, ...data }), syntax_error); }; -const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ loc, sort, ...data }) => { +const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ + loc, + sort, + modular, + unit, + context, + ...data +}) => { return in_isolation( loc, (loc) => - preexpand_forms({ loc, sort, ...data }).then( - ({ loc, unit, counter, context, lexical, imp, helpers }) => - postexpand_body({ - loc, - modular: { extensible: false }, - unit, - counter, - context, - imp, - sort, - helpers, - lexical, - }).then(({ loc, imp, counter, modular }) => ({ - unit, - context, - helpers, - lexical, - loc, - imp, - counter, - modular, - })), + preexpand_forms({ loc, sort, modular: { extensible: false }, unit, context, ...data }).then( + (data) => postexpand_body({ ...data, sort }), ), - (loc, data) => ({ loc, ...data }), + (loc, new_data) => ({ loc, ...data, ...new_data, modular, unit, context }), ); }; @@ -1227,27 +1214,36 @@ function rename(loc: Loc, new_name: string): Loc { const sort_env = { type: "types_env" as const, value: "normal_env" as const }; -async function postexpand_body({ +const postexpand_forms: walkerplus<{ sort: "type" | "value" }> = ({ modular, ...data }) => + postexpand_body({ modular: { extensible: false }, ...data }).then((new_data) => ({ + ...data, + ...new_data, + modular, + })); + +const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ loc, modular, - unit, counter, - context, imp, sort, - helpers, - lexical, -}: data & { sort: "type" | "value" }): Promise<{ - loc: Loc; - modular: modular_extension; - imp: import_req; - counter: number; -}> { - type T = Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }>; + ...data +}) => { + type T = Promise; async function done(loc: Loc, modular: modular_extension, imp: import_req, counter: number): T { - return { loc, modular, imp, counter }; + return { ...data, loc, modular, imp, counter }; } - function cont(loc: Loc, modular: modular_extension, imp: import_req, counter: number): T { + function cont({ + loc, + imp, + modular, + counter, + }: { + loc: Loc; + modular: modular_extension; + imp: import_req; + counter: number; + }): T { return go_next( loc, (loc) => h(find_form(loc), modular, imp, counter), @@ -1264,7 +1260,14 @@ async function postexpand_body({ const { tag, content, wrap } = loc.t; switch (tag) { case "identifier": { - const resolution = await resolve(content, wrap, context, unit, sort_env[sort], helpers); + const resolution = await resolve( + content, + wrap, + data.context, + data.unit, + sort_env[sort], + data.helpers, + ); switch (resolution.type) { case "bound": { const { binding, label } = resolution; @@ -1272,12 +1275,12 @@ async function postexpand_body({ case "ts": case "type": case "lexical": { - return cont(rename(loc, binding.name), modular, imp, counter); + return cont({ loc: rename(loc, binding.name), modular, imp, counter }); } case "imported_lexical": { const existing = (imp[label.cuid] ?? {})[label.name]; if (existing) { - return cont(rename(loc, existing.new_name), modular, imp, counter); + return cont({ loc: rename(loc, existing.new_name), modular, imp, counter }); } else { const { name } = binding; const new_name = `${name}_${counter}`; @@ -1289,7 +1292,12 @@ async function postexpand_body({ [label.name]: { type: "value", new_name }, }, }; - return cont(rename(loc, new_name), modular, new_imp, new_counter); + return cont({ + loc: rename(loc, new_name), + modular, + imp: new_imp, + counter: new_counter, + }); } } default: { @@ -1312,55 +1320,39 @@ async function postexpand_body({ switch (loc.t.tag) { case "lexical_declaration": assert(sort === "value"); - return postexpand_lexical_declaration({ - loc, - modular, - unit, - counter, - context, - imp, - helpers, - lexical, - }).then(({ loc, modular, imp, counter }) => cont(loc, modular, imp, counter)); + return postexpand_lexical_declaration({ loc, modular, counter, imp, ...data }).then( + cont, + ); case "arrow_function": { return in_isolation( loc, - (loc) => expand_arrow_function(loc, counter, context, imp, unit, helpers, modular), + (loc) => + expand_arrow_function( + loc, + counter, + data.context, + imp, + data.unit, + data.helpers, + modular, + ), (loc, gs) => ({ ...gs, loc }), - ).then(({ loc, imp, counter }) => cont(loc, modular, imp, counter)); + ).then(cont); } case "slice": { return syntax_error(loc, "invalid slice"); } case "type_alias_declaration": { - return postexpand_type_alias_declaration({ - loc, - modular, - unit, - counter, - context, - imp, - helpers, - lexical, - }).then(({ loc, modular, imp, counter }) => cont(loc, modular, imp, counter)); + return postexpand_type_alias_declaration({ loc, modular, counter, imp, ...data }).then( + cont, + ); } case "member_expression": { return go_down(loc, (loc) => in_isolation( loc, - (loc) => - postexpand_body({ - loc, - modular: { extensible: false }, - unit, - counter, - context, - imp, - sort, - helpers, - lexical, - }), - (loc, { modular: _ignored_modular, imp, counter }) => + (loc) => postexpand_forms({ loc, modular, counter, imp, sort, ...data }), + (loc, { modular, imp, counter }) => go_right(loc, (loc) => { assert(loc.t.content === "."); return go_right(loc, (loc) => { @@ -1372,18 +1364,18 @@ async function postexpand_body({ } }); }), - ).then(({ loc, modular, imp, counter }) => cont(loc, modular, imp, counter)), + ).then(cont), ); } default: { if (list_handlers_table[loc.t.tag] !== "descend") { debug(loc, `unhandled '${loc.t.tag}' form in postexpand_body`); } - return cont(loc, modular, imp, counter); + return cont({ loc, modular, imp, counter }); } } } } } return h(find_form(loc), modular, imp, counter); -} +}; From 432d3b9cb089314f07f2b364c124cb156e4d1520 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 04:24:43 +0300 Subject: [PATCH 20/35] refactoring --- src/expander.ts | 90 ++++++++++++++++++------------------------------- 1 file changed, 33 insertions(+), 57 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 143ff84..beb3e44 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -489,21 +489,11 @@ function find_form(loc: Loc): ffrv { return find_form(loc); } -function postexpand_program({ - loc, - modular, - unit, - counter, - context, - imp, - helpers, - lexical, -}: data): Promise<{ loc: Loc; modular: modular_extension; counter: number; imp: import_req }> { - assert(loc.t.tag === "program"); - return go_down(loc, (loc) => - postexpand_body({ loc, modular, unit, counter, context, imp, sort: "value", helpers, lexical }), - ); -} +const postexpand_program: walker = ({ loc, ...data }: data) => + go_down(loc, (loc) => postexpand_body({ loc, sort: "value", ...data })).then((new_data) => ({ + ...data, + ...new_data, + })); function invalid_form(loc: Loc): never { syntax_error(loc, "invalid form"); @@ -516,39 +506,28 @@ function itself(loc: Loc): Loc { const extract_parameters: swalker = (data) => { // const tail: swalker = ({ loc, ...data }) => { - switch (loc.t.type) { - case "atom": { - switch (loc.t.tag) { - case "other": { - switch (loc.t.content) { - case ",": - return go_right(loc, (loc) => head({ ...data, loc }), invalid_form); - case ")": - return go_right(loc, invalid_form, (loc) => ({ ...data, loc: go_up(loc) })); - } - } - } - } + switch (loc.t.content) { + case ",": + return go_right(loc, (loc) => head({ ...data, loc }), invalid_form); + case ")": + return go_right(loc, invalid_form, (loc) => ({ ...data, loc: go_up(loc) })); + default: + syntax_error(loc); } - syntax_error(loc); }; const head: swalker = ({ loc, ...data }) => { - switch (loc.t.type) { - case "atom": { - switch (loc.t.tag) { - case "identifier": { - const gs = identifier({ loc, ...data }); - return go_right(gs.loc, (loc) => tail({ ...gs, loc }), invalid_form); - } - case "other": { - switch (loc.t.content) { - case ",": - return invalid_form(loc); - case ")": - return go_right(loc, invalid_form, (loc) => ({ ...data, loc: go_up(loc) })); - } - } + switch (loc.t.tag) { + case "identifier": { + const gs = identifier({ loc, ...data }); + return go_right(gs.loc, (loc) => tail({ ...gs, loc }), invalid_form); + } + case "other": { + switch (loc.t.content) { + case ",": + return invalid_form(loc); + case ")": + return go_right(loc, invalid_form, (loc) => ({ ...data, loc: go_up(loc) })); } } } @@ -563,23 +542,20 @@ const extract_parameters: swalker = (data) => { }; const first_param: swalker = (data) => { - switch (data.loc.t.type) { - case "atom": { - switch (data.loc.t.tag) { - case "identifier": - const gs = identifier(data); - return go_right(gs.loc, invalid_form, (loc) => ({ ...gs, loc: go_up(loc) })); - case "other": { - if (data.loc.t.content === "(") { - return go_right(data.loc, (loc) => head({ ...data, loc }), invalid_form); - } - } + switch (data.loc.t.tag) { + case "identifier": + const gs = identifier(data); + return go_right(gs.loc, invalid_form, (loc) => ({ ...gs, loc: go_up(loc) })); + case "other": { + if (data.loc.t.content === "(") { + return go_right(data.loc, (loc) => head({ ...data, loc }), invalid_form); } - return syntax_error(data.loc); } + default: + syntax_error(data.loc); } - debug(data.loc, "non atom first_param"); }; + { assert(data.loc.t.type === "list" && data.loc.t.tag === "formal_parameters"); return go_down(data.loc, (loc) => first_param({ ...data, loc }), invalid_form); From c3ebbaa2c9928412a9c68b6360208e1b3997e813 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 04:35:05 +0300 Subject: [PATCH 21/35] refactored expand_arrow_function --- src/expander.ts | 84 +++++++++++++++++++++---------------------------- 1 file changed, 35 insertions(+), 49 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index beb3e44..35600a9 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -568,15 +568,15 @@ function check_punct(loc: Loc, content: string) { } } -function expand_arrow_function( - loc: Loc, - counter: number, - context: Context, - imp: import_req, - unit: CompilationUnit, - helpers: preexpand_helpers, - modular: modular_extension, -): Promise<{ loc: Loc; imp: import_req; counter: number; modular: modular_extension }> { +function expand_arrow_function({ + loc, + counter, + context, + imp, + unit, + helpers, + modular, +}: data): Promise<{ loc: Loc; imp: import_req; counter: number; modular: modular_extension }> { return go_down( loc, (loc) => { @@ -840,12 +840,17 @@ const as_keyword: STX = { src: false, }; -function insert_export_keyword( - loc: Loc, - counter: number, - modular: modular_extension, - imp: import_req, -): { +function insert_export_keyword({ + loc, + counter, + modular, + imp, +}: { + loc: Loc; + counter: number; + modular: modular_extension; + imp: import_req; +}): { loc: Loc; modular: modular_extension; counter: number; @@ -1001,7 +1006,7 @@ async function postexpand_type_alias_declaration({ default: syntax_error(loc); } - }).then(({ loc, modular, imp, counter }) => insert_export_keyword(loc, counter, modular, imp)); + }).then(insert_export_keyword); } async function postexpand_lexical_declaration({ @@ -1146,35 +1151,25 @@ async function postexpand_lexical_declaration({ counter: number, ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { assert(loc.t.content === "let" || loc.t.content === "const"); - return go_right( - loc, - (loc) => handle_declarations(loc, exporting, modular, imp, counter), - syntax_error, - ); + return go_right(loc, (loc) => handle_declarations(loc, exporting, modular, imp, counter)); } async function handle_export( loc: Loc, ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { if (!modular.extensible) syntax_error(loc, "unexpected export keyword"); - return go_right(loc, (loc) => handle_declaration_list(loc, true, imp, counter), syntax_error); + return go_right(loc, (loc) => handle_declaration_list(loc, true, imp, counter)); } - return go_down( - loc, - (loc) => { - switch (loc.t.content) { - case "export": - return handle_export(loc); - case "const": - case "let": - return handle_declaration_list(loc, false, imp, counter); - default: - syntax_error(loc); - } - }, - syntax_error, - ).then(({ loc, modular: new_modular, imp, counter }) => - insert_export_keyword(loc, counter, new_modular, imp), - ); + return go_down(loc, (loc) => { + switch (loc.t.content) { + case "export": + return handle_export(loc); + case "const": + case "let": + return handle_declaration_list(loc, false, imp, counter); + default: + syntax_error(loc); + } + }).then(insert_export_keyword); } function rename(loc: Loc, new_name: string): Loc { @@ -1302,16 +1297,7 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ case "arrow_function": { return in_isolation( loc, - (loc) => - expand_arrow_function( - loc, - counter, - data.context, - imp, - data.unit, - data.helpers, - modular, - ), + (loc) => expand_arrow_function({ ...data, loc, counter, imp, modular }), (loc, gs) => ({ ...gs, loc }), ).then(cont); } From 2af84d2f098aacfb3b518ca0e02bd53abff1715f Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 05:26:56 +0300 Subject: [PATCH 22/35] more refactoring --- src/expander.ts | 239 ++++++++++++++++++------------------------------ 1 file changed, 90 insertions(+), 149 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 35600a9..401d040 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -840,22 +840,7 @@ const as_keyword: STX = { src: false, }; -function insert_export_keyword({ - loc, - counter, - modular, - imp, -}: { - loc: Loc; - counter: number; - modular: modular_extension; - imp: import_req; -}): { - loc: Loc; - modular: modular_extension; - counter: number; - imp: import_req; -} { +function insert_export_keyword({ loc, counter, modular, imp }: ppdata): ppdata { if (modular.extensible) { assert(loc.t.type === "list"); const content = stx_list_content(loc.t); @@ -885,14 +870,14 @@ async function postexpand_type_alias_declaration({ imp, helpers, lexical, -}: data): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { +}: data): Promise { async function do_after_equal( loc: Loc, counter: number, unit: CompilationUnit, context: Context, imp: import_req, - ): Promise<{ loc: Loc; imp: import_req; counter: number }> { + ): Promise { return expand_expr({ loc, counter, @@ -903,9 +888,9 @@ async function postexpand_type_alias_declaration({ helpers, lexical, modular, - }).then(({ loc, unit: _unit, counter, context: _context, imp }) => { + }).then(({ loc, ...data }) => { function done(loc: Loc) { - return { loc: go_up(loc), imp, counter }; + return { ...data, loc: go_up(loc) }; } return go_right( loc, @@ -923,7 +908,7 @@ async function postexpand_type_alias_declaration({ unit: CompilationUnit, context: Context, imp: import_req, - ): Promise<{ loc: Loc; imp: import_req; counter: number }> { + ): Promise { switch (loc.t.content) { case "=": return go_right(loc, (loc) => do_after_equal(loc, counter, unit, context, imp)); @@ -962,10 +947,7 @@ async function postexpand_type_alias_declaration({ } } - function handle_type( - loc: Loc, - exporting: boolean, - ): Promise<{ loc: Loc; imp: import_req; counter: number; modular: modular_extension }> { + function handle_type(loc: Loc, exporting: boolean): Promise { assert(loc.t.content === "type"); return go_right(loc, async (loc) => { assert(loc.t.tag === "identifier"); @@ -986,13 +968,11 @@ async function postexpand_type_alias_declaration({ "types_env", loc, ); - return { loc: gs.loc, modular: new_modular, counter: gs.counter, imp: gs.imp }; + return { ...gs, modular: new_modular }; }); } - function handle_export( - loc: Loc, - ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { + function handle_export(loc: Loc): Promise { assert(loc.t.content === "export"); if (!modular.extensible) syntax_error(loc, "location does not permit export"); return go_right(loc, (loc) => handle_type(loc, true), syntax_error); @@ -1009,53 +989,29 @@ async function postexpand_type_alias_declaration({ }).then(insert_export_keyword); } -async function postexpand_lexical_declaration({ - loc, - modular, - unit, - counter, - context, - imp, - helpers, - lexical, -}: data): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { - async function handle_value_initializer( - loc: Loc, - ): Promise<{ loc: Loc; imp: import_req; counter: number }> { +async function postexpand_lexical_declaration({ loc, ...data }: data): Promise { + async function handle_value_initializer(loc: Loc): Promise { assert(loc.t.content === "="); return go_right( loc, - (loc) => - expand_expr({ loc, counter, unit, context, imp, sort: "value", helpers, lexical, modular }), + (loc) => expand_expr({ loc, sort: "value", ...data }), (loc) => syntax_error(loc, "expected an expression following the '=' sign"), ); } - async function handle_type_then_initializer( - loc: Loc, - ): Promise<{ loc: Loc; imp: import_req; counter: number }> { + + async function handle_type_then_initializer(loc: Loc): Promise { assert(loc.t.content === ":"); return go_right( loc, (loc) => - expand_expr({ - loc, - counter, - unit, - context, - imp, - sort: "type", - helpers, - lexical, - modular, - }).then(({ loc, counter, unit: _ignored_unit, context: _ignored_context, imp }) => - go_right(loc, handle_value_initializer, (loc) => Promise.resolve({ loc, imp, counter })), + expand_expr({ loc, sort: "type", ...data }).then(({ loc, ...data }) => + go_right(loc, handle_value_initializer, (loc) => Promise.resolve({ loc, ...data })), ), (loc) => syntax_error(loc, "expected an expression following the '=' sign"), ); } - async function handle_initializer( - loc: Loc, - ): Promise<{ loc: Loc; imp: import_req; counter: number }> { + + async function handle_initializer(loc: Loc): Promise { switch (loc.t.content) { case "=": return handle_value_initializer(loc); @@ -1065,63 +1021,52 @@ async function postexpand_lexical_declaration({ syntax_error(loc); } } - async function handle_inner_variable_declarator( - loc: Loc, - exporting: boolean, - modular: modular_extension, - imp: import_req, - counter: number, - ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { - assert(loc.t.tag === "identifier"); - const { content, wrap } = loc.t; - const resolution = await resolve(content, wrap, context, unit, "normal_env", helpers); - assert(resolution.type === "bound"); - assert(resolution.binding.type === "lexical"); - const new_name = resolution.binding.name; - const gs = await go_right( - rename(loc, new_name), - (loc) => handle_initializer(loc), - (loc) => Promise.resolve({ loc, imp, counter }), - ); - return { - loc: go_up(gs.loc), - modular: extend_modular( - modular, - exporting, + + function handle_declaration_list(exporting: boolean) { + // + async function handle_inner_variable_declarator(loc: Loc): Promise { + assert(loc.t.tag === "identifier"); + const { content, wrap } = loc.t; + const resolution = await resolve( content, - wrap.marks, - resolution.label, + wrap, + data.context, + data.unit, "normal_env", - loc, - ), - imp: gs.imp, - counter: gs.counter, - }; - } - async function handle_variable_declarator( - loc: Loc, - exporting: boolean, - modular: modular_extension, - imp: import_req, - counter: number, - ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { - assert(loc.t.tag === "variable_declarator"); - return go_down( - loc, - (loc) => handle_inner_variable_declarator(loc, exporting, modular, imp, counter), - syntax_error, - ); - } - async function handle_declarations( - loc: Loc, - exporting: boolean, - modular: modular_extension, - imp: import_req, - counter: number, - ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { - if (loc.t.tag === "variable_declarator") { - return handle_variable_declarator(loc, exporting, modular, imp, counter).then( - ({ loc, modular, imp, counter }) => + data.helpers, + ); + assert(resolution.type === "bound"); + assert(resolution.binding.type === "lexical"); + const new_name = resolution.binding.name; + const gs = await go_right( + rename(loc, new_name), + (loc) => handle_initializer(loc), + (loc) => Promise.resolve({ ...data, loc }), + ); + return { + ...data, + ...gs, + loc: go_up(gs.loc), + modular: extend_modular( + data.modular, + exporting, + content, + wrap.marks, + resolution.label, + "normal_env", + loc, + ), + }; + } + + async function handle_variable_declarator(loc: Loc): Promise { + assert(loc.t.tag === "variable_declarator"); + return go_down(loc, (loc) => handle_inner_variable_declarator(loc)); + } + + async function handle_declarations(loc: Loc): Promise { + if (loc.t.tag === "variable_declarator") { + return handle_variable_declarator(loc).then(({ loc, ...data }) => go_right( loc, (loc) => { @@ -1129,43 +1074,42 @@ async function postexpand_lexical_declaration({ case ",": return go_right( loc, - (loc) => handle_declarations(loc, exporting, modular, imp, counter), - (loc) => Promise.resolve({ loc: go_up(loc), modular, imp, counter }), + (loc) => handle_declarations(loc), + (loc) => Promise.resolve({ loc: go_up(loc), ...data }), ); case ";": - return Promise.resolve({ loc: go_up(loc), modular, imp, counter }); + return Promise.resolve({ loc: go_up(loc), ...data }); default: syntax_error(loc); } }, - (loc) => Promise.resolve({ loc: go_up(loc), modular, imp, counter }), + (loc) => Promise.resolve({ loc: go_up(loc), ...data }), ), - ); + ); + } + debug(loc, "handle_declarations"); } - debug(loc, "handle_declarations"); - } - async function handle_declaration_list( - loc: Loc, - exporting: boolean, - imp: import_req, - counter: number, - ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { - assert(loc.t.content === "let" || loc.t.content === "const"); - return go_right(loc, (loc) => handle_declarations(loc, exporting, modular, imp, counter)); + + async function handle_declaration_list(loc: Loc): Promise { + assert(loc.t.content === "let" || loc.t.content === "const"); + return go_right(loc, (loc) => handle_declarations(loc)); + } + + return handle_declaration_list; } - async function handle_export( - loc: Loc, - ): Promise<{ loc: Loc; modular: modular_extension; imp: import_req; counter: number }> { - if (!modular.extensible) syntax_error(loc, "unexpected export keyword"); - return go_right(loc, (loc) => handle_declaration_list(loc, true, imp, counter)); + + async function handle_export(loc: Loc): Promise { + if (!data.modular.extensible) syntax_error(loc, "unexpected export keyword"); + return go_right(loc, handle_declaration_list(true)); } + return go_down(loc, (loc) => { switch (loc.t.content) { case "export": return handle_export(loc); case "const": case "let": - return handle_declaration_list(loc, false, imp, counter); + return handle_declaration_list(false)(loc); default: syntax_error(loc); } @@ -1192,6 +1136,13 @@ const postexpand_forms: walkerplus<{ sort: "type" | "value" }> = ({ modular, ... modular, })); +type ppdata = { + loc: Loc; + modular: modular_extension; + imp: import_req; + counter: number; +}; + const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ loc, modular, @@ -1204,17 +1155,7 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ async function done(loc: Loc, modular: modular_extension, imp: import_req, counter: number): T { return { ...data, loc, modular, imp, counter }; } - function cont({ - loc, - imp, - modular, - counter, - }: { - loc: Loc; - modular: modular_extension; - imp: import_req; - counter: number; - }): T { + function cont({ loc, imp, modular, counter }: ppdata): T { return go_next( loc, (loc) => h(find_form(loc), modular, imp, counter), From 3001ac5910123d7e3203eb3cbac5f4182e983ac5 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 05:39:01 +0300 Subject: [PATCH 23/35] refactoring --- src/expander.ts | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 401d040..889f66c 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -840,16 +840,17 @@ const as_keyword: STX = { src: false, }; -function insert_export_keyword({ loc, counter, modular, imp }: ppdata): ppdata { +const insert_export_keyword: swalker = ({ loc, counter, modular, imp, ...data }) => { if (modular.extensible) { assert(loc.t.type === "list"); const content = stx_list_content(loc.t); assert(content !== null); const fst = content[0]; if (fst.content === "export") { - return { loc, modular, imp, counter }; + return { ...data, loc, modular, imp, counter }; } else { return { + ...data, loc: { type: "loc", t: { ...loc.t, content: [export_keyword, content] }, p: loc.p }, modular, imp, @@ -857,11 +858,11 @@ function insert_export_keyword({ loc, counter, modular, imp }: ppdata): ppdata { }; } } else { - return { loc, modular, counter, imp }; + return { ...data, loc, modular, counter, imp }; } -} +}; -async function postexpand_type_alias_declaration({ +const postexpand_type_alias_declaration: walker = async ({ loc, modular, unit, @@ -870,7 +871,8 @@ async function postexpand_type_alias_declaration({ imp, helpers, lexical, -}: data): Promise { + ...data +}) => { async function do_after_equal( loc: Loc, counter: number, @@ -972,7 +974,7 @@ async function postexpand_type_alias_declaration({ }); } - function handle_export(loc: Loc): Promise { + function handle_export(loc: Loc): Promise { assert(loc.t.content === "export"); if (!modular.extensible) syntax_error(loc, "location does not permit export"); return go_right(loc, (loc) => handle_type(loc, true), syntax_error); @@ -987,9 +989,9 @@ async function postexpand_type_alias_declaration({ syntax_error(loc); } }).then(insert_export_keyword); -} +}; -async function postexpand_lexical_declaration({ loc, ...data }: data): Promise { +const postexpand_lexical_declaration: walker = async ({ loc, ...data }) => { async function handle_value_initializer(loc: Loc): Promise { assert(loc.t.content === "="); return go_right( @@ -1024,7 +1026,7 @@ async function postexpand_lexical_declaration({ loc, ...data }: data): Promise

{ + async function handle_inner_variable_declarator(loc: Loc): Promise { assert(loc.t.tag === "identifier"); const { content, wrap } = loc.t; const resolution = await resolve( @@ -1059,12 +1061,12 @@ async function postexpand_lexical_declaration({ loc, ...data }: data): Promise

{ + async function handle_variable_declarator(loc: Loc): Promise { assert(loc.t.tag === "variable_declarator"); return go_down(loc, (loc) => handle_inner_variable_declarator(loc)); } - async function handle_declarations(loc: Loc): Promise { + async function handle_declarations(loc: Loc): Promise { if (loc.t.tag === "variable_declarator") { return handle_variable_declarator(loc).then(({ loc, ...data }) => go_right( @@ -1090,7 +1092,7 @@ async function postexpand_lexical_declaration({ loc, ...data }: data): Promise

{ + async function handle_declaration_list(loc: Loc): Promise { assert(loc.t.content === "let" || loc.t.content === "const"); return go_right(loc, (loc) => handle_declarations(loc)); } @@ -1098,7 +1100,7 @@ async function postexpand_lexical_declaration({ loc, ...data }: data): Promise

{ + async function handle_export(loc: Loc): Promise { if (!data.modular.extensible) syntax_error(loc, "unexpected export keyword"); return go_right(loc, handle_declaration_list(true)); } @@ -1114,7 +1116,7 @@ async function postexpand_lexical_declaration({ loc, ...data }: data): Promise

Date: Tue, 17 Dec 2024 05:59:28 +0300 Subject: [PATCH 24/35] more --- src/expander.ts | 47 +++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 889f66c..cc0578b 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -1145,30 +1145,24 @@ type ppdata = { counter: number; }; -const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ - loc, - modular, - counter, - imp, - sort, - ...data -}) => { +const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data }) => { type T = Promise; - async function done(loc: Loc, modular: modular_extension, imp: import_req, counter: number): T { - return { ...data, loc, modular, imp, counter }; + async function done(new_data: ppdata): T { + return { ...data, ...new_data }; } - function cont({ loc, imp, modular, counter }: ppdata): T { + function cont({ loc, ...data }: ppdata): T { return go_next( loc, - (loc) => h(find_form(loc), modular, imp, counter), - (loc) => done(loc, modular, imp, counter), + (loc) => h({ loc, ...data }), + (loc) => done({ loc, ...data }), ); } - async function h(ffrv: ffrv, modular: modular_extension, imp: import_req, counter: number): T { + async function h({ loc: old_loc, ...hdata }: ppdata): T { + const ffrv = find_form(old_loc); const loc = ffrv.loc; switch (ffrv.type) { case "done": - return done(loc, modular, imp, counter); + return done({ ...data, loc }); case "identifier": { assert(loc.t.type === "atom"); const { tag, content, wrap } = loc.t; @@ -1189,12 +1183,13 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ case "ts": case "type": case "lexical": { - return cont({ loc: rename(loc, binding.name), modular, imp, counter }); + return cont({ ...hdata, loc: rename(loc, binding.name) }); } case "imported_lexical": { + const { imp, counter } = hdata; const existing = (imp[label.cuid] ?? {})[label.name]; if (existing) { - return cont({ loc: rename(loc, existing.new_name), modular, imp, counter }); + return cont({ ...hdata, loc: rename(loc, existing.new_name) }); } else { const { name } = binding; const new_name = `${name}_${counter}`; @@ -1207,8 +1202,8 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ }, }; return cont({ + ...hdata, loc: rename(loc, new_name), - modular, imp: new_imp, counter: new_counter, }); @@ -1234,13 +1229,11 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ switch (loc.t.tag) { case "lexical_declaration": assert(sort === "value"); - return postexpand_lexical_declaration({ loc, modular, counter, imp, ...data }).then( - cont, - ); + return postexpand_lexical_declaration({ ...data, ...hdata, loc }).then(cont); case "arrow_function": { return in_isolation( loc, - (loc) => expand_arrow_function({ ...data, loc, counter, imp, modular }), + (loc) => expand_arrow_function({ ...data, ...hdata, loc }), (loc, gs) => ({ ...gs, loc }), ).then(cont); } @@ -1248,15 +1241,13 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ return syntax_error(loc, "invalid slice"); } case "type_alias_declaration": { - return postexpand_type_alias_declaration({ loc, modular, counter, imp, ...data }).then( - cont, - ); + return postexpand_type_alias_declaration({ ...data, ...hdata, loc }).then(cont); } case "member_expression": { return go_down(loc, (loc) => in_isolation( loc, - (loc) => postexpand_forms({ loc, modular, counter, imp, sort, ...data }), + (loc) => postexpand_forms({ ...data, ...hdata, loc, sort }), (loc, { modular, imp, counter }) => go_right(loc, (loc) => { assert(loc.t.content === "."); @@ -1276,11 +1267,11 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ if (list_handlers_table[loc.t.tag] !== "descend") { debug(loc, `unhandled '${loc.t.tag}' form in postexpand_body`); } - return cont({ loc, modular, imp, counter }); + return cont({ ...hdata, loc }); } } } } } - return h(find_form(loc), modular, imp, counter); + return h(data); }; From 34fb667b5ea2abde14f80ee63d3757235cd3868f Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 06:22:54 +0300 Subject: [PATCH 25/35] removed ppdata --- src/expander.ts | 48 ++++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index cc0578b..54ab1dd 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -1138,31 +1138,19 @@ const postexpand_forms: walkerplus<{ sort: "type" | "value" }> = ({ modular, ... modular, })); -type ppdata = { - loc: Loc; - modular: modular_extension; - imp: import_req; - counter: number; -}; - const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data }) => { - type T = Promise; - async function done(new_data: ppdata): T { - return { ...data, ...new_data }; - } - function cont({ loc, ...data }: ppdata): T { - return go_next( + const cont: walker = ({ loc, ...data }) => + go_next( loc, (loc) => h({ loc, ...data }), - (loc) => done({ loc, ...data }), + (loc) => Promise.resolve({ loc, ...data }), ); - } - async function h({ loc: old_loc, ...hdata }: ppdata): T { + const h: walker = async ({ loc: old_loc, ...data }) => { const ffrv = find_form(old_loc); const loc = ffrv.loc; switch (ffrv.type) { case "done": - return done({ ...data, loc }); + return { ...data, loc }; case "identifier": { assert(loc.t.type === "atom"); const { tag, content, wrap } = loc.t; @@ -1183,13 +1171,13 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data case "ts": case "type": case "lexical": { - return cont({ ...hdata, loc: rename(loc, binding.name) }); + return cont({ ...data, loc: rename(loc, binding.name) }); } case "imported_lexical": { - const { imp, counter } = hdata; + const { imp, counter } = data; const existing = (imp[label.cuid] ?? {})[label.name]; if (existing) { - return cont({ ...hdata, loc: rename(loc, existing.new_name) }); + return cont({ ...data, loc: rename(loc, existing.new_name) }); } else { const { name } = binding; const new_name = `${name}_${counter}`; @@ -1202,7 +1190,7 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data }, }; return cont({ - ...hdata, + ...data, loc: rename(loc, new_name), imp: new_imp, counter: new_counter, @@ -1229,32 +1217,32 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data switch (loc.t.tag) { case "lexical_declaration": assert(sort === "value"); - return postexpand_lexical_declaration({ ...data, ...hdata, loc }).then(cont); + return postexpand_lexical_declaration({ ...data, loc }).then(cont); case "arrow_function": { return in_isolation( loc, - (loc) => expand_arrow_function({ ...data, ...hdata, loc }), - (loc, gs) => ({ ...gs, loc }), + (loc) => expand_arrow_function({ ...data, loc }), + (loc, gs) => ({ ...data, ...gs, loc }), ).then(cont); } case "slice": { return syntax_error(loc, "invalid slice"); } case "type_alias_declaration": { - return postexpand_type_alias_declaration({ ...data, ...hdata, loc }).then(cont); + return postexpand_type_alias_declaration({ ...data, loc }).then(cont); } case "member_expression": { return go_down(loc, (loc) => in_isolation( loc, - (loc) => postexpand_forms({ ...data, ...hdata, loc, sort }), - (loc, { modular, imp, counter }) => + (loc) => postexpand_forms({ ...data, loc, sort }), + (loc, data) => go_right(loc, (loc) => { assert(loc.t.content === "."); return go_right(loc, (loc) => { if (loc.t.tag === "identifier") { // rename to identifier name itself - return { loc: rename(loc, loc.t.content), modular, imp, counter }; + return { ...data, loc: rename(loc, loc.t.content) }; } else { return syntax_error(loc, "not an identifier"); } @@ -1267,11 +1255,11 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data if (list_handlers_table[loc.t.tag] !== "descend") { debug(loc, `unhandled '${loc.t.tag}' form in postexpand_body`); } - return cont({ ...hdata, loc }); + return cont({ ...data, loc }); } } } } - } + }; return h(data); }; From 7334cd404fb311443ab7297dd57c44b03cdad49c Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 06:23:54 +0300 Subject: [PATCH 26/35] removed goodies --- src/data.ts | 5 ----- src/preexpand-handlers.ts | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/data.ts b/src/data.ts index 51a2fbb..7a5d3c3 100644 --- a/src/data.ts +++ b/src/data.ts @@ -13,11 +13,6 @@ export type data = { modular: modular_extension; }; -export type goodies = data; - -//export type data = { -//}; - export type walker = (data: data) => Promise; export type walkerplus = (data: data & T) => Promise; diff --git a/src/preexpand-handlers.ts b/src/preexpand-handlers.ts index 07e973d..1d066bd 100644 --- a/src/preexpand-handlers.ts +++ b/src/preexpand-handlers.ts @@ -1,5 +1,5 @@ import { assert } from "./assert"; -import { data, goodies, walker } from "./data"; +import { data, walker } from "./data"; import { imported_module } from "./preexpand-helpers"; import { extend_context_lexical, From 84d0dd049d520cf62083057b9d90596f9073db91 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 06:43:41 +0300 Subject: [PATCH 27/35] simplified --- src/expander.ts | 96 ++++++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 50 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 54ab1dd..4697559 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -294,7 +294,7 @@ async function expand_concise_body( sort: "type" | "value", helpers: preexpand_helpers, modular: modular_extension, -): Promise<{ loc: Loc; imp: import_req; counter: number }> { +): Promise { const gs = await (loc.t.type === "list" && loc.t.tag === "statement_block" ? preexpand_block({ loc, lexical, counter, unit, context, helpers, imp, modular }).then( ({ loc, ...gs }) => @@ -577,55 +577,51 @@ function expand_arrow_function({ helpers, modular, }: data): Promise<{ loc: Loc; imp: import_req; counter: number; modular: modular_extension }> { - return go_down( - loc, - (loc) => { - const [rib_id, new_counter] = new_rib_id(counter); - const lexical: lexical_extension = { - extensible: true, - rib_id, - rib: { type: "rib", normal_env: {}, types_env: {} }, - }; - const pgs = extract_parameters({ - loc, - lexical, - counter, - context, - unit, - helpers, - imp, - modular, - }); - const arr = go_right(pgs.loc, itself, invalid_form); - check_punct(arr, "=>"); - const body = go_right(arr, itself, invalid_form); - return in_isolation( - body, - async (body) => { - const wrap: Wrap = { - marks: null, - subst: [{ rib_id, cu_id: unit.cu_id }, null], - aes: null, - }; - const loc = wrap_loc(body, wrap); - const new_unit = extend_unit(pgs.unit, pgs.lexical); // params are in rib - return expand_concise_body( - loc, - pgs.lexical, - new_counter, - new_unit, - pgs.context, - imp, - "value", - helpers, - modular, - ); - }, - (loc, { imp, counter }) => ({ loc, imp, counter, modular }), - ); - }, - invalid_form, - ); + return go_down(loc, (loc) => { + const [rib_id, new_counter] = new_rib_id(counter); + const lexical: lexical_extension = { + extensible: true, + rib_id, + rib: { type: "rib", normal_env: {}, types_env: {} }, + }; + const pgs = extract_parameters({ + loc, + lexical, + counter, + context, + unit, + helpers, + imp, + modular, + }); + const arr = go_right(pgs.loc, itself, invalid_form); + check_punct(arr, "=>"); + const body = go_right(arr, itself, invalid_form); + return in_isolation( + body, + (body) => { + const wrap: Wrap = { + marks: null, + subst: [{ rib_id, cu_id: unit.cu_id }, null], + aes: null, + }; + const loc = wrap_loc(body, wrap); + const new_unit = extend_unit(pgs.unit, pgs.lexical); // params are in rib + return expand_concise_body( + loc, + pgs.lexical, + new_counter, + new_unit, + pgs.context, + imp, + "value", + helpers, + modular, + ); + }, + (loc, { imp, counter }) => ({ loc, imp, counter, modular }), + ); + }); } const expand_type_parameters: walker = ({ loc, ...data }) => { From 92413a940f3614b0728f288c177e42ec899114fc Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 07:08:01 +0300 Subject: [PATCH 28/35] simplified expand concise body --- src/expander.ts | 55 +++++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 4697559..d230be4 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -284,40 +284,24 @@ const preexpand_block: walker = async ({ loc, ...data }) => { return gs; }; -async function expand_concise_body( - loc: Loc, - lexical: lexical_extension, - counter: number, - unit: CompilationUnit, - context: Context, - imp: import_req, - sort: "type" | "value", - helpers: preexpand_helpers, - modular: modular_extension, -): Promise { +const expand_concise_body: walker = async ({ loc, ...data }) => { + const sort = "value"; + const modular: modular_extension = { extensible: false }; const gs = await (loc.t.type === "list" && loc.t.tag === "statement_block" - ? preexpand_block({ loc, lexical, counter, unit, context, helpers, imp, modular }).then( - ({ loc, ...gs }) => - go_down( - loc, - (loc) => ({ ...gs, loc }), - (loc) => debug(loc, "???"), - ), + ? preexpand_block({ ...data, loc, modular }).then(({ loc, ...gs }) => + go_down( + loc, + (loc) => ({ ...gs, loc }), + (loc) => debug(loc, "???"), + ), ) - : preexpand_forms({ loc, lexical, counter, unit, context, sort, helpers, imp, modular })); - const new_unit = extend_unit(gs.unit, gs.lexical); + : preexpand_forms({ ...data, loc, sort, modular })); return postexpand_body({ - loc: gs.loc, - modular: { extensible: false }, - unit: new_unit, - counter: gs.counter, - context: gs.context, - imp, + ...gs, + unit: extend_unit(gs.unit, gs.lexical), sort, - helpers, - lexical, }); -} +}; function rewrap(loc: Loc, rib_id: string, cu_id: string): Loc { return { @@ -607,17 +591,16 @@ function expand_arrow_function({ }; const loc = wrap_loc(body, wrap); const new_unit = extend_unit(pgs.unit, pgs.lexical); // params are in rib - return expand_concise_body( + return expand_concise_body({ loc, - pgs.lexical, - new_counter, - new_unit, - pgs.context, + lexical: pgs.lexical, + counter: new_counter, + unit: new_unit, + context: pgs.context, imp, - "value", helpers, modular, - ); + }); }, (loc, { imp, counter }) => ({ loc, imp, counter, modular }), ); From 11fe7554305c85675fb0fbafc6aaf39ff389d2a4 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 07:28:11 +0300 Subject: [PATCH 29/35] fixed wrong counter --- examples/arrow-function-1.ts.md | 6 +++--- examples/arrow-function-3.ts.md | 4 ++-- examples/arrow-function-4.ts.md | 4 ++-- examples/arrow-function-5.ts.md | 4 ++-- examples/confused-parens-with-calls.ts.md | 6 +++--- examples/curry-1.ts.md | 2 +- examples/curry-2.ts.md | 2 +- examples/expr-dot-where.ts.md | 2 +- examples/lexical-declarations-1.ts.md | 4 ++-- examples/macro-generating-macro-1.ts.md | 2 +- examples/macro-generating-macro-2.ts.md | 6 +++--- examples/not-test-1.ts.md | 2 +- examples/splice-2.ts.md | 6 +++--- examples/using-rewrite-rules-3.ts.md | 2 +- examples/using-rewrite-rules-4.ts.md | 2 +- src/expander.ts | 10 +++++----- 16 files changed, 32 insertions(+), 32 deletions(-) diff --git a/examples/arrow-function-1.ts.md b/examples/arrow-function-1.ts.md index 78a2c03..51b9531 100644 --- a/examples/arrow-function-1.ts.md +++ b/examples/arrow-function-1.ts.md @@ -13,8 +13,8 @@ const h = (x) => x((x) => f(x)); ### Output Program ```typescript -export const f_2 = (x_8) => x_8; -export const g_4 = (x_9) => f_2(x_9); -export const h_6 = (x_10) => x_10((x_11) => f_2(x_11)); +export const f_2 = (x_9) => x_9; +export const g_4 = (x_12) => f_2(x_12); +export const h_6 = (x_15) => x_15((x_18) => f_2(x_18)); ``` diff --git a/examples/arrow-function-3.ts.md b/examples/arrow-function-3.ts.md index 26fcbb2..36c3c70 100644 --- a/examples/arrow-function-3.ts.md +++ b/examples/arrow-function-3.ts.md @@ -13,8 +13,8 @@ const foo = (x) => { ### Output Program ```typescript -export const foo_2 = (x_4) => { - const bar_5 = x_4(13); +export const foo_2 = (x_5) => { + const bar_7 = x_5(13); }; ``` diff --git a/examples/arrow-function-4.ts.md b/examples/arrow-function-4.ts.md index 8644b64..5c1972d 100644 --- a/examples/arrow-function-4.ts.md +++ b/examples/arrow-function-4.ts.md @@ -13,8 +13,8 @@ const foo = (x) => { ### Output Program ```typescript -export const foo_2 = (x_4) => { - x_4; +export const foo_2 = (x_5) => { + x_5; }; ``` diff --git a/examples/arrow-function-5.ts.md b/examples/arrow-function-5.ts.md index b7eeffa..e16a9e9 100644 --- a/examples/arrow-function-5.ts.md +++ b/examples/arrow-function-5.ts.md @@ -15,8 +15,8 @@ const foo = (x) => { ### Output Program ```typescript -export const foo_2 = (x_4) => { - x_4; +export const foo_2 = (x_5) => { + x_5; }; ``` diff --git a/examples/confused-parens-with-calls.ts.md b/examples/confused-parens-with-calls.ts.md index 794a0d3..14e42c0 100644 --- a/examples/confused-parens-with-calls.ts.md +++ b/examples/confused-parens-with-calls.ts.md @@ -18,9 +18,9 @@ const foo = (x) => { ### Output Program ```typescript -export const foo_2 = (x_4) => { - x_4; - x_4; +export const foo_2 = (x_5) => { + x_5; + x_5; }; ``` diff --git a/examples/curry-1.ts.md b/examples/curry-1.ts.md index 6247425..686812e 100644 --- a/examples/curry-1.ts.md +++ b/examples/curry-1.ts.md @@ -16,6 +16,6 @@ using_rewrite_rules( ### Output Program ```typescript -(a_5) => (b_7) => (c_9) => (d_11) => a_5 + b_7 + c_9 + d_11; +(a_6) => (b_10) => (c_14) => (d_18) => a_6 + b_10 + c_14 + d_18; ``` diff --git a/examples/curry-2.ts.md b/examples/curry-2.ts.md index 9692825..8ac692c 100644 --- a/examples/curry-2.ts.md +++ b/examples/curry-2.ts.md @@ -19,6 +19,6 @@ const curried = ### Output Program ```typescript -export const curried_3 = (a_6) => (b_8) => (c_10) => (d_12) => a_6 + b_8 + c_10 + d_12; +export const curried_3 = (a_7) => (b_11) => (c_15) => (d_19) => a_7 + b_11 + c_15 + d_19; ``` diff --git a/examples/expr-dot-where.ts.md b/examples/expr-dot-where.ts.md index fa9187e..627da55 100644 --- a/examples/expr-dot-where.ts.md +++ b/examples/expr-dot-where.ts.md @@ -20,6 +20,6 @@ console.log(x + y).where(x = 1, y = x + 2); ### Output Program ```typescript -((x_4) => ((y_6) => console.log(x_4 + y_6))(x_4 + 2))(1); +((x_5) => ((y_9) => console.log(x_5 + y_9))(x_5 + 2))(1); ``` diff --git a/examples/lexical-declarations-1.ts.md b/examples/lexical-declarations-1.ts.md index a62b8d9..25ee8aa 100644 --- a/examples/lexical-declarations-1.ts.md +++ b/examples/lexical-declarations-1.ts.md @@ -21,8 +21,8 @@ export const y_4 = 13, z_6: t_2 = y_4, q_8: t_2, r_10; -export const x_12 = (z_14) => { - const t_15 = z_14; +export const x_12 = (z_15) => { + const t_17 = z_15; }; ``` diff --git a/examples/macro-generating-macro-1.ts.md b/examples/macro-generating-macro-1.ts.md index 2855eb6..cab8057 100644 --- a/examples/macro-generating-macro-1.ts.md +++ b/examples/macro-generating-macro-1.ts.md @@ -15,6 +15,6 @@ using_rewrite_rules( ### Output Program ```typescript -(x_4) => (x_8) => x_8 + x_4; +(x_5) => (x_11) => x_11 + x_5; ``` diff --git a/examples/macro-generating-macro-2.ts.md b/examples/macro-generating-macro-2.ts.md index a2eb0a9..988a633 100644 --- a/examples/macro-generating-macro-2.ts.md +++ b/examples/macro-generating-macro-2.ts.md @@ -22,9 +22,9 @@ using_rewrite_rules( ### Output Program ```typescript -(x_4) => { - const using_rewrite_rules_5 = 10; - (x_10) => x_10 + x_4; +(x_5) => { + const using_rewrite_rules_7 = 10; + (x_13) => x_13 + x_5; }; ``` diff --git a/examples/not-test-1.ts.md b/examples/not-test-1.ts.md index 61f3703..bfa3cb8 100644 --- a/examples/not-test-1.ts.md +++ b/examples/not-test-1.ts.md @@ -15,6 +15,6 @@ using_rewrite_rules( ### Output Program ```typescript -1 ? !3 : (x_9) => !x_9; +1 ? !3 : (x_10) => !x_10; ``` diff --git a/examples/splice-2.ts.md b/examples/splice-2.ts.md index 7dd87f1..f1e2811 100644 --- a/examples/splice-2.ts.md +++ b/examples/splice-2.ts.md @@ -16,9 +16,9 @@ const foo = (x) => { ### Output Program ```typescript -export const foo_2 = (x_4) => { - x_4; - x_4; +export const foo_2 = (x_5) => { + x_5; + x_5; }; ``` diff --git a/examples/using-rewrite-rules-3.ts.md b/examples/using-rewrite-rules-3.ts.md index c425b77..2a88269 100644 --- a/examples/using-rewrite-rules-3.ts.md +++ b/examples/using-rewrite-rules-3.ts.md @@ -15,7 +15,7 @@ const x = 12; ### Output Program ```typescript -(foo_7) => x_5 + x_5; +(foo_8) => x_5 + x_5; export const x_5 = 12; ``` diff --git a/examples/using-rewrite-rules-4.ts.md b/examples/using-rewrite-rules-4.ts.md index 4d744b3..5591071 100644 --- a/examples/using-rewrite-rules-4.ts.md +++ b/examples/using-rewrite-rules-4.ts.md @@ -16,7 +16,7 @@ const x = 12; ### Output Program ```typescript -x_6 + ((foo_8, foo_10) => foo_10 + foo_8); +x_6 + ((foo_9, foo_11) => foo_11 + foo_9); export const x_6 = 12; ``` diff --git a/src/expander.ts b/src/expander.ts index d230be4..46681d4 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -300,7 +300,7 @@ const expand_concise_body: walker = async ({ loc, ...data }) => { ...gs, unit: extend_unit(gs.unit, gs.lexical), sort, - }); + }).then((new_data) => ({ ...new_data, modular: data.modular })); }; function rewrap(loc: Loc, rib_id: string, cu_id: string): Loc { @@ -571,7 +571,7 @@ function expand_arrow_function({ const pgs = extract_parameters({ loc, lexical, - counter, + counter: new_counter, context, unit, helpers, @@ -594,15 +594,15 @@ function expand_arrow_function({ return expand_concise_body({ loc, lexical: pgs.lexical, - counter: new_counter, - unit: new_unit, context: pgs.context, + counter: pgs.counter, + unit: new_unit, imp, helpers, modular, }); }, - (loc, { imp, counter }) => ({ loc, imp, counter, modular }), + (loc, data) => ({ loc, ...data }), ); }); } From 3e9b9e3aa9e855c8652446ca30cc6ccb689161b5 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 07:37:22 +0300 Subject: [PATCH 30/35] fixed arrow functions --- src/expander.ts | 39 +++++++-------------------------------- 1 file changed, 7 insertions(+), 32 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 46681d4..ec940bc 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -552,32 +552,15 @@ function check_punct(loc: Loc, content: string) { } } -function expand_arrow_function({ - loc, - counter, - context, - imp, - unit, - helpers, - modular, -}: data): Promise<{ loc: Loc; imp: import_req; counter: number; modular: modular_extension }> { - return go_down(loc, (loc) => { +const expand_arrow_function: walker = ({ loc, counter, ...data }) => + go_down(loc, (loc) => { const [rib_id, new_counter] = new_rib_id(counter); const lexical: lexical_extension = { extensible: true, rib_id, rib: { type: "rib", normal_env: {}, types_env: {} }, }; - const pgs = extract_parameters({ - loc, - lexical, - counter: new_counter, - context, - unit, - helpers, - imp, - modular, - }); + const pgs = extract_parameters({ ...data, loc, lexical, counter: new_counter }); const arr = go_right(pgs.loc, itself, invalid_form); check_punct(arr, "=>"); const body = go_right(arr, itself, invalid_form); @@ -586,26 +569,18 @@ function expand_arrow_function({ (body) => { const wrap: Wrap = { marks: null, - subst: [{ rib_id, cu_id: unit.cu_id }, null], + subst: [{ rib_id, cu_id: pgs.unit.cu_id }, null], aes: null, }; - const loc = wrap_loc(body, wrap); - const new_unit = extend_unit(pgs.unit, pgs.lexical); // params are in rib return expand_concise_body({ - loc, - lexical: pgs.lexical, - context: pgs.context, - counter: pgs.counter, - unit: new_unit, - imp, - helpers, - modular, + ...pgs, + loc: wrap_loc(body, wrap), + unit: extend_unit(pgs.unit, pgs.lexical), }); }, (loc, data) => ({ loc, ...data }), ); }); -} const expand_type_parameters: walker = ({ loc, ...data }) => { // From ba15f3805a76cce00e41858c3169dd030b59e1d0 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 08:14:09 +0300 Subject: [PATCH 31/35] simplified in_isolation --- src/expander.ts | 103 +++++++++++++++++------------------------------ src/stx-error.ts | 7 ++-- 2 files changed, 40 insertions(+), 70 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index ec940bc..76b9ecd 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -179,30 +179,19 @@ async function expand_program({ loc, ...data }: data): Promise<{ } const preexpand_body: walkerplus<{ sort: "type" | "value" }> = async ({ loc, sort, ...data }) => - in_isolation( - loc, - (loc) => preexpand_forms({ loc, sort, ...data }), - (loc, data) => - go_next( - loc, - (loc) => preexpand_body({ loc, sort, ...data }), - (loc) => Promise.resolve({ loc, ...data }), - ), + in_isolation(loc, (loc) => preexpand_forms({ loc, sort, ...data })).then(({ loc, ...data }) => + go_next( + loc, + (loc) => preexpand_body({ loc, sort, ...data }), + (loc) => Promise.resolve({ loc, ...data }), + ), ); const preexpand_body_curly: walker = async ({ loc, ...data }) => - loc.t.type === "atom" && loc.t.tag === "other" && loc.t.content === "}" + loc.t.content === "}" ? go_right(loc, syntax_error, () => ({ loc: go_up(loc), ...data })) - : in_isolation( - loc, - (loc) => preexpand_forms({ loc, sort: "value", ...data }), - (loc, data) => { - return go_right( - loc, - (loc) => preexpand_body_curly({ loc, ...data }), - (loc) => syntax_error(loc, "no right"), - ); - }, + : in_isolation(loc, (loc) => preexpand_forms({ loc, sort: "value", ...data })).then( + ({ loc, ...data }) => go_right(loc, (loc) => preexpand_body_curly({ loc, ...data })), ); async function handle_core_syntax({ name, ...data }: data & { name: string }): Promise<{ @@ -564,22 +553,18 @@ const expand_arrow_function: walker = ({ loc, counter, ...data }) => const arr = go_right(pgs.loc, itself, invalid_form); check_punct(arr, "=>"); const body = go_right(arr, itself, invalid_form); - return in_isolation( - body, - (body) => { - const wrap: Wrap = { - marks: null, - subst: [{ rib_id, cu_id: pgs.unit.cu_id }, null], - aes: null, - }; - return expand_concise_body({ - ...pgs, - loc: wrap_loc(body, wrap), - unit: extend_unit(pgs.unit, pgs.lexical), - }); - }, - (loc, data) => ({ loc, ...data }), - ); + return in_isolation(body, (body) => { + const wrap: Wrap = { + marks: null, + subst: [{ rib_id, cu_id: pgs.unit.cu_id }, null], + aes: null, + }; + return expand_concise_body({ + ...pgs, + loc: wrap_loc(body, wrap), + unit: extend_unit(pgs.unit, pgs.lexical), + }); + }); }); const expand_type_parameters: walker = ({ loc, ...data }) => { @@ -685,16 +670,11 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { ); }; - const end: walker = async ({ loc, ...data }) => { - return go_right( - loc, - (loc) => { - assert(loc.t.content === ">"); - return { loc, ...data }; - }, - syntax_error, - ); - }; + const end: walker = async ({ loc, ...data }) => + go_right(loc, (loc) => { + assert(loc.t.content === ">"); + return { loc, ...data }; + }); assert(loc.t.content === "<"); return go_right(loc, (loc) => start({ loc, ...data }), syntax_error); @@ -707,16 +687,12 @@ const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ unit, context, ...data -}) => { - return in_isolation( - loc, - (loc) => - preexpand_forms({ loc, sort, modular: { extensible: false }, unit, context, ...data }).then( - (data) => postexpand_body({ ...data, sort }), - ), - (loc, new_data) => ({ loc, ...data, ...new_data, modular, unit, context }), - ); -}; +}) => + in_isolation(loc, (loc) => + preexpand_forms({ loc, sort, modular: { extensible: false }, unit, context, ...data }).then( + (data) => postexpand_body({ ...data, sort }), + ), + ).then((data) => ({ ...data, modular, unit, context })); const empty_wrap: Wrap = { marks: null, subst: null, aes: null }; @@ -1173,11 +1149,7 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data assert(sort === "value"); return postexpand_lexical_declaration({ ...data, loc }).then(cont); case "arrow_function": { - return in_isolation( - loc, - (loc) => expand_arrow_function({ ...data, loc }), - (loc, gs) => ({ ...data, ...gs, loc }), - ).then(cont); + return in_isolation(loc, (loc) => expand_arrow_function({ ...data, loc })).then(cont); } case "slice": { return syntax_error(loc, "invalid slice"); @@ -1187,10 +1159,8 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data } case "member_expression": { return go_down(loc, (loc) => - in_isolation( - loc, - (loc) => postexpand_forms({ ...data, loc, sort }), - (loc, data) => + in_isolation(loc, (loc) => postexpand_forms({ ...data, loc, sort })) + .then(({ loc, ...data }) => go_right(loc, (loc) => { assert(loc.t.content === "."); return go_right(loc, (loc) => { @@ -1202,7 +1172,8 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data } }); }), - ).then(cont), + ) + .then(cont), ); } default: { diff --git a/src/stx-error.ts b/src/stx-error.ts index d9d432d..a34cacb 100644 --- a/src/stx-error.ts +++ b/src/stx-error.ts @@ -28,12 +28,11 @@ export function syntax_error(loc: Loc, reason?: string): never { throw new StxError("SyntaxError", loc, reason ?? "syntax error"); } -export const in_isolation: ( +export const in_isolation: ( loc: Loc, f: (loc: Loc) => Promise, - k: (loc: Loc, g: Omit) => T, -) => Promise = async (loc, f, k) => { - return f(isolate(loc)).then(({ loc: res, ...g }) => k(unisolate(loc, res), g)); +) => Promise & { loc: Loc }> = async (loc, f) => { + return f(isolate(loc)).then(({ loc: res, ...g }) => ({ ...g, loc: unisolate(loc, res) })); }; type LibraryManager = { From 0048194637b332ffe509a1a607acf7862e61ebd3 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 08:41:55 +0300 Subject: [PATCH 32/35] removed ugly types --- src/expander.ts | 118 ++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 75 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 76b9ecd..c1742cf 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -792,94 +792,57 @@ const insert_export_keyword: swalker = ({ loc, counter, modular, imp, ...data }) } }; -const postexpand_type_alias_declaration: walker = async ({ - loc, - modular, - unit, - context, - counter, - imp, - helpers, - lexical, - ...data -}) => { - async function do_after_equal( - loc: Loc, - counter: number, - unit: CompilationUnit, - context: Context, - imp: import_req, - ): Promise { - return expand_expr({ - loc, - counter, - unit, - context, - imp, - sort: "type", - helpers, - lexical, - modular, - }).then(({ loc, ...data }) => { - function done(loc: Loc) { - return { ...data, loc: go_up(loc) }; - } - return go_right( - loc, - (loc) => { - assert(loc.t.content === ";"); - return go_right(loc, syntax_error, done); - }, - done, - ); - }); +const handle_optional_semi: walker = async ({ loc, ...data }) => { + function done(loc: Loc) { + return { ...data, loc: go_up(loc) }; } - async function do_after_identifier( - loc: Loc, - counter: number, - unit: CompilationUnit, - context: Context, - imp: import_req, - ): Promise { + return go_right( + loc, + (loc) => { + assert(loc.t.content === ";"); + return go_right(loc, syntax_error, done); + }, + done, + ); +}; + +const postexpand_type_alias_declaration: walker = async (data) => { + const do_after_equal: walker = (data: data) => + expand_expr({ sort: "type", ...data }).then(handle_optional_semi); + const do_after_identifier: walker = async ({ loc, ...data }) => { switch (loc.t.content) { case "=": - return go_right(loc, (loc) => do_after_equal(loc, counter, unit, context, imp)); + return go_right(loc, (loc) => do_after_equal({ loc, ...data })); case "<": return expand_type_parameters({ loc, - unit, - counter, - context, - imp, - helpers, - lexical, - modular, - }).then(({ loc, counter, unit, context, lexical, imp }) => { + ...data, + }).then(({ loc, unit, lexical, ...data }) => { assert(loc.t.content === ">"); assert(lexical.extensible); return go_right(loc, (loc) => { if (loc.t.content !== "=") syntax_error(loc, "expected '='"); return go_right(loc, (loc) => - do_after_equal( - wrap_loc(loc, { + do_after_equal({ + loc: wrap_loc(loc, { marks: null, subst: [{ rib_id: lexical.rib_id, cu_id: unit.cu_id }, null], aes: null, }), - counter, unit, - context, - imp, - ), + lexical, + ...data, + }), ); }); }); default: return syntax_error(loc); } - } + }; function handle_type(loc: Loc, exporting: boolean): Promise { + const { context, unit, modular, helpers } = data; assert(loc.t.content === "type"); return go_right(loc, async (loc) => { assert(loc.t.tag === "identifier"); @@ -889,7 +852,7 @@ const postexpand_type_alias_declaration: walker = async ({ assert(resolution.binding.type === "type"); const new_name = resolution.binding.name; const gs = await go_right(rename(loc, new_name), (loc) => - do_after_identifier(loc, counter, unit, context, imp), + do_after_identifier({ ...data, loc }), ); const new_modular = extend_modular( modular, @@ -906,19 +869,24 @@ const postexpand_type_alias_declaration: walker = async ({ function handle_export(loc: Loc): Promise { assert(loc.t.content === "export"); + const { modular } = data; if (!modular.extensible) syntax_error(loc, "location does not permit export"); return go_right(loc, (loc) => handle_type(loc, true), syntax_error); } - return go_down(loc, (loc) => { - switch (loc.t.content) { - case "type": - return handle_type(loc, false); - case "export": - return handle_export(loc); - default: - syntax_error(loc); - } - }).then(insert_export_keyword); + + { + const { loc } = data; + return go_down(loc, (loc) => { + switch (loc.t.content) { + case "type": + return handle_type(loc, false); + case "export": + return handle_export(loc); + default: + syntax_error(loc); + } + }).then(insert_export_keyword); + } }; const postexpand_lexical_declaration: walker = async ({ loc, ...data }) => { From c6194ac558fb7bdb52230b99749130e86c0bdb08 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 09:16:51 +0300 Subject: [PATCH 33/35] more --- src/expander.ts | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index c1742cf..50e2513 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -468,10 +468,6 @@ const postexpand_program: walker = ({ loc, ...data }: data) => ...new_data, })); -function invalid_form(loc: Loc): never { - syntax_error(loc, "invalid form"); -} - function itself(loc: Loc): Loc { return loc; } @@ -481,9 +477,9 @@ const extract_parameters: swalker = (data) => { const tail: swalker = ({ loc, ...data }) => { switch (loc.t.content) { case ",": - return go_right(loc, (loc) => head({ ...data, loc }), invalid_form); + return go_right(loc, (loc) => head({ ...data, loc })); case ")": - return go_right(loc, invalid_form, (loc) => ({ ...data, loc: go_up(loc) })); + return go_right(loc, syntax_error, (loc) => ({ ...data, loc: go_up(loc) })); default: syntax_error(loc); } @@ -493,14 +489,14 @@ const extract_parameters: swalker = (data) => { switch (loc.t.tag) { case "identifier": { const gs = identifier({ loc, ...data }); - return go_right(gs.loc, (loc) => tail({ ...gs, loc }), invalid_form); + return go_right(gs.loc, (loc) => tail({ ...gs, loc })); } case "other": { switch (loc.t.content) { case ",": - return invalid_form(loc); + return syntax_error(loc); case ")": - return go_right(loc, invalid_form, (loc) => ({ ...data, loc: go_up(loc) })); + return go_right(loc, syntax_error, (loc) => ({ ...data, loc: go_up(loc) })); } } } @@ -518,10 +514,10 @@ const extract_parameters: swalker = (data) => { switch (data.loc.t.tag) { case "identifier": const gs = identifier(data); - return go_right(gs.loc, invalid_form, (loc) => ({ ...gs, loc: go_up(loc) })); + return go_right(gs.loc, syntax_error, (loc) => ({ ...gs, loc: go_up(loc) })); case "other": { if (data.loc.t.content === "(") { - return go_right(data.loc, (loc) => head({ ...data, loc }), invalid_form); + return go_right(data.loc, (loc) => head({ ...data, loc })); } } default: @@ -531,7 +527,7 @@ const extract_parameters: swalker = (data) => { { assert(data.loc.t.type === "list" && data.loc.t.tag === "formal_parameters"); - return go_down(data.loc, (loc) => first_param({ ...data, loc }), invalid_form); + return go_down(data.loc, (loc) => first_param({ ...data, loc })); } }; @@ -550,9 +546,9 @@ const expand_arrow_function: walker = ({ loc, counter, ...data }) => rib: { type: "rib", normal_env: {}, types_env: {} }, }; const pgs = extract_parameters({ ...data, loc, lexical, counter: new_counter }); - const arr = go_right(pgs.loc, itself, invalid_form); + const arr = go_right(pgs.loc, itself); check_punct(arr, "=>"); - const body = go_right(arr, itself, invalid_form); + const body = go_right(arr, itself); return in_isolation(body, (body) => { const wrap: Wrap = { marks: null, @@ -680,19 +676,12 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { return go_right(loc, (loc) => start({ loc, ...data }), syntax_error); }; -const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ - loc, - sort, - modular, - unit, - context, - ...data -}) => +const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ loc, sort, modular, ...data }) => in_isolation(loc, (loc) => - preexpand_forms({ loc, sort, modular: { extensible: false }, unit, context, ...data }).then( - (data) => postexpand_body({ ...data, sort }), + preexpand_forms({ loc, sort, modular: { extensible: false }, ...data }).then((data) => + postexpand_body({ ...data, sort }), ), - ).then((data) => ({ ...data, modular, unit, context })); + ).then((data) => ({ ...data, modular })); const empty_wrap: Wrap = { marks: null, subst: null, aes: null }; @@ -1031,7 +1020,6 @@ const sort_env = { type: "types_env" as const, value: "normal_env" as const }; const postexpand_forms: walkerplus<{ sort: "type" | "value" }> = ({ modular, ...data }) => postexpand_body({ modular: { extensible: false }, ...data }).then((new_data) => ({ - ...data, ...new_data, modular, })); From 409e63ddf261192bd56fcea4adc10340bfe67180 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 09:40:05 +0300 Subject: [PATCH 34/35] currying sort parameter --- src/expander.ts | 250 ++++++++++++++++++++++++------------------------ 1 file changed, 124 insertions(+), 126 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index 50e2513..c205f6f 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -179,7 +179,7 @@ async function expand_program({ loc, ...data }: data): Promise<{ } const preexpand_body: walkerplus<{ sort: "type" | "value" }> = async ({ loc, sort, ...data }) => - in_isolation(loc, (loc) => preexpand_forms({ loc, sort, ...data })).then(({ loc, ...data }) => + in_isolation(loc, (loc) => preexpand_forms(sort)({ loc, ...data })).then(({ loc, ...data }) => go_next( loc, (loc) => preexpand_body({ loc, sort, ...data }), @@ -190,7 +190,7 @@ const preexpand_body: walkerplus<{ sort: "type" | "value" }> = async ({ loc, sor const preexpand_body_curly: walker = async ({ loc, ...data }) => loc.t.content === "}" ? go_right(loc, syntax_error, () => ({ loc: go_up(loc), ...data })) - : in_isolation(loc, (loc) => preexpand_forms({ loc, sort: "value", ...data })).then( + : in_isolation(loc, (loc) => preexpand_forms("value")({ loc, ...data })).then( ({ loc, ...data }) => go_right(loc, (loc) => preexpand_body_curly({ loc, ...data })), ); @@ -273,24 +273,27 @@ const preexpand_block: walker = async ({ loc, ...data }) => { return gs; }; -const expand_concise_body: walker = async ({ loc, ...data }) => { +const non_modular: (walker: walker) => walker = + (walker) => + ({ modular, ...data }) => + walker({ ...data, modular: { extensible: false } }).then((data) => ({ ...data, modular })); + +const expand_concise_body = non_modular(async ({ loc, ...data }) => { const sort = "value"; - const modular: modular_extension = { extensible: false }; const gs = await (loc.t.type === "list" && loc.t.tag === "statement_block" - ? preexpand_block({ ...data, loc, modular }).then(({ loc, ...gs }) => + ? preexpand_block({ ...data, loc }).then(({ loc, ...gs }) => go_down( loc, (loc) => ({ ...gs, loc }), (loc) => debug(loc, "???"), ), ) - : preexpand_forms({ ...data, loc, sort, modular })); - return postexpand_body({ + : preexpand_forms(sort)({ ...data, loc })); + return postexpand_body(sort)({ ...gs, unit: extend_unit(gs.unit, gs.lexical), - sort, - }).then((new_data) => ({ ...new_data, modular: data.modular })); -}; + }); +}); function rewrap(loc: Loc, rib_id: string, cu_id: string): Loc { return { @@ -300,110 +303,115 @@ function rewrap(loc: Loc, rib_id: string, cu_id: string): Loc { }; } -const preexpand_forms: walkerplus<{ sort: "type" | "value" }> = async ({ loc, sort, ...data }) => { - function done(loc: Loc): Promise { - return Promise.resolve({ loc, ...data }); - } - function next(loc: Loc): Promise { - return go_next(loc, (loc) => h(find_form(loc)), done); - } - function descend(loc: Loc): Promise { - return go_down(loc, (loc) => h(find_form(loc)), syntax_error); - } - async function h(ffrv: ffrv): Promise { - const loc = ffrv.loc; - switch (ffrv.type) { - case "done": - return done(loc); - case "identifier": { - assert(loc.t.type === "atom" && loc.t.tag === "identifier", loc.t); - const { content, wrap } = loc.t; - const resolution = await resolve( - content, - wrap, - data.context, - data.unit, - sort_env[sort], - data.helpers, - ); - switch (resolution.type) { - case "unbound": - return next(loc); - case "bound": { - const binding = resolution.binding; - switch (binding.type) { - case "lexical": - case "type": - case "ts": - case "imported_lexical": - return next(loc); - case "core_syntax": { - const { name } = binding; - return data.helpers.inspect(loc, "core form", () => - handle_core_syntax({ ...data, loc, name }).then(({ loc, ...new_data }) => - data.helpers.inspect(loc, `core output`, () => - preexpand_forms({ loc, sort, ...data, ...new_data }), +const preexpand_forms = + (sort: "type" | "value") => + async ({ loc, ...data }: data) => { + function done(loc: Loc): Promise { + return Promise.resolve({ loc, ...data }); + } + function next(loc: Loc): Promise { + return go_next(loc, (loc) => h(find_form(loc)), done); + } + function descend(loc: Loc): Promise { + return go_down(loc, (loc) => h(find_form(loc)), syntax_error); + } + async function h(ffrv: ffrv): Promise { + const loc = ffrv.loc; + switch (ffrv.type) { + case "done": + return done(loc); + case "identifier": { + assert(loc.t.type === "atom" && loc.t.tag === "identifier", loc.t); + const { content, wrap } = loc.t; + const resolution = await resolve( + content, + wrap, + data.context, + data.unit, + sort_env[sort], + data.helpers, + ); + switch (resolution.type) { + case "unbound": + return next(loc); + case "bound": { + const binding = resolution.binding; + switch (binding.type) { + case "lexical": + case "type": + case "ts": + case "imported_lexical": + return next(loc); + case "core_syntax": { + const { name } = binding; + return data.helpers.inspect(loc, "core form", () => + handle_core_syntax({ ...data, loc, name }).then(({ loc, ...new_data }) => + data.helpers.inspect(loc, `core output`, () => + preexpand_forms(sort)({ loc, ...data, ...new_data }), + ), ), - ), - ); - } - case "syntax_rules_transformer": { - const { clauses } = binding; - return data.helpers.inspect(loc, `transformer form`, () => - apply_syntax_rules(loc, clauses, data.unit, data.counter, data.helpers).then( - ({ loc, counter }) => { - const rewrapped = data.lexical.extensible - ? rewrap(loc, data.lexical.rib_id, data.unit.cu_id) - : loc; - return data.helpers.inspect(rewrapped, `transformer output`, () => - preexpand_forms({ loc: rewrapped, ...data, counter, sort }), - ); - }, - ), - ); + ); + } + case "syntax_rules_transformer": { + const { clauses } = binding; + return data.helpers.inspect(loc, `transformer form`, () => + apply_syntax_rules(loc, clauses, data.unit, data.counter, data.helpers).then( + ({ loc, counter }) => { + const rewrapped = data.lexical.extensible + ? rewrap(loc, data.lexical.rib_id, data.unit.cu_id) + : loc; + return data.helpers.inspect(rewrapped, `transformer output`, () => + preexpand_forms(sort)({ loc: rewrapped, ...data, counter }), + ); + }, + ), + ); + } + default: + const invalid: never = binding; + throw invalid; } - default: - const invalid: never = binding; - throw invalid; } + case "error": + syntax_error(loc, resolution.reason); + default: + const invalid: never = resolution; + throw invalid; } - case "error": - syntax_error(loc, resolution.reason); - default: - const invalid: never = resolution; - throw invalid; - } - } - case "list": { - assert(loc.t.type === "list"); - const h = preexpand_list_handlers[loc.t.tag]; - if (h) { - return h({ loc, ...data }).then(({ loc, ...data }) => - go_next( - loc, - (loc) => preexpand_forms({ loc, sort, ...data }), - (loc) => Promise.resolve({ loc, ...data }), - ), - ); } - switch (loc.t.tag) { - case "arrow_function": - return next(loc); - case "member_expression": - return descend(loc); - default: { - if (list_handlers_table[loc.t.tag] === "todo") { - debug(loc, `todo list handler for '${loc.t.tag}'`); + case "list": { + assert(loc.t.type === "list"); + const h = preexpand_list_handlers[loc.t.tag]; + if (h) { + return h({ loc, ...data }).then(({ loc, ...data }) => + go_next( + loc, + (loc) => preexpand_forms(sort)({ loc, ...data }), + (loc) => Promise.resolve({ loc, ...data }), + ), + ); + } + switch (loc.t.tag) { + case "arrow_function": + return next(loc); + case "member_expression": + return descend(loc); + default: { + if (list_handlers_table[loc.t.tag] === "todo") { + debug(loc, `todo list handler for '${loc.t.tag}'`); + } + assert( + list_handlers_table[loc.t.tag] === "descend", + `non descend tag '${loc.t.tag}'`, + ); + return next(loc); } - assert(list_handlers_table[loc.t.tag] === "descend", `non descend tag '${loc.t.tag}'`); - return next(loc); } } } } - } - return h(find_form(loc)); -}; + return h(find_form(loc)); + }; type ffrv = | { type: "done"; loc: Loc } @@ -463,10 +471,7 @@ function find_form(loc: Loc): ffrv { } const postexpand_program: walker = ({ loc, ...data }: data) => - go_down(loc, (loc) => postexpand_body({ loc, sort: "value", ...data })).then((new_data) => ({ - ...data, - ...new_data, - })); + go_down(loc, (loc) => postexpand_body("value")({ loc, ...data })); function itself(loc: Loc): Loc { return loc; @@ -593,13 +598,12 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { if (loc.t.content !== "extends") syntax_error(loc, "expected 'extends'"); assert(lexical.extensible); return go_right(loc, (loc) => - expand_expr({ + expand_expr("type")({ loc: wrap_loc(loc, { marks: null, subst: [{ rib_id: lexical.rib_id, cu_id: data.unit.cu_id }, null], aes: null, }), - sort: "type", lexical, ...data, }).then(({ loc, ...data }) => @@ -676,12 +680,10 @@ const expand_type_parameters: walker = ({ loc, ...data }) => { return go_right(loc, (loc) => start({ loc, ...data }), syntax_error); }; -const expand_expr: walkerplus<{ sort: "type" | "value" }> = ({ loc, sort, modular, ...data }) => - in_isolation(loc, (loc) => - preexpand_forms({ loc, sort, modular: { extensible: false }, ...data }).then((data) => - postexpand_body({ ...data, sort }), - ), - ).then((data) => ({ ...data, modular })); +const expand_expr = (sort: "type" | "value") => + non_modular(({ loc, ...data }) => + in_isolation(loc, (loc) => preexpand_forms(sort)({ loc, ...data }).then(postexpand_body(sort))), + ); const empty_wrap: Wrap = { marks: null, subst: null, aes: null }; @@ -797,7 +799,7 @@ const handle_optional_semi: walker = async ({ loc, ...data }) => { const postexpand_type_alias_declaration: walker = async (data) => { const do_after_equal: walker = (data: data) => - expand_expr({ sort: "type", ...data }).then(handle_optional_semi); + expand_expr("type")(data).then(handle_optional_semi); const do_after_identifier: walker = async ({ loc, ...data }) => { switch (loc.t.content) { case "=": @@ -883,7 +885,7 @@ const postexpand_lexical_declaration: walker = async ({ loc, ...data }) => { assert(loc.t.content === "="); return go_right( loc, - (loc) => expand_expr({ loc, sort: "value", ...data }), + (loc) => expand_expr("value")({ loc, ...data }), (loc) => syntax_error(loc, "expected an expression following the '=' sign"), ); } @@ -893,7 +895,7 @@ const postexpand_lexical_declaration: walker = async ({ loc, ...data }) => { return go_right( loc, (loc) => - expand_expr({ loc, sort: "type", ...data }).then(({ loc, ...data }) => + expand_expr("type")({ loc, ...data }).then(({ loc, ...data }) => go_right(loc, handle_value_initializer, (loc) => Promise.resolve({ loc, ...data })), ), (loc) => syntax_error(loc, "expected an expression following the '=' sign"), @@ -1018,13 +1020,9 @@ function rename(loc: Loc, new_name: string): Loc { const sort_env = { type: "types_env" as const, value: "normal_env" as const }; -const postexpand_forms: walkerplus<{ sort: "type" | "value" }> = ({ modular, ...data }) => - postexpand_body({ modular: { extensible: false }, ...data }).then((new_data) => ({ - ...new_data, - modular, - })); +const postexpand_forms = (sort: "type" | "value") => non_modular(postexpand_body(sort)); -const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data }) => { +const postexpand_body = (sort: "type" | "value") => (data: data) => { const cont: walker = ({ loc, ...data }) => go_next( loc, @@ -1115,7 +1113,7 @@ const postexpand_body: walkerplus<{ sort: "type" | "value" }> = ({ sort, ...data } case "member_expression": { return go_down(loc, (loc) => - in_isolation(loc, (loc) => postexpand_forms({ ...data, loc, sort })) + in_isolation(loc, (loc) => postexpand_forms(sort)({ ...data, loc })) .then(({ loc, ...data }) => go_right(loc, (loc) => { assert(loc.t.content === "."); From 7a12a77d8562f69f60c3d2e1ea496c5e671c79ce Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Tue, 17 Dec 2024 10:08:41 +0300 Subject: [PATCH 35/35] simplified handling concise bodies --- src/expander.ts | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/src/expander.ts b/src/expander.ts index c205f6f..a570a63 100644 --- a/src/expander.ts +++ b/src/expander.ts @@ -278,22 +278,21 @@ const non_modular: (walker: walker) => walker = ({ modular, ...data }) => walker({ ...data, modular: { extensible: false } }).then((data) => ({ ...data, modular })); -const expand_concise_body = non_modular(async ({ loc, ...data }) => { - const sort = "value"; - const gs = await (loc.t.type === "list" && loc.t.tag === "statement_block" - ? preexpand_block({ ...data, loc }).then(({ loc, ...gs }) => - go_down( - loc, - (loc) => ({ ...gs, loc }), - (loc) => debug(loc, "???"), - ), - ) - : preexpand_forms(sort)({ ...data, loc })); - return postexpand_body(sort)({ - ...gs, - unit: extend_unit(gs.unit, gs.lexical), - }); -}); +const preexpand_concise_body: walker = ({ loc, ...data }) => + loc.t.tag === "statement_block" + ? preexpand_block({ ...data, loc }) + : preexpand_forms("value")({ ...data, loc }); + +const postexpand_concise_body: walker = ({ loc, ...data }) => + loc.t.tag === "statement_block" + ? go_down(loc, (loc) => postexpand_body("value")({ loc, ...data })) + : postexpand_body("value")({ loc, ...data }); + +const expand_concise_body = non_modular((data) => + preexpand_concise_body(data) + .then(({ unit, lexical, ...data }) => ({ ...data, lexical, unit: extend_unit(unit, lexical) })) + .then(postexpand_concise_body), +); function rewrap(loc: Loc, rib_id: string, cu_id: string): Loc { return {