UNPKG

logica

Version:

a compile-to-javascript predicate logic language

122 lines (72 loc) 4.29 kB
# logica a compile-to-javascript predicate logic language note: this is a preview public release, so documentation is a bit sparse right now. logica is a language for expressing [Boolean algebra](http://en.wikipedia.org/wiki/Boolean_algebra). It's clean syntax makes it easy for non-programmers and domain experts to express complex logic and conditional knowledge. * flexible syntax * interpreted or compile-to-javascript * all operators support multiple arguments (except `not`) * extensible with custom predicate operators ## basic usage in logica, you create predicates (functions which result in a `true` or `false` value). The simplest predicate is a literal boolean value. That is, the following is valid logica: true This, clearly, will always evaluate to true. Of course, you probably want more complex things: (OR (Today = "wednesday") (Today = "mittwoch") ) Whitespace doesn't matter, but it can improve usability. Optionally, commas can be used to separate the various pieces. We could also write: (OR,(Today="wednesday"),(=,Today,"mittwoch")) Here, we're using a symbolic variable, `Today`, and comparing it to the literal values `wednesday` and `mittwoch`. In JavaScript, you might write: Today === "wednesday" || Today === "mittwoch" Notice the parentheses? You can nest predicates as deeply as you'd like. Note that since this predicate references `Today`, we can't evaluate it without a value for `Today`. It might help to think about it like this: in logica, you're writing a function. Each symbolic variable you use requires a corresponding argument. When using logica in JavaScript, these are supplied as properties on a `state` object which is passed in. Putting it all together, var logica = require('logica') var source = '(OR (Today = "wednesday"), (Today = "mittwoch"))' logica.exec(source, {Today: 'mittwoch'}) // => true logica.exec(source, {Today: 'wednesday'}) // => true logica.exec(source, {Today: 'tuesday'}) // => false Now that you've got the basics, check out the `/examples/` folder for more. A slightly more elaborate (and contrived, but valid) predicate might be: # a logica program (AND (foo = 'baz') faa (NOT (NOT true)) (pizzas >= 23) ('cheese' IN toppings) (and (foo = bar)) ) ## using the compiler logica can be compiled to JavaScript sourcecode so that the overhead of parsing only has to occur once. For example, a server can pre-compile logica predicates for use on a client application. in node, simply: var compile = require('logica') var jsCode = compile(sourceString, options); ## using a compiled function The compiler generates JavaScript sourcecode as a string. This intermediate form expects certain functions to exist in the runtime environment implementing logica operators. The easiest way to consume this source is using the hydrate function: var hydrate = require('logica/hydrate') var logicaFn hydrate(compiledLogicaSource) var state = { foo: true, bar: false } var result = logicaFn(state) Hydrate is a standalone module with no dependencies. You can use it, for example, to execute functions clientside that were precompiled on the server. ## compile options You can supply and `opts` object as the optional second argument of `compile`. - `prettyPrint`: boolean (default false). If true, will generate code with line breaks and indentation ## examples See the `/examples` folder. Files ending in `.logica` are plain logica source files. ## running the unit tests $ make test ## hacking on the parser logica's parser is implemented in [jison](http://zaach.github.com/jison/). The lexer and parser definitions are implemented in the file `logica.jison`, which generates `parser.js`. This file will get overwritten - do not make modifications to this file. Instead, modifications can be made in `logica.jison` itself or in `postParser.js`, which is just JavaScript. To generate `parser.js`: $ make ## contributors Jason Denizac - jden - <jason@denizac.org> ## license MIT (c) 2013 Agile Diagnosis, Inc. See LICENSE.md