Skip to content

Commit

Permalink
Create conditional statement
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrosnk committed Jul 31, 2016
1 parent a06b116 commit 71af502
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
60 changes: 60 additions & 0 deletions mach/lib/mach/statement/if.ex
@@ -0,0 +1,60 @@
defmodule Mach.Statement.If do
alias Mach.Statement.DoNothing
alias Mach.Boolean

defstruct [
condition: %Boolean{value: true},
consequence: %DoNothing{},
alternative: %DoNothing{},
_reducible?: true
]

@doc """
Reduce conditional statements
iex(1)> Mach.Statement.If.reduce(
iex(1)> %{},
iex(1)> %Mach.Statement.If{
iex(1)> condition: %Mach.LessThan{
iex(1)> left: %Mach.Number{value: 4},
iex(1)> right: %Mach.Number{value: 5},
iex(1)> }
iex(1)> }
iex(1)> )
{%{}, %Mach.Statement.If{condition: %Mach.Boolean{value: true}}}
"""
def reduce(env, %{condition: %{_reducible?: true}} = statement) do
condition = statement.condition
reduced_condition = condition.__struct__.reduce(env, condition)
{env, %Mach.Statement.If{statement | condition: reduced_condition}}
end

def reduce(env, %{condition: %Boolean{value: true},
consequence: %{_reducible?: true}} = statement) do
consequence = statement.consequence
reduced_consequence = consequence.__struct__.reduce(env, consequence)
{env, %Mach.Statement.If{statement | consequence: reduced_consequence}}
end

def reduce(env, %{condition: %Boolean{value: true}} = statement ) do
{env, statement.consequence}
end

def reduce(env, %{condition: %Boolean{value: false},
alternative: %{_reducible?: true}} = statement) do
alternative = statement.alternative
reduced_alternative = alternative.__struct__.reduce(env, alternative)
{env, %Mach.Statement.If{statement | alternative: reduced_alternative}}
end

def reduce(env, %{condition: %Boolean{value: false}} = statement) do
{env, statement.alternative}
end

end

defimpl String.Chars, for: Mach.Statement.If do
def to_string statement do
"if (#{statement.condition}) { #{statement.consequence} }"
end
end
19 changes: 19 additions & 0 deletions mach/test/mach/statement/if_test.exs
@@ -0,0 +1,19 @@
defmodule Mach.Statement.IfTest do
use ExUnit.Case
alias Mach.Statement.If
alias Mach.Statement.DoNothing
alias Mach.GreaterThan
doctest If

test "#to_string" do
statement = %If{
condition: %GreaterThan{
left: %Mach.Number{value: 2},
right: %Mach.Number{value: 3},
}
}

assert String.Chars.to_string(statement) == "if (2 > 3) { do-nothing }"
end

end

0 comments on commit 71af502

Please sign in to comment.