Comparing version 0.0.2 to 0.0.3
@@ -33,3 +33,2 @@ /* | ||
grunt.initConfig({ | ||
version: grunt.file.readYAML("VERSION.yml"), | ||
eslint: { | ||
@@ -48,8 +47,2 @@ options: { | ||
transform: [ | ||
[ "browserify-replace", { replace: [ | ||
{ from: /\$major/g, to: "<%= version.major %>" }, | ||
{ from: /\$minor/g, to: "<%= version.minor %>" }, | ||
{ from: /\$micro/g, to: "<%= version.micro %>" }, | ||
{ from: /\$date/g, to: "<%= version.date %>" } | ||
]}], | ||
[ "babelify", { | ||
@@ -83,8 +76,2 @@ presets: [ | ||
transform: [ | ||
[ "browserify-replace", { replace: [ | ||
{ from: /\$major/g, to: "<%= version.major %>" }, | ||
{ from: /\$minor/g, to: "<%= version.minor %>" }, | ||
{ from: /\$micro/g, to: "<%= version.micro %>" }, | ||
{ from: /\$date/g, to: "<%= version.date %>" } | ||
]}], | ||
[ "babelify", { | ||
@@ -91,0 +78,0 @@ presets: [ |
{ | ||
"name": "ael", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Advanced Expression Language", | ||
@@ -47,4 +47,3 @@ "keywords": [ "expression", "language", "evaluation" ], | ||
"browserify-header": "1.0.1", | ||
"browserify-derequire": "1.0.1", | ||
"browserify-replace": "1.0.1" | ||
"browserify-derequire": "1.0.1" | ||
}, | ||
@@ -51,0 +50,0 @@ "engines": { |
@@ -77,18 +77,2 @@ | ||
- `AEL#version(): { major: Number, minor: Number, micro: Number, date: Number }`:<br/> | ||
Return the current AEL library version details. | ||
- `AEL#func(name: String, func: (adapter: Adapter, node: Object, [...]) => Any): AEL`:<br/> | ||
Register function named `name` by providing the callback `func` which has | ||
to return an arbitrary value and optionally can access the current `node` with | ||
the help of the selected `adapter`. Returns the API itself. | ||
/* the built-in implementation for "depth" */ | ||
ael.func("depth", function (adapter, node) => { | ||
var depth = 1 | ||
while ((node = adapter.getParentNode(node)) !== null) | ||
depth++ | ||
return depth | ||
}) | ||
- `AEL#cache(num: Number): AEL`:<br/> | ||
@@ -95,0 +79,0 @@ Set the upper limit for the internal query cache to `num`, i.e., |
@@ -5,5 +5,5 @@ | ||
let ael = new AEL() | ||
ael.compile(`/* query all variable declaration */ | ||
foo.bar.quux && (bar.foo)[foo ? "quux" : "quux2"].bar == 2 | ||
`, true) | ||
let ast = ael.compile(`foo.bar.quux()`, true) | ||
let result = ael.execute(ast, { foo: { bar: { quux: () => 42 } } }, true) | ||
console.log(result) | ||
@@ -26,10 +26,17 @@ /* | ||
/* load external depdendencies */ | ||
import CacheLRU from "cache-lru" | ||
import CacheLRU from "cache-lru" | ||
import ASTY from "asty" | ||
import PEGUtil from "pegjs-util" | ||
/* load internal dependencies */ | ||
import AELFuncs from "./ael-funcs.js" | ||
import AELFuncsSTD from "./ael-funcs-std.js" | ||
import AELExpr from "./ael-expr.js" | ||
import AELVersion from "./ael-version.js" | ||
/* get expression evaluator */ | ||
import AELEval from "./ael-eval.js" | ||
/* get expression parser (by loading and on-the-fly compiling PEG.js grammar) */ | ||
const PEG = require("pegjs-otf") | ||
const AELParser = PEG.generateFromFile( | ||
/* eslint node/no-path-concat: off */ | ||
__dirname + "/ael-parse.pegjs", | ||
{ optimize: "speed", cache: true } | ||
) | ||
/* define the API class */ | ||
@@ -39,7 +46,2 @@ class AEL { | ||
constructor () { | ||
/* create function registry and pre-register standard functions */ | ||
this._funcs = new AELFuncs() | ||
for (let name in AELFuncsSTD) | ||
this.func(name, AELFuncsSTD[name]) | ||
/* create LRU cache */ | ||
@@ -49,15 +51,2 @@ this._cache = new CacheLRU() | ||
/* return the version information */ | ||
version () { | ||
return AELVersion | ||
} | ||
/* register an additional function */ | ||
func (name, func) { | ||
if (arguments.length !== 2) | ||
throw new Error("AEL#func: invalid number of arguments") | ||
this._funcs.register(name, func) | ||
return this | ||
} | ||
/* configure the LRU cache limit */ | ||
@@ -81,4 +70,21 @@ cache (entries) { | ||
if (ast === undefined) { | ||
ast = new AELExpr() | ||
ast.compile(expr, trace) | ||
if (trace) | ||
console.log("AEL: compile: +---(expression)------------------------" + | ||
"----------------------------------------------------------------\n" + | ||
expr.replace(/\n$/, "").replace(/^/mg, "AEL: compile: | ")) | ||
const asty = new ASTY() | ||
let result = PEGUtil.parse(AELParser, expr, { | ||
startRule: "expression", | ||
makeAST: (line, column, offset, args) => { | ||
return asty.create.apply(asty, args).pos(line, column, offset) | ||
} | ||
}) | ||
if (result.error !== null) | ||
throw new Error("AEL: compile: expression parsing failed:\n" + | ||
PEGUtil.errorMessage(result.error, true).replace(/^/mg, "ERROR: ")) | ||
ast = result.ast | ||
if (trace) | ||
console.log("AEL: compile: +---(AST)-------------------------------" + | ||
"----------------------------------------------------------------\n" + | ||
ast.dump().replace(/\n$/, "").replace(/^/mg, "AEL: compile: | ")) | ||
this._cache.set(expr, ast) | ||
@@ -90,26 +96,31 @@ } | ||
/* individual step 2: execute AST */ | ||
execute (ast, params, vars, trace) { | ||
execute (ast, vars, trace) { | ||
if (arguments.length < 1) | ||
throw new Error("AEL#execute: too less arguments") | ||
if (arguments.length > 4) | ||
if (arguments.length > 3) | ||
throw new Error("AEL#execute: too many arguments") | ||
if (params === undefined) | ||
params = {} | ||
if (vars === undefined) | ||
vars = {} | ||
if (trace === undefined) | ||
trace = false | ||
return ast.execute(params, vars, this._funcs, trace) | ||
if (trace) | ||
console.log("AEL: execute: +---(result)----------------------------" + | ||
"----------------------------------------------------------------") | ||
const evaluator = new AELEval(vars, trace) | ||
const result = evaluator.eval(ast) | ||
return result | ||
} | ||
/* all-in-one step */ | ||
evaluate (expr, params, vars, trace) { | ||
evaluate (expr, vars, trace) { | ||
if (arguments.length < 1) | ||
throw new Error("AEL#evaluate: too less arguments") | ||
if (arguments.length > 4) | ||
if (arguments.length > 3) | ||
throw new Error("AEL#evaluate: too many arguments") | ||
if (params === undefined) | ||
params = {} | ||
if (vars === undefined) | ||
vars = {} | ||
if (trace === undefined) | ||
trace = false | ||
const ast = this.compile(expr, trace) | ||
return this.execute(ast, params, vars, trace) | ||
return this.execute(ast, vars, trace) | ||
} | ||
@@ -116,0 +127,0 @@ } |
@@ -40,4 +40,2 @@ /* | ||
it("API availability", () => { | ||
expect(ael).to.respondTo("version") | ||
expect(ael).to.respondTo("func") | ||
expect(ael).to.respondTo("cache") | ||
@@ -47,10 +45,4 @@ expect(ael).to.respondTo("compile") | ||
expect(ael).to.respondTo("evaluate") | ||
expect(ael.version()).to.have.property("major") | ||
expect(ael.version()).to.have.property("minor") | ||
expect(ael.version()).to.have.property("micro") | ||
expect(ael.version()).to.have.property("date") | ||
}) | ||
ael.func("add", (a, b) => { return a + b }) | ||
it("simple expressions", () => { | ||
@@ -61,9 +53,9 @@ expect(ael.evaluate("true")).to.be.equal(true) | ||
}) | ||
it("parameter expressions", () => { | ||
expect(ael.evaluate("$1", [ 1, 2, 3 ])).to.be.equal(2) | ||
}) | ||
it("variable expressions", () => { | ||
expect(ael.evaluate("foo + bar", [], { foo: "foo", bar: "bar" })).to.be.equal("foobar") | ||
expect(ael.evaluate("foo + bar", { foo: "foo", bar: "bar" })).to.be.equal("foobar") | ||
}) | ||
it("function calls", () => { | ||
expect(ael.evaluate("foo() + bar.baz()", { foo: () => 42, bar: { baz: () => 7 } }), true).to.be.equal(49) | ||
}) | ||
}) | ||
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20
231231
15
4662
153