Last active
June 30, 2022 04:32
-
-
Save dfkaye/c50ff265f4411145151fff2f44c2e1bf to your computer and use it in GitHub Desktop.
parse body of a function given constraints
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 24 June 2022 | |
// parse the body of a function if its only parameter is self | |
// 25 june 2022 | |
// - added full body test, | |
// - fixed trailing brace regexp (missing $). | |
// 29 June 2022 | |
// - append semi-colon and linebreak to each parsed function body, to enable | |
// concatenating multiple functions in the next post, "communicating embedded | |
// worker factories" at | |
// https://gist.github.com/dfkaye/c6d77fde86aea70ef6ae79bda2219582 | |
// ...companion to "parse parameter names from function argument list" | |
// at https://gist.github.com/dfkaye/51550ec0818e507aebd89a585b2c05c4 | |
// ...continued from "import an embedded worker within another embedded worker" | |
// at https://gist.github.com/dfkaye/20ff0934cd8d2b0fa7aea5606ac7ab89 | |
// Self() is a special purpose function meant to extract a stringified function | |
// body for use as an embedded worker script, loaded as a blob with an object | |
// URL. | |
// Self() extracts the body of a function argument if: | |
// 1. it has only one argument, | |
// 2. the argument is `self` or has a `self` property defined (i.e., `self` is | |
// not a fallback, as in `( self = "value" )`, e.g.), | |
// 3. it's an arrow function, and | |
// 3.1 parentheses surround the function argument, | |
// 3.2 braces surround the function body. | |
// Self() is meant to extract a stringified function body for use as an embedded | |
// worker script, loaded as a blob with an object URL. | |
function Self(fn) { | |
var fs = String(fn).trim(); | |
var parseable = typeof fn == "function" | |
&& fn.length === 1 | |
&& fs.match(/(self)[^\)]*\)[^\{]*\{/); | |
if (!parseable) { | |
return; | |
} | |
return fs /* .substring(fs.indexOf("self") + 4) */ | |
.replace(/(self)?[^\)]*\)[^\{]*\{/, '') | |
.replace(/\s*\}\s*$/, '') | |
.split("\n") | |
.filter(s => /\S/.test(s)) | |
.join("\n") | |
.concat(";\n"); | |
} | |
/* test it out */ | |
console.group("* failing *"); | |
[ | |
function Named (param) { console.log( "named" ); }, | |
function (param) { console.log( "anonymous" ); }, | |
function Named ( { param = "function" }) { console.log( "named:param" ); }, | |
function ( { param = "function" }) { console.log( "anonymous:param" ); }, | |
param => "arrow", | |
( { param = "arrow"} ) => "arrow:param", | |
( { param = "arrow"} ) => { "arrow:braces" }, | |
self => "arrow:no-braces", | |
self => { "arrow:braces:no-parens" }, | |
( self = "arrow" ) => { "arrow:parens:fallback" } | |
].forEach(fn => { | |
console.log(Self(fn)) | |
}); | |
console.groupEnd("* failing *"); | |
console.group("** passing **"); | |
[ | |
function (self) { console.log( "anonymous:self" ); }, | |
function Named (self) { console.log( "named:self" ); }, | |
( self ) => { | |
console.log( "arrow:self" ); | |
}, | |
function Named ( { self = "function" } ) { console.log( "named:self:param" ); }, | |
function ( { self = "function" } ) { console.log( "anonymous:self:param" ); }, | |
( { self = "arrow" } ) => { | |
console.log("arrow:self:param"); | |
} | |
].forEach(fn => { | |
console.log(Self(fn)) | |
}); | |
console.groupEnd("** passing **"); | |
console.group("*** fullbody ***"); | |
function FullBody(self) { | |
// full body script test | |
function credentials({ sender, address }) { | |
return address === self.location | |
&& senders.has(sender) | |
} | |
self.senders = new Set(); | |
self.init = function(data) { | |
senders.has(data.sender) || senders.add(data.sender); | |
return credentials(data); | |
} | |
self.onmessage = function (request) { | |
var data = Object(request.data); | |
console.warn(data.sender, data.address, data.action, data.value); | |
if (data.action === 'init') { | |
self.init(data); | |
} | |
var response = Object.assign({}, data); | |
self.postMessage(response); | |
} | |
} | |
console.log( | |
Self( FullBody ) | |
); | |
console.groupEnd("*** fullbody ***"); | |
/* | |
* failing * | |
undefined | |
undefined | |
undefined | |
undefined | |
undefined | |
undefined | |
undefined | |
undefined | |
undefined | |
undefined | |
** passing ** | |
console.log( "anonymous:self" ); debugger eval code:83:11 | |
console.log( "named:self" ); debugger eval code:83:11 | |
console.log( "arrow:self" ); debugger eval code:83:11 | |
console.log( "named:self:param" ); debugger eval code:83:11 | |
console.log( "anonymous:self:param" ); debugger eval code:83:11 | |
console.log("arrow:self:param"); | |
*** full body *** | |
// full body script test | |
function credentials({ sender, address }) { | |
return address === self.location | |
&& senders.has(sender) | |
} | |
self.senders = new Set(); | |
self.init = function(data) { | |
senders.has(data.sender) || senders.add(data.sender); | |
return credentials(data); | |
} | |
self.onmessage = function (request) { | |
var data = Object(request.data); | |
console.warn(data.sender, data.address, data.action, data.value); | |
if (data.action === 'init') { | |
self.init(data); | |
} | |
var response = Object.assign({}, data); | |
self.postMessage(response); | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment