Skip to content

Commit

Permalink
imports (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
DerThorsten authored Jan 26, 2024
1 parent 7754558 commit 91e8c42
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 19 deletions.
79 changes: 67 additions & 12 deletions notebooks/xeus-javascript.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Imports\n",
"the following 2 ways of importing are supported atm"
"# Imports"
]
},
{
Expand All @@ -238,7 +237,7 @@
},
"outputs": [],
"source": [
"import \"https://cdn.jsdelivr.net/npm/mathjs@12.3.0/lib/browser/math.min.js\"\n",
"import * as math from \"https://cdn.jsdelivr.net/npm/mathjs@12.3.0/+esm\"\n",
"\n",
"let d = math.derivative('x^2 + x', 'x');\n",
"`${d}`"
Expand All @@ -254,15 +253,69 @@
},
"outputs": [],
"source": [
"// same as above but with import scripts\n",
"importScripts(\"https://cdn.jsdelivr.net/npm/mathjs@12.3.0/lib/browser/math.min.js\");"
"const {default: OpenAI} = await import('https://cdn.jsdelivr.net/npm/openai@4.26.0/+esm');\n",
"console.log(OpenAI.OpenAI);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "plaintext"
}
},
"outputs": [],
"source": [
"import OpenAI from \"https://cdn.jsdelivr.net/npm/openai@4.26.0/+esm\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "plaintext"
}
},
"outputs": [],
"source": [
"import {default as fubar} from \"https://cdn.jsdelivr.net/npm/openai@4.26.0/+esm\"\n",
"new fubar.OpenAI()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "plaintext"
}
},
"outputs": [],
"source": [
"import {\n",
" atan2, chain, derivative, e, evaluate, log, pi, pow, round, sqrt\n",
"} from 'https://cdn.jsdelivr.net/npm/mathjs@12.3.0/+esm'\n",
"\n",
"sqrt(16)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "plaintext"
}
},
"outputs": [],
"source": [
"# Dynamic imports"
"import {\n",
" atan2 as fubar, pi\n",
"} from 'https://cdn.jsdelivr.net/npm/mathjs@12.3.0/+esm'\n",
"\n",
"fubar(-pi,pi)/pi"
]
},
{
Expand All @@ -275,8 +328,9 @@
},
"outputs": [],
"source": [
"const {default: openai} = await import('https://cdn.jsdelivr.net/npm/openai@4.26.0/+esm');\n",
"console.log(openai.OpenAI);"
"import * as erossonpolynomial from 'https://cdn.jsdelivr.net/npm/@erosson/polynomial@5.0.3/+esm';\n",
"let p = erossonpolynomial.Polynomial.parse([3,2,1]);\n",
"`${p}`"
]
},
{
Expand All @@ -289,8 +343,9 @@
},
"outputs": [],
"source": [
"const {OpenAI} = await import('https://cdn.jsdelivr.net/npm/openai@4.26.0/+esm');\n",
"console.log(OpenAI);"
"import {Polynomial} from 'https://cdn.jsdelivr.net/npm/@erosson/polynomial@5.0.3/+esm'\n",
"const p = Polynomial.parse([3,2,1]);\n",
"`${p}`"
]
}
],
Expand Down
89 changes: 83 additions & 6 deletions src/pre.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,25 +119,100 @@ Module["_handle_last_statement"] = function (
Module["_rewrite_import_statements"] = function (code, ast)
{
let modified_user_code = code;
let code_add_to_global_scope = "";
// handle import statements (in reverse order)
// so that the line numbers stay correct
for(let i=ast.body.length-1; i>=0; i--){
const node = ast.body[i];
if(node.type == "ImportDeclaration"){
// most simple case, no specifiers

const import_source = node.source.value;

if(node.specifiers.length == 0){
// import nothing, only side effects
const start = node.start;
const end = node.end;
if(node.source.type != "Literal"){
throw Error("import source is not a literal");
}
const module_name = node.source.value;
const new_code_of_node = `importScripts("${module_name}");`;
const new_code_of_node = `await import("${import_source}");\n`;
modified_user_code = modified_user_code.substring(0, start) + new_code_of_node + modified_user_code.substring(end);
}
else{

let has_default_import = false;
let default_import_name = "";

let has_namespace_import = false;
let namespace_import_name = "";

let imported_names = [];
let local_names = [];

// get imported and local names
for(const specifier of node.specifiers){
Module["clog"](specifier.type);
if(specifier.type == "ImportSpecifier"){
if(specifier.imported.name == "default"){
has_default_import = true;
default_import_name = specifier.local.name;
}
else{
imported_names.push(specifier.imported.name);
local_names.push(specifier.local.name);
}
}
else if(specifier.type == "ImportDefaultSpecifier"){
has_default_import = true;
default_import_name = specifier.local.name;
}
else if(specifier.type == "ImportNamespaceSpecifier"){
has_namespace_import = true;
namespace_import_name = specifier.local.name;

}
else{
throw Error(`unknown specifier type ${specifier.type}`);
}
}

let new_code_of_node = "";
if(has_default_import){
new_code_of_node += `const { default: ${default_import_name} } = await import("${import_source}");\n`;
code_add_to_global_scope += `globalThis[\"${default_import_name}\"] = ${default_import_name};\n`;
}

if(has_namespace_import){
new_code_of_node += `const ${namespace_import_name} = await import("${import_source}");\n`;
code_add_to_global_scope += `globalThis[\"${namespace_import_name}\"] = ${namespace_import_name};\n`;
}


if(imported_names.length > 0){
new_code_of_node += `const { `;
for(let i=0; i<imported_names.length; i++){
const imported_name = imported_names[i];
const local_name = local_names[i];
new_code_of_node += `${imported_name}`;
code_add_to_global_scope += `globalThis[\"${local_name}\"] = ${imported_name};\n`;
if(i<imported_names.length-1){
new_code_of_node += ", ";
}
}
new_code_of_node += `} = await import("${import_source}");\n`;
}

modified_user_code = modified_user_code.substring(0, node.start) + new_code_of_node + modified_user_code.substring(node.end);

}


}
}
return modified_user_code;
return {
modified_user_code: modified_user_code,
code_add_to_global_scope: code_add_to_global_scope
};
}


Expand All @@ -155,7 +230,7 @@ Module["_make_async_from_code"] = function (code) {
console.dir(ast.body, {depth: null});

// code to add top level variables to global scope
const code_add_to_global_scope = Module["_add_to_global_scope"](ast);
let code_add_to_global_scope = Module["_add_to_global_scope"](ast);

// handle last statement / add return if needed
let {with_return, modified_user_code, extra_return_code} = Module["_handle_last_statement"](
Expand All @@ -164,7 +239,9 @@ Module["_make_async_from_code"] = function (code) {
);

// handle import statements
modified_user_code = Module["_rewrite_import_statements"](modified_user_code, ast);
const res = Module["_rewrite_import_statements"](modified_user_code, ast);
modified_user_code = res.modified_user_code;
code_add_to_global_scope += res.code_add_to_global_scope;


const combined_code = `
Expand Down
2 changes: 1 addition & 1 deletion src/xinterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ namespace xeus_javascript

interpreter::interpreter()
{
std::cout<<"115th iteration of this file kernel (due to the service worker caching I need to print this to keep sanity)"<<std::endl;
std::cout<<"130th iteration of this file kernel (due to the service worker caching I need to print this to keep sanity)"<<std::endl;
xeus::register_interpreter(this);
}

Expand Down

0 comments on commit 91e8c42

Please sign in to comment.