made with requirebin
Last active
February 6, 2016 10:30
-
-
Save Hypercubed/befa878a2b75fd878c5e to your computer and use it in GitHub Desktop.
requirebin sketch
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
var typed = require("typed-function"); | |
typed.addType({ | |
name: 'zero', | |
test: function (x) { return x === 0; } | |
}); | |
typed.addType({ | |
name: 'one', | |
test: function (x) { return x === 1; } | |
}); | |
const fib = typed({ | |
'zero': function (n) { return 0 }, | |
'one': function (n) { return 1 }, | |
'any': function (n) { return fib(n - 1) + fib(n - 2); } | |
}); | |
document.body.innerHTML = | |
new Array(20).fill().map(function (x,i) { return fib(i); }); |
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
require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({"typed-function":[function(require,module,exports){"use strict";(function(factory){if(typeof define==="function"&&define.amd){define([],factory)}else if(typeof exports==="object"){module.exports=factory()}else{window.typed=factory()}})(function(){function create(){function getTypeTest(name){var test;for(var i=0;i<typed.types.length;i++){var entry=typed.types[i];if(entry.name===name){test=entry.test;break}}if(!test){var hint;for(i=0;i<typed.types.length;i++){entry=typed.types[i];if(entry.name.toLowerCase()==name.toLowerCase()){hint=entry.name;break}}throw new Error('Unknown type "'+name+'"'+(hint?'. Did you mean "'+hint+'"?':""))}return test}function getName(fns){var name="";for(var i=0;i<fns.length;i++){var fn=fns[i];if(fn.name!=""){if(name==""){name=fn.name}else if(name!=fn.name){var err=new Error("Function names do not match (expected: "+name+", actual: "+fn.name+")");err.data={actual:fn.name,expected:name};throw err}}}return name}function createError(fn,argCount,index,actual,expected){var actualType=getTypeOf(actual);var _expected=expected?expected.split(","):null;var _fn=fn||"unnamed";var anyType=_expected&&contains(_expected,"any");var message;var data={fn:fn,index:index,actual:actual,expected:_expected};if(_expected){if(argCount>index&&!anyType){message="Unexpected type of argument in function "+_fn+" (expected: "+_expected.join(" or ")+", actual: "+actualType+", index: "+index+")"}else{message="Too few arguments in function "+_fn+" (expected: "+_expected.join(" or ")+", index: "+index+")"}}else{message="Too many arguments in function "+_fn+" (expected: "+index+", actual: "+argCount+")"}var err=new TypeError(message);err.data=data;return err}function Refs(name){this.name=name||"refs";this.categories={}}Refs.prototype.add=function(fn,category){var cat=category||"fn";if(!this.categories[cat])this.categories[cat]=[];var index=this.categories[cat].indexOf(fn);if(index==-1){index=this.categories[cat].length;this.categories[cat].push(fn)}return cat+index};Refs.prototype.toCode=function(){var code=[];var path=this.name+".categories";var categories=this.categories;for(var cat in categories){if(categories.hasOwnProperty(cat)){var category=categories[cat];for(var i=0;i<category.length;i++){code.push("var "+cat+i+" = "+path+"['"+cat+"']["+i+"];")}}}return code.join("\n")};function Param(types,varArgs){if(typeof types==="string"){var _types=types.trim();var _varArgs=_types.substr(0,3)==="...";if(_varArgs){_types=_types.substr(3)}if(_types===""){this.types=["any"]}else{this.types=_types.split("|");for(var i=0;i<this.types.length;i++){this.types[i]=this.types[i].trim()}}}else if(Array.isArray(types)){this.types=types}else if(types instanceof Param){return types.clone()}else{throw new Error("String or Array expected")}this.conversions=[];this.varArgs=_varArgs||varArgs||false;this.anyType=this.types.indexOf("any")!==-1}Param.compare=function(a,b){if(a.anyType)return 1;if(b.anyType)return-1;if(contains(a.types,"Object"))return 1;if(contains(b.types,"Object"))return-1;if(a.hasConversions()){if(b.hasConversions()){var i,ac,bc;for(i=0;i<a.conversions.length;i++){if(a.conversions[i]!==undefined){ac=a.conversions[i];break}}for(i=0;i<b.conversions.length;i++){if(b.conversions[i]!==undefined){bc=b.conversions[i];break}}return typed.conversions.indexOf(ac)-typed.conversions.indexOf(bc)}else{return 1}}else{if(b.hasConversions()){return-1}else{var ai,bi;for(i=0;i<typed.types.length;i++){if(typed.types[i].name===a.types[0]){ai=i;break}}for(i=0;i<typed.types.length;i++){if(typed.types[i].name===b.types[0]){bi=i;break}}return ai-bi}}};Param.prototype.overlapping=function(other){for(var i=0;i<this.types.length;i++){if(contains(other.types,this.types[i])){return true}}return false};Param.prototype.clone=function(){var param=new Param(this.types.slice(),this.varArgs);param.conversions=this.conversions.slice();return param};Param.prototype.hasConversions=function(){return this.conversions.length>0};Param.prototype.contains=function(types){for(var i=0;i<this.types.length;i++){if(types[this.types[i]]){return true}}return false};Param.prototype.toString=function(toConversion){var types=[];var keys={};for(var i=0;i<this.types.length;i++){var conversion=this.conversions[i];var type=toConversion&&conversion?conversion.to:this.types[i];if(!(type in keys)){keys[type]=true;types.push(type)}}return(this.varArgs?"...":"")+types.join("|")};function Signature(params,fn){var _params;if(typeof params==="string"){_params=params!==""?params.split(","):[]}else if(Array.isArray(params)){_params=params}else{throw new Error("string or Array expected")}this.params=new Array(_params.length);for(var i=0;i<_params.length;i++){var param=new Param(_params[i]);this.params[i]=param;if(i===_params.length-1){this.varArgs=param.varArgs}else{if(param.varArgs){throw new SyntaxError('Unexpected variable arguments operator "..."')}}}this.fn=fn}Signature.prototype.clone=function(){return new Signature(this.params.slice(),this.fn)};Signature.prototype.expand=function(){var signatures=[];function recurse(signature,path){if(path.length<signature.params.length){var i,newParam,conversion;var param=signature.params[path.length];if(param.varArgs){newParam=param.clone();for(i=0;i<typed.conversions.length;i++){conversion=typed.conversions[i];if(!contains(param.types,conversion.from)&&contains(param.types,conversion.to)){var j=newParam.types.length;newParam.types[j]=conversion.from;newParam.conversions[j]=conversion}}recurse(signature,path.concat(newParam))}else{for(i=0;i<param.types.length;i++){recurse(signature,path.concat(new Param(param.types[i])))}for(i=0;i<typed.conversions.length;i++){conversion=typed.conversions[i];if(!contains(param.types,conversion.from)&&contains(param.types,conversion.to)){newParam=new Param(conversion.from);newParam.conversions[0]=conversion;recurse(signature,path.concat(newParam))}}}}else{signatures.push(new Signature(path,signature.fn))}}recurse(this,[]);return signatures};Signature.compare=function(a,b){if(a.params.length>b.params.length)return 1;if(a.params.length<b.params.length)return-1;var i;var len=a.params.length;var ac=0;var bc=0;for(i=0;i<len;i++){if(a.params[i].hasConversions())ac++;if(b.params[i].hasConversions())bc++}if(ac>bc)return 1;if(ac<bc)return-1;for(i=0;i<a.params.length;i++){var cmp=Param.compare(a.params[i],b.params[i]);if(cmp!==0){return cmp}}return 0};Signature.prototype.hasConversions=function(){for(var i=0;i<this.params.length;i++){if(this.params[i].hasConversions()){return true}}return false};Signature.prototype.ignore=function(){var types={};for(var i=0;i<typed.ignore.length;i++){types[typed.ignore[i]]=true}for(i=0;i<this.params.length;i++){if(this.params[i].contains(types)){return true}}return false};Signature.prototype.toCode=function(refs,prefix){var code=[];var args=new Array(this.params.length);for(var i=0;i<this.params.length;i++){var param=this.params[i];var conversion=param.conversions[0];if(param.varArgs){args[i]="varArgs"}else if(conversion){args[i]=refs.add(conversion.convert,"convert")+"(arg"+i+")"}else{args[i]="arg"+i}}var ref=this.fn?refs.add(this.fn,"signature"):undefined;if(ref){return prefix+"return "+ref+"("+args.join(", ")+"); // signature: "+this.params.join(", ")}return code.join("\n")};Signature.prototype.toString=function(){return this.params.join(", ")};function Node(path,signature,childs){this.path=path||[];this.param=path[path.length-1]||null;this.signature=signature||null;this.childs=childs||[]}Node.prototype.toCode=function(refs,prefix,anyType){var code=[];if(this.param){var index=this.path.length-1;var conversion=this.param.conversions[0];var comment="// type: "+(conversion?conversion.from+" (convert to "+conversion.to+")":this.param);if(this.param.varArgs){if(this.param.anyType){code.push(prefix+"if (arguments.length > "+index+") {");code.push(prefix+" var varArgs = [];");code.push(prefix+" for (var i = "+index+"; i < arguments.length; i++) {");code.push(prefix+" varArgs.push(arguments[i]);");code.push(prefix+" }");code.push(this.signature.toCode(refs,prefix+" "));code.push(prefix+"}")}else{var getTests=function(types,arg){var tests=[];for(var i=0;i<types.length;i++){tests[i]=refs.add(getTypeTest(types[i]),"test")+"("+arg+")"}return tests.join(" || ")}.bind(this);var allTypes=this.param.types;var exactTypes=[];for(var i=0;i<allTypes.length;i++){if(this.param.conversions[i]===undefined){exactTypes.push(allTypes[i])}}code.push(prefix+"if ("+getTests(allTypes,"arg"+index)+") { "+comment);code.push(prefix+" var varArgs = [arg"+index+"];");code.push(prefix+" for (var i = "+(index+1)+"; i < arguments.length; i++) {");code.push(prefix+" if ("+getTests(exactTypes,"arguments[i]")+") {");code.push(prefix+" varArgs.push(arguments[i]);");for(var i=0;i<allTypes.length;i++){var conversion_i=this.param.conversions[i];if(conversion_i){var test=refs.add(getTypeTest(allTypes[i]),"test");var convert=refs.add(conversion_i.convert,"convert");code.push(prefix+" }");code.push(prefix+" else if ("+test+"(arguments[i])) {");code.push(prefix+" varArgs.push("+convert+"(arguments[i]));")}}code.push(prefix+" } else {");code.push(prefix+" throw createError(name, arguments.length, i, arguments[i], '"+exactTypes.join(",")+"');");code.push(prefix+" }");code.push(prefix+" }");code.push(this.signature.toCode(refs,prefix+" "));code.push(prefix+"}")}}else{if(this.param.anyType){code.push(prefix+"// type: any");code.push(this._innerCode(refs,prefix,anyType))}else{var type=this.param.types[0];var test=type!=="any"?refs.add(getTypeTest(type),"test"):null;code.push(prefix+"if ("+test+"(arg"+index+")) { "+comment);code.push(this._innerCode(refs,prefix+" ",anyType));code.push(prefix+"}")}}}else{code.push(this._innerCode(refs,prefix,anyType))}return code.join("\n")};Node.prototype._innerCode=function(refs,prefix,anyType){var code=[];var i;if(this.signature){code.push(prefix+"if (arguments.length === "+this.path.length+") {");code.push(this.signature.toCode(refs,prefix+" "));code.push(prefix+"}")}var nextAnyType;for(i=0;i<this.childs.length;i++){if(this.childs[i].param.anyType){nextAnyType=this.childs[i];break}}for(i=0;i<this.childs.length;i++){code.push(this.childs[i].toCode(refs,prefix,nextAnyType))}if(anyType&&!this.param.anyType){code.push(anyType.toCode(refs,prefix,nextAnyType))}var exceptions=this._exceptions(refs,prefix);if(exceptions){code.push(exceptions)}return code.join("\n")};Node.prototype._exceptions=function(refs,prefix){var index=this.path.length;if(this.childs.length===0){return[prefix+"if (arguments.length > "+index+") {",prefix+" throw createError(name, arguments.length, "+index+", arguments["+index+"]);",prefix+"}"].join("\n")}else{var keys={};var types=[];for(var i=0;i<this.childs.length;i++){var node=this.childs[i];if(node.param){for(var j=0;j<node.param.types.length;j++){var type=node.param.types[j];if(!(type in keys)&&!node.param.conversions[j]){keys[type]=true;types.push(type)}}}}return prefix+"throw createError(name, arguments.length, "+index+", arguments["+index+"], '"+types.join(",")+"');"}};function parseSignatures(rawSignatures){var signature;var keys={};var signatures=[];var i;for(var types in rawSignatures){if(rawSignatures.hasOwnProperty(types)){var fn=rawSignatures[types];signature=new Signature(types,fn);if(signature.ignore()){continue}var expanded=signature.expand();for(i=0;i<expanded.length;i++){var signature_i=expanded[i];var key=signature_i.toString();var existing=keys[key];if(!existing){keys[key]=signature_i}else{var cmp=Signature.compare(signature_i,existing);if(cmp<0){keys[key]=signature_i}else if(cmp===0){throw new Error('Signature "'+key+'" is defined twice')}}}}}for(key in keys){if(keys.hasOwnProperty(key)){signatures.push(keys[key])}}signatures.sort(function(a,b){return Signature.compare(a,b)});for(i=0;i<signatures.length;i++){signature=signatures[i];if(signature.varArgs){var index=signature.params.length-1;var param=signature.params[index];var t=0;while(t<param.types.length){if(param.conversions[t]){var type=param.types[t];for(var j=0;j<signatures.length;j++){var other=signatures[j];var p=other.params[index];if(other!==signature&&p&&contains(p.types,type)&&!p.conversions[index]){param.types.splice(t,1);param.conversions.splice(t,1);t--;break}}}t++}}}return signatures}function mapSignatures(signatures){var normalized={};for(var i=0;i<signatures.length;i++){var signature=signatures[i];if(signature.fn&&!signature.hasConversions()){var params=signature.params.join(",");normalized[params]=signature.fn}}return normalized}function parseTree(signatures,path){var i,signature;var index=path.length;var nodeSignature;var filtered=[];for(i=0;i<signatures.length;i++){signature=signatures[i];if(signature.params.length===index&&!nodeSignature){nodeSignature=signature}if(signature.params[index]!=undefined){filtered.push(signature)}}filtered.sort(function(a,b){return Param.compare(a.params[index],b.params[index])});var entries=[];for(i=0;i<filtered.length;i++){signature=filtered[i];var param=signature.params[index];var existing=entries.filter(function(entry){return entry.param.overlapping(param)})[0];if(existing){if(existing.param.varArgs){throw new Error('Conflicting types "'+existing.param+'" and "'+param+'"')}existing.signatures.push(signature)}else{entries.push({param:param,signatures:[signature]})}}var childs=new Array(entries.length);for(i=0;i<entries.length;i++){var entry=entries[i];childs[i]=parseTree(entry.signatures,path.concat(entry.param))}return new Node(path,nodeSignature,childs)}function getArgs(count){var args=[];for(var i=0;i<count;i++){args[i]="arg"+i}return args}function _typed(name,signatures){var refs=new Refs;var _signatures=parseSignatures(signatures);if(_signatures.length==0){throw new Error("No signatures provided")}var node=parseTree(_signatures,[]);var code=[];var _name=name||"";var _args=getArgs(maxParams(_signatures));code.push("function "+_name+"("+_args.join(", ")+") {");code.push(' "use strict";');code.push(" var name = '"+_name+"';");code.push(node.toCode(refs," "));code.push("}");var body=[refs.toCode(),"return "+code.join("\n")].join("\n");var factory=new Function(refs.name,"createError",body);var fn=factory(refs,createError);fn.signatures=mapSignatures(_signatures);return fn}function maxParams(signatures){var max=0;for(var i=0;i<signatures.length;i++){var len=signatures[i].params.length;if(len>max){max=len}}return max}function getTypeOf(x){var obj;for(var i=0;i<typed.types.length;i++){var entry=typed.types[i];if(entry.name==="Object"){obj=entry}else{if(entry.test(x))return entry.name}}if(obj&&obj.test(x))return obj.name;return"unknown"}function contains(array,entry){return array.indexOf(entry)!==-1}var types=[{name:"number",test:function(x){return typeof x==="number"}},{name:"string",test:function(x){return typeof x==="string"}},{name:"boolean",test:function(x){return typeof x==="boolean"}},{name:"Function",test:function(x){return typeof x==="function"}},{name:"Array",test:Array.isArray},{name:"Date",test:function(x){return x instanceof Date}},{name:"RegExp",test:function(x){return x instanceof RegExp}},{name:"Object",test:function(x){return typeof x==="object"}},{name:"null",test:function(x){return x===null}},{name:"undefined",test:function(x){return x===undefined}}];var config={};var conversions=[];var ignore=[];var typed={config:config,types:types,conversions:conversions,ignore:ignore};typed=_typed("typed",{Object:function(signatures){var fns=[];for(var signature in signatures){if(signatures.hasOwnProperty(signature)){fns.push(signatures[signature])}}var name=getName(fns);return _typed(name,signatures)},"string, Object":_typed,"...Function":function(fns){var err;var name=getName(fns);var signatures={};for(var i=0;i<fns.length;i++){var fn=fns[i];if(!(typeof fn.signatures==="object")){err=new TypeError("Function is no typed-function (index: "+i+")");err.data={index:i};throw err}for(var signature in fn.signatures){if(fn.signatures.hasOwnProperty(signature)){if(signatures.hasOwnProperty(signature)){if(fn.signatures[signature]!==signatures[signature]){err=new Error('Signature "'+signature+'" is defined twice');err.data={signature:signature};throw err}}else{signatures[signature]=fn.signatures[signature]}}}}return _typed(name,signatures)}});function find(fn,signature){if(!fn.signatures){throw new TypeError("Function is no typed-function")}var arr;if(typeof signature==="string"){arr=signature.split(",");for(var i=0;i<arr.length;i++){arr[i]=arr[i].trim()}}else if(Array.isArray(signature)){arr=signature}else{throw new TypeError("String array or a comma separated string expected")}var str=arr.join(",");var match=fn.signatures[str];if(match){return match}throw new TypeError("Signature not found (signature: "+(fn.name||"unnamed")+"("+arr.join(", ")+"))")}function convert(value,type){var from=getTypeOf(value);if(type===from){return value}for(var i=0;i<typed.conversions.length;i++){var conversion=typed.conversions[i];if(conversion.from===from&&conversion.to===type){return conversion.convert(value)}}throw new Error("Cannot convert from "+from+" to "+type)}typed.config=config;typed.types=types;typed.conversions=conversions;typed.ignore=ignore;typed.create=create;typed.find=find;typed.convert=convert;typed.addType=function(type){if(!type||typeof type.name!=="string"||typeof type.test!=="function"){throw new TypeError("Object with properties {name: string, test: function} expected")}typed.types.push(type)};typed.addConversion=function(conversion){if(!conversion||typeof conversion.from!=="string"||typeof conversion.to!=="string"||typeof conversion.convert!=="function"){throw new TypeError("Object with properties {from: string, to: string, convert: function} expected")}typed.conversions.push(conversion)};return typed}return create()})},{}]},{},[]);var typed=require("typed-function");typed.addType({name:"zero",test:function(x){return x===0}});typed.addType({name:"one",test:function(x){return x===1}});const fib=typed({zero:function(n){return 0},one:function(n){return 1},any:function(n){return fib(n-1)+fib(n-2)}});document.body.innerHTML=new Array(20).fill().map(function(x,i){return fib(i)}); |
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
{ | |
"name": "requirebin-sketch", | |
"version": "1.0.0", | |
"dependencies": { | |
"typed-function": "0.10.3" | |
} | |
} |
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
<!-- contents of this file will be placed inside the <body> --> |
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
<!-- contents of this file will be placed inside the <head> --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment