4 Star 8 Fork 1

Rezero / defun

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
defun.js 15.96 KB
一键复制 编辑 原始数据 按行查看 历史
zhenlong.qin 提交于 2016-09-23 21:59 . defun
/*
*@author diqye
*@version 0.0.1
*/
(function(exports){
function headStr(str){
return str == null ? null
: str == "" ? ""
: str.charAt(0);
}
function lastStr(str){
return str == null ? null
: str == "" ? ""
: str.charAt(str.length-1);
}
function tailStr(str){
return str == null ? null
: str == "" ? ""
: str.slice(1);
}
function initStr(str){
return str == null ? null
: str == "" ? ""
: str.slice(0,-1);
}
function findIdxStr(flg,str){
return str == null ? null
:str.indexOf(flg);
}
function takeStr(len,str){
return str.slice(0,len);
}
function dropStr(len,str){
return str.slice(len);
}
function drop(len,arr){
if(typeof arr === "string") return dropStr(len,arr);
return arr.slice(len);
}
function isEmptyStr(str){
return str === "" ? true
: false;
}
function isStringToken(token){
var hstr = headStr(token);
var lstr = lastStr(token);
if(hstr === '"'){
if(lstr === '"'){
return true;
}else{
return false;
}
}else if(hstr === "'"){
if(lstr === "'"){
return true;
}else{
return false;
}
}else{
return false;
}
}
function stringTokenToData(token){
return initStr(tailStr(token));
}
function isNumberToken(token){
return isNaN(Number(token)) == false;
}
function numberTokenToData(token){
return Number(token);
}
function isBooleanToken(token){
return token == "true" ? true
: token == "false" ? true
:false;
}
function boolTokenToData(token){
return token == "true";
}
function isEmptyArrToken(token){
return token == "[]";
}
function emptyArrTokenToData(){
return {type:"q",value:isEmptyArr};
}
function isEmptyObjToken(token){
return token == "{}";
}
function emptyObjTokenToData(){
return {type:"q",value:isEmptyObj};
}
function isEmptyArr(arr){
return arr == null ? false
: arr.length == 0 ? true
: false
}
function isEmptyObj(obj){
if(obj == null) return false;
if(isobject(obj) == false) return false;
var r = true;
for(var key in obj)r=false;
return r;
}
function isNullToken(token){
return token == "null";
}
function isIgnoreToken(token){
return token == "_";
}
function ignoreTokenToData(){
return {type:"ignore",value:"_"};
}
function isIgnoreType(obj){
return obj.type === "ignore";
}
function isArrayToken(token){
var hstr = headStr(token);
var lstr = lastStr(token);
if(hstr=="@" && lstr == ")"){
return true;
}
return hstr == "(" && lstr == ")";
}
function arrayTokenToData(token){
var hstr = headStr(token);
var all = null;
var arrtoken=token;
if(hstr == "@"){
var t1 = tailStr(token);
var idx = findIdxStr("(",t1);
all = symbalTokenToData(trim(takeStr(idx,t1)));
arrtoken = dropStr(idx,t1);
}
var t2 = tailStr(arrtoken);
var tend = initStr(t2);
var result = parsecase(tend,"",{},"array");
return {type:"array",value:result,all:all};
}
function symbalTokenToData(token){
if(token.indexOf(" ") != -1){
throw new SyntaxError(token+":不是合法的符号命名 Illegal naming");
}
var qidx = token.indexOf("?");
if(qidx != -1){
var val = takeStr(qidx,token);
var qfn = dropStr(qidx+1,token);
return {
type:"symbal",
value:val,
qfn:qfn
}
}
return {
type:"symbal",
value:token
}
}
function isSymbalType(a){
return a == null ? false
: a.type == "symbal" ? true
:false;
}
function isObjectToken(token){
var hstr = headStr(token);
var lstr = lastStr(token);
if(hstr=="@" && lstr == "}"){
return true;
}
return hstr == "{" && lstr == "}";
}
function objectTokenToData(token){
var hstr = headStr(token);
var all = null;
var arrtoken=token;
if(hstr == "@"){
var t1 = tailStr(token);
var idx = findIdxStr("{",t1);
var alltoken = takeStr(idx,t1);
all = symbalTokenToData(trim(alltoken));
arrtoken = dropStr(idx,t1);
}
var t2 = tailStr(arrtoken);
var tend = initStr(t2);
var result = parsecase(tend,"",{},"object");
var tempvarr=[];
var valueReult=[];
function checkObjSynctax(tempvarr){
if(tempvarr.length == 0){
throw new SyntaxError(token+":对象语法错误");
}else if(tempvarr.length ==1){
var tmp1 = tempvarr[0];
if(isSymbalType(tmp1)) tempvarr.push(tmp1);
else new SyntaxError(token+":对象语法错误");
}else if(tempvarr.length == 2){
void null;
}else{
throw new SyntaxError(token+":对象语法错误");
}
}
for(var i=0;i<result.length;i++){
var item = result[i];
if(isHolder(item)){
checkObjSynctax(tempvarr);
valueReult.push(tempvarr);
tempvarr=[];
continue;
}
tempvarr.push(item);
}
checkObjSynctax(tempvarr);
valueReult.push(tempvarr);
return {type:"object",value:valueReult,all:all};
}
function isHolder(obj){
return obj["@holder@"]=="|";
}
function tokenToData(token){
return isBooleanToken(token) ? boolTokenToData(token)
: isStringToken(token) ? stringTokenToData(token)
: isNumberToken(token) ? numberTokenToData(token)
: isEmptyArrToken(token) ? emptyArrTokenToData(token)
: isEmptyObjToken(token) ? emptyObjTokenToData(token)
: isArrayToken(token) ? arrayTokenToData(token)
: isObjectToken(token) ? objectTokenToData(token)
: isNullToken(token) ? null
: isIgnoreToken(token) ? ignoreTokenToData(token)
: symbalTokenToData(token)
}
function trim(str){
if(headStr(str) == " "){
return trim(tailStr(str));
}else if(lastStr(str) == " "){
return trim(initStr(str));
}else{
return str;
}
}
function parsecase(casetoken,token,ctx,otype){
var head = headStr(casetoken);
function makeSymbal(entityToken){
entityToken = trim(entityToken);
return isEmptyStr(entityToken) ? []
: [tokenToData(entityToken)];
}
function endSyncMakeSymbal(entityToken){
if(ctx.end != null){
throw new SyntaxError(entityToken+":类型"+ctx.type+"缺少结束标志"+ctx.end
+" the type "+ctx.type+" miss end flag "+ctx.end);
}
return makeSymbal(entityToken);
}
function ignoreSpaceCall(){
return ctx.type == "string" ? parsecase(tailStr(casetoken),token+head,ctx,otype)
: parsecase(tailStr(casetoken),token,ctx,otype);
}
function restartCall(){
return parsecase(tailStr(casetoken),"",{},otype);
}
function endFlag(){
if(ctx.type2=="string"){
return parsecase(tailStr(casetoken),token+head,ctx,otype);
}else if(ctx.endNum==1){
return makeSymbal(token+head).concat(restartCall());
}else{
ctx.endNum--;
return parsecase(tailStr(casetoken),token+head,ctx,otype);
}
}
function doIgnoreString(type,startFlag){
if(ctx.type==type){
if(ctx.type2=="string"){
if(ctx.end2==head){
ctx.type2=null;
}else{
}
}else if(head==startFlag){
ctx.endNum++;
}else if(head =="'"){
ctx.type2="string";
ctx.end2="'";
}else if(head=='"'){
ctx.type2="string";
ctx.end2='"';
}else{
}
}
}
doIgnoreString("array","(");
doIgnoreString("object","{");
//{key:11,key2:'33',key3:x,key4:y}
return isEmptyStr(casetoken) ? endSyncMakeSymbal(token)
: ctx.end==null&&head === "'" ? parsecase(tailStr(casetoken),token+head,{type:"string",end:"'",endNum:1},otype)
: ctx.end==null&&head === '"' ? parsecase(tailStr(casetoken),token+head,{type:"string",end:'"',endNum:1},otype)
: ctx.end==null&&head === '(' ? parsecase(tailStr(casetoken),token+head,{type:"array",end:')',endNum:1},otype)
: ctx.end==null&&head === '{' ? parsecase(tailStr(casetoken),token+head,{type:"object",end:'}',endNum:1},otype)
: otype=="array"&&ctx.end==null&&head === ":" ? makeSymbal(token).concat(restartCall())
: otype=="object"&&ctx.end==null&&head==":" ? makeSymbal(token).concat(restartCall())
: otype=="object"&&ctx.end==null&&head=="," ? makeSymbal(token).concat({"@holder@":"|"}).concat(restartCall())
: head === ctx.end ? endFlag()
: ctx.end==null&&head === "," ? makeSymbal(token).concat(restartCall())
: parsecase(tailStr(casetoken),token+head,ctx,otype);
}
function toArray(a){
return [].slice.call(a,0);
}
//=============array object type=====
function isArrayType(obj){
return obj.type == "array";
}
function isQType(obj){
return obj.type == "q";
}
function qtest(obj,test){
return obj.value(test);
}
function getArrayAll(obj){
return obj.all;
}
function getArrayVal(obj){
return obj.value;
}
function isObjectType(obj){
return obj.type =="object";
}
function getObjectVal(obj){
return obj.value;
}
function getObjectAll(obj){
return obj.all;
}
//=============
function matchcase(casetoken,scope){
function getJiegouKeyString(a){
return typeof a === "string" ? a : a.value;
}
function jiegouObject(objarr,obj){
if(obj == null)return false;
if(typeof obj !== "object")return false;
var jarr = [];
for(var i=0;i<objarr.length;i++){
var item = objarr[i];
var key = getJiegouKeyString(item[0]);
var objval = obj[key];
var rarr= domatch([item[1]],[objval],0,0,"object");
if(rarr === false)return false;
jarr=jarr.concat(rarr);
}
return jarr;
}
var casearr = parsecase(casetoken,"",{},"none");
function notListType(obj){
return typeof obj === "string" ? false
: Object.prototype.toString.call(obj)==="[object Array]" ? false
: true;
}
function domatch(casearr,args,ai,ci,otype){
ai=ai||0;
ci=ci||0;
if(casearr.length == ci) return [];
var arg = typeof args == "string" ? args.charAt(ai) : args[ai];
if(otype == "array"){
if(ci == casearr.length-1){
arg = drop(ai,args);
}
if(arg === undefined){
if(ai>=args.length)return false;
}
}
var crg = casearr[ci];
if(typeof crg !== "object"){
if(arg === crg) return domatch(casearr,args,ai+1,ci+1,otype);
else return false;
}else if(crg == null){
if(arg == null) return domatch(casearr,args,ai+1,ci+1,otype);
else return false;
}else if(isSymbalType(crg)){
if(crg.qfn != null){
if(!symbalQfn(crg.qfn,arg,scope)) return false;
}
var tr = domatch(casearr,args,ai+1,ci+1,otype)
if(tr === false) return false;
else return [arg].concat(tr);
}else if(isIgnoreType(crg)){
return domatch(casearr,args,ai+1,ci+1,otype)
}else if(isArrayType(crg)){
if(notListType(arg))return false;
var all = getArrayAll(crg);
var rarr = [];
if(all != null){
var allval = domatch([all],[arg],0,0,"none");
if(allval === false)return false;
rarr=rarr.concat(allval);
}
var subarr = domatch(getArrayVal(crg),arg,0,0,"array");
if(subarr === false) return false;
var endarr = domatch(casearr,args,ai+1,ci+1,otype);
if(endarr === false) return false;
return rarr.concat(subarr).concat(endarr);
}else if(isQType(crg)){
if(qtest(crg,arg)) return domatch(casearr,args,ai+1,ci+1,otype);
else return false;
}else if(isObjectType(crg)){
var all = getObjectAll(crg);
var oarr = [];
if(all != null){
var oarrval = domatch([all],[arg],0,0,"none");
if(oarrval === false)return false;
oarr=oarr.concat(oarrval);
}
var arr1 = jiegouObject(getObjectVal(crg),arg);
if(arr1 === false)return false;
var arr2 = domatch(casearr,args,ai+1,ci+1,otype);
return arr2 === false ? false : oarr.concat(arr1).concat(arr2);
}else{
return false;
}
}
return function(){
var args = toArray(arguments);
return args.length !== casearr.length ? false
: domatch(casearr,args);
}
}
function defun(matchObj,scope){
return function(){
var args = toArray(arguments);
for(key in matchObj){
var val = matchObj[key];
if(key == "else"){
if(typeof val !== "function") return val;
return val.apply(null,args);
}
var nargs = matchcase(key,scope).apply(null,args);
if(nargs === false) continue;
if(typeof val !== "function") return val;
return val.apply(null,nargs);
}
}
}
function symbalQfn(fnname,arg,scope){
return scope != null&&typeof scope[fnname] == "function" ? scope[fnname](arg)
: typeof defun.globalScope[fnname] == "function" ? defun.globalScope[fnname](arg)
: typeof exports[fnname] == "function" ? exports[fnname](arg)
: false;
}
// scope function
function isarray(a){
return a == null ? false
: Object.prototype.toString.call(a) == "[object Array]";
}
function isobject(a){
return a == null ? false
:Object.prototype.toString.call(a) == "[object Object]";
}
function isnumber(a){
return typeof a == "number";
}
function isstring(a){
return typeof a == "string";
}
function isdate(a){
return a == null ? false
:Object.prototype.toString.call(a) == "[object Date]";
}
defun.globalScope={
array:isarray
,object:isobject
,number:isnumber
,string:isstring
,date:isdate
};
exports.defun=defun;
defun.parsecase=parsecase;
}(this))
JavaScript
1
https://gitee.com/diqye/defun.git
git@gitee.com:diqye/defun.git
diqye
defun
defun
master

搜索帮助