Idorobots / spartan

A small Lisp dialect that serves me as a test bed for programming language features.
MIT License
13 stars 3 forks source link

Global value hoisting should deduplicate the hoisted values. #201

Closed Idorobots closed 1 day ago

Idorobots commented 1 month ago

Currently, when passing through the AST and hoisting values into the global scope, the transformation just blindly moves each value giving it a new name. This results in duplicates, lots of duplicates. Compiling the core scheduler into JS results in multiple duplicate state definitions:

const __global4726 = "halted";
const __global4727 = "running";
const __global4729 = "waiting";
const __global4731 = "waiting-4-msg";
const __global4780 = "waiting";
const __global4805 = "waiting";
const __global4808 = "waiting";
const __global4811 = "waiting";
const __global4814 = "waiting";

The same is true for continuations, especially final, leaf continuations:

const __global4662 = ((__env4460, __value3484) => {const __value3486 = makeCons((__env4460.cdr), __value3484); const __kont5306 = (__env4460.car); if (__kontCounter-- > 0) { return __kont5306.fun(__kont5306.env, __value3486) } else { __kontCounter = 1; return makeResumable(__kont5306, __value3486) }});
const __global4663 = ((__env4461, __value3488) => {const __value3489 = makeCons((__env4461.cdr), __value3488); const __kont5305 = (__env4461.car); if (__kontCounter-- > 0) { return __kont5305.fun(__kont5305.env, __value3489) } else { __kontCounter = 1; return makeResumable(__kont5305, __value3489) }});

Hoisting should first normalize a value AST and then attempt to check the global scope for the normalized value before adding a new name to it. This will likely reuse a value originating from a different location in the source, but that should be fine at that stage of the compilation pipeline.