diff --git a/lib/parser/nools/tokens.js b/lib/parser/nools/tokens.js index 2e30a73..872a33c 100644 --- a/lib/parser/nools/tokens.js +++ b/lib/parser/nools/tokens.js @@ -141,6 +141,29 @@ module.exports = { } }, + "global": function (orig, context) { + var src = orig.replace(/^global\s*/, ""); + var name = src.match(/^([a-zA-Z_$][0-9a-zA-Z_$]*\s*)/); + if (name) { + src = src.replace(name[0], "").replace(/^\s*|\s*$/g, ""); + if (utils.findNextToken(src) === "=") { + name = name[1].replace(/^\s+|\s+$/g, ''); + var fullbody = utils.getTokensBetween(src, "=", ";", true).join(""); + var body = fullbody.substring(1, fullbody.length - 1); + body = body.replace(/^\s+|\s+$/g, ''); + context.scope.push({name: name, body: body}); + src = src.replace(fullbody, ""); + return src; + } + else { + throw new Error("unexpected token : expected : '=' found : '" + utils.findNextToken(src) + "'"); + } + } + else { + throw new Error("missing name"); + } + }, + "function": function (orig, context) { var src = orig.replace(/^function\s*/, ""); var name = src.match(/^([a-zA-Z_$][0-9a-zA-Z_$]*)\s*/); diff --git a/readme.md b/readme.md index ce47f3e..ac56b12 100644 --- a/readme.md +++ b/readme.md @@ -26,6 +26,7 @@ Or [download the source](https://raw.github.com/doug-martin/C2FO/master/nools.js * [Structure](#rule-structure) * [Constraints](#constraints) * [Actions](#action) + * [Globals](#globals) * [Browser Support](#browser-support) * [Fibonacci](#fib) @@ -586,6 +587,26 @@ then { For rules defined using the rules language nools will automatically determine what parameters need to be passed in based on what is referenced in the action. + + +### Globals + +Globals are accessible through the current working scope in your rules runs from the nools rules format. Note that globals are not part of the working +memory so are not accessible during the when portion of your rules run. Globals are used like the following: + +``` +global util = require('util'); + +rule "A Rule" { + when { + $obj: Object; + } + then{ + util.log("Hello Globals :)"); + } +} +``` + ## Emitting custom events. You may also emit events from your rule actions using the sessions emit function. diff --git a/test/noolsParser.test.js b/test/noolsParser.test.js index 04ed12a..c851267 100644 --- a/test/noolsParser.test.js +++ b/test/noolsParser.test.js @@ -32,6 +32,12 @@ it.describe("nools dsl parser",function (it) { }); }); + it.should("parse a global statement", function () { + var parsed = noolsParser.parse("global util = require('util');"); + assert.equal(parsed.scope[0].name, 'util'); + assert.equal(parsed.scope[0].body, "require('util')"); + }); + it.should("throw an error when the define block is missing a name", function () { assert.throws(function () { noolsParser.parse("define {myProp : 'value'"); @@ -46,6 +52,18 @@ it.describe("nools dsl parser",function (it) { noolsParser.parse("define Test myProp : 'value'}"); }); }); + + it.should("throw an error when the global statement is missing a name", function () { + assert.throws(function () { + noolsParser.parse("global = require('util');"); + }); + }); + + it.should("throw an error when the global statement is missing a ;", function () { + assert.throws(function () { + noolsParser.parse("global util = require('util')"); + }); + }); }); it.describe("parsing function", function (it) { diff --git a/test/rules/scope.nools b/test/rules/scope.nools index 884d2b1..afbc0b9 100644 --- a/test/rules/scope.nools +++ b/test/rules/scope.nools @@ -9,11 +9,14 @@ function matches(str, regex){ return regex.test(str); } +global util = require('util'); + rule Hello { when { m : Message matches(m.message, /^hello(\\s*world)?$/); } then { + util.log("Hello Globals :)"); modify(m, function(){ this.message += " goodbye"; })