Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

numenor

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

numenor - npm Package Compare versions

Comparing version 0.1.5 to 0.1.6

lib/Compiler/Evaluator/Group.js

36

lib/Compiler/Evaluator/Lambda.js

@@ -23,8 +23,24 @@ "use strict";

const {
length
} = expr.args;
const body = compile(expr.body, options, compile);
const isConst = (0, _.hasConstValue)(body);
const isAsync = (0, _.hasAsyncValue)(body);
let isConst = (0, _.hasConstValue)(body);
let isAsync = (0, _.hasAsyncValue)(body);
const args = expr.args.map(arg => {
let defaultValue;
if (arg.variadic) {
defaultValue = () => [];
} else if (arg.default) {
defaultValue = compile(arg.default, options, compile);
isConst = !isConst && (0, _.hasConstValue)(defaultValue);
isAsync = !isAsync && (0, _.hasAsyncValue)(defaultValue);
} else {
defaultValue = () => undefined;
}
return {
name: arg.name,
variadic: !!arg.variadic,
defaultValue
};
});
return (0, _.mark)({

@@ -34,7 +50,11 @@ isAsync,

}, (context, stack) => {
return (...args) => {
return (...params) => {
const invocationContext = _objectSpread({}, context);
for (let i = 0; i < length; i++) {
invocationContext[expr.args[i].name] = i < length ? args[i] : undefined;
for (let i = 0; i < args.length; i++) {
if (args[i].variadic) {
invocationContext[args[i].name] = params.slice(i);
} else {
invocationContext[args[i].name] = i < params.length ? params[i] : args[i].defaultValue(invocationContext, stack);
}
}

@@ -41,0 +61,0 @@

@@ -40,2 +40,6 @@ "use strict";

var _Group = require("./Compiler/Evaluator/Group");
var _Spread = require("./Compiler/Evaluator/Spread");
class ExpressionCompiler extends _Compiler.Compiler {

@@ -65,2 +69,4 @@ constructor() {

this.setCompiler(_Parser.ExpressionType.Lambda, _Lambda.Lambda);
this.setCompiler(_Parser.ExpressionType.Group, _Group.Group);
this.setCompiler(_Parser.ExpressionType.Spread, _Spread.Spread);
}

@@ -67,0 +73,0 @@

@@ -29,2 +29,3 @@ "use strict";

this.appendScanner(_NumberLiteral.NumberLiteral);
this.appendScanner((0, _Punctuation.makePunctuationScanner)('...', _Lexer.TokenType.Ellipsis));
this.appendScanner((0, _Punctuation.makePunctuationScanner)('.', _Lexer.TokenType.Dot));

@@ -31,0 +32,0 @@ this.appendScanner((0, _Punctuation.makePunctuationScanner)('(', _Lexer.TokenType.LParen));

@@ -40,2 +40,4 @@ "use strict";

var _Spread = require("./Parser/Parselet/Spread");
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }

@@ -102,4 +104,4 @@

this.setInfix(_Lexer.TokenType.QuestionDot, _Conditional.NullConditional);
this.setInfix(_Lexer.TokenType.RightArrow, _Lambda.LambdaInfix);
this.setPrefix(_Lexer.TokenType.LParen, _Lambda.LambdaPrefix);
this.setPrefix(_Lexer.TokenType.Ellipsis, _Spread.Spread);
this.setInfix(_Lexer.TokenType.RightArrow, _Lambda.Lambda);
this.setPrefix(_Lexer.TokenType.LParen, _Group.Group);

@@ -106,0 +108,0 @@ this.setPrefix(_Lexer.TokenType.Identifier, _Value.Identifier);

@@ -6,3 +6,3 @@ "use strict";

});
exports.RightArrow = exports.Await = exports.In = exports.Colon = exports.QuestionQuestionEq = exports.QuestionQuestion = exports.QuestionDot = exports.Question = exports.GtGtGtEq = exports.GtGtGt = exports.GtGtEq = exports.GtGt = exports.GtEq = exports.Gt = exports.LtLtEq = exports.LtLt = exports.LtEq = exports.Lt = exports.PercentEq = exports.Percent = exports.SlashEq = exports.Slash = exports.StarStarEq = exports.StarStar = exports.StarEq = exports.Star = exports.TildeEq = exports.Tilde = exports.CaretEq = exports.Caret = exports.PipePipe = exports.PipeEq = exports.Pipe = exports.AmpAmp = exports.AmpEq = exports.Amp = exports.BangEqEq = exports.BangEq = exports.Bang = exports.EqEqEq = exports.EqEq = exports.Eq = exports.MinusMinus = exports.MinusEq = exports.Minus = exports.PlusPlus = exports.PlusEq = exports.Plus = exports.Dot = exports.Comma = exports.RBracket = exports.LBracket = exports.RBrace = exports.LBrace = exports.RParen = exports.LParen = exports.LineTerminator = exports.Whitespace = exports.Identifier = exports.UndefinedLiteral = exports.NullLiteral = exports.BooleanLiteral = exports.StringLiteral = exports.NumberLiteral = exports.EOF = exports.Invalid = exports.Unknown = void 0;
exports.Ellipsis = exports.RightArrow = exports.Await = exports.In = exports.Colon = exports.QuestionQuestionEq = exports.QuestionQuestion = exports.QuestionDot = exports.Question = exports.GtGtGtEq = exports.GtGtGt = exports.GtGtEq = exports.GtGt = exports.GtEq = exports.Gt = exports.LtLtEq = exports.LtLt = exports.LtEq = exports.Lt = exports.PercentEq = exports.Percent = exports.SlashEq = exports.Slash = exports.StarStarEq = exports.StarStar = exports.StarEq = exports.Star = exports.TildeEq = exports.Tilde = exports.CaretEq = exports.Caret = exports.PipePipe = exports.PipeEq = exports.Pipe = exports.AmpAmp = exports.AmpEq = exports.Amp = exports.BangEqEq = exports.BangEq = exports.Bang = exports.EqEqEq = exports.EqEq = exports.Eq = exports.MinusMinus = exports.MinusEq = exports.Minus = exports.PlusPlus = exports.PlusEq = exports.Plus = exports.Dot = exports.Comma = exports.RBracket = exports.LBracket = exports.RBrace = exports.LBrace = exports.RParen = exports.LParen = exports.LineTerminator = exports.Whitespace = exports.Identifier = exports.UndefinedLiteral = exports.NullLiteral = exports.BooleanLiteral = exports.StringLiteral = exports.NumberLiteral = exports.EOF = exports.Invalid = exports.Unknown = void 0;
const Unknown = Symbol.for('numenor:tok:unknown');

@@ -141,2 +141,4 @@ exports.Unknown = Unknown;

const RightArrow = Symbol.for('numenor:tok:=>');
exports.RightArrow = RightArrow;
exports.RightArrow = RightArrow;
const Ellipsis = Symbol.for('numenor:tok:...');
exports.Ellipsis = Ellipsis;

@@ -6,3 +6,3 @@ "use strict";

});
exports.InvalidLeftHandSide = exports.UnexpectedToken = exports.UnknownToken = void 0;
exports.InvalidArgumentList = exports.InvalidLeftHandSide = exports.UnexpectedToken = exports.UnknownToken = void 0;

@@ -30,2 +30,4 @@ function str(tokenType) {

const InvalidLeftHandSide = `Invalid left-hand side in assignment`;
exports.InvalidLeftHandSide = InvalidLeftHandSide;
exports.InvalidLeftHandSide = InvalidLeftHandSide;
const InvalidArgumentList = `Invalid argument list in lambda expression`;
exports.InvalidArgumentList = InvalidArgumentList;

@@ -6,3 +6,3 @@ "use strict";

});
exports.Lambda = exports.ComputedMemberAccess = exports.MemberAccess = exports.Sequence = exports.Await = exports.Call = exports.PostfixOperation = exports.PrefixOperation = exports.BinaryOperation = exports.Conditional = exports.ObjectLiteral = exports.ArrayLiteral = exports.Assignment = exports.UndefinedLiteral = exports.NullLiteral = exports.BooleanLiteral = exports.StringLiteral = exports.NumberLiteral = exports.StackRef = exports.StackPop = exports.StackPush = exports.Identifier = void 0;
exports.Spread = exports.Group = exports.Lambda = exports.ComputedMemberAccess = exports.MemberAccess = exports.Sequence = exports.Await = exports.Call = exports.PostfixOperation = exports.PrefixOperation = exports.BinaryOperation = exports.Conditional = exports.ObjectLiteral = exports.ArrayLiteral = exports.Assignment = exports.UndefinedLiteral = exports.NullLiteral = exports.BooleanLiteral = exports.StringLiteral = exports.NumberLiteral = exports.StackRef = exports.StackPop = exports.StackPush = exports.Identifier = void 0;
const Identifier = Symbol.for('numenor:expr:ident');

@@ -51,2 +51,6 @@ exports.Identifier = Identifier;

const Lambda = Symbol.for('numenor:expr:lambda');
exports.Lambda = Lambda;
exports.Lambda = Lambda;
const Group = Symbol.for('numenor:expr:group');
exports.Group = Group;
const Spread = Symbol.for('numenor:expr:spread');
exports.Spread = Spread;

@@ -185,6 +185,7 @@ "use strict";

this.ignored = new Set();
this.lexerState = this.lexer.currentState;
}
get state() {
return this.lexer.currentState;
return this.lexerState;
}

@@ -205,2 +206,12 @@

const {
offset,
line,
col
} = parserContext.shift();
this.lexerState = {
offset,
line,
col
};
return expression;

@@ -207,0 +218,0 @@ }

@@ -8,2 +8,4 @@ "use strict";

var _ = require("../");
var _Lexer = require("../../Lexer");

@@ -18,7 +20,16 @@

if (parser.accept(_Lexer.TokenType.RParen)) {
return {
type: _.ExpressionType.Group
};
}
const expression = parser.parse();
parser.expect(_Lexer.TokenType.RParen);
return expression;
return {
type: _.ExpressionType.Group,
expression
};
};
exports.Group = Group;

@@ -6,3 +6,3 @@ "use strict";

});
exports.LambdaInfix = exports.LambdaPrefix = void 0;
exports.Lambda = void 0;

@@ -17,94 +17,54 @@ var _ = require("./");

var _Value = require("./Value");
var _Precedence = require("../Precedence");
const prefix = (parser, token) => {
if (token.type !== _Lexer.TokenType.LParen) {
throw new SyntaxError((0, _Error.UnknownToken)(token));
const lambda = (parser, lhs, token) => {
if (token.type !== _Lexer.TokenType.RightArrow) {
throw new SyntaxError((0, _Error.UnexpectedToken)(_Lexer.TokenType.RightArrow, token));
}
const args = [];
let paramList = [lhs];
if (!parser.accept(_Lexer.TokenType.RParen)) {
do {
// support trailing comma
if (parser.match(_Lexer.TokenType.RParen)) {
// but not (,)
if (args.length === 0) {
throw new SyntaxError((0, _Error.UnknownToken)(parser.token));
}
if (lhs.type === _2.ExpressionType.Group) {
if (!lhs.expression) {
paramList = [];
} else if (lhs.expression.type === _2.ExpressionType.Sequence) {
paramList = lhs.expression.expressions;
} else {
paramList = [lhs.expression];
}
} else if (lhs.type !== _2.ExpressionType.Identifier) {
throw new SyntaxError(_Error.InvalidArgumentList);
}
break;
}
const args = paramList.map((expr, index) => {
if (expr.type === _2.ExpressionType.Identifier) {
return {
name: expr.name
};
}
args.push((0, _Value.Identifier)(parser, parser.shift()));
} while (parser.accept(_Lexer.TokenType.Comma));
if (expr.type === _2.ExpressionType.Assignment && expr.lhs.type === _2.ExpressionType.Identifier) {
return {
name: expr.lhs.name,
default: expr.rhs
};
}
parser.expect(_Lexer.TokenType.RParen);
}
if (expr.type === _2.ExpressionType.Spread && expr.rhs.type === _2.ExpressionType.Identifier && index === paramList.length - 1) {
return {
name: expr.rhs.name,
variadic: true
};
}
parser.expect(_Lexer.TokenType.RightArrow);
throw new SyntaxError(_Error.InvalidArgumentList);
});
return {
type: _2.ExpressionType.Lambda,
args,
body: parser.parse()
body: parser.parse(_Precedence.Assignment - 1)
};
};
const infix = (parser, lhs, token) => {
if (lhs.type !== _2.ExpressionType.Identifier || token.type !== _Lexer.TokenType.RightArrow) {
throw new SyntaxError((0, _Error.UnexpectedToken)(_Lexer.TokenType.RightArrow, token));
}
return {
type: _2.ExpressionType.Lambda,
args: [lhs],
body: parser.parse()
};
}; // returns true if following grammar is matched:
// * ::= '(' IdentifierList ')' '=>'
// IdentifierList ::= Identifier | Identifier ',' IdentifierList | <empty>
const matches = (parser, token) => {
let offset = 0;
const peek = () => parser.peek(offset++).type;
if (token.type !== _Lexer.TokenType.LParen) {
return false;
}
list: while (true) {
switch (peek()) {
case _Lexer.TokenType.RParen:
{
break list;
}
case _Lexer.TokenType.Identifier:
{
const next = peek();
if (next === _Lexer.TokenType.RParen) {
break list;
} else if (next === _Lexer.TokenType.Comma) {
continue;
}
return false;
}
default:
{
return false;
}
}
}
return peek() === _Lexer.TokenType.RightArrow;
};
const LambdaPrefix = (0, _.makePrefix)(prefix, matches);
exports.LambdaPrefix = LambdaPrefix;
const LambdaInfix = (0, _.makeInfix)(infix, _2.Precedence.Primary);
exports.LambdaInfix = LambdaInfix;
const Lambda = (0, _.makeInfix)(lambda, _2.Precedence.Primary);
exports.Lambda = Lambda;

@@ -374,2 +374,16 @@ "use strict";

});
it('Evaluates lambda expressions with optional arguments', () => {
const lambda = $eval('(x, y = 2) => x * y');
expect(lambda(16)).toBe(32);
expect(lambda(16, 3)).toBe(48);
expect($eval('(x, y = x * 2) => x * y')(16)).toBe(512);
});
it('Evaluates lambda expressions with rest arguments', () => {
const lambda = $compile('(n, ...numbers) => numbers.reduce((x, sum) => sum + x * n, 0)', {
NoProtoAccess: false
})();
expect(lambda(2, 1, 2, 3)).toBe(11);
expect(lambda(2, 42)).toBe(42);
expect(lambda(2)).toBe(0);
});
});

@@ -187,2 +187,3 @@ "use strict";

it('Parses punctuation operators', () => {
lex('...', token => expect(token.type).toBe(_Lexer.TokenType.Ellipsis));
lex('.', token => expect(token.type).toBe(_Lexer.TokenType.Dot));

@@ -189,0 +190,0 @@ lex('(', token => expect(token.type).toBe(_Lexer.TokenType.LParen));

@@ -146,3 +146,2 @@ "use strict";

args: [{
type: ExpressionType.Identifier,
name: 'x'

@@ -165,3 +164,2 @@ }],

expect(parser.parse('(x) => x ** 2')).toEqual(squareAST);
expect(parser.parse('(x,) => x ** 2')).toEqual(squareAST);
expect(parser.parse('() => 2')).toEqual({

@@ -178,6 +176,4 @@ type: ExpressionType.Lambda,

args: [{
type: ExpressionType.Identifier,
name: 'fn'
}, {
type: ExpressionType.Identifier,
name: 'x'

@@ -188,3 +184,2 @@ }],

args: [{
type: ExpressionType.Identifier,
name: 'y'

@@ -208,6 +203,5 @@ }],

});
expect(parser.parse('x => y => (a, b, c) => x, a, b, c, y')).toEqual({
expect(parser.parse('x => y => (a, b, c) => (x, a, b, c, y)')).toEqual({
type: ExpressionType.Lambda,
args: [{
type: ExpressionType.Identifier,
name: 'x'

@@ -218,3 +212,2 @@ }],

args: [{
type: ExpressionType.Identifier,
name: 'y'

@@ -225,29 +218,29 @@ }],

args: [{
type: ExpressionType.Identifier,
name: 'a'
}, {
type: ExpressionType.Identifier,
name: 'b'
}, {
type: ExpressionType.Identifier,
name: 'c'
}],
body: {
type: ExpressionType.Sequence,
expressions: [{
type: ExpressionType.Identifier,
name: 'x'
}, {
type: ExpressionType.Identifier,
name: 'a'
}, {
type: ExpressionType.Identifier,
name: 'b'
}, {
type: ExpressionType.Identifier,
name: 'c'
}, {
type: ExpressionType.Identifier,
name: 'y'
}]
type: ExpressionType.Group,
expression: {
type: ExpressionType.Sequence,
expressions: [{
type: ExpressionType.Identifier,
name: 'x'
}, {
type: ExpressionType.Identifier,
name: 'a'
}, {
type: ExpressionType.Identifier,
name: 'b'
}, {
type: ExpressionType.Identifier,
name: 'c'
}, {
type: ExpressionType.Identifier,
name: 'y'
}]
}
}

@@ -258,2 +251,45 @@ }

});
it('Parses lambda expression with default argument values', () => {
expect(parser.parse('(x = 2) => x')).toEqual({
type: ExpressionType.Lambda,
args: [{
name: 'x',
default: {
type: ExpressionType.NumberLiteral,
value: 2
}
}],
body: {
type: ExpressionType.Identifier,
name: 'x'
}
});
});
it('Parses lambda expression with the rest argument', () => {
expect(parser.parse('(...numbers) => numbers.reduce(sum, 0)')).toEqual({
type: ExpressionType.Lambda,
args: [{
name: 'numbers',
variadic: true
}],
body: {
type: ExpressionType.Call,
lhs: {
type: ExpressionType.MemberAccess,
lhs: {
type: ExpressionType.Identifier,
name: 'numbers'
},
name: 'reduce'
},
args: [{
type: ExpressionType.Identifier,
name: 'sum'
}, {
type: ExpressionType.NumberLiteral,
value: 0
}]
}
});
});
it('Supports scope:enter and scope:leave events', () => {

@@ -260,0 +296,0 @@ const args = [];

{
"name": "numenor",
"version": "0.1.5",
"version": "0.1.6",
"description": "Customizable, safe evaluator of JavaScript-like expressions.",

@@ -5,0 +5,0 @@ "keywords": [

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc