del-js-lang 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # del-js
2
2
 
3
3
  [![version](https://img.shields.io/npm/v/del-js-lang.svg)](https://www.npmjs.com/package/del-js-lang)
4
- [![license](https://img.shields.io/github/license/polioan/zod-env)](https://opensource.org/licenses/MIT)
4
+ [![license](https://img.shields.io/github/license/polioan/del-js)](https://opensource.org/licenses/MIT)
5
5
  [![created by Ivan Polushin](https://img.shields.io/badge/created%20by-@polioan-4BBAAB.svg)](https://github.com/polioan)
6
6
 
7
7
  Dumb expression language
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var e="0.0.1";exports.DelJS=void 0,function(t){let n,r,u,a,l,i;t.version=e,function(e){e.Tokenizer="tokenizer",e.Parser="parser",e.Interpreter="interpreter",e.Stop="stop"}(n=t.ErrorKind||(t.ErrorKind={})),function(e){e.TokenizerInvalidPeek="tokenizer-invalid-peek",e.TokenizerUnexpectedCharacter="tokenizer-unexpected-character",e.TokenizerUnterminatedStringLiteral="tokenizer-unterminated-string-literal",e.ParserInvalidAdvance="parser-invalid-advance",e.ParserUnexpectedEndOfInput="parser-unexpected-end-of-input",e.ParserUnexpectedTokenInExpression="parser-unexpected-token-in-expression",e.ParserUnexpectedToken="parser-unexpected-token",e.InterpreterUnreachable="interpreter-unreachable",e.InterpreterCalledNotFunction="interpreter-called-not-function",e.InterpreterInvalidFor="interpreter-invalid-for",e.InterpreterInvalidWhile="interpreter-invalid-while",e.InterpreterInvalidIfs="interpreter-invalid-ifs",e.InterpreterInvalidReuse="interpreter-invalid-reuse",e.InterpreterRuntime="interpreter-runtime",e.Stop="stop"}(r=t.ErrorCode||(t.ErrorCode={}));class s extends Error{code;kind;constructor({message:e,cause:t,code:r}){super(e,null==t?{}:{cause:t}),this.code=r,this.kind=(()=>{for(const e of Object.values(n))if(r.startsWith(e))return e;return n.Interpreter})(),this.name="DelError"}}t.DelError=s,function(e){e.Identifier="identifier",e.String="string",e.Comma="comma",e.LParen="lparen",e.RParen="rparen",e.EOF="eof"}(u=t.TokenType||(t.TokenType={}));class o{input;pos=0;constructor(e){this.input=e}static isWhitespace(e){return" "===e||"\n"===e||"\t"===e||"\r"===e}peek(){const e=this.input[this.pos];if(null==e)throw new s({code:r.TokenizerInvalidPeek,message:"Invalid peek"});return e}advance(){this.pos++}isEOF(){return this.pos>=this.input.length}readIdentifier(){let e="";for(;!this.isEOF();){const t=this.peek();if(o.isWhitespace(t)||"("===t||")"===t||'"'===t)break;e+=t,this.advance()}if(0===e.length)throw new s({code:r.TokenizerUnexpectedCharacter,message:`Unexpected character: ${this.peek()}`});return{type:u.Identifier,value:e}}readString(){this.advance();let e="";for(;!this.isEOF()&&'"'!==this.peek();){e+=this.peek(),this.advance()}if('"'!==this.peek())throw new s({code:r.TokenizerUnterminatedStringLiteral,message:"Unterminated string literal"});return this.advance(),{type:u.String,value:e}}tokenize(){const e=[];for(;!this.isEOF();){const t=this.peek();o.isWhitespace(t)?this.advance():'"'!==t?"("!==t?")"!==t?","!==t?e.push(this.readIdentifier()):(e.push({type:u.Comma,value:null}),this.advance()):(e.push({type:u.RParen,value:null}),this.advance()):(e.push({type:u.LParen,value:null}),this.advance()):e.push(this.readString())}return e.push({type:u.EOF,value:null}),e}}t.Tokenizer=o,function(e){e.Identifier="identifier",e.String="string",e.Call="call"}(a=t.NodeType||(t.NodeType={}));class c{tokens;pos=0;constructor(e){this.tokens=e}parseExpression(){const e=this.peek();if(null==e)throw new s({code:r.ParserUnexpectedEndOfInput,message:"Unexpected end of input"});if(e.type===u.String)return this.advance(),{type:a.String,value:e.value};if(e.type===u.Identifier){this.advance();const t={type:a.Identifier,value:e.value};if(this.match(u.LParen)){const e=this.parseArguments();return{type:a.Call,value:{callee:t,args:e}}}return t}throw new s({code:r.ParserUnexpectedTokenInExpression,message:`Unexpected token: ${e.type}`})}parseArguments(){const e=[];if(this.match(u.RParen))return e;for(;;)if(e.push(this.parseExpression()),!this.match(u.Comma)){this.expect(u.RParen);break}return e}match(e){return this.peek()?.type===e&&(this.advance(),!0)}peek(){return this.tokens[this.pos]}advance(){const e=this.tokens[this.pos++];if(null==e)throw new s({code:r.ParserInvalidAdvance,message:"Invalid advance"});return e}expect(e){const t=this.peek();if(t?.type!==e)throw new s({code:r.ParserUnexpectedToken,message:`Expected ${e}, got ${t?.type??"nothing"}`});return this.advance()}parse(){const e=this.parseExpression();return this.expect(u.EOF),e}}t.Parser=c,function(e){e.String="string",e.Function="function",e.Nil="nil",e.Number="number",e.Boolean="boolean",e.Reuse="reuse",e.Table="table"}(l=t.ValueType||(t.ValueType={}));class p{parent;args;static globalEnv(){const e=new p;for(const[t,n]of Object.entries(i))t.startsWith("_")||"function"==typeof n||e.set(t.charAt(0).toUpperCase()+t.slice(1),n);return e}constructor(e,t){this.parent=e,this.args=t}values=new Map;has(e){return!!this.values.has(e)||null!=this.parent&&this.parent.has(e)}get(e){return this.values.has(e)?this.values.get(e):null!=this.parent?this.parent.get(e):{type:l.Nil,value:null}}set(e,t){this.values.set(e,t)}getArgs(){return null!=this.args?this.args:null!=this.parent?this.parent.getArgs():[]}}t.Env=p;class v{evaluate(e,t){switch(e.type){case a.String:return{type:l.String,value:e.value};case a.Identifier:return t.get(e.value);case a.Call:return this.evaluateCall(e,t);default:throw new s({code:r.InterpreterUnreachable,message:"Unreachable! node.type"})}}evaluateBlock(e,t){const n=new p(t);let r={type:l.Nil,value:null};for(const t of e.value.args)r=this.evaluate(t,n);return r}evaluateFor(e,t){const[n,u,a,i]=e.value.args;if(null==n||null==u||null==a||null==i)throw new s({code:r.InterpreterInvalidFor,message:"Invalid for"});const o=new p(t);this.evaluate(n,o);let c={type:l.Nil,value:null};for(;;){const e=this.evaluate(u,o);if(!v.isTruthy(e))break;c=this.evaluate(i,o),this.evaluate(a,o)}return c}evaluateWhile(e,t){const[n,u]=e.value.args;if(null==n||null==u)throw new s({code:r.InterpreterInvalidWhile,message:"Invalid while"});const a=new p(t);let i={type:l.Nil,value:null};for(;;){const e=this.evaluate(n,a);if(!v.isTruthy(e))break;i=this.evaluate(u,a)}return i}static isTruthy(e){if(null==e)return!1;switch(e.type){case l.String:return Boolean(e.value);case l.Function:return!0;case l.Nil:return!1;case l.Number:return Boolean(e.value);case l.Boolean:return e.value;case l.Reuse:case l.Table:return!0;default:throw new s({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}evaluateIfs(e,t){if(e.value.args.length<3)throw new s({code:r.InterpreterInvalidIfs,message:"ifs expects at least 3 arguments"});if(e.value.args.length%2==0)throw new s({code:r.InterpreterInvalidIfs,message:"Ifs expects odd number of arguments"});for(let n=0;n<e.value.args.length-1;n+=2){const r=this.evaluate(e.value.args[n],t);if(v.isTruthy(r))return this.evaluate(e.value.args[n+1],t)}return this.evaluate(e.value.args.at(-1),t)}evaluateReuse(e,t){const[n,u]=e.value.args;if(null==n||null==u)throw new s({code:r.InterpreterInvalidReuse,message:"Invalid reuse"});if(n.type!==a.String)throw new s({code:r.InterpreterInvalidReuse,message:"Invalid reuse, name must be string"});const i={type:l.Reuse,value:u};return t.set(n.value,i),{type:l.Nil,value:null}}callReuse(e,t,n){const r=new p(n,t.map(e=>this.evaluate(e,n)));return this.evaluate(e.value,r)}evaluateCall(e,t){const n=t.get(e.value.callee.value);if(n.type===l.Reuse)return this.callReuse(n,e.value.args,t);if(n.type!==l.Function)throw new s({code:r.InterpreterCalledNotFunction,message:`${e.value.callee.value} is not a function`});if("WhileDo"===e.value.callee.value)return this.evaluateWhile(e,t);if("ForDo"===e.value.callee.value)return this.evaluateFor(e,t);if("Block"===e.value.callee.value)return this.evaluateBlock(e,t);if("Reuse"===e.value.callee.value)return this.evaluateReuse(e,t);if("Ifs"===e.value.callee.value)return this.evaluateIfs(e,t);const u=e.value.args.map(e=>this.evaluate(e,t));return n.value(u,t)}}t.Interpreter=v,t.evaluate=function(e,t){const n=new o(e).tokenize(),r=new c(n).parse(),u=p.globalEnv();for(const[e,n]of Object.entries(t??{}))u.set(e,n);return(new v).evaluate(r,u)},function(t){function n(e){if(null==e)throw new s({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be defined!"});return e}function u(e){if(e.type!==l.Number)throw new s({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be number!"});return e}function a(e){if(e.type!==l.Boolean)throw new s({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be boolean!"});return e}function i(e){if(e.type!==l.String)throw new s({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be string!"});return e}function o(e){if(e.type!==l.Table)throw new s({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be table!"});return e}function c(e,t){return{type:l.Nil,value:null}}function p(e){if(!Number.isFinite(e))throw new s({code:r.InterpreterRuntime,message:"Invalid number"});return e}function h(e,t){const{value:r}=i(n(e[0])),u=Number(r);return{type:l.Number,value:p(u)}}function f(e,t){const{value:u}=i(n(e[0]));switch(u){case"true":return{type:l.Boolean,value:!0};case"false":return{type:l.Boolean,value:!1};default:throw new s({code:r.InterpreterRuntime,message:"Invalid boolean"})}}function y(e,t){const{value:r}=i(n(e[0]));return{type:l.String,value:r}}function d(e,t){const n=e[0];if(null==n)return{type:l.String,value:"(nil)"};switch(n.type){case l.String:return{type:l.String,value:n.value};case l.Function:return{type:l.String,value:"(function)"};case l.Nil:return{type:l.String,value:"(nil)"};case l.Number:case l.Boolean:return{type:l.String,value:String(n.value)};case l.Reuse:return{type:l.String,value:"(reuse)"};case l.Table:return{type:l.String,value:"(table)"};default:throw new s({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}function g(e,t){const r=n(e[0]);return{type:l.String,value:r.type}}function m(e,t){return console.info(d(e).value),{type:l.Nil,value:null}}function b(e,t){return n(e[0])}function w(e,t){const n=e[0];if(null==n)return{type:l.Number,value:0};switch(n.type){case l.String:try{return{type:l.Number,value:h([n]).value}}catch{return{type:l.Number,value:0}}case l.Function:case l.Nil:return{type:l.Number,value:0};case l.Number:return{type:l.Number,value:n.value};case l.Boolean:return{type:l.Number,value:Number(n.value)};case l.Reuse:case l.Table:return{type:l.Number,value:0};default:throw new s({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}function I(e,t){return{type:l.Boolean,value:v.isTruthy(e[0])}}function F(e,t){return{type:l.Nil,value:null}}function N(e,t){throw new s({code:r.Stop,message:"Stop"})}function S(e,t){const r=i(n(e[0])).value,u=n(e[1]);return t.set(r,{type:l.Function,value:(e,t)=>u}),{type:l.Nil,value:null}}function _(e,t){const r=i(n(e[0])).value,u=n(e[1]);let a=t.parent;for(;a;)a.values.has(r)&&a.set(r,{type:l.Function,value:(e,t)=>u}),a=a.parent;return{type:l.Nil,value:null}}function k(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value<=a.value}}function R(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value<a.value}}function x(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value>a.value}}function T(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value>=a.value}}function U(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value+a.value)}}function B(e,t){const r=a(n(e[0])),u=a(n(e[1]));return{type:l.Boolean,value:r.value&&u.value}}function E(e,t){const r=a(n(e[0])),u=a(n(e[1]));return{type:l.Boolean,value:r.value||u.value}}function A(e,t){const r=a(n(e[0]));return{type:l.Boolean,value:!r.value}}function P(e,t){const r=n(e[0]),u=n(e[1]);return{type:l.Boolean,value:r.type===u.type&&r.value===u.value}}function z(e,t){const r=n(e[0]),u=n(e[1]);return{type:l.Boolean,value:!(r.type===u.type&&r.value===u.value)}}function C(e,t){const a=u(n(e[0])),i=u(n(e[1]));if(0===i.value)throw new s({code:r.InterpreterRuntime,message:"Mod by zero"});return{type:l.Number,value:p(a.value%i.value)}}function O(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value**a.value)}}function D(e,t){const a=u(n(e[0])),i=u(n(e[1]));if(0===i.value)throw new s({code:r.InterpreterRuntime,message:"Division by zero"});return{type:l.Number,value:p(a.value/i.value)}}function V(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value*a.value)}}function W(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value-a.value)}}function L(t,n){return{type:l.String,value:e}}function q(e,t){const n=e.map(e=>i(e).value);return{type:l.String,value:n.join("")}}function $(e,t){const{value:r}=i(n(e[0]));switch(r){case"n":return{type:l.String,value:"\n"};case"t":return{type:l.String,value:"\t"};case"r":return{type:l.String,value:"\r"};case"b":return{type:l.String,value:"\b"};case"f":return{type:l.String,value:"\f"};case"v":return{type:l.String,value:"\v"};default:return{type:l.String,value:r}}}function j(e,t){return{type:l.String,value:'"'}}function M(e,t){const{value:r}=o(n(e[0]));let u=0;for(const e of r.keys())"number"==typeof e&&Number.isInteger(e)&&e>=0&&u++;return{type:l.Number,value:p(u)}}function J(e,t){const u=n(e[0]);switch(u.type){case l.String:return{type:l.Number,value:u.value.length};case l.Function:case l.Nil:case l.Number:case l.Boolean:case l.Reuse:return{type:l.Number,value:0};case l.Table:return{type:l.Number,value:M([u]).value};default:throw new s({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}function K(e,t){return{type:l.Number,value:Math.random()}}function X(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value&a.value)}}function G(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value|a.value)}}function H(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value^a.value)}}function Q(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value<<(31&a.value))}}function Y(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value>>(31&a.value))}}function Z(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value>>>0>>>(31&a.value))}}function ee(e,t){const r=u(n(e[0])).value;return t.getArgs()[r]??{type:l.Nil,value:null}}function te(e,t){return{type:l.Table,value:new Map}}function ne(e,t){const u=o(n(e[0])),a=n(e[1]);if(a.type!==l.String&&a.type!==l.Number)throw new s({code:r.InterpreterRuntime,message:"Table key must be string or number"});return u.value.get(a.value)??{type:l.Nil,value:null}}function re(e,t){const u=o(n(e[0])),a=n(e[1]),i=n(e[2]);if(a.type!==l.String&&a.type!==l.Number)throw new s({code:r.InterpreterRuntime,message:"Table key must be string or number"});return u.value.set(a.value,i),{type:l.Nil,value:null}}t._assert=n,t._asNumberValue=u,t._asBooleanValue=a,t._asStringValue=i,t._asNilValue=function(e){if(e.type!==l.Nil)throw new s({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be nil!"});return e},t._asFunctionValue=function(e){if(e.type!==l.Function)throw new s({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be function!"});return e},t._asReuseValue=function(e){if(e.type!==l.Reuse)throw new s({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be reuse!"});return e},t._asTableValue=o,t._noop=c,t.nil={type:l.Function,value:c},t._assertValidNumber=p,t._number=h,t.number={type:l.Function,value:h},t._boolean=f,t.boolean={type:l.Function,value:f},t._string=y,t.string={type:l.Function,value:y},t.noop={type:l.Function,value:c},t.block={type:l.Function,value:c},t.forDo={type:l.Function,value:c},t.whileDo={type:l.Function,value:c},t.ifs={type:l.Function,value:c},t.reuse={type:l.Function,value:c},t._toString=d,t.toString={type:l.Function,value:d},t._type=g,t.type={type:l.Function,value:g},t._print=m,t.print={type:l.Function,value:m},t._id=b,t.id={type:l.Function,value:b},t._toNumber=w,t.toNumber={type:l.Function,value:w},t._toBoolean=I,t.toBoolean={type:l.Function,value:I},t._toNil=F,t.toNil={type:l.Function,value:F},t._stop=N,t.stop={type:l.Function,value:N},t._lets=S,t.lets={type:l.Function,value:S},t._env=_,t.env={type:l.Function,value:_},t._lte=k,t.lte={type:l.Function,value:k},t._lt=R,t.lt={type:l.Function,value:R},t._gt=x,t.gt={type:l.Function,value:x},t._gte=T,t.gte={type:l.Function,value:T},t._add=U,t.add={type:l.Function,value:U},t._and=B,t.and={type:l.Function,value:B},t._or=E,t.or={type:l.Function,value:E},t._not=A,t.not={type:l.Function,value:A},t._eq=P,t.eq={type:l.Function,value:P},t._neq=z,t.neq={type:l.Function,value:z},t._mod=C,t.mod={type:l.Function,value:C},t._power=O,t.power={type:l.Function,value:O},t._div=D,t.div={type:l.Function,value:D},t._mul=V,t.mul={type:l.Function,value:V},t._sub=W,t.sub={type:l.Function,value:W},t._version=L,t.version={type:l.Function,value:L},t._concat=q,t.concat={type:l.Function,value:q},t._escape=$,t.escape={type:l.Function,value:$},t._quote=j,t.quote={type:l.Function,value:j},t._lenArr=M,t.lenArr={type:l.Function,value:M},t._len=J,t.len={type:l.Function,value:J},t._random=K,t.random={type:l.Function,value:K},t._binAnd=X,t.binAnd={type:l.Function,value:X},t._binOr=G,t.binOr={type:l.Function,value:G},t._binXor=H,t.binXor={type:l.Function,value:H},t._binLeftShift=Q,t.binLeftShift={type:l.Function,value:Q},t._binRightShift=Y,t.binRightShift={type:l.Function,value:Y},t._binUnsignedRightShift=Z,t.binUnsignedRightShift={type:l.Function,value:Z},t._arg=ee,t.arg={type:l.Function,value:ee},t._table=te,t.table={type:l.Function,value:te},t._get=ne,t.get={type:l.Function,value:ne},t._set=re,t.set={type:l.Function,value:re}}(i=t.Std||(t.Std={}))}(exports.DelJS||(exports.DelJS={}));
1
+ "use strict";var e="0.0.2";exports.DelJS=void 0,function(t){let n,a,r,u,l,i,s;t.version=e,function(e){e.Tokenizer="tokenizer",e.Parser="parser",e.Interpreter="interpreter",e.Stop="stop"}(n=t.ErrorKind||(t.ErrorKind={})),function(e){e.TokenizerInvalidPeek="tokenizer-invalid-peek",e.TokenizerUnexpectedCharacter="tokenizer-unexpected-character",e.TokenizerUnterminatedStringLiteral="tokenizer-unterminated-string-literal",e.ParserInvalidAdvance="parser-invalid-advance",e.ParserUnexpectedEndOfInput="parser-unexpected-end-of-input",e.ParserUnexpectedTokenInExpression="parser-unexpected-token-in-expression",e.ParserUnexpectedToken="parser-unexpected-token",e.InterpreterUnreachable="interpreter-unreachable",e.InterpreterCalledNotFunction="interpreter-called-not-function",e.InterpreterInvalidFor="interpreter-invalid-for",e.InterpreterInvalidWhile="interpreter-invalid-while",e.InterpreterInvalidIfs="interpreter-invalid-ifs",e.InterpreterInvalidReuse="interpreter-invalid-reuse",e.InterpreterRuntime="interpreter-runtime",e.Stop="stop"}(a=t.ErrorCode||(t.ErrorCode={}));class o extends Error{code;kind;constructor({message:e,cause:t,code:a}){super(e,null==t?{}:{cause:t}),this.code=a,this.kind=(()=>{for(const e of Object.values(n))if(a.startsWith(e))return e;return n.Interpreter})(),this.name="DelError"}}t.DelError=o,function(e){e.Identifier="identifier",e.String="string",e.Comma="comma",e.LParen="lparen",e.RParen="rparen",e.EOF="eof"}(r=t.TokenType||(t.TokenType={}));class c{input;pos=0;constructor(e){this.input=e}static isWhitespace(e){return" "===e||"\n"===e||"\t"===e||"\r"===e}peek(){const e=this.input[this.pos];if(null==e)throw new o({code:a.TokenizerInvalidPeek,message:"Invalid peek"});return e}advance(){this.pos++}isEOF(){return this.pos>=this.input.length}readIdentifier(){let e="";for(;!this.isEOF();){const t=this.peek();if(c.isWhitespace(t)||"("===t||")"===t||'"'===t)break;e+=t,this.advance()}if(0===e.length)throw new o({code:a.TokenizerUnexpectedCharacter,message:`Unexpected character: ${this.peek()}`});return{type:r.Identifier,value:e}}readString(){this.advance();let e="";for(;!this.isEOF()&&'"'!==this.peek();){e+=this.peek(),this.advance()}if('"'!==this.peek())throw new o({code:a.TokenizerUnterminatedStringLiteral,message:"Unterminated string literal"});return this.advance(),{type:r.String,value:e}}tokenize(){const e=[];for(;!this.isEOF();){const t=this.peek();c.isWhitespace(t)?this.advance():'"'!==t?"("!==t?")"!==t?","!==t?e.push(this.readIdentifier()):(e.push({type:r.Comma,value:null}),this.advance()):(e.push({type:r.RParen,value:null}),this.advance()):(e.push({type:r.LParen,value:null}),this.advance()):e.push(this.readString())}return e.push({type:r.EOF,value:null}),e}}t.Tokenizer=c,function(e){e.Identifier="identifier",e.String="string",e.Call="call"}(u=t.NodeType||(t.NodeType={}));class v{tokens;pos=0;constructor(e){this.tokens=e}parseExpression(){const e=this.peek();if(null==e)throw new o({code:a.ParserUnexpectedEndOfInput,message:"Unexpected end of input"});if(e.type===r.String)return this.advance(),{type:u.String,value:e.value};if(e.type===r.Identifier){this.advance();const t={type:u.Identifier,value:e.value};if(this.match(r.LParen)){const e=this.parseArguments();return{type:u.Call,value:{callee:t,args:e}}}return t}throw new o({code:a.ParserUnexpectedTokenInExpression,message:`Unexpected token: ${e.type}`})}parseArguments(){const e=[];if(this.match(r.RParen))return e;for(;;)if(e.push(this.parseExpression()),!this.match(r.Comma)){this.expect(r.RParen);break}return e}match(e){return this.peek()?.type===e&&(this.advance(),!0)}peek(){return this.tokens[this.pos]}advance(){const e=this.tokens[this.pos++];if(null==e)throw new o({code:a.ParserInvalidAdvance,message:"Invalid advance"});return e}expect(e){const t=this.peek();if(t?.type!==e)throw new o({code:a.ParserUnexpectedToken,message:`Expected ${e}, got ${t?.type??"nothing"}`});return this.advance()}parse(){const e=this.parseExpression();return this.expect(r.EOF),e}}t.Parser=v,function(e){e.String="string",e.Function="function",e.AsyncFunction="async-function",e.Nil="nil",e.Number="number",e.Boolean="boolean",e.Reuse="reuse",e.Table="table"}(l=t.ValueType||(t.ValueType={}));class p{parent;args;static globalEnv(){const e=new p;for(const[t,n]of Object.entries(s))t.startsWith("_")||"function"==typeof n||e.set(t.charAt(0).toUpperCase()+t.slice(1),n);return e}constructor(e,t){this.parent=e,this.args=t}values=new Map;has(e){return!!this.values.has(e)||null!=this.parent&&this.parent.has(e)}get(e){return this.values.has(e)?this.values.get(e):null!=this.parent?this.parent.get(e):{type:l.Nil,value:null}}set(e,t){this.values.set(e,t)}getArgs(){return null!=this.args?this.args:null!=this.parent?this.parent.getArgs():[]}}t.Env=p,function(e){e.Block="Block",e.ForDo="ForDo",e.WhileDo="WhileDo",e.Ifs="Ifs",e.Reuse="Reuse"}(i=t.InterpreterKeywordsLike||(t.InterpreterKeywordsLike={}));class y{evaluate(e,t){switch(e.type){case u.String:return{type:l.String,value:e.value};case u.Identifier:return t.get(e.value);case u.Call:return this.evaluateCall(e,t);default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! node.type"})}}async evaluateAsync(e,t){switch(e.type){case u.String:return{type:l.String,value:e.value};case u.Identifier:return t.get(e.value);case u.Call:return await this.evaluateCallAsync(e,t);default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! node.type"})}}evaluateBlock(e,t){const n=new p(t);let a={type:l.Nil,value:null};for(const t of e.value.args)a=this.evaluate(t,n);return a}async evaluateBlockAsync(e,t){const n=new p(t);let a={type:l.Nil,value:null};for(const t of e.value.args)a=await this.evaluateAsync(t,n);return a}evaluateFor(e,t){const[n,r,u,i]=e.value.args;if(null==n||null==r||null==u||null==i)throw new o({code:a.InterpreterInvalidFor,message:"Invalid for"});const s=new p(t);this.evaluate(n,s);let c={type:l.Nil,value:null};for(;;){const e=this.evaluate(r,s);if(!y.isTruthy(e))break;c=this.evaluate(i,s),this.evaluate(u,s)}return c}async evaluateForAsync(e,t){const[n,r,u,i]=e.value.args;if(null==n||null==r||null==u||null==i)throw new o({code:a.InterpreterInvalidFor,message:"Invalid for"});const s=new p(t);await this.evaluateAsync(n,s);let c={type:l.Nil,value:null};for(;;){const e=await this.evaluateAsync(r,s);if(!y.isTruthy(e))break;c=await this.evaluateAsync(i,s),await this.evaluateAsync(u,s)}return c}evaluateWhile(e,t){const[n,r]=e.value.args;if(null==n||null==r)throw new o({code:a.InterpreterInvalidWhile,message:"Invalid while"});const u=new p(t);let i={type:l.Nil,value:null};for(;;){const e=this.evaluate(n,u);if(!y.isTruthy(e))break;i=this.evaluate(r,u)}return i}async evaluateWhileAsync(e,t){const[n,r]=e.value.args;if(null==n||null==r)throw new o({code:a.InterpreterInvalidWhile,message:"Invalid while"});const u=new p(t);let i={type:l.Nil,value:null};for(;;){const e=await this.evaluateAsync(n,u);if(!y.isTruthy(e))break;i=await this.evaluateAsync(r,u)}return i}static isTruthy(e){if(null==e)return!1;switch(e.type){case l.String:return Boolean(e.value);case l.Function:case l.AsyncFunction:return!0;case l.Nil:return!1;case l.Number:return Boolean(e.value);case l.Boolean:return e.value;case l.Reuse:case l.Table:return!0;default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}evaluateIfs(e,t){if(e.value.args.length<3)throw new o({code:a.InterpreterInvalidIfs,message:"ifs expects at least 3 arguments"});if(e.value.args.length%2==0)throw new o({code:a.InterpreterInvalidIfs,message:"Ifs expects odd number of arguments"});for(let n=0;n<e.value.args.length-1;n+=2){const a=this.evaluate(e.value.args[n],t);if(y.isTruthy(a))return this.evaluate(e.value.args[n+1],t)}return this.evaluate(e.value.args.at(-1),t)}async evaluateIfsAsync(e,t){if(e.value.args.length<3)throw new o({code:a.InterpreterInvalidIfs,message:"ifs expects at least 3 arguments"});if(e.value.args.length%2==0)throw new o({code:a.InterpreterInvalidIfs,message:"Ifs expects odd number of arguments"});for(let n=0;n<e.value.args.length-1;n+=2){const a=await this.evaluateAsync(e.value.args[n],t);if(y.isTruthy(a)){return await this.evaluateAsync(e.value.args[n+1],t)}}return await this.evaluateAsync(e.value.args.at(-1),t)}evaluateReuse(e,t){const[n,r]=e.value.args;if(null==n||null==r)throw new o({code:a.InterpreterInvalidReuse,message:"Invalid reuse"});if(n.type!==u.String)throw new o({code:a.InterpreterInvalidReuse,message:"Invalid reuse, name must be string"});const i={type:l.Reuse,value:r};return t.set(n.value,i),{type:l.Nil,value:null}}callReuse(e,t,n){const a=new p(n,t.map(e=>this.evaluate(e,n)));return this.evaluate(e.value,a)}async callReuseAsync(e,t,n){const a=new p(n,await Promise.all(t.map(e=>this.evaluateAsync(e,n))));return await this.evaluateAsync(e.value,a)}evaluateCall(e,t){const n=t.get(e.value.callee.value);if(n.type===l.Reuse)return this.callReuse(n,e.value.args,t);if(n.type!==l.Function)throw new o({code:a.InterpreterCalledNotFunction,message:`${e.value.callee.value} is not a function`});if(e.value.callee.value===i.WhileDo)return this.evaluateWhile(e,t);if(e.value.callee.value===i.ForDo)return this.evaluateFor(e,t);if(e.value.callee.value===i.Block)return this.evaluateBlock(e,t);if(e.value.callee.value===i.Reuse)return this.evaluateReuse(e,t);if(e.value.callee.value===i.Ifs)return this.evaluateIfs(e,t);const r=e.value.args.map(e=>this.evaluate(e,t));return n.value(r,t)}async evaluateCallAsync(e,t){const n=t.get(e.value.callee.value);if(n.type===l.Reuse){return await this.callReuseAsync(n,e.value.args,t)}if(n.type!==l.Function&&n.type!==l.AsyncFunction)throw new o({code:a.InterpreterCalledNotFunction,message:`${e.value.callee.value} is not a function`});if(e.value.callee.value===i.WhileDo){return await this.evaluateWhileAsync(e,t)}if(e.value.callee.value===i.ForDo){return await this.evaluateForAsync(e,t)}if(e.value.callee.value===i.Block){return await this.evaluateBlockAsync(e,t)}if(e.value.callee.value===i.Reuse)return this.evaluateReuse(e,t);if(e.value.callee.value===i.Ifs){return await this.evaluateIfsAsync(e,t)}const r=await Promise.all(e.value.args.map(e=>this.evaluateAsync(e,t)));return await n.value(r,t)}}t.Interpreter=y,t.evaluate=function(e,t){const n=new c(e).tokenize(),a=new v(n).parse(),r=p.globalEnv();for(const[e,n]of Object.entries(t??{}))r.set(e,n);return(new y).evaluate(a,r)},t.evaluateAsync=async function(e,t){const n=new c(e).tokenize(),a=new v(n).parse(),r=p.globalEnv();for(const[e,n]of Object.entries(t??{}))r.set(e,n);const u=new y;return await u.evaluateAsync(a,r)},function(t){function n(e){if(null==e)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be defined!"});return e}function r(e){if(e.type!==l.Number)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be number!"});return e}function u(e){if(e.type!==l.Boolean)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be boolean!"});return e}function i(e){if(e.type!==l.String)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be string!"});return e}function s(e){if(e.type!==l.Table)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be table!"});return e}function c(e,t){return{type:l.Nil,value:null}}function v(e){if(!Number.isFinite(e))throw new o({code:a.InterpreterRuntime,message:"Invalid number"});return e}function p(e,t){const{value:a}=i(n(e[0])),r=Number(a);return{type:l.Number,value:v(r)}}function h(e,t){const{value:r}=i(n(e[0]));switch(r){case"true":return{type:l.Boolean,value:!0};case"false":return{type:l.Boolean,value:!1};default:throw new o({code:a.InterpreterRuntime,message:"Invalid boolean"})}}function f(e,t){const{value:a}=i(n(e[0]));return{type:l.String,value:a}}function d(e,t){const n=e[0];if(null==n)return{type:l.String,value:"(nil)"};switch(n.type){case l.String:return{type:l.String,value:n.value};case l.Function:return{type:l.String,value:"(function)"};case l.AsyncFunction:return{type:l.String,value:"(async-function)"};case l.Nil:return{type:l.String,value:"(nil)"};case l.Number:case l.Boolean:return{type:l.String,value:String(n.value)};case l.Reuse:return{type:l.String,value:"(reuse)"};case l.Table:return{type:l.String,value:"(table)"};default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}function g(e,t){const a=n(e[0]);return{type:l.String,value:a.type}}function m(e,t){return console.info(d(e).value),{type:l.Nil,value:null}}function w(e,t){return n(e[0])}function b(e,t){const n=e[0];if(null==n)return{type:l.Number,value:0};switch(n.type){case l.String:try{return{type:l.Number,value:p([n]).value}}catch{return{type:l.Number,value:0}}case l.Function:case l.AsyncFunction:case l.Nil:return{type:l.Number,value:0};case l.Number:return{type:l.Number,value:n.value};case l.Boolean:return{type:l.Number,value:Number(n.value)};case l.Reuse:case l.Table:return{type:l.Number,value:0};default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}function I(e,t){return{type:l.Boolean,value:y.isTruthy(e[0])}}function F(e,t){return{type:l.Nil,value:null}}function N(e,t){throw new o({code:a.Stop,message:"Stop"})}function k(e,t){const a=i(n(e[0])).value,r=n(e[1]);return t.set(a,{type:l.Function,value:(e,t)=>r}),{type:l.Nil,value:null}}function S(e,t){const a=i(n(e[0])).value,r=n(e[1]);let u=t.parent;for(;u;)u.values.has(a)&&u.set(a,{type:l.Function,value:(e,t)=>r}),u=u.parent;return{type:l.Nil,value:null}}function _(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value<=u.value}}function A(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value<u.value}}function R(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value>u.value}}function x(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value>=u.value}}function T(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value+u.value)}}function B(e,t){const a=u(n(e[0])),r=u(n(e[1]));return{type:l.Boolean,value:a.value&&r.value}}function U(e,t){const a=u(n(e[0])),r=u(n(e[1]));return{type:l.Boolean,value:a.value||r.value}}function E(e,t){const a=u(n(e[0]));return{type:l.Boolean,value:!a.value}}function P(e,t){const a=n(e[0]),r=n(e[1]);return{type:l.Boolean,value:a.type===r.type&&a.value===r.value}}function C(e,t){const a=n(e[0]),r=n(e[1]);return{type:l.Boolean,value:!(a.type===r.type&&a.value===r.value)}}function z(e,t){const u=r(n(e[0])),i=r(n(e[1]));if(0===i.value)throw new o({code:a.InterpreterRuntime,message:"Mod by zero"});return{type:l.Number,value:v(u.value%i.value)}}function D(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value**u.value)}}function W(e,t){const u=r(n(e[0])),i=r(n(e[1]));if(0===i.value)throw new o({code:a.InterpreterRuntime,message:"Division by zero"});return{type:l.Number,value:v(u.value/i.value)}}function O(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value*u.value)}}function V(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value-u.value)}}function L(t,n){return{type:l.String,value:e}}function q(e,t){const n=e.map(e=>i(e).value);return{type:l.String,value:n.join("")}}function $(e,t){const{value:a}=i(n(e[0]));switch(a){case"n":return{type:l.String,value:"\n"};case"t":return{type:l.String,value:"\t"};case"r":return{type:l.String,value:"\r"};case"b":return{type:l.String,value:"\b"};case"f":return{type:l.String,value:"\f"};case"v":return{type:l.String,value:"\v"};default:return{type:l.String,value:a}}}function j(e,t){return{type:l.String,value:'"'}}function K(e,t){const{value:a}=s(n(e[0]));let r=0;for(const e of a.keys())"number"==typeof e&&Number.isInteger(e)&&e>=0&&r++;return{type:l.Number,value:v(r)}}function M(e,t){const r=n(e[0]);switch(r.type){case l.String:return{type:l.Number,value:r.value.length};case l.Function:case l.AsyncFunction:case l.Nil:case l.Number:case l.Boolean:case l.Reuse:return{type:l.Number,value:0};case l.Table:return{type:l.Number,value:K([r]).value};default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}function J(e,t){return{type:l.Number,value:Math.random()}}function X(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value&u.value)}}function G(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value|u.value)}}function H(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value^u.value)}}function Q(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value<<(31&u.value))}}function Y(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value>>(31&u.value))}}function Z(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value>>>0>>>(31&u.value))}}function ee(e,t){const a=r(n(e[0])).value;return t.getArgs()[a]??{type:l.Nil,value:null}}function te(e,t){return{type:l.Table,value:new Map}}function ne(e,t){const r=s(n(e[0])),u=n(e[1]);if(u.type!==l.String&&u.type!==l.Number)throw new o({code:a.InterpreterRuntime,message:"Table key must be string or number"});return r.value.get(u.value)??{type:l.Nil,value:null}}function ae(e,t){const r=s(n(e[0])),u=n(e[1]),i=n(e[2]);if(u.type!==l.String&&u.type!==l.Number)throw new o({code:a.InterpreterRuntime,message:"Table key must be string or number"});return r.value.set(u.value,i),{type:l.Nil,value:null}}t._assert=n,t._asNumberValue=r,t._asBooleanValue=u,t._asStringValue=i,t._asNilValue=function(e){if(e.type!==l.Nil)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be nil!"});return e},t._asFunctionValue=function(e){if(e.type!==l.Function)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be function!"});return e},t._asReuseValue=function(e){if(e.type!==l.Reuse)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be reuse!"});return e},t._asTableValue=s,t._noop=c,t.nil={type:l.Function,value:c},t._assertValidNumber=v,t._number=p,t.number={type:l.Function,value:p},t._boolean=h,t.boolean={type:l.Function,value:h},t._string=f,t.string={type:l.Function,value:f},t.noop={type:l.Function,value:c},t.block={type:l.Function,value:c},t.forDo={type:l.Function,value:c},t.whileDo={type:l.Function,value:c},t.ifs={type:l.Function,value:c},t.reuse={type:l.Function,value:c},t._toString=d,t.toString={type:l.Function,value:d},t._type=g,t.type={type:l.Function,value:g},t._print=m,t.print={type:l.Function,value:m},t._id=w,t.id={type:l.Function,value:w},t._toNumber=b,t.toNumber={type:l.Function,value:b},t._toBoolean=I,t.toBoolean={type:l.Function,value:I},t._toNil=F,t.toNil={type:l.Function,value:F},t._stop=N,t.stop={type:l.Function,value:N},t._lets=k,t.lets={type:l.Function,value:k},t._env=S,t.env={type:l.Function,value:S},t._lte=_,t.lte={type:l.Function,value:_},t._lt=A,t.lt={type:l.Function,value:A},t._gt=R,t.gt={type:l.Function,value:R},t._gte=x,t.gte={type:l.Function,value:x},t._add=T,t.add={type:l.Function,value:T},t._and=B,t.and={type:l.Function,value:B},t._or=U,t.or={type:l.Function,value:U},t._not=E,t.not={type:l.Function,value:E},t._eq=P,t.eq={type:l.Function,value:P},t._neq=C,t.neq={type:l.Function,value:C},t._mod=z,t.mod={type:l.Function,value:z},t._power=D,t.power={type:l.Function,value:D},t._div=W,t.div={type:l.Function,value:W},t._mul=O,t.mul={type:l.Function,value:O},t._sub=V,t.sub={type:l.Function,value:V},t._version=L,t.version={type:l.Function,value:L},t._concat=q,t.concat={type:l.Function,value:q},t._escape=$,t.escape={type:l.Function,value:$},t._quote=j,t.quote={type:l.Function,value:j},t._lenArr=K,t.lenArr={type:l.Function,value:K},t._len=M,t.len={type:l.Function,value:M},t._random=J,t.random={type:l.Function,value:J},t._binAnd=X,t.binAnd={type:l.Function,value:X},t._binOr=G,t.binOr={type:l.Function,value:G},t._binXor=H,t.binXor={type:l.Function,value:H},t._binLeftShift=Q,t.binLeftShift={type:l.Function,value:Q},t._binRightShift=Y,t.binRightShift={type:l.Function,value:Y},t._binUnsignedRightShift=Z,t.binUnsignedRightShift={type:l.Function,value:Z},t._arg=ee,t.arg={type:l.Function,value:ee},t._table=te,t.table={type:l.Function,value:te},t._get=ne,t.get={type:l.Function,value:ne},t._set=ae,t.set={type:l.Function,value:ae}}(s=t.Std||(t.Std={}))}(exports.DelJS||(exports.DelJS={}));
package/dist/index.d.ts CHANGED
@@ -114,6 +114,7 @@ declare namespace DelJS {
114
114
  enum ValueType {
115
115
  String = "string",
116
116
  Function = "function",
117
+ AsyncFunction = "async-function",
117
118
  Nil = "nil",
118
119
  Number = "number",
119
120
  Boolean = "boolean",
@@ -128,6 +129,10 @@ declare namespace DelJS {
128
129
  type: ValueType.Function;
129
130
  value: (args: readonly Value[], env: Env) => Value;
130
131
  }
132
+ interface ValueAsyncFunction {
133
+ type: ValueType.AsyncFunction;
134
+ value: (args: readonly Value[], env: Env) => AsyncValue;
135
+ }
131
136
  interface ValueNil {
132
137
  type: ValueType.Nil;
133
138
  value: null;
@@ -148,7 +153,8 @@ declare namespace DelJS {
148
153
  type: ValueType.Table;
149
154
  value: Map<string | number, Value>;
150
155
  }
151
- type Value = ValueString | ValueFunction | ValueNil | ValueNumber | ValueBoolean | ValueReuse | ValueTable;
156
+ type Value = ValueString | ValueFunction | ValueAsyncFunction | ValueNil | ValueNumber | ValueBoolean | ValueReuse | ValueTable;
157
+ type AsyncValue = Value | Promise<Value>;
152
158
  class Env {
153
159
  readonly parent?: Env | undefined;
154
160
  readonly args?: Value[] | undefined;
@@ -160,18 +166,33 @@ declare namespace DelJS {
160
166
  set(name: string, value: Value): void;
161
167
  getArgs(): Value[];
162
168
  }
169
+ enum InterpreterKeywordsLike {
170
+ Block = "Block",
171
+ ForDo = "ForDo",
172
+ WhileDo = "WhileDo",
173
+ Ifs = "Ifs",
174
+ Reuse = "Reuse"
175
+ }
163
176
  class Interpreter {
164
177
  evaluate(node: Node, env: Env): Value;
178
+ evaluateAsync(node: Node, env: Env): Promise<Value>;
165
179
  private evaluateBlock;
180
+ private evaluateBlockAsync;
166
181
  private evaluateFor;
182
+ private evaluateForAsync;
167
183
  private evaluateWhile;
184
+ private evaluateWhileAsync;
168
185
  static isTruthy(value?: Value): boolean;
169
186
  private evaluateIfs;
187
+ private evaluateIfsAsync;
170
188
  private evaluateReuse;
171
189
  private callReuse;
190
+ private callReuseAsync;
172
191
  private evaluateCall;
192
+ private evaluateCallAsync;
173
193
  }
174
194
  function evaluate(input: string, overrideEnv?: Record<string, Value>): Value;
195
+ function evaluateAsync(input: string, overrideEnv?: Record<string, Value>): Promise<Value>;
175
196
  namespace Std {
176
197
  function _assert<T>(value: T): NonNullable<T>;
177
198
  function _asNumberValue(value: Value): ValueNumber;
@@ -1 +1 @@
1
- var DelJS=function(e){"use strict";var t="0.0.1";return e.default=void 0,function(e){let n,r,u,a,l,i;e.version=t,function(e){e.Tokenizer="tokenizer",e.Parser="parser",e.Interpreter="interpreter",e.Stop="stop"}(n=e.ErrorKind||(e.ErrorKind={})),function(e){e.TokenizerInvalidPeek="tokenizer-invalid-peek",e.TokenizerUnexpectedCharacter="tokenizer-unexpected-character",e.TokenizerUnterminatedStringLiteral="tokenizer-unterminated-string-literal",e.ParserInvalidAdvance="parser-invalid-advance",e.ParserUnexpectedEndOfInput="parser-unexpected-end-of-input",e.ParserUnexpectedTokenInExpression="parser-unexpected-token-in-expression",e.ParserUnexpectedToken="parser-unexpected-token",e.InterpreterUnreachable="interpreter-unreachable",e.InterpreterCalledNotFunction="interpreter-called-not-function",e.InterpreterInvalidFor="interpreter-invalid-for",e.InterpreterInvalidWhile="interpreter-invalid-while",e.InterpreterInvalidIfs="interpreter-invalid-ifs",e.InterpreterInvalidReuse="interpreter-invalid-reuse",e.InterpreterRuntime="interpreter-runtime",e.Stop="stop"}(r=e.ErrorCode||(e.ErrorCode={}));class o extends Error{code;kind;constructor({message:e,cause:t,code:r}){super(e,null==t?{}:{cause:t}),this.code=r,this.kind=(()=>{for(const e of Object.values(n))if(r.startsWith(e))return e;return n.Interpreter})(),this.name="DelError"}}e.DelError=o,function(e){e.Identifier="identifier",e.String="string",e.Comma="comma",e.LParen="lparen",e.RParen="rparen",e.EOF="eof"}(u=e.TokenType||(e.TokenType={}));class s{input;pos=0;constructor(e){this.input=e}static isWhitespace(e){return" "===e||"\n"===e||"\t"===e||"\r"===e}peek(){const e=this.input[this.pos];if(null==e)throw new o({code:r.TokenizerInvalidPeek,message:"Invalid peek"});return e}advance(){this.pos++}isEOF(){return this.pos>=this.input.length}readIdentifier(){let e="";for(;!this.isEOF();){const t=this.peek();if(s.isWhitespace(t)||"("===t||")"===t||'"'===t)break;e+=t,this.advance()}if(0===e.length)throw new o({code:r.TokenizerUnexpectedCharacter,message:`Unexpected character: ${this.peek()}`});return{type:u.Identifier,value:e}}readString(){this.advance();let e="";for(;!this.isEOF()&&'"'!==this.peek();){e+=this.peek(),this.advance()}if('"'!==this.peek())throw new o({code:r.TokenizerUnterminatedStringLiteral,message:"Unterminated string literal"});return this.advance(),{type:u.String,value:e}}tokenize(){const e=[];for(;!this.isEOF();){const t=this.peek();s.isWhitespace(t)?this.advance():'"'!==t?"("!==t?")"!==t?","!==t?e.push(this.readIdentifier()):(e.push({type:u.Comma,value:null}),this.advance()):(e.push({type:u.RParen,value:null}),this.advance()):(e.push({type:u.LParen,value:null}),this.advance()):e.push(this.readString())}return e.push({type:u.EOF,value:null}),e}}e.Tokenizer=s,function(e){e.Identifier="identifier",e.String="string",e.Call="call"}(a=e.NodeType||(e.NodeType={}));class c{tokens;pos=0;constructor(e){this.tokens=e}parseExpression(){const e=this.peek();if(null==e)throw new o({code:r.ParserUnexpectedEndOfInput,message:"Unexpected end of input"});if(e.type===u.String)return this.advance(),{type:a.String,value:e.value};if(e.type===u.Identifier){this.advance();const t={type:a.Identifier,value:e.value};if(this.match(u.LParen)){const e=this.parseArguments();return{type:a.Call,value:{callee:t,args:e}}}return t}throw new o({code:r.ParserUnexpectedTokenInExpression,message:`Unexpected token: ${e.type}`})}parseArguments(){const e=[];if(this.match(u.RParen))return e;for(;;)if(e.push(this.parseExpression()),!this.match(u.Comma)){this.expect(u.RParen);break}return e}match(e){return this.peek()?.type===e&&(this.advance(),!0)}peek(){return this.tokens[this.pos]}advance(){const e=this.tokens[this.pos++];if(null==e)throw new o({code:r.ParserInvalidAdvance,message:"Invalid advance"});return e}expect(e){const t=this.peek();if(t?.type!==e)throw new o({code:r.ParserUnexpectedToken,message:`Expected ${e}, got ${t?.type??"nothing"}`});return this.advance()}parse(){const e=this.parseExpression();return this.expect(u.EOF),e}}e.Parser=c,function(e){e.String="string",e.Function="function",e.Nil="nil",e.Number="number",e.Boolean="boolean",e.Reuse="reuse",e.Table="table"}(l=e.ValueType||(e.ValueType={}));class p{parent;args;static globalEnv(){const e=new p;for(const[t,n]of Object.entries(i))t.startsWith("_")||"function"==typeof n||e.set(t.charAt(0).toUpperCase()+t.slice(1),n);return e}constructor(e,t){this.parent=e,this.args=t}values=new Map;has(e){return!!this.values.has(e)||null!=this.parent&&this.parent.has(e)}get(e){return this.values.has(e)?this.values.get(e):null!=this.parent?this.parent.get(e):{type:l.Nil,value:null}}set(e,t){this.values.set(e,t)}getArgs(){return null!=this.args?this.args:null!=this.parent?this.parent.getArgs():[]}}e.Env=p;class v{evaluate(e,t){switch(e.type){case a.String:return{type:l.String,value:e.value};case a.Identifier:return t.get(e.value);case a.Call:return this.evaluateCall(e,t);default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! node.type"})}}evaluateBlock(e,t){const n=new p(t);let r={type:l.Nil,value:null};for(const t of e.value.args)r=this.evaluate(t,n);return r}evaluateFor(e,t){const[n,u,a,i]=e.value.args;if(null==n||null==u||null==a||null==i)throw new o({code:r.InterpreterInvalidFor,message:"Invalid for"});const s=new p(t);this.evaluate(n,s);let c={type:l.Nil,value:null};for(;;){const e=this.evaluate(u,s);if(!v.isTruthy(e))break;c=this.evaluate(i,s),this.evaluate(a,s)}return c}evaluateWhile(e,t){const[n,u]=e.value.args;if(null==n||null==u)throw new o({code:r.InterpreterInvalidWhile,message:"Invalid while"});const a=new p(t);let i={type:l.Nil,value:null};for(;;){const e=this.evaluate(n,a);if(!v.isTruthy(e))break;i=this.evaluate(u,a)}return i}static isTruthy(e){if(null==e)return!1;switch(e.type){case l.String:return Boolean(e.value);case l.Function:return!0;case l.Nil:return!1;case l.Number:return Boolean(e.value);case l.Boolean:return e.value;case l.Reuse:case l.Table:return!0;default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}evaluateIfs(e,t){if(e.value.args.length<3)throw new o({code:r.InterpreterInvalidIfs,message:"ifs expects at least 3 arguments"});if(e.value.args.length%2==0)throw new o({code:r.InterpreterInvalidIfs,message:"Ifs expects odd number of arguments"});for(let n=0;n<e.value.args.length-1;n+=2){const r=this.evaluate(e.value.args[n],t);if(v.isTruthy(r))return this.evaluate(e.value.args[n+1],t)}return this.evaluate(e.value.args.at(-1),t)}evaluateReuse(e,t){const[n,u]=e.value.args;if(null==n||null==u)throw new o({code:r.InterpreterInvalidReuse,message:"Invalid reuse"});if(n.type!==a.String)throw new o({code:r.InterpreterInvalidReuse,message:"Invalid reuse, name must be string"});const i={type:l.Reuse,value:u};return t.set(n.value,i),{type:l.Nil,value:null}}callReuse(e,t,n){const r=new p(n,t.map(e=>this.evaluate(e,n)));return this.evaluate(e.value,r)}evaluateCall(e,t){const n=t.get(e.value.callee.value);if(n.type===l.Reuse)return this.callReuse(n,e.value.args,t);if(n.type!==l.Function)throw new o({code:r.InterpreterCalledNotFunction,message:`${e.value.callee.value} is not a function`});if("WhileDo"===e.value.callee.value)return this.evaluateWhile(e,t);if("ForDo"===e.value.callee.value)return this.evaluateFor(e,t);if("Block"===e.value.callee.value)return this.evaluateBlock(e,t);if("Reuse"===e.value.callee.value)return this.evaluateReuse(e,t);if("Ifs"===e.value.callee.value)return this.evaluateIfs(e,t);const u=e.value.args.map(e=>this.evaluate(e,t));return n.value(u,t)}}e.Interpreter=v,e.evaluate=function(e,t){const n=new s(e).tokenize(),r=new c(n).parse(),u=p.globalEnv();for(const[e,n]of Object.entries(t??{}))u.set(e,n);return(new v).evaluate(r,u)},function(e){function n(e){if(null==e)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be defined!"});return e}function u(e){if(e.type!==l.Number)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be number!"});return e}function a(e){if(e.type!==l.Boolean)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be boolean!"});return e}function i(e){if(e.type!==l.String)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be string!"});return e}function s(e){if(e.type!==l.Table)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be table!"});return e}function c(e,t){return{type:l.Nil,value:null}}function p(e){if(!Number.isFinite(e))throw new o({code:r.InterpreterRuntime,message:"Invalid number"});return e}function f(e,t){const{value:r}=i(n(e[0])),u=Number(r);return{type:l.Number,value:p(u)}}function h(e,t){const{value:u}=i(n(e[0]));switch(u){case"true":return{type:l.Boolean,value:!0};case"false":return{type:l.Boolean,value:!1};default:throw new o({code:r.InterpreterRuntime,message:"Invalid boolean"})}}function y(e,t){const{value:r}=i(n(e[0]));return{type:l.String,value:r}}function d(e,t){const n=e[0];if(null==n)return{type:l.String,value:"(nil)"};switch(n.type){case l.String:return{type:l.String,value:n.value};case l.Function:return{type:l.String,value:"(function)"};case l.Nil:return{type:l.String,value:"(nil)"};case l.Number:case l.Boolean:return{type:l.String,value:String(n.value)};case l.Reuse:return{type:l.String,value:"(reuse)"};case l.Table:return{type:l.String,value:"(table)"};default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}function g(e,t){const r=n(e[0]);return{type:l.String,value:r.type}}function m(e,t){return console.info(d(e).value),{type:l.Nil,value:null}}function b(e,t){return n(e[0])}function w(e,t){const n=e[0];if(null==n)return{type:l.Number,value:0};switch(n.type){case l.String:try{return{type:l.Number,value:f([n]).value}}catch{return{type:l.Number,value:0}}case l.Function:case l.Nil:return{type:l.Number,value:0};case l.Number:return{type:l.Number,value:n.value};case l.Boolean:return{type:l.Number,value:Number(n.value)};case l.Reuse:case l.Table:return{type:l.Number,value:0};default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}function I(e,t){return{type:l.Boolean,value:v.isTruthy(e[0])}}function F(e,t){return{type:l.Nil,value:null}}function N(e,t){throw new o({code:r.Stop,message:"Stop"})}function S(e,t){const r=i(n(e[0])).value,u=n(e[1]);return t.set(r,{type:l.Function,value:(e,t)=>u}),{type:l.Nil,value:null}}function _(e,t){const r=i(n(e[0])).value,u=n(e[1]);let a=t.parent;for(;a;)a.values.has(r)&&a.set(r,{type:l.Function,value:(e,t)=>u}),a=a.parent;return{type:l.Nil,value:null}}function k(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value<=a.value}}function R(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value<a.value}}function x(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value>a.value}}function T(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value>=a.value}}function U(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value+a.value)}}function B(e,t){const r=a(n(e[0])),u=a(n(e[1]));return{type:l.Boolean,value:r.value&&u.value}}function E(e,t){const r=a(n(e[0])),u=a(n(e[1]));return{type:l.Boolean,value:r.value||u.value}}function A(e,t){const r=a(n(e[0]));return{type:l.Boolean,value:!r.value}}function P(e,t){const r=n(e[0]),u=n(e[1]);return{type:l.Boolean,value:r.type===u.type&&r.value===u.value}}function z(e,t){const r=n(e[0]),u=n(e[1]);return{type:l.Boolean,value:!(r.type===u.type&&r.value===u.value)}}function C(e,t){const a=u(n(e[0])),i=u(n(e[1]));if(0===i.value)throw new o({code:r.InterpreterRuntime,message:"Mod by zero"});return{type:l.Number,value:p(a.value%i.value)}}function O(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value**a.value)}}function V(e,t){const a=u(n(e[0])),i=u(n(e[1]));if(0===i.value)throw new o({code:r.InterpreterRuntime,message:"Division by zero"});return{type:l.Number,value:p(a.value/i.value)}}function W(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value*a.value)}}function D(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value-a.value)}}function L(e,n){return{type:l.String,value:t}}function q(e,t){const n=e.map(e=>i(e).value);return{type:l.String,value:n.join("")}}function $(e,t){const{value:r}=i(n(e[0]));switch(r){case"n":return{type:l.String,value:"\n"};case"t":return{type:l.String,value:"\t"};case"r":return{type:l.String,value:"\r"};case"b":return{type:l.String,value:"\b"};case"f":return{type:l.String,value:"\f"};case"v":return{type:l.String,value:"\v"};default:return{type:l.String,value:r}}}function j(e,t){return{type:l.String,value:'"'}}function M(e,t){const{value:r}=s(n(e[0]));let u=0;for(const e of r.keys())"number"==typeof e&&Number.isInteger(e)&&e>=0&&u++;return{type:l.Number,value:p(u)}}function K(e,t){const u=n(e[0]);switch(u.type){case l.String:return{type:l.Number,value:u.value.length};case l.Function:case l.Nil:case l.Number:case l.Boolean:case l.Reuse:return{type:l.Number,value:0};case l.Table:return{type:l.Number,value:M([u]).value};default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}function X(e,t){return{type:l.Number,value:Math.random()}}function J(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value&a.value)}}function G(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value|a.value)}}function H(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value^a.value)}}function Q(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value<<(31&a.value))}}function Y(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value>>(31&a.value))}}function Z(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value>>>0>>>(31&a.value))}}function ee(e,t){const r=u(n(e[0])).value;return t.getArgs()[r]??{type:l.Nil,value:null}}function te(e,t){return{type:l.Table,value:new Map}}function ne(e,t){const u=s(n(e[0])),a=n(e[1]);if(a.type!==l.String&&a.type!==l.Number)throw new o({code:r.InterpreterRuntime,message:"Table key must be string or number"});return u.value.get(a.value)??{type:l.Nil,value:null}}function re(e,t){const u=s(n(e[0])),a=n(e[1]),i=n(e[2]);if(a.type!==l.String&&a.type!==l.Number)throw new o({code:r.InterpreterRuntime,message:"Table key must be string or number"});return u.value.set(a.value,i),{type:l.Nil,value:null}}e._assert=n,e._asNumberValue=u,e._asBooleanValue=a,e._asStringValue=i,e._asNilValue=function(e){if(e.type!==l.Nil)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be nil!"});return e},e._asFunctionValue=function(e){if(e.type!==l.Function)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be function!"});return e},e._asReuseValue=function(e){if(e.type!==l.Reuse)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be reuse!"});return e},e._asTableValue=s,e._noop=c,e.nil={type:l.Function,value:c},e._assertValidNumber=p,e._number=f,e.number={type:l.Function,value:f},e._boolean=h,e.boolean={type:l.Function,value:h},e._string=y,e.string={type:l.Function,value:y},e.noop={type:l.Function,value:c},e.block={type:l.Function,value:c},e.forDo={type:l.Function,value:c},e.whileDo={type:l.Function,value:c},e.ifs={type:l.Function,value:c},e.reuse={type:l.Function,value:c},e._toString=d,e.toString={type:l.Function,value:d},e._type=g,e.type={type:l.Function,value:g},e._print=m,e.print={type:l.Function,value:m},e._id=b,e.id={type:l.Function,value:b},e._toNumber=w,e.toNumber={type:l.Function,value:w},e._toBoolean=I,e.toBoolean={type:l.Function,value:I},e._toNil=F,e.toNil={type:l.Function,value:F},e._stop=N,e.stop={type:l.Function,value:N},e._lets=S,e.lets={type:l.Function,value:S},e._env=_,e.env={type:l.Function,value:_},e._lte=k,e.lte={type:l.Function,value:k},e._lt=R,e.lt={type:l.Function,value:R},e._gt=x,e.gt={type:l.Function,value:x},e._gte=T,e.gte={type:l.Function,value:T},e._add=U,e.add={type:l.Function,value:U},e._and=B,e.and={type:l.Function,value:B},e._or=E,e.or={type:l.Function,value:E},e._not=A,e.not={type:l.Function,value:A},e._eq=P,e.eq={type:l.Function,value:P},e._neq=z,e.neq={type:l.Function,value:z},e._mod=C,e.mod={type:l.Function,value:C},e._power=O,e.power={type:l.Function,value:O},e._div=V,e.div={type:l.Function,value:V},e._mul=W,e.mul={type:l.Function,value:W},e._sub=D,e.sub={type:l.Function,value:D},e._version=L,e.version={type:l.Function,value:L},e._concat=q,e.concat={type:l.Function,value:q},e._escape=$,e.escape={type:l.Function,value:$},e._quote=j,e.quote={type:l.Function,value:j},e._lenArr=M,e.lenArr={type:l.Function,value:M},e._len=K,e.len={type:l.Function,value:K},e._random=X,e.random={type:l.Function,value:X},e._binAnd=J,e.binAnd={type:l.Function,value:J},e._binOr=G,e.binOr={type:l.Function,value:G},e._binXor=H,e.binXor={type:l.Function,value:H},e._binLeftShift=Q,e.binLeftShift={type:l.Function,value:Q},e._binRightShift=Y,e.binRightShift={type:l.Function,value:Y},e._binUnsignedRightShift=Z,e.binUnsignedRightShift={type:l.Function,value:Z},e._arg=ee,e.arg={type:l.Function,value:ee},e._table=te,e.table={type:l.Function,value:te},e._get=ne,e.get={type:l.Function,value:ne},e._set=re,e.set={type:l.Function,value:re}}(i=e.Std||(e.Std={}))}(e.default||(e.default={})),e.default}({});
1
+ var DelJS=function(e){"use strict";var t="0.0.2";return e.default=void 0,function(e){let n,a,r,u,l,i,s;e.version=t,function(e){e.Tokenizer="tokenizer",e.Parser="parser",e.Interpreter="interpreter",e.Stop="stop"}(n=e.ErrorKind||(e.ErrorKind={})),function(e){e.TokenizerInvalidPeek="tokenizer-invalid-peek",e.TokenizerUnexpectedCharacter="tokenizer-unexpected-character",e.TokenizerUnterminatedStringLiteral="tokenizer-unterminated-string-literal",e.ParserInvalidAdvance="parser-invalid-advance",e.ParserUnexpectedEndOfInput="parser-unexpected-end-of-input",e.ParserUnexpectedTokenInExpression="parser-unexpected-token-in-expression",e.ParserUnexpectedToken="parser-unexpected-token",e.InterpreterUnreachable="interpreter-unreachable",e.InterpreterCalledNotFunction="interpreter-called-not-function",e.InterpreterInvalidFor="interpreter-invalid-for",e.InterpreterInvalidWhile="interpreter-invalid-while",e.InterpreterInvalidIfs="interpreter-invalid-ifs",e.InterpreterInvalidReuse="interpreter-invalid-reuse",e.InterpreterRuntime="interpreter-runtime",e.Stop="stop"}(a=e.ErrorCode||(e.ErrorCode={}));class o extends Error{code;kind;constructor({message:e,cause:t,code:a}){super(e,null==t?{}:{cause:t}),this.code=a,this.kind=(()=>{for(const e of Object.values(n))if(a.startsWith(e))return e;return n.Interpreter})(),this.name="DelError"}}e.DelError=o,function(e){e.Identifier="identifier",e.String="string",e.Comma="comma",e.LParen="lparen",e.RParen="rparen",e.EOF="eof"}(r=e.TokenType||(e.TokenType={}));class c{input;pos=0;constructor(e){this.input=e}static isWhitespace(e){return" "===e||"\n"===e||"\t"===e||"\r"===e}peek(){const e=this.input[this.pos];if(null==e)throw new o({code:a.TokenizerInvalidPeek,message:"Invalid peek"});return e}advance(){this.pos++}isEOF(){return this.pos>=this.input.length}readIdentifier(){let e="";for(;!this.isEOF();){const t=this.peek();if(c.isWhitespace(t)||"("===t||")"===t||'"'===t)break;e+=t,this.advance()}if(0===e.length)throw new o({code:a.TokenizerUnexpectedCharacter,message:`Unexpected character: ${this.peek()}`});return{type:r.Identifier,value:e}}readString(){this.advance();let e="";for(;!this.isEOF()&&'"'!==this.peek();){e+=this.peek(),this.advance()}if('"'!==this.peek())throw new o({code:a.TokenizerUnterminatedStringLiteral,message:"Unterminated string literal"});return this.advance(),{type:r.String,value:e}}tokenize(){const e=[];for(;!this.isEOF();){const t=this.peek();c.isWhitespace(t)?this.advance():'"'!==t?"("!==t?")"!==t?","!==t?e.push(this.readIdentifier()):(e.push({type:r.Comma,value:null}),this.advance()):(e.push({type:r.RParen,value:null}),this.advance()):(e.push({type:r.LParen,value:null}),this.advance()):e.push(this.readString())}return e.push({type:r.EOF,value:null}),e}}e.Tokenizer=c,function(e){e.Identifier="identifier",e.String="string",e.Call="call"}(u=e.NodeType||(e.NodeType={}));class v{tokens;pos=0;constructor(e){this.tokens=e}parseExpression(){const e=this.peek();if(null==e)throw new o({code:a.ParserUnexpectedEndOfInput,message:"Unexpected end of input"});if(e.type===r.String)return this.advance(),{type:u.String,value:e.value};if(e.type===r.Identifier){this.advance();const t={type:u.Identifier,value:e.value};if(this.match(r.LParen)){const e=this.parseArguments();return{type:u.Call,value:{callee:t,args:e}}}return t}throw new o({code:a.ParserUnexpectedTokenInExpression,message:`Unexpected token: ${e.type}`})}parseArguments(){const e=[];if(this.match(r.RParen))return e;for(;;)if(e.push(this.parseExpression()),!this.match(r.Comma)){this.expect(r.RParen);break}return e}match(e){return this.peek()?.type===e&&(this.advance(),!0)}peek(){return this.tokens[this.pos]}advance(){const e=this.tokens[this.pos++];if(null==e)throw new o({code:a.ParserInvalidAdvance,message:"Invalid advance"});return e}expect(e){const t=this.peek();if(t?.type!==e)throw new o({code:a.ParserUnexpectedToken,message:`Expected ${e}, got ${t?.type??"nothing"}`});return this.advance()}parse(){const e=this.parseExpression();return this.expect(r.EOF),e}}e.Parser=v,function(e){e.String="string",e.Function="function",e.AsyncFunction="async-function",e.Nil="nil",e.Number="number",e.Boolean="boolean",e.Reuse="reuse",e.Table="table"}(l=e.ValueType||(e.ValueType={}));class p{parent;args;static globalEnv(){const e=new p;for(const[t,n]of Object.entries(s))t.startsWith("_")||"function"==typeof n||e.set(t.charAt(0).toUpperCase()+t.slice(1),n);return e}constructor(e,t){this.parent=e,this.args=t}values=new Map;has(e){return!!this.values.has(e)||null!=this.parent&&this.parent.has(e)}get(e){return this.values.has(e)?this.values.get(e):null!=this.parent?this.parent.get(e):{type:l.Nil,value:null}}set(e,t){this.values.set(e,t)}getArgs(){return null!=this.args?this.args:null!=this.parent?this.parent.getArgs():[]}}e.Env=p,function(e){e.Block="Block",e.ForDo="ForDo",e.WhileDo="WhileDo",e.Ifs="Ifs",e.Reuse="Reuse"}(i=e.InterpreterKeywordsLike||(e.InterpreterKeywordsLike={}));class y{evaluate(e,t){switch(e.type){case u.String:return{type:l.String,value:e.value};case u.Identifier:return t.get(e.value);case u.Call:return this.evaluateCall(e,t);default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! node.type"})}}async evaluateAsync(e,t){switch(e.type){case u.String:return{type:l.String,value:e.value};case u.Identifier:return t.get(e.value);case u.Call:return await this.evaluateCallAsync(e,t);default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! node.type"})}}evaluateBlock(e,t){const n=new p(t);let a={type:l.Nil,value:null};for(const t of e.value.args)a=this.evaluate(t,n);return a}async evaluateBlockAsync(e,t){const n=new p(t);let a={type:l.Nil,value:null};for(const t of e.value.args)a=await this.evaluateAsync(t,n);return a}evaluateFor(e,t){const[n,r,u,i]=e.value.args;if(null==n||null==r||null==u||null==i)throw new o({code:a.InterpreterInvalidFor,message:"Invalid for"});const s=new p(t);this.evaluate(n,s);let c={type:l.Nil,value:null};for(;;){const e=this.evaluate(r,s);if(!y.isTruthy(e))break;c=this.evaluate(i,s),this.evaluate(u,s)}return c}async evaluateForAsync(e,t){const[n,r,u,i]=e.value.args;if(null==n||null==r||null==u||null==i)throw new o({code:a.InterpreterInvalidFor,message:"Invalid for"});const s=new p(t);await this.evaluateAsync(n,s);let c={type:l.Nil,value:null};for(;;){const e=await this.evaluateAsync(r,s);if(!y.isTruthy(e))break;c=await this.evaluateAsync(i,s),await this.evaluateAsync(u,s)}return c}evaluateWhile(e,t){const[n,r]=e.value.args;if(null==n||null==r)throw new o({code:a.InterpreterInvalidWhile,message:"Invalid while"});const u=new p(t);let i={type:l.Nil,value:null};for(;;){const e=this.evaluate(n,u);if(!y.isTruthy(e))break;i=this.evaluate(r,u)}return i}async evaluateWhileAsync(e,t){const[n,r]=e.value.args;if(null==n||null==r)throw new o({code:a.InterpreterInvalidWhile,message:"Invalid while"});const u=new p(t);let i={type:l.Nil,value:null};for(;;){const e=await this.evaluateAsync(n,u);if(!y.isTruthy(e))break;i=await this.evaluateAsync(r,u)}return i}static isTruthy(e){if(null==e)return!1;switch(e.type){case l.String:return Boolean(e.value);case l.Function:case l.AsyncFunction:return!0;case l.Nil:return!1;case l.Number:return Boolean(e.value);case l.Boolean:return e.value;case l.Reuse:case l.Table:return!0;default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}evaluateIfs(e,t){if(e.value.args.length<3)throw new o({code:a.InterpreterInvalidIfs,message:"ifs expects at least 3 arguments"});if(e.value.args.length%2==0)throw new o({code:a.InterpreterInvalidIfs,message:"Ifs expects odd number of arguments"});for(let n=0;n<e.value.args.length-1;n+=2){const a=this.evaluate(e.value.args[n],t);if(y.isTruthy(a))return this.evaluate(e.value.args[n+1],t)}return this.evaluate(e.value.args.at(-1),t)}async evaluateIfsAsync(e,t){if(e.value.args.length<3)throw new o({code:a.InterpreterInvalidIfs,message:"ifs expects at least 3 arguments"});if(e.value.args.length%2==0)throw new o({code:a.InterpreterInvalidIfs,message:"Ifs expects odd number of arguments"});for(let n=0;n<e.value.args.length-1;n+=2){const a=await this.evaluateAsync(e.value.args[n],t);if(y.isTruthy(a)){return await this.evaluateAsync(e.value.args[n+1],t)}}return await this.evaluateAsync(e.value.args.at(-1),t)}evaluateReuse(e,t){const[n,r]=e.value.args;if(null==n||null==r)throw new o({code:a.InterpreterInvalidReuse,message:"Invalid reuse"});if(n.type!==u.String)throw new o({code:a.InterpreterInvalidReuse,message:"Invalid reuse, name must be string"});const i={type:l.Reuse,value:r};return t.set(n.value,i),{type:l.Nil,value:null}}callReuse(e,t,n){const a=new p(n,t.map(e=>this.evaluate(e,n)));return this.evaluate(e.value,a)}async callReuseAsync(e,t,n){const a=new p(n,await Promise.all(t.map(e=>this.evaluateAsync(e,n))));return await this.evaluateAsync(e.value,a)}evaluateCall(e,t){const n=t.get(e.value.callee.value);if(n.type===l.Reuse)return this.callReuse(n,e.value.args,t);if(n.type!==l.Function)throw new o({code:a.InterpreterCalledNotFunction,message:`${e.value.callee.value} is not a function`});if(e.value.callee.value===i.WhileDo)return this.evaluateWhile(e,t);if(e.value.callee.value===i.ForDo)return this.evaluateFor(e,t);if(e.value.callee.value===i.Block)return this.evaluateBlock(e,t);if(e.value.callee.value===i.Reuse)return this.evaluateReuse(e,t);if(e.value.callee.value===i.Ifs)return this.evaluateIfs(e,t);const r=e.value.args.map(e=>this.evaluate(e,t));return n.value(r,t)}async evaluateCallAsync(e,t){const n=t.get(e.value.callee.value);if(n.type===l.Reuse){return await this.callReuseAsync(n,e.value.args,t)}if(n.type!==l.Function&&n.type!==l.AsyncFunction)throw new o({code:a.InterpreterCalledNotFunction,message:`${e.value.callee.value} is not a function`});if(e.value.callee.value===i.WhileDo){return await this.evaluateWhileAsync(e,t)}if(e.value.callee.value===i.ForDo){return await this.evaluateForAsync(e,t)}if(e.value.callee.value===i.Block){return await this.evaluateBlockAsync(e,t)}if(e.value.callee.value===i.Reuse)return this.evaluateReuse(e,t);if(e.value.callee.value===i.Ifs){return await this.evaluateIfsAsync(e,t)}const r=await Promise.all(e.value.args.map(e=>this.evaluateAsync(e,t)));return await n.value(r,t)}}e.Interpreter=y,e.evaluate=function(e,t){const n=new c(e).tokenize(),a=new v(n).parse(),r=p.globalEnv();for(const[e,n]of Object.entries(t??{}))r.set(e,n);return(new y).evaluate(a,r)},e.evaluateAsync=async function(e,t){const n=new c(e).tokenize(),a=new v(n).parse(),r=p.globalEnv();for(const[e,n]of Object.entries(t??{}))r.set(e,n);const u=new y;return await u.evaluateAsync(a,r)},function(e){function n(e){if(null==e)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be defined!"});return e}function r(e){if(e.type!==l.Number)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be number!"});return e}function u(e){if(e.type!==l.Boolean)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be boolean!"});return e}function i(e){if(e.type!==l.String)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be string!"});return e}function s(e){if(e.type!==l.Table)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be table!"});return e}function c(e,t){return{type:l.Nil,value:null}}function v(e){if(!Number.isFinite(e))throw new o({code:a.InterpreterRuntime,message:"Invalid number"});return e}function p(e,t){const{value:a}=i(n(e[0])),r=Number(a);return{type:l.Number,value:v(r)}}function f(e,t){const{value:r}=i(n(e[0]));switch(r){case"true":return{type:l.Boolean,value:!0};case"false":return{type:l.Boolean,value:!1};default:throw new o({code:a.InterpreterRuntime,message:"Invalid boolean"})}}function h(e,t){const{value:a}=i(n(e[0]));return{type:l.String,value:a}}function d(e,t){const n=e[0];if(null==n)return{type:l.String,value:"(nil)"};switch(n.type){case l.String:return{type:l.String,value:n.value};case l.Function:return{type:l.String,value:"(function)"};case l.AsyncFunction:return{type:l.String,value:"(async-function)"};case l.Nil:return{type:l.String,value:"(nil)"};case l.Number:case l.Boolean:return{type:l.String,value:String(n.value)};case l.Reuse:return{type:l.String,value:"(reuse)"};case l.Table:return{type:l.String,value:"(table)"};default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}function g(e,t){const a=n(e[0]);return{type:l.String,value:a.type}}function m(e,t){return console.info(d(e).value),{type:l.Nil,value:null}}function w(e,t){return n(e[0])}function b(e,t){const n=e[0];if(null==n)return{type:l.Number,value:0};switch(n.type){case l.String:try{return{type:l.Number,value:p([n]).value}}catch{return{type:l.Number,value:0}}case l.Function:case l.AsyncFunction:case l.Nil:return{type:l.Number,value:0};case l.Number:return{type:l.Number,value:n.value};case l.Boolean:return{type:l.Number,value:Number(n.value)};case l.Reuse:case l.Table:return{type:l.Number,value:0};default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}function I(e,t){return{type:l.Boolean,value:y.isTruthy(e[0])}}function F(e,t){return{type:l.Nil,value:null}}function N(e,t){throw new o({code:a.Stop,message:"Stop"})}function k(e,t){const a=i(n(e[0])).value,r=n(e[1]);return t.set(a,{type:l.Function,value:(e,t)=>r}),{type:l.Nil,value:null}}function S(e,t){const a=i(n(e[0])).value,r=n(e[1]);let u=t.parent;for(;u;)u.values.has(a)&&u.set(a,{type:l.Function,value:(e,t)=>r}),u=u.parent;return{type:l.Nil,value:null}}function _(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value<=u.value}}function A(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value<u.value}}function R(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value>u.value}}function x(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value>=u.value}}function T(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value+u.value)}}function B(e,t){const a=u(n(e[0])),r=u(n(e[1]));return{type:l.Boolean,value:a.value&&r.value}}function U(e,t){const a=u(n(e[0])),r=u(n(e[1]));return{type:l.Boolean,value:a.value||r.value}}function E(e,t){const a=u(n(e[0]));return{type:l.Boolean,value:!a.value}}function P(e,t){const a=n(e[0]),r=n(e[1]);return{type:l.Boolean,value:a.type===r.type&&a.value===r.value}}function C(e,t){const a=n(e[0]),r=n(e[1]);return{type:l.Boolean,value:!(a.type===r.type&&a.value===r.value)}}function z(e,t){const u=r(n(e[0])),i=r(n(e[1]));if(0===i.value)throw new o({code:a.InterpreterRuntime,message:"Mod by zero"});return{type:l.Number,value:v(u.value%i.value)}}function W(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value**u.value)}}function O(e,t){const u=r(n(e[0])),i=r(n(e[1]));if(0===i.value)throw new o({code:a.InterpreterRuntime,message:"Division by zero"});return{type:l.Number,value:v(u.value/i.value)}}function D(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value*u.value)}}function V(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value-u.value)}}function L(e,n){return{type:l.String,value:t}}function q(e,t){const n=e.map(e=>i(e).value);return{type:l.String,value:n.join("")}}function $(e,t){const{value:a}=i(n(e[0]));switch(a){case"n":return{type:l.String,value:"\n"};case"t":return{type:l.String,value:"\t"};case"r":return{type:l.String,value:"\r"};case"b":return{type:l.String,value:"\b"};case"f":return{type:l.String,value:"\f"};case"v":return{type:l.String,value:"\v"};default:return{type:l.String,value:a}}}function j(e,t){return{type:l.String,value:'"'}}function K(e,t){const{value:a}=s(n(e[0]));let r=0;for(const e of a.keys())"number"==typeof e&&Number.isInteger(e)&&e>=0&&r++;return{type:l.Number,value:v(r)}}function M(e,t){const r=n(e[0]);switch(r.type){case l.String:return{type:l.Number,value:r.value.length};case l.Function:case l.AsyncFunction:case l.Nil:case l.Number:case l.Boolean:case l.Reuse:return{type:l.Number,value:0};case l.Table:return{type:l.Number,value:K([r]).value};default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}function X(e,t){return{type:l.Number,value:Math.random()}}function J(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value&u.value)}}function G(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value|u.value)}}function H(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value^u.value)}}function Q(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value<<(31&u.value))}}function Y(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value>>(31&u.value))}}function Z(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value>>>0>>>(31&u.value))}}function ee(e,t){const a=r(n(e[0])).value;return t.getArgs()[a]??{type:l.Nil,value:null}}function te(e,t){return{type:l.Table,value:new Map}}function ne(e,t){const r=s(n(e[0])),u=n(e[1]);if(u.type!==l.String&&u.type!==l.Number)throw new o({code:a.InterpreterRuntime,message:"Table key must be string or number"});return r.value.get(u.value)??{type:l.Nil,value:null}}function ae(e,t){const r=s(n(e[0])),u=n(e[1]),i=n(e[2]);if(u.type!==l.String&&u.type!==l.Number)throw new o({code:a.InterpreterRuntime,message:"Table key must be string or number"});return r.value.set(u.value,i),{type:l.Nil,value:null}}e._assert=n,e._asNumberValue=r,e._asBooleanValue=u,e._asStringValue=i,e._asNilValue=function(e){if(e.type!==l.Nil)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be nil!"});return e},e._asFunctionValue=function(e){if(e.type!==l.Function)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be function!"});return e},e._asReuseValue=function(e){if(e.type!==l.Reuse)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be reuse!"});return e},e._asTableValue=s,e._noop=c,e.nil={type:l.Function,value:c},e._assertValidNumber=v,e._number=p,e.number={type:l.Function,value:p},e._boolean=f,e.boolean={type:l.Function,value:f},e._string=h,e.string={type:l.Function,value:h},e.noop={type:l.Function,value:c},e.block={type:l.Function,value:c},e.forDo={type:l.Function,value:c},e.whileDo={type:l.Function,value:c},e.ifs={type:l.Function,value:c},e.reuse={type:l.Function,value:c},e._toString=d,e.toString={type:l.Function,value:d},e._type=g,e.type={type:l.Function,value:g},e._print=m,e.print={type:l.Function,value:m},e._id=w,e.id={type:l.Function,value:w},e._toNumber=b,e.toNumber={type:l.Function,value:b},e._toBoolean=I,e.toBoolean={type:l.Function,value:I},e._toNil=F,e.toNil={type:l.Function,value:F},e._stop=N,e.stop={type:l.Function,value:N},e._lets=k,e.lets={type:l.Function,value:k},e._env=S,e.env={type:l.Function,value:S},e._lte=_,e.lte={type:l.Function,value:_},e._lt=A,e.lt={type:l.Function,value:A},e._gt=R,e.gt={type:l.Function,value:R},e._gte=x,e.gte={type:l.Function,value:x},e._add=T,e.add={type:l.Function,value:T},e._and=B,e.and={type:l.Function,value:B},e._or=U,e.or={type:l.Function,value:U},e._not=E,e.not={type:l.Function,value:E},e._eq=P,e.eq={type:l.Function,value:P},e._neq=C,e.neq={type:l.Function,value:C},e._mod=z,e.mod={type:l.Function,value:z},e._power=W,e.power={type:l.Function,value:W},e._div=O,e.div={type:l.Function,value:O},e._mul=D,e.mul={type:l.Function,value:D},e._sub=V,e.sub={type:l.Function,value:V},e._version=L,e.version={type:l.Function,value:L},e._concat=q,e.concat={type:l.Function,value:q},e._escape=$,e.escape={type:l.Function,value:$},e._quote=j,e.quote={type:l.Function,value:j},e._lenArr=K,e.lenArr={type:l.Function,value:K},e._len=M,e.len={type:l.Function,value:M},e._random=X,e.random={type:l.Function,value:X},e._binAnd=J,e.binAnd={type:l.Function,value:J},e._binOr=G,e.binOr={type:l.Function,value:G},e._binXor=H,e.binXor={type:l.Function,value:H},e._binLeftShift=Q,e.binLeftShift={type:l.Function,value:Q},e._binRightShift=Y,e.binRightShift={type:l.Function,value:Y},e._binUnsignedRightShift=Z,e.binUnsignedRightShift={type:l.Function,value:Z},e._arg=ee,e.arg={type:l.Function,value:ee},e._table=te,e.table={type:l.Function,value:te},e._get=ne,e.get={type:l.Function,value:ne},e._set=ae,e.set={type:l.Function,value:ae}}(s=e.Std||(e.Std={}))}(e.default||(e.default={})),e.default}({});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var e,t="0.0.1";!function(e){let n,r,u,a,l,i;e.version=t,function(e){e.Tokenizer="tokenizer",e.Parser="parser",e.Interpreter="interpreter",e.Stop="stop"}(n=e.ErrorKind||(e.ErrorKind={})),function(e){e.TokenizerInvalidPeek="tokenizer-invalid-peek",e.TokenizerUnexpectedCharacter="tokenizer-unexpected-character",e.TokenizerUnterminatedStringLiteral="tokenizer-unterminated-string-literal",e.ParserInvalidAdvance="parser-invalid-advance",e.ParserUnexpectedEndOfInput="parser-unexpected-end-of-input",e.ParserUnexpectedTokenInExpression="parser-unexpected-token-in-expression",e.ParserUnexpectedToken="parser-unexpected-token",e.InterpreterUnreachable="interpreter-unreachable",e.InterpreterCalledNotFunction="interpreter-called-not-function",e.InterpreterInvalidFor="interpreter-invalid-for",e.InterpreterInvalidWhile="interpreter-invalid-while",e.InterpreterInvalidIfs="interpreter-invalid-ifs",e.InterpreterInvalidReuse="interpreter-invalid-reuse",e.InterpreterRuntime="interpreter-runtime",e.Stop="stop"}(r=e.ErrorCode||(e.ErrorCode={}));class o extends Error{code;kind;constructor({message:e,cause:t,code:r}){super(e,null==t?{}:{cause:t}),this.code=r,this.kind=(()=>{for(const e of Object.values(n))if(r.startsWith(e))return e;return n.Interpreter})(),this.name="DelError"}}e.DelError=o,function(e){e.Identifier="identifier",e.String="string",e.Comma="comma",e.LParen="lparen",e.RParen="rparen",e.EOF="eof"}(u=e.TokenType||(e.TokenType={}));class s{input;pos=0;constructor(e){this.input=e}static isWhitespace(e){return" "===e||"\n"===e||"\t"===e||"\r"===e}peek(){const e=this.input[this.pos];if(null==e)throw new o({code:r.TokenizerInvalidPeek,message:"Invalid peek"});return e}advance(){this.pos++}isEOF(){return this.pos>=this.input.length}readIdentifier(){let e="";for(;!this.isEOF();){const t=this.peek();if(s.isWhitespace(t)||"("===t||")"===t||'"'===t)break;e+=t,this.advance()}if(0===e.length)throw new o({code:r.TokenizerUnexpectedCharacter,message:`Unexpected character: ${this.peek()}`});return{type:u.Identifier,value:e}}readString(){this.advance();let e="";for(;!this.isEOF()&&'"'!==this.peek();){e+=this.peek(),this.advance()}if('"'!==this.peek())throw new o({code:r.TokenizerUnterminatedStringLiteral,message:"Unterminated string literal"});return this.advance(),{type:u.String,value:e}}tokenize(){const e=[];for(;!this.isEOF();){const t=this.peek();s.isWhitespace(t)?this.advance():'"'!==t?"("!==t?")"!==t?","!==t?e.push(this.readIdentifier()):(e.push({type:u.Comma,value:null}),this.advance()):(e.push({type:u.RParen,value:null}),this.advance()):(e.push({type:u.LParen,value:null}),this.advance()):e.push(this.readString())}return e.push({type:u.EOF,value:null}),e}}e.Tokenizer=s,function(e){e.Identifier="identifier",e.String="string",e.Call="call"}(a=e.NodeType||(e.NodeType={}));class c{tokens;pos=0;constructor(e){this.tokens=e}parseExpression(){const e=this.peek();if(null==e)throw new o({code:r.ParserUnexpectedEndOfInput,message:"Unexpected end of input"});if(e.type===u.String)return this.advance(),{type:a.String,value:e.value};if(e.type===u.Identifier){this.advance();const t={type:a.Identifier,value:e.value};if(this.match(u.LParen)){const e=this.parseArguments();return{type:a.Call,value:{callee:t,args:e}}}return t}throw new o({code:r.ParserUnexpectedTokenInExpression,message:`Unexpected token: ${e.type}`})}parseArguments(){const e=[];if(this.match(u.RParen))return e;for(;;)if(e.push(this.parseExpression()),!this.match(u.Comma)){this.expect(u.RParen);break}return e}match(e){return this.peek()?.type===e&&(this.advance(),!0)}peek(){return this.tokens[this.pos]}advance(){const e=this.tokens[this.pos++];if(null==e)throw new o({code:r.ParserInvalidAdvance,message:"Invalid advance"});return e}expect(e){const t=this.peek();if(t?.type!==e)throw new o({code:r.ParserUnexpectedToken,message:`Expected ${e}, got ${t?.type??"nothing"}`});return this.advance()}parse(){const e=this.parseExpression();return this.expect(u.EOF),e}}e.Parser=c,function(e){e.String="string",e.Function="function",e.Nil="nil",e.Number="number",e.Boolean="boolean",e.Reuse="reuse",e.Table="table"}(l=e.ValueType||(e.ValueType={}));class p{parent;args;static globalEnv(){const e=new p;for(const[t,n]of Object.entries(i))t.startsWith("_")||"function"==typeof n||e.set(t.charAt(0).toUpperCase()+t.slice(1),n);return e}constructor(e,t){this.parent=e,this.args=t}values=new Map;has(e){return!!this.values.has(e)||null!=this.parent&&this.parent.has(e)}get(e){return this.values.has(e)?this.values.get(e):null!=this.parent?this.parent.get(e):{type:l.Nil,value:null}}set(e,t){this.values.set(e,t)}getArgs(){return null!=this.args?this.args:null!=this.parent?this.parent.getArgs():[]}}e.Env=p;class v{evaluate(e,t){switch(e.type){case a.String:return{type:l.String,value:e.value};case a.Identifier:return t.get(e.value);case a.Call:return this.evaluateCall(e,t);default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! node.type"})}}evaluateBlock(e,t){const n=new p(t);let r={type:l.Nil,value:null};for(const t of e.value.args)r=this.evaluate(t,n);return r}evaluateFor(e,t){const[n,u,a,i]=e.value.args;if(null==n||null==u||null==a||null==i)throw new o({code:r.InterpreterInvalidFor,message:"Invalid for"});const s=new p(t);this.evaluate(n,s);let c={type:l.Nil,value:null};for(;;){const e=this.evaluate(u,s);if(!v.isTruthy(e))break;c=this.evaluate(i,s),this.evaluate(a,s)}return c}evaluateWhile(e,t){const[n,u]=e.value.args;if(null==n||null==u)throw new o({code:r.InterpreterInvalidWhile,message:"Invalid while"});const a=new p(t);let i={type:l.Nil,value:null};for(;;){const e=this.evaluate(n,a);if(!v.isTruthy(e))break;i=this.evaluate(u,a)}return i}static isTruthy(e){if(null==e)return!1;switch(e.type){case l.String:return Boolean(e.value);case l.Function:return!0;case l.Nil:return!1;case l.Number:return Boolean(e.value);case l.Boolean:return e.value;case l.Reuse:case l.Table:return!0;default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}evaluateIfs(e,t){if(e.value.args.length<3)throw new o({code:r.InterpreterInvalidIfs,message:"ifs expects at least 3 arguments"});if(e.value.args.length%2==0)throw new o({code:r.InterpreterInvalidIfs,message:"Ifs expects odd number of arguments"});for(let n=0;n<e.value.args.length-1;n+=2){const r=this.evaluate(e.value.args[n],t);if(v.isTruthy(r))return this.evaluate(e.value.args[n+1],t)}return this.evaluate(e.value.args.at(-1),t)}evaluateReuse(e,t){const[n,u]=e.value.args;if(null==n||null==u)throw new o({code:r.InterpreterInvalidReuse,message:"Invalid reuse"});if(n.type!==a.String)throw new o({code:r.InterpreterInvalidReuse,message:"Invalid reuse, name must be string"});const i={type:l.Reuse,value:u};return t.set(n.value,i),{type:l.Nil,value:null}}callReuse(e,t,n){const r=new p(n,t.map(e=>this.evaluate(e,n)));return this.evaluate(e.value,r)}evaluateCall(e,t){const n=t.get(e.value.callee.value);if(n.type===l.Reuse)return this.callReuse(n,e.value.args,t);if(n.type!==l.Function)throw new o({code:r.InterpreterCalledNotFunction,message:`${e.value.callee.value} is not a function`});if("WhileDo"===e.value.callee.value)return this.evaluateWhile(e,t);if("ForDo"===e.value.callee.value)return this.evaluateFor(e,t);if("Block"===e.value.callee.value)return this.evaluateBlock(e,t);if("Reuse"===e.value.callee.value)return this.evaluateReuse(e,t);if("Ifs"===e.value.callee.value)return this.evaluateIfs(e,t);const u=e.value.args.map(e=>this.evaluate(e,t));return n.value(u,t)}}e.Interpreter=v,e.evaluate=function(e,t){const n=new s(e).tokenize(),r=new c(n).parse(),u=p.globalEnv();for(const[e,n]of Object.entries(t??{}))u.set(e,n);return(new v).evaluate(r,u)},function(e){function n(e){if(null==e)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be defined!"});return e}function u(e){if(e.type!==l.Number)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be number!"});return e}function a(e){if(e.type!==l.Boolean)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be boolean!"});return e}function i(e){if(e.type!==l.String)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be string!"});return e}function s(e){if(e.type!==l.Table)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be table!"});return e}function c(e,t){return{type:l.Nil,value:null}}function p(e){if(!Number.isFinite(e))throw new o({code:r.InterpreterRuntime,message:"Invalid number"});return e}function h(e,t){const{value:r}=i(n(e[0])),u=Number(r);return{type:l.Number,value:p(u)}}function f(e,t){const{value:u}=i(n(e[0]));switch(u){case"true":return{type:l.Boolean,value:!0};case"false":return{type:l.Boolean,value:!1};default:throw new o({code:r.InterpreterRuntime,message:"Invalid boolean"})}}function y(e,t){const{value:r}=i(n(e[0]));return{type:l.String,value:r}}function d(e,t){const n=e[0];if(null==n)return{type:l.String,value:"(nil)"};switch(n.type){case l.String:return{type:l.String,value:n.value};case l.Function:return{type:l.String,value:"(function)"};case l.Nil:return{type:l.String,value:"(nil)"};case l.Number:case l.Boolean:return{type:l.String,value:String(n.value)};case l.Reuse:return{type:l.String,value:"(reuse)"};case l.Table:return{type:l.String,value:"(table)"};default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}function g(e,t){const r=n(e[0]);return{type:l.String,value:r.type}}function m(e,t){return console.info(d(e).value),{type:l.Nil,value:null}}function b(e,t){return n(e[0])}function w(e,t){const n=e[0];if(null==n)return{type:l.Number,value:0};switch(n.type){case l.String:try{return{type:l.Number,value:h([n]).value}}catch{return{type:l.Number,value:0}}case l.Function:case l.Nil:return{type:l.Number,value:0};case l.Number:return{type:l.Number,value:n.value};case l.Boolean:return{type:l.Number,value:Number(n.value)};case l.Reuse:case l.Table:return{type:l.Number,value:0};default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}function I(e,t){return{type:l.Boolean,value:v.isTruthy(e[0])}}function F(e,t){return{type:l.Nil,value:null}}function N(e,t){throw new o({code:r.Stop,message:"Stop"})}function _(e,t){const r=i(n(e[0])).value,u=n(e[1]);return t.set(r,{type:l.Function,value:(e,t)=>u}),{type:l.Nil,value:null}}function k(e,t){const r=i(n(e[0])).value,u=n(e[1]);let a=t.parent;for(;a;)a.values.has(r)&&a.set(r,{type:l.Function,value:(e,t)=>u}),a=a.parent;return{type:l.Nil,value:null}}function S(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value<=a.value}}function R(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value<a.value}}function x(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value>a.value}}function T(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Boolean,value:r.value>=a.value}}function U(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value+a.value)}}function B(e,t){const r=a(n(e[0])),u=a(n(e[1]));return{type:l.Boolean,value:r.value&&u.value}}function E(e,t){const r=a(n(e[0])),u=a(n(e[1]));return{type:l.Boolean,value:r.value||u.value}}function A(e,t){const r=a(n(e[0]));return{type:l.Boolean,value:!r.value}}function P(e,t){const r=n(e[0]),u=n(e[1]);return{type:l.Boolean,value:r.type===u.type&&r.value===u.value}}function z(e,t){const r=n(e[0]),u=n(e[1]);return{type:l.Boolean,value:!(r.type===u.type&&r.value===u.value)}}function C(e,t){const a=u(n(e[0])),i=u(n(e[1]));if(0===i.value)throw new o({code:r.InterpreterRuntime,message:"Mod by zero"});return{type:l.Number,value:p(a.value%i.value)}}function O(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value**a.value)}}function V(e,t){const a=u(n(e[0])),i=u(n(e[1]));if(0===i.value)throw new o({code:r.InterpreterRuntime,message:"Division by zero"});return{type:l.Number,value:p(a.value/i.value)}}function W(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value*a.value)}}function D(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value-a.value)}}function L(e,n){return{type:l.String,value:t}}function q(e,t){const n=e.map(e=>i(e).value);return{type:l.String,value:n.join("")}}function $(e,t){const{value:r}=i(n(e[0]));switch(r){case"n":return{type:l.String,value:"\n"};case"t":return{type:l.String,value:"\t"};case"r":return{type:l.String,value:"\r"};case"b":return{type:l.String,value:"\b"};case"f":return{type:l.String,value:"\f"};case"v":return{type:l.String,value:"\v"};default:return{type:l.String,value:r}}}function j(e,t){return{type:l.String,value:'"'}}function M(e,t){const{value:r}=s(n(e[0]));let u=0;for(const e of r.keys())"number"==typeof e&&Number.isInteger(e)&&e>=0&&u++;return{type:l.Number,value:p(u)}}function K(e,t){const u=n(e[0]);switch(u.type){case l.String:return{type:l.Number,value:u.value.length};case l.Function:case l.Nil:case l.Number:case l.Boolean:case l.Reuse:return{type:l.Number,value:0};case l.Table:return{type:l.Number,value:M([u]).value};default:throw new o({code:r.InterpreterUnreachable,message:"Unreachable! value.type"})}}function X(e,t){return{type:l.Number,value:Math.random()}}function G(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value&a.value)}}function H(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value|a.value)}}function J(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value^a.value)}}function Q(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value<<(31&a.value))}}function Y(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value>>(31&a.value))}}function Z(e,t){const r=u(n(e[0])),a=u(n(e[1]));return{type:l.Number,value:p(r.value>>>0>>>(31&a.value))}}function ee(e,t){const r=u(n(e[0])).value;return t.getArgs()[r]??{type:l.Nil,value:null}}function te(e,t){return{type:l.Table,value:new Map}}function ne(e,t){const u=s(n(e[0])),a=n(e[1]);if(a.type!==l.String&&a.type!==l.Number)throw new o({code:r.InterpreterRuntime,message:"Table key must be string or number"});return u.value.get(a.value)??{type:l.Nil,value:null}}function re(e,t){const u=s(n(e[0])),a=n(e[1]),i=n(e[2]);if(a.type!==l.String&&a.type!==l.Number)throw new o({code:r.InterpreterRuntime,message:"Table key must be string or number"});return u.value.set(a.value,i),{type:l.Nil,value:null}}e._assert=n,e._asNumberValue=u,e._asBooleanValue=a,e._asStringValue=i,e._asNilValue=function(e){if(e.type!==l.Nil)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be nil!"});return e},e._asFunctionValue=function(e){if(e.type!==l.Function)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be function!"});return e},e._asReuseValue=function(e){if(e.type!==l.Reuse)throw new o({code:r.InterpreterRuntime,message:"Assertion failed, value expected to be reuse!"});return e},e._asTableValue=s,e._noop=c,e.nil={type:l.Function,value:c},e._assertValidNumber=p,e._number=h,e.number={type:l.Function,value:h},e._boolean=f,e.boolean={type:l.Function,value:f},e._string=y,e.string={type:l.Function,value:y},e.noop={type:l.Function,value:c},e.block={type:l.Function,value:c},e.forDo={type:l.Function,value:c},e.whileDo={type:l.Function,value:c},e.ifs={type:l.Function,value:c},e.reuse={type:l.Function,value:c},e._toString=d,e.toString={type:l.Function,value:d},e._type=g,e.type={type:l.Function,value:g},e._print=m,e.print={type:l.Function,value:m},e._id=b,e.id={type:l.Function,value:b},e._toNumber=w,e.toNumber={type:l.Function,value:w},e._toBoolean=I,e.toBoolean={type:l.Function,value:I},e._toNil=F,e.toNil={type:l.Function,value:F},e._stop=N,e.stop={type:l.Function,value:N},e._lets=_,e.lets={type:l.Function,value:_},e._env=k,e.env={type:l.Function,value:k},e._lte=S,e.lte={type:l.Function,value:S},e._lt=R,e.lt={type:l.Function,value:R},e._gt=x,e.gt={type:l.Function,value:x},e._gte=T,e.gte={type:l.Function,value:T},e._add=U,e.add={type:l.Function,value:U},e._and=B,e.and={type:l.Function,value:B},e._or=E,e.or={type:l.Function,value:E},e._not=A,e.not={type:l.Function,value:A},e._eq=P,e.eq={type:l.Function,value:P},e._neq=z,e.neq={type:l.Function,value:z},e._mod=C,e.mod={type:l.Function,value:C},e._power=O,e.power={type:l.Function,value:O},e._div=V,e.div={type:l.Function,value:V},e._mul=W,e.mul={type:l.Function,value:W},e._sub=D,e.sub={type:l.Function,value:D},e._version=L,e.version={type:l.Function,value:L},e._concat=q,e.concat={type:l.Function,value:q},e._escape=$,e.escape={type:l.Function,value:$},e._quote=j,e.quote={type:l.Function,value:j},e._lenArr=M,e.lenArr={type:l.Function,value:M},e._len=K,e.len={type:l.Function,value:K},e._random=X,e.random={type:l.Function,value:X},e._binAnd=G,e.binAnd={type:l.Function,value:G},e._binOr=H,e.binOr={type:l.Function,value:H},e._binXor=J,e.binXor={type:l.Function,value:J},e._binLeftShift=Q,e.binLeftShift={type:l.Function,value:Q},e._binRightShift=Y,e.binRightShift={type:l.Function,value:Y},e._binUnsignedRightShift=Z,e.binUnsignedRightShift={type:l.Function,value:Z},e._arg=ee,e.arg={type:l.Function,value:ee},e._table=te,e.table={type:l.Function,value:te},e._get=ne,e.get={type:l.Function,value:ne},e._set=re,e.set={type:l.Function,value:re}}(i=e.Std||(e.Std={}))}(e||(e={}));export{e as DelJS};
1
+ var e,t="0.0.2";!function(e){let n,a,r,u,l,i,s;e.version=t,function(e){e.Tokenizer="tokenizer",e.Parser="parser",e.Interpreter="interpreter",e.Stop="stop"}(n=e.ErrorKind||(e.ErrorKind={})),function(e){e.TokenizerInvalidPeek="tokenizer-invalid-peek",e.TokenizerUnexpectedCharacter="tokenizer-unexpected-character",e.TokenizerUnterminatedStringLiteral="tokenizer-unterminated-string-literal",e.ParserInvalidAdvance="parser-invalid-advance",e.ParserUnexpectedEndOfInput="parser-unexpected-end-of-input",e.ParserUnexpectedTokenInExpression="parser-unexpected-token-in-expression",e.ParserUnexpectedToken="parser-unexpected-token",e.InterpreterUnreachable="interpreter-unreachable",e.InterpreterCalledNotFunction="interpreter-called-not-function",e.InterpreterInvalidFor="interpreter-invalid-for",e.InterpreterInvalidWhile="interpreter-invalid-while",e.InterpreterInvalidIfs="interpreter-invalid-ifs",e.InterpreterInvalidReuse="interpreter-invalid-reuse",e.InterpreterRuntime="interpreter-runtime",e.Stop="stop"}(a=e.ErrorCode||(e.ErrorCode={}));class o extends Error{code;kind;constructor({message:e,cause:t,code:a}){super(e,null==t?{}:{cause:t}),this.code=a,this.kind=(()=>{for(const e of Object.values(n))if(a.startsWith(e))return e;return n.Interpreter})(),this.name="DelError"}}e.DelError=o,function(e){e.Identifier="identifier",e.String="string",e.Comma="comma",e.LParen="lparen",e.RParen="rparen",e.EOF="eof"}(r=e.TokenType||(e.TokenType={}));class c{input;pos=0;constructor(e){this.input=e}static isWhitespace(e){return" "===e||"\n"===e||"\t"===e||"\r"===e}peek(){const e=this.input[this.pos];if(null==e)throw new o({code:a.TokenizerInvalidPeek,message:"Invalid peek"});return e}advance(){this.pos++}isEOF(){return this.pos>=this.input.length}readIdentifier(){let e="";for(;!this.isEOF();){const t=this.peek();if(c.isWhitespace(t)||"("===t||")"===t||'"'===t)break;e+=t,this.advance()}if(0===e.length)throw new o({code:a.TokenizerUnexpectedCharacter,message:`Unexpected character: ${this.peek()}`});return{type:r.Identifier,value:e}}readString(){this.advance();let e="";for(;!this.isEOF()&&'"'!==this.peek();){e+=this.peek(),this.advance()}if('"'!==this.peek())throw new o({code:a.TokenizerUnterminatedStringLiteral,message:"Unterminated string literal"});return this.advance(),{type:r.String,value:e}}tokenize(){const e=[];for(;!this.isEOF();){const t=this.peek();c.isWhitespace(t)?this.advance():'"'!==t?"("!==t?")"!==t?","!==t?e.push(this.readIdentifier()):(e.push({type:r.Comma,value:null}),this.advance()):(e.push({type:r.RParen,value:null}),this.advance()):(e.push({type:r.LParen,value:null}),this.advance()):e.push(this.readString())}return e.push({type:r.EOF,value:null}),e}}e.Tokenizer=c,function(e){e.Identifier="identifier",e.String="string",e.Call="call"}(u=e.NodeType||(e.NodeType={}));class v{tokens;pos=0;constructor(e){this.tokens=e}parseExpression(){const e=this.peek();if(null==e)throw new o({code:a.ParserUnexpectedEndOfInput,message:"Unexpected end of input"});if(e.type===r.String)return this.advance(),{type:u.String,value:e.value};if(e.type===r.Identifier){this.advance();const t={type:u.Identifier,value:e.value};if(this.match(r.LParen)){const e=this.parseArguments();return{type:u.Call,value:{callee:t,args:e}}}return t}throw new o({code:a.ParserUnexpectedTokenInExpression,message:`Unexpected token: ${e.type}`})}parseArguments(){const e=[];if(this.match(r.RParen))return e;for(;;)if(e.push(this.parseExpression()),!this.match(r.Comma)){this.expect(r.RParen);break}return e}match(e){return this.peek()?.type===e&&(this.advance(),!0)}peek(){return this.tokens[this.pos]}advance(){const e=this.tokens[this.pos++];if(null==e)throw new o({code:a.ParserInvalidAdvance,message:"Invalid advance"});return e}expect(e){const t=this.peek();if(t?.type!==e)throw new o({code:a.ParserUnexpectedToken,message:`Expected ${e}, got ${t?.type??"nothing"}`});return this.advance()}parse(){const e=this.parseExpression();return this.expect(r.EOF),e}}e.Parser=v,function(e){e.String="string",e.Function="function",e.AsyncFunction="async-function",e.Nil="nil",e.Number="number",e.Boolean="boolean",e.Reuse="reuse",e.Table="table"}(l=e.ValueType||(e.ValueType={}));class p{parent;args;static globalEnv(){const e=new p;for(const[t,n]of Object.entries(s))t.startsWith("_")||"function"==typeof n||e.set(t.charAt(0).toUpperCase()+t.slice(1),n);return e}constructor(e,t){this.parent=e,this.args=t}values=new Map;has(e){return!!this.values.has(e)||null!=this.parent&&this.parent.has(e)}get(e){return this.values.has(e)?this.values.get(e):null!=this.parent?this.parent.get(e):{type:l.Nil,value:null}}set(e,t){this.values.set(e,t)}getArgs(){return null!=this.args?this.args:null!=this.parent?this.parent.getArgs():[]}}e.Env=p,function(e){e.Block="Block",e.ForDo="ForDo",e.WhileDo="WhileDo",e.Ifs="Ifs",e.Reuse="Reuse"}(i=e.InterpreterKeywordsLike||(e.InterpreterKeywordsLike={}));class y{evaluate(e,t){switch(e.type){case u.String:return{type:l.String,value:e.value};case u.Identifier:return t.get(e.value);case u.Call:return this.evaluateCall(e,t);default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! node.type"})}}async evaluateAsync(e,t){switch(e.type){case u.String:return{type:l.String,value:e.value};case u.Identifier:return t.get(e.value);case u.Call:return await this.evaluateCallAsync(e,t);default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! node.type"})}}evaluateBlock(e,t){const n=new p(t);let a={type:l.Nil,value:null};for(const t of e.value.args)a=this.evaluate(t,n);return a}async evaluateBlockAsync(e,t){const n=new p(t);let a={type:l.Nil,value:null};for(const t of e.value.args)a=await this.evaluateAsync(t,n);return a}evaluateFor(e,t){const[n,r,u,i]=e.value.args;if(null==n||null==r||null==u||null==i)throw new o({code:a.InterpreterInvalidFor,message:"Invalid for"});const s=new p(t);this.evaluate(n,s);let c={type:l.Nil,value:null};for(;;){const e=this.evaluate(r,s);if(!y.isTruthy(e))break;c=this.evaluate(i,s),this.evaluate(u,s)}return c}async evaluateForAsync(e,t){const[n,r,u,i]=e.value.args;if(null==n||null==r||null==u||null==i)throw new o({code:a.InterpreterInvalidFor,message:"Invalid for"});const s=new p(t);await this.evaluateAsync(n,s);let c={type:l.Nil,value:null};for(;;){const e=await this.evaluateAsync(r,s);if(!y.isTruthy(e))break;c=await this.evaluateAsync(i,s),await this.evaluateAsync(u,s)}return c}evaluateWhile(e,t){const[n,r]=e.value.args;if(null==n||null==r)throw new o({code:a.InterpreterInvalidWhile,message:"Invalid while"});const u=new p(t);let i={type:l.Nil,value:null};for(;;){const e=this.evaluate(n,u);if(!y.isTruthy(e))break;i=this.evaluate(r,u)}return i}async evaluateWhileAsync(e,t){const[n,r]=e.value.args;if(null==n||null==r)throw new o({code:a.InterpreterInvalidWhile,message:"Invalid while"});const u=new p(t);let i={type:l.Nil,value:null};for(;;){const e=await this.evaluateAsync(n,u);if(!y.isTruthy(e))break;i=await this.evaluateAsync(r,u)}return i}static isTruthy(e){if(null==e)return!1;switch(e.type){case l.String:return Boolean(e.value);case l.Function:case l.AsyncFunction:return!0;case l.Nil:return!1;case l.Number:return Boolean(e.value);case l.Boolean:return e.value;case l.Reuse:case l.Table:return!0;default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}evaluateIfs(e,t){if(e.value.args.length<3)throw new o({code:a.InterpreterInvalidIfs,message:"ifs expects at least 3 arguments"});if(e.value.args.length%2==0)throw new o({code:a.InterpreterInvalidIfs,message:"Ifs expects odd number of arguments"});for(let n=0;n<e.value.args.length-1;n+=2){const a=this.evaluate(e.value.args[n],t);if(y.isTruthy(a))return this.evaluate(e.value.args[n+1],t)}return this.evaluate(e.value.args.at(-1),t)}async evaluateIfsAsync(e,t){if(e.value.args.length<3)throw new o({code:a.InterpreterInvalidIfs,message:"ifs expects at least 3 arguments"});if(e.value.args.length%2==0)throw new o({code:a.InterpreterInvalidIfs,message:"Ifs expects odd number of arguments"});for(let n=0;n<e.value.args.length-1;n+=2){const a=await this.evaluateAsync(e.value.args[n],t);if(y.isTruthy(a)){return await this.evaluateAsync(e.value.args[n+1],t)}}return await this.evaluateAsync(e.value.args.at(-1),t)}evaluateReuse(e,t){const[n,r]=e.value.args;if(null==n||null==r)throw new o({code:a.InterpreterInvalidReuse,message:"Invalid reuse"});if(n.type!==u.String)throw new o({code:a.InterpreterInvalidReuse,message:"Invalid reuse, name must be string"});const i={type:l.Reuse,value:r};return t.set(n.value,i),{type:l.Nil,value:null}}callReuse(e,t,n){const a=new p(n,t.map(e=>this.evaluate(e,n)));return this.evaluate(e.value,a)}async callReuseAsync(e,t,n){const a=new p(n,await Promise.all(t.map(e=>this.evaluateAsync(e,n))));return await this.evaluateAsync(e.value,a)}evaluateCall(e,t){const n=t.get(e.value.callee.value);if(n.type===l.Reuse)return this.callReuse(n,e.value.args,t);if(n.type!==l.Function)throw new o({code:a.InterpreterCalledNotFunction,message:`${e.value.callee.value} is not a function`});if(e.value.callee.value===i.WhileDo)return this.evaluateWhile(e,t);if(e.value.callee.value===i.ForDo)return this.evaluateFor(e,t);if(e.value.callee.value===i.Block)return this.evaluateBlock(e,t);if(e.value.callee.value===i.Reuse)return this.evaluateReuse(e,t);if(e.value.callee.value===i.Ifs)return this.evaluateIfs(e,t);const r=e.value.args.map(e=>this.evaluate(e,t));return n.value(r,t)}async evaluateCallAsync(e,t){const n=t.get(e.value.callee.value);if(n.type===l.Reuse){return await this.callReuseAsync(n,e.value.args,t)}if(n.type!==l.Function&&n.type!==l.AsyncFunction)throw new o({code:a.InterpreterCalledNotFunction,message:`${e.value.callee.value} is not a function`});if(e.value.callee.value===i.WhileDo){return await this.evaluateWhileAsync(e,t)}if(e.value.callee.value===i.ForDo){return await this.evaluateForAsync(e,t)}if(e.value.callee.value===i.Block){return await this.evaluateBlockAsync(e,t)}if(e.value.callee.value===i.Reuse)return this.evaluateReuse(e,t);if(e.value.callee.value===i.Ifs){return await this.evaluateIfsAsync(e,t)}const r=await Promise.all(e.value.args.map(e=>this.evaluateAsync(e,t)));return await n.value(r,t)}}e.Interpreter=y,e.evaluate=function(e,t){const n=new c(e).tokenize(),a=new v(n).parse(),r=p.globalEnv();for(const[e,n]of Object.entries(t??{}))r.set(e,n);return(new y).evaluate(a,r)},e.evaluateAsync=async function(e,t){const n=new c(e).tokenize(),a=new v(n).parse(),r=p.globalEnv();for(const[e,n]of Object.entries(t??{}))r.set(e,n);const u=new y;return await u.evaluateAsync(a,r)},function(e){function n(e){if(null==e)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be defined!"});return e}function r(e){if(e.type!==l.Number)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be number!"});return e}function u(e){if(e.type!==l.Boolean)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be boolean!"});return e}function i(e){if(e.type!==l.String)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be string!"});return e}function s(e){if(e.type!==l.Table)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be table!"});return e}function c(e,t){return{type:l.Nil,value:null}}function v(e){if(!Number.isFinite(e))throw new o({code:a.InterpreterRuntime,message:"Invalid number"});return e}function p(e,t){const{value:a}=i(n(e[0])),r=Number(a);return{type:l.Number,value:v(r)}}function h(e,t){const{value:r}=i(n(e[0]));switch(r){case"true":return{type:l.Boolean,value:!0};case"false":return{type:l.Boolean,value:!1};default:throw new o({code:a.InterpreterRuntime,message:"Invalid boolean"})}}function f(e,t){const{value:a}=i(n(e[0]));return{type:l.String,value:a}}function d(e,t){const n=e[0];if(null==n)return{type:l.String,value:"(nil)"};switch(n.type){case l.String:return{type:l.String,value:n.value};case l.Function:return{type:l.String,value:"(function)"};case l.AsyncFunction:return{type:l.String,value:"(async-function)"};case l.Nil:return{type:l.String,value:"(nil)"};case l.Number:case l.Boolean:return{type:l.String,value:String(n.value)};case l.Reuse:return{type:l.String,value:"(reuse)"};case l.Table:return{type:l.String,value:"(table)"};default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}function g(e,t){const a=n(e[0]);return{type:l.String,value:a.type}}function m(e,t){return console.info(d(e).value),{type:l.Nil,value:null}}function w(e,t){return n(e[0])}function b(e,t){const n=e[0];if(null==n)return{type:l.Number,value:0};switch(n.type){case l.String:try{return{type:l.Number,value:p([n]).value}}catch{return{type:l.Number,value:0}}case l.Function:case l.AsyncFunction:case l.Nil:return{type:l.Number,value:0};case l.Number:return{type:l.Number,value:n.value};case l.Boolean:return{type:l.Number,value:Number(n.value)};case l.Reuse:case l.Table:return{type:l.Number,value:0};default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}function I(e,t){return{type:l.Boolean,value:y.isTruthy(e[0])}}function F(e,t){return{type:l.Nil,value:null}}function N(e,t){throw new o({code:a.Stop,message:"Stop"})}function k(e,t){const a=i(n(e[0])).value,r=n(e[1]);return t.set(a,{type:l.Function,value:(e,t)=>r}),{type:l.Nil,value:null}}function S(e,t){const a=i(n(e[0])).value,r=n(e[1]);let u=t.parent;for(;u;)u.values.has(a)&&u.set(a,{type:l.Function,value:(e,t)=>r}),u=u.parent;return{type:l.Nil,value:null}}function _(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value<=u.value}}function A(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value<u.value}}function R(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value>u.value}}function x(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Boolean,value:a.value>=u.value}}function T(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value+u.value)}}function B(e,t){const a=u(n(e[0])),r=u(n(e[1]));return{type:l.Boolean,value:a.value&&r.value}}function U(e,t){const a=u(n(e[0])),r=u(n(e[1]));return{type:l.Boolean,value:a.value||r.value}}function E(e,t){const a=u(n(e[0]));return{type:l.Boolean,value:!a.value}}function P(e,t){const a=n(e[0]),r=n(e[1]);return{type:l.Boolean,value:a.type===r.type&&a.value===r.value}}function C(e,t){const a=n(e[0]),r=n(e[1]);return{type:l.Boolean,value:!(a.type===r.type&&a.value===r.value)}}function z(e,t){const u=r(n(e[0])),i=r(n(e[1]));if(0===i.value)throw new o({code:a.InterpreterRuntime,message:"Mod by zero"});return{type:l.Number,value:v(u.value%i.value)}}function W(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value**u.value)}}function O(e,t){const u=r(n(e[0])),i=r(n(e[1]));if(0===i.value)throw new o({code:a.InterpreterRuntime,message:"Division by zero"});return{type:l.Number,value:v(u.value/i.value)}}function D(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value*u.value)}}function V(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value-u.value)}}function L(e,n){return{type:l.String,value:t}}function q(e,t){const n=e.map(e=>i(e).value);return{type:l.String,value:n.join("")}}function $(e,t){const{value:a}=i(n(e[0]));switch(a){case"n":return{type:l.String,value:"\n"};case"t":return{type:l.String,value:"\t"};case"r":return{type:l.String,value:"\r"};case"b":return{type:l.String,value:"\b"};case"f":return{type:l.String,value:"\f"};case"v":return{type:l.String,value:"\v"};default:return{type:l.String,value:a}}}function j(e,t){return{type:l.String,value:'"'}}function K(e,t){const{value:a}=s(n(e[0]));let r=0;for(const e of a.keys())"number"==typeof e&&Number.isInteger(e)&&e>=0&&r++;return{type:l.Number,value:v(r)}}function M(e,t){const r=n(e[0]);switch(r.type){case l.String:return{type:l.Number,value:r.value.length};case l.Function:case l.AsyncFunction:case l.Nil:case l.Number:case l.Boolean:case l.Reuse:return{type:l.Number,value:0};case l.Table:return{type:l.Number,value:K([r]).value};default:throw new o({code:a.InterpreterUnreachable,message:"Unreachable! value.type"})}}function X(e,t){return{type:l.Number,value:Math.random()}}function G(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value&u.value)}}function H(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value|u.value)}}function J(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value^u.value)}}function Q(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value<<(31&u.value))}}function Y(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value>>(31&u.value))}}function Z(e,t){const a=r(n(e[0])),u=r(n(e[1]));return{type:l.Number,value:v(a.value>>>0>>>(31&u.value))}}function ee(e,t){const a=r(n(e[0])).value;return t.getArgs()[a]??{type:l.Nil,value:null}}function te(e,t){return{type:l.Table,value:new Map}}function ne(e,t){const r=s(n(e[0])),u=n(e[1]);if(u.type!==l.String&&u.type!==l.Number)throw new o({code:a.InterpreterRuntime,message:"Table key must be string or number"});return r.value.get(u.value)??{type:l.Nil,value:null}}function ae(e,t){const r=s(n(e[0])),u=n(e[1]),i=n(e[2]);if(u.type!==l.String&&u.type!==l.Number)throw new o({code:a.InterpreterRuntime,message:"Table key must be string or number"});return r.value.set(u.value,i),{type:l.Nil,value:null}}e._assert=n,e._asNumberValue=r,e._asBooleanValue=u,e._asStringValue=i,e._asNilValue=function(e){if(e.type!==l.Nil)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be nil!"});return e},e._asFunctionValue=function(e){if(e.type!==l.Function)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be function!"});return e},e._asReuseValue=function(e){if(e.type!==l.Reuse)throw new o({code:a.InterpreterRuntime,message:"Assertion failed, value expected to be reuse!"});return e},e._asTableValue=s,e._noop=c,e.nil={type:l.Function,value:c},e._assertValidNumber=v,e._number=p,e.number={type:l.Function,value:p},e._boolean=h,e.boolean={type:l.Function,value:h},e._string=f,e.string={type:l.Function,value:f},e.noop={type:l.Function,value:c},e.block={type:l.Function,value:c},e.forDo={type:l.Function,value:c},e.whileDo={type:l.Function,value:c},e.ifs={type:l.Function,value:c},e.reuse={type:l.Function,value:c},e._toString=d,e.toString={type:l.Function,value:d},e._type=g,e.type={type:l.Function,value:g},e._print=m,e.print={type:l.Function,value:m},e._id=w,e.id={type:l.Function,value:w},e._toNumber=b,e.toNumber={type:l.Function,value:b},e._toBoolean=I,e.toBoolean={type:l.Function,value:I},e._toNil=F,e.toNil={type:l.Function,value:F},e._stop=N,e.stop={type:l.Function,value:N},e._lets=k,e.lets={type:l.Function,value:k},e._env=S,e.env={type:l.Function,value:S},e._lte=_,e.lte={type:l.Function,value:_},e._lt=A,e.lt={type:l.Function,value:A},e._gt=R,e.gt={type:l.Function,value:R},e._gte=x,e.gte={type:l.Function,value:x},e._add=T,e.add={type:l.Function,value:T},e._and=B,e.and={type:l.Function,value:B},e._or=U,e.or={type:l.Function,value:U},e._not=E,e.not={type:l.Function,value:E},e._eq=P,e.eq={type:l.Function,value:P},e._neq=C,e.neq={type:l.Function,value:C},e._mod=z,e.mod={type:l.Function,value:z},e._power=W,e.power={type:l.Function,value:W},e._div=O,e.div={type:l.Function,value:O},e._mul=D,e.mul={type:l.Function,value:D},e._sub=V,e.sub={type:l.Function,value:V},e._version=L,e.version={type:l.Function,value:L},e._concat=q,e.concat={type:l.Function,value:q},e._escape=$,e.escape={type:l.Function,value:$},e._quote=j,e.quote={type:l.Function,value:j},e._lenArr=K,e.lenArr={type:l.Function,value:K},e._len=M,e.len={type:l.Function,value:M},e._random=X,e.random={type:l.Function,value:X},e._binAnd=G,e.binAnd={type:l.Function,value:G},e._binOr=H,e.binOr={type:l.Function,value:H},e._binXor=J,e.binXor={type:l.Function,value:J},e._binLeftShift=Q,e.binLeftShift={type:l.Function,value:Q},e._binRightShift=Y,e.binRightShift={type:l.Function,value:Y},e._binUnsignedRightShift=Z,e.binUnsignedRightShift={type:l.Function,value:Z},e._arg=ee,e.arg={type:l.Function,value:ee},e._table=te,e.table={type:l.Function,value:te},e._get=ne,e.get={type:l.Function,value:ne},e._set=ae,e.set={type:l.Function,value:ae}}(s=e.Std||(e.Std={}))}(e||(e={}));export{e as DelJS};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "del-js-lang",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "author": {
5
5
  "name": "Ivan Polushin",
6
6
  "url": "https://t.me/polioan"