Skip to content
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ demo-webpage/html/runner.js
package-lock.json
auth-trial/html/src-noconflict
/benchmarks
.vscode
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, why? you need to stick to vim for a little longer.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah well, I wanted to feel like I wasn't in the 90s (plus I finally got a computer that can support an actual editor) . Didn't really work out. VS Code's vim emulation isn't that great.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, being fluent in Vim or Emacs is an important part of street cred. But you probably have that already.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I am fluent in vim. I even wrote most of the vim stuff for pyret: brownplt/pyret-lang#1150

(the name of the PR is in sync with the Pyret theme :) )

52 changes: 47 additions & 5 deletions src/callcc/declVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function declToAssign(decl: t.VariableDeclarator): t.AssignmentExpression | null

function getFunctionArgs(path: NodePath<t.Node>): string[] {
const node = path.node;
if (node.type === 'FunctionDeclaration' ||
if (node.type === 'FunctionDeclaration' ||
node.type === 'FunctionExpression') {
return (<any>node).params.map((x: t.Identifier) => x.name);
}
Expand All @@ -37,7 +37,7 @@ function getFunctionArgs(path: NodePath<t.Node>): string[] {
}

function getBlock(node: t.Node): t.Statement[] {
if (node.type === 'FunctionDeclaration' ||
if (node.type === 'FunctionDeclaration' ||
node.type === 'FunctionExpression') {
return (<t.FunctionDeclaration>node).body.body;
}
Expand All @@ -49,7 +49,36 @@ function getBlock(node: t.Node): t.Statement[] {
}
}

const func = {
enter(path: NodePath<t.FunctionDeclaration|t.FunctionExpression>) {
(<any>path.node).toDecl = []
},
exit(path: NodePath<t.FunctionDeclaration|t.FunctionExpression>) {
const toDecl: t.Identifier[] | undefined = (<any>path.node).toDecl
if(toDecl && toDecl.length > 0) {
path.node.body.body.unshift(lifted(t.variableDeclaration('var',
toDecl.map(d => t.variableDeclarator(d)))))
}
}
}

const prog = {
enter(path: NodePath<t.Program>) {
(<any>path.node).toDecl = []
},
exit(path: NodePath<t.Program>) {
const toDecl: t.Identifier[] | undefined = (<any>path.node).toDecl
if(toDecl && toDecl.length > 0) {
path.node.body.unshift(lifted(t.variableDeclaration('var',
toDecl.map(d => t.variableDeclarator(d)))))
}
}
}

const lift: Visitor = {
Program: prog,
FunctionDeclaration: func,
FunctionExpression: func,
VariableDeclaration(path: NodePath<Lifted<t.VariableDeclaration>>) {
if (path.node.lifted) {
return;
Expand All @@ -73,9 +102,22 @@ const lift: Visitor = {
throw new Error(`Destructuring assignment not supported`);
}
const id = decl.id.name;
const newDecl = t.variableDeclaration(kind,
[t.variableDeclarator(decl.id)]);
getBlock(topScope.node).unshift(lifted(newDecl));
// This checks for the following case:
//
// function(x) { var x = 10; }
//
// is the same as:
//
// function(x) { x = 10; }
//
// Therefore, we do not need to lift x. Instead, we eliminate the
// declaration and only turn it into an assignment.
if ((kind === 'var' && topArgs.includes(id)) === false) {
//const newDecl = t.variableDeclaration(kind,
//[t.variableDeclarator(decl.id)]);
//getBlock(topScope.node).unshift(lifted(newDecl));
(<any>topScope.node).toDecl.push(decl.id)
}
if (decl.init !== null) {
// If we call path.insertAfter here, we will add assignments in reverse
// order. Fortunately, path.insertAfter can take an array of nodes.
Expand Down
8 changes: 5 additions & 3 deletions test/testFixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export function callCCTest(srcPath: string, transform: string) {
}

it(testName, () => {
const { name: dstPath } = tmp.fileSync({ dir: ".", postfix: ".js" });
const basename = path.basename(srcPath, '.js')
const { name: dstPath } = tmp.fileSync({ dir: ".", postfix: `${basename}.js` });
execSync(`./bin/compile --transform ${transform} ${srcPath} ${dstPath}`);
try {
execSync(`./bin/run ${dstPath} --yield 1`, { timeout: 30000 });
Expand All @@ -34,6 +35,7 @@ export function callCCTest(srcPath: string, transform: string) {

export function browserTest(srcPath: string, transform: string) {
const testName = `${srcPath} (${transform}) (in-browser)`;
const basename = path.basename(srcPath, '.js')

// Skip tests we know we can't handle
if ( srcPath.indexOf("dart") >= 0 ||
Expand All @@ -43,8 +45,8 @@ export function browserTest(srcPath: string, transform: string) {
}

it(testName, () => {
const { name: dstPath } = tmp.fileSync({ dir: ".", postfix: ".js" });
const { name: htmlPath } = tmp.fileSync({ dir: ".", postfix: ".html" });
const { name: dstPath } = tmp.fileSync({ dir: ".", postfix: `${basename}.js` });
const { name: htmlPath } = tmp.fileSync({ dir: ".", postfix: `${basename}.html` });
execSync(`./bin/compile --transform ${transform} ${srcPath} ${dstPath}`);
execSync(`./bin/webpack ${dstPath} ${htmlPath}`);
execSync(`./bin/browser ${htmlPath} --yield 1000 --env chrome`);
Expand Down