Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a new AST that will allow executing a simple expression and conditionally pass/fail and cleanup when it completes.
- Loading branch information
1 parent
7faebcb
commit 52f0cce
Showing
12 changed files
with
351 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,3 +56,4 @@ nerves-hub | |
*.pem | ||
*.db | ||
*.db-journal | ||
*.lua |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# CeleryScript IF `expression` field. | ||
|
||
The CeleryScript `if` block takes a possible left hand side value of | ||
`expression` which allows an arbitrary string to be evaluated. This | ||
expression is evaluated against a lua 5.2 interpreter. | ||
|
||
## Lua API | ||
The following functions are available for usage along with [Lua's | ||
standard library](https://www.lua.org/manual/5.2/). | ||
|
||
```lua | ||
-- Comments are ignored by the interpreter | ||
|
||
-- help(function_name) | ||
-- Returns docs for a function | ||
|
||
print(help("send_message")); | ||
print(help("get_position")); | ||
|
||
-- get_position() | ||
-- Returns a table containing the current position data | ||
|
||
position = get_position(); | ||
if position.x <= 20.55 then | ||
return true; | ||
else | ||
print("current position: (", position.x, ",", position.y, "," position.z, ")"); | ||
return false; | ||
end | ||
|
||
-- get_pins() | ||
-- Returns a table containing current pin data | ||
|
||
pins = get_pins(); | ||
if pins[9] == 1.0 then | ||
return true; | ||
end | ||
|
||
-- send_message(type, message, channels) | ||
-- Sends a message to farmbot's logger | ||
|
||
send_message("info", "hello, world", ["toast"]) | ||
``` | ||
|
||
## Expression contract | ||
Expressions are expected to be evaluated in a certain way. The evaluation will fail | ||
if this contract is not met. An expression should return one of the following values: | ||
* `true` | ||
* `false` | ||
* `("error", "string reason signaling an error happened")` | ||
|
||
### Examples | ||
|
||
Check if the x position is within a range of 5 and 10 | ||
|
||
```lua | ||
position = get_position(); | ||
return position.x >= 5 and position.x <= 10; | ||
``` | ||
|
||
Check is a pin is a toggled, with error checking | ||
|
||
```lua | ||
-- All farmbot functions will return a tuple containing an error | ||
-- if something bad happens | ||
|
||
position, positionErr = get_position(); | ||
pins, pinErr = get_pins(); | ||
if positionErr or pinErr then | ||
return "error", positionErr or pinErr; | ||
else | ||
return pins[9] == 1.0 | ||
end | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
defmodule FarmbotOS.Lua do | ||
@type t() :: tuple() | ||
@type table() :: [{any, any}] | ||
alias FarmbotOS.Lua.CeleryScript | ||
|
||
@doc """ | ||
Evaluates some Lua code. The code should | ||
return a boolean value. | ||
""" | ||
def eval_assertion(str) when is_binary(str) do | ||
init() | ||
|> set_table([:get_position], &CeleryScript.get_position/2) | ||
|> set_table([:get_pins], &CeleryScript.get_pins/2) | ||
|> set_table([:send_message], &CeleryScript.send_message/2) | ||
|> set_table([:help], &CeleryScript.help/2) | ||
|> set_table([:version], &CeleryScript.version/2) | ||
|> eval(str) | ||
|> case do | ||
{:ok, [true | _]} -> | ||
true | ||
|
||
{:ok, [false | _]} -> | ||
false | ||
|
||
{:ok, [_, reason]} when is_binary(reason) -> | ||
{:error, reason} | ||
|
||
{:ok, _data} -> | ||
{:error, "bad return value from expression evaluation"} | ||
|
||
{:error, {:lua_error, _error, _lua}} -> | ||
{:error, "lua runtime error evaluating expression"} | ||
|
||
{:error, {:badmatch, {:error, [{line, :luerl_parse, parse_error}], _}}} -> | ||
{:error, "failed to parse expression (line:#{line}): #{IO.iodata_to_binary(parse_error)}"} | ||
|
||
error -> | ||
error | ||
end | ||
end | ||
|
||
@spec init() :: t() | ||
def init do | ||
:luerl.init() | ||
end | ||
|
||
@spec set_table(t(), Path.t(), any()) :: t() | ||
def set_table(lua, path, value) do | ||
:luerl.set_table(path, value, lua) | ||
end | ||
|
||
@spec eval(t(), String.t()) :: {:ok, any()} | {:error, any()} | ||
def eval(lua, hook) when is_binary(hook) do | ||
:luerl.eval(hook, lua) | ||
end | ||
end |
Oops, something went wrong.