Variable resolution works?

pull/974/head
connor rigby 2019-01-31 10:20:47 -08:00 committed by Connor Rigby
parent 2b83e76233
commit a28b6c4141
No known key found for this signature in database
GPG Key ID: 29A88B24B70456E0
3 changed files with 132 additions and 21 deletions

View File

@ -33,14 +33,19 @@ defmodule Farmbot.CeleryScript.AST.Compiler do
end
end)
assignments = compile_block(body, celery_env)
steps = compile_block(block, celery_env) |> decompose_block_to_steps()
quote do
fn params ->
import Farmbot.CeleryScript.Syscalls
# Fetches variables from the previous execute()
# example:
# parent = Keyword.fetch!(params, :parent)
unquote_splicing(params)
# Unquote the remaining sequence steps.
unquote(compile_block(body ++ block, celery_env))
unquote(assignments)
unquote(steps)
end
end
|> add_meta(ast, celery_env)
@ -94,10 +99,12 @@ defmodule Farmbot.CeleryScript.AST.Compiler do
"x" -> quote do: get_current_x()
"y" -> quote do: get_current_y()
"z" -> quote do: get_current_z()
"pin" <> pin -> {:read_pin, [], [String.to_integer(pin), nil]}
"pin" <> pin -> quote do: read_pin(unquote(String.to_integer(pin)), nil)
%AST{} = ast -> compile(ast, celery_env)
end
rhs = compile(rhs, celery_env)
# Turn the `op` arg into Elixir code
if_eval =
case op do
@ -110,13 +117,13 @@ defmodule Farmbot.CeleryScript.AST.Compiler do
# read_pin(22, nil) == 5
# The ast will look like: {:==, [], lhs, compile(rhs)}
quote do
unquote(lhs) == unquote(compile(rhs, celery_env))
unquote(lhs) == unquote(rhs)
end
"not" ->
# ast will look like: {:!=, [], [lhs, compile(rhs)]}
quote do
unquote(lhs) != unquote(compile(rhs, celery_env))
unquote(lhs) != unquote(rhs)
end
"is_undefined" ->
@ -128,13 +135,13 @@ defmodule Farmbot.CeleryScript.AST.Compiler do
"<" ->
# ast will look like: {:<, [], [lhs, compile(rhs)]}
quote do
unquote(lhs) < unquote(compile(rhs, celery_env))
unquote(lhs) < unquote(rhs)
end
">" ->
# ast will look like: {:>, [], [lhs, compile(rhs)]}
quote do
unquote(lhs) > unquote(compile(rhs, celery_env))
unquote(lhs) > unquote(rhs)
end
end
@ -160,17 +167,16 @@ defmodule Farmbot.CeleryScript.AST.Compiler do
) do
quote do
# We have to lookup the sequence by it's id.
case get_sequence(unquote(id)) do
{:ok, %AST{} = ast, new_celery_env} ->
# compile the ast
fun = unquote(__MODULE__).compile(ast, new_celery_env)
# And call it, serializing all the variables it expects.
# see the `compile_param_application/1` docs for more info.
fun.(unquote(compile_param_application(variable_declarations)))
%Farmbot.CeleryScript.AST{} = ast = get_sequence(unquote(id))
# compile the ast
fun =
unquote(__MODULE__).compile(ast)
|> Code.eval_quoted()
|> elem(0)
err ->
handle_error(err)
end
# And call it, serializing all the variables it expects.
# see the `compile_param_application/1` docs for more info.
fun.(unquote(compile_param_application(variable_declarations)))
end
|> add_meta(ast, celery_env)
end
@ -187,7 +193,7 @@ defmodule Farmbot.CeleryScript.AST.Compiler do
end)
quote do
execute_script(unquote(package), unquote(Map.new(env)))
execute_script(unquote(package), unquote(Macro.escape(Map.new(env))))
end
|> add_meta(ast, celery_env)
end
@ -248,7 +254,7 @@ defmodule Farmbot.CeleryScript.AST.Compiler do
# build a vec3 of the current position
%{x: offx, y: offy, z: offz} = %{
x: get_current_x(),
y: get_current_y,
y: get_current_y(),
z: get_current_y()
}
@ -493,4 +499,14 @@ defmodule Farmbot.CeleryScript.AST.Compiler do
{a, meta, body}
end
defp decompose_block_to_steps({:__block__, _, steps} = orig) do
Enum.map(steps, fn step ->
quote do
fn ->
unquote(step)
end
end
end)
end
end

View File

@ -0,0 +1,83 @@
defmodule Farmbot.CeleryScript.Syscalls do
alias Farmbot.CeleryScript.{AST, AST.Compiler}
def test(params \\ []) do
File.read!("fixture/sequence_pair.json")
|> Jason.decode!()
|> Enum.at(0)
|> AST.decode()
|> Compiler.compile()
|> Code.eval_quoted()
|> elem(0)
# generates the sequence
|> apply([params])
|> Enum.map(fn step -> apply(step, []) end)
end
def point(type, id) do
IO.puts("point(#{type}, #{id})")
%{x: 1, y: 122, z: 100}
end
def coordinate(x, y, z) do
IO.puts("coodinate(#{x}, #{y}, #{z})")
%{x: x, y: y, z: z}
end
def move_absolute(x, y, z, speed) do
IO.puts("move_absolute(#{x}, #{y}, #{z}, #{speed})")
end
def get_current_x() do
100
end
def get_current_y() do
234
end
def get_current_z() do
12
end
def write_pin(pin, mode, value) do
IO.puts("write_pin(#{pin}, #{mode}, #{value}")
end
def pin(type, id) do
IO.puts("pin(#{type}, #{id})")
end
def read_pin(pin, mode) do
IO.puts("read_pin(#{pin}, #{mode})")
end
def find_home(axis, speed) do
IO.puts("find_home(#{axis}, #{speed})")
end
def find_home(axis) do
IO.puts("find_home(#{axis})")
end
def send_message(level, message, channels) do
IO.puts("send_message(#{level}, #{message}, #{inspect(channels)}")
end
def nothing do
IO.puts("nothing()")
end
def get_sequence(id) do
IO.puts("get_sequence(#{id})")
File.read!("fixture/sequence_pair.json")
|> Jason.decode!()
|> Enum.at(1)
|> AST.decode()
end
def execute_script(name, env) do
IO.puts("execute_script(#{name}, #{inspect(env)})")
end
end

View File

@ -18,9 +18,11 @@ defmodule Farmbot.System.NervesHub do
## On host.
Just return :ok to everything.
"""
import Farmbot.Config, only: [
get_config_value: 3, update_config_value: 4
]
import Farmbot.Config,
only: [
get_config_value: 3,
update_config_value: 4
]
@behaviour Farmbot.AMQP.NervesHubTransport
@ -100,6 +102,7 @@ defmodule Farmbot.System.NervesHub do
end
def detect_channel do
<<<<<<< HEAD
channel_from_branch = case Farmbot.Project.branch() do
"master" -> "stable"
"beta" -> "beta"
@ -109,6 +112,15 @@ defmodule Farmbot.System.NervesHub do
channel_from_config = get_config_value(:string, "settings", "update_channel")
"channel:#{channel_from_config || channel_from_branch}"
=======
get_config_value(:string, "settings", "update_channel") ||
case Farmbot.Project.branch() do
"master" -> "channel:stable"
"beta" -> "channel:beta"
"staging" -> "channel:staging"
branch -> "channel:#{branch}"
end
>>>>>>> 6208022c... Format
end
def get_config do