Thanks for the link - a lot of interesting literature to dig into!
Generally with unknown (at compile-time) variable types, you need to box the variables (carry type information in addition to the value).
The operators may then either work on the boxed variables and choose behaviour based on the type information or the operators may be specialized in many versions to work on the unboxed variables (this requires the run-time to dispatch to the correct specialized version, if the types cannot be determined statically).
This is generally a trade-off between space and execution time - if the number of possible types are low (either because of a limited type system or because the possible different types can be determined statically), then it may make sense to specialize.
In JS, in addition to mutable types and values for each variable, you also have a challenge with variable scope. It is possible to introduce new variables in the global scope from a local scope, so depending on run-time values, a variable for a given statement may or may not have been declared.
An example from the thesis:
function f(){
a = 5;
}
function g(){
console.log(a);
}
if(x){
f();
}
g();
Assuming that 'a' was not declared elsewhere also, the call to 'g()' will either print out the value of 'a' (ie. "5") or will result in a run-time error.
Co-author of the thesis here - if anybody is interested in the source code, let me know.
Keep in mind that JS has changed quite a bit in the years that have passed and that certain aspects ('eval' in particular) was excluded from the project.
Though, it may be an interesting starting point for anybody, who wants to play around with compiling JS.
Co-author of the thesis here - we wrote it almost 6 years ago, so my memory may be a little rusty :-)
The question we dealt with was how to compile a weakly, implicitly and dynamically typed language (see the definitions in the thesis, but basically a language where the variable types cannot be statically determined in the general case and will be coerced if the run-time type does not match operator requirements) in a manner that is more efficient than simply interpreting the program source code.
I do not recall seeing any related work with regards to BASIC and Lisp at the time, however, we may very well have overlooked something. Thank you for the references!
Generally with unknown (at compile-time) variable types, you need to box the variables (carry type information in addition to the value). The operators may then either work on the boxed variables and choose behaviour based on the type information or the operators may be specialized in many versions to work on the unboxed variables (this requires the run-time to dispatch to the correct specialized version, if the types cannot be determined statically).
This is generally a trade-off between space and execution time - if the number of possible types are low (either because of a limited type system or because the possible different types can be determined statically), then it may make sense to specialize.
In JS, in addition to mutable types and values for each variable, you also have a challenge with variable scope. It is possible to introduce new variables in the global scope from a local scope, so depending on run-time values, a variable for a given statement may or may not have been declared.
An example from the thesis:
Assuming that 'a' was not declared elsewhere also, the call to 'g()' will either print out the value of 'a' (ie. "5") or will result in a run-time error.