UNPKG

3h-ast

Version:
1 lines 3.57 kB
const e={normalSymbols:new Set("()[]{}<>+-*/\\?~!@#$%^&=|,.:;"),twoCharacterSymbols:new Set(["&&","||","??","==",">=","<=","!=","<<",">>","++","--","**","+=","-=","*=","/=","%=","&=","^=","|=","|>","->","=>","..","//","/*","*/"]),threeCharacterSymbols:new Set(["&&=","||=","??=","===","!==","<<=",">>=","**=","...",">>>"]),fourCharacterSymbols:new Set([">>>="]),globSymbols:new Set(['"',"'","`"]),numberCharacters:new Set("0123456789"),extendedNumberCharacters:new Set(".ABCDEF"),numberSuffixes:new Set(["D","B","O","H"]),spaceCharacters:new Set(" \r\n\t")},tokenize=(t,s)=>{const n=Object.assign({},e,s),{normalSymbols:a,twoCharacterSymbols:o,threeCharacterSymbols:l,fourCharacterSymbols:r,globSymbols:h,numberCharacters:c,extendedNumberCharacters:f,numberSuffixes:i,spaceCharacters:u}=n,m=[];let p=t[0],b="",g=0,S=!1;h.has(p)?b=p:u.has(p)?g=1:c.has(p)?g=2:a.has(p)&&(m.push(p),p="");for(let e=1;e<t.length;e++){const s=t[e];if(b){p+=s,S?S=!1:s===b?(m.push(p),p="",b="",g=0):S="\\"===s;continue}if(h.has(s)){p&&m.push(p),p=s,b=s,S=!1;continue}if((2===g||3===g)&&i.has(s)){p+=s,g=3;continue}if(0===g&&!p&&a.has(s)&&m.length){const e=m[m.length-1];if(1===e.length&&o.has(e+s)){m[m.length-1]+=s;continue}if(2===e.length&&l.has(e+s)){m[m.length-1]+=s;continue}if(3===e.length&&r.has(e+s)){m[m.length-1]+=s;continue}}let n=0;if(u.has(s))n=1;else if(c.has(s)||2===g&&f.has(s)&&!p.includes("."))n=2;else if(a.has(s)){p&&m.push(p),m.push(s),p="",g=0;continue}if(g===n)p+=s;else if(0===g&&2===n){if(p+=s,p.length>1)continue}else p&&m.push(p),p=s;g=n}return p&&m.push(p),m},t=Object.assign({},e,{spanSymbols:new Map([["(",")"],["[","]"],["{","}"]]),escapeCharacters:new Map([["t","\t"],["r","\r"],["n","\n"],["\n",""],["\\","\\"],['"','"'],["'","'"],["`","`"]])}),token2ast=(e,s,n=0,a=1,o=1,l=0,r=e.length)=>{const h=Object.assign({},t,s),{normalSymbols:c,twoCharacterSymbols:f,threeCharacterSymbols:i,fourCharacterSymbols:u,globSymbols:m,numberCharacters:p,numberSuffixes:b,spaceCharacters:g,spanSymbols:S,escapeCharacters:y}=h,w=[];let C=n,x=a,d=o;for(let t=l;t<r;t++){const s=e[t];if(S.has(s)){const n=S.get(s);let a=0,o=t+1;for(;o<e.length;o++)if(e[o]!==s){if(e[o]===n){if(!a)break;a--}}else a++;if(o===e.length)throw new SyntaxError(`missing ${n} for ${s} at line ${x} column ${d}`);if(o===t+1)w.push({type:"span",start:s,stop:n,body:[],offset:C,line:x,column:d}),C++;else{const a=token2ast(e,h,C+1,x,d+1,t+1,o),l=a.ast;w.push({type:"span",start:s,stop:n,body:l,offset:C,line:x,column:d}),C=a.stopOffset,x=a.stopLine,d=a.stopColumn}t=o}else if(c.has(s)||f.has(s)||i.has(s)||u.has(s))w.push({type:"symbol",value:s,offset:C,line:x,column:d});else if(m.has(s[0])){let e=s[0],t=!1;for(let n=1;n<s.length-1;n++){const a=s[n];if(t){if(!y.has(a)){if("\r"===a&&"\n"===s[n+1])continue;throw new SyntaxError("unknown escape character: \\"+a)}e+=y.get(a),t=!1}else{if("\\"===a){t=!0;continue}e+=a}}if(t||s[s.length-1]!==s[0]||1===s.length)throw new SyntaxError(`missing corresponding ${S} at line ${x} column ${d}`);e+=s[0],w.push({type:"glob",value:e,offset:C,line:x,column:d})}else if(p.has(s[0])){let e=s.length-1;for(;e>=0&&b.has(s[e]);e--);e++,w.push({type:"number",value:s.slice(0,e),suffix:s.slice(e),offset:C,line:x,column:d})}else g.has(s[0])||w.push({type:"word",value:s,offset:C,line:x,column:d});C+=s.length;for(let e=0;e<s.length;e++)"\n"===s[e]&&x++;const n=s.lastIndexOf("\n");~n?d=s.length-n:d+=s.length}return{ast:w,stopOffset:C,stopLine:x,stopColumn:d}},parse=(e,t)=>token2ast(tokenize(e,t),t);export{t as astDefaults,parse,token2ast,tokenize,e as tokenizeDefaults};