Skip to content

Commit

Permalink
Keywords (let) can be used as functions too
Browse files Browse the repository at this point in the history
  • Loading branch information
project-eutopia committed Dec 27, 2017
1 parent 114af24 commit ff82444
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
6 changes: 2 additions & 4 deletions lib/keisan/functions/let.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ def initialize
end

def value(ast_function, context = nil)
validate_arguments!(ast_function.children.count)
assignment(ast_function).value(context)
evaluate(ast_function, context)
end

def evaluate(ast_function, context = nil)
Expand All @@ -16,8 +15,7 @@ def evaluate(ast_function, context = nil)
end

def simplify(ast_function, context = nil)
validate_arguments!(ast_function.children.count)
assignment(ast_function).simplify(context)
evaluate(ast_function, context)
end

private
Expand Down
9 changes: 8 additions & 1 deletion lib/keisan/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,15 @@ def parse_multi_line!

def parse_keyword!
keyword = tokens.first.string
arguments = if tokens[1].is_a?(Tokens::Group)
tokens[1].sub_tokens.split {|token| token.is_a?(Tokens::Comma)}.map {|argument_tokens|
Parsing::Argument.new(argument_tokens)
}
else
Parsing::Argument.new(tokens[1..-1])
end
@components = [
Parsing::Function.new(keyword, Parsing::Argument.new(tokens[1..-1]))
Parsing::Function.new(keyword, arguments)
]
end

Expand Down
19 changes: 17 additions & 2 deletions spec/keisan/let_spec.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,32 @@
require "spec_helper"

RSpec.describe Keisan::Functions::Let do
let(:calculator) { Keisan::Calculator.new }

it "can be used to assign variables" do
calculator = Keisan::Calculator.new
calculator.evaluate("let x = 4")
expect(calculator.evaluate("2*x")).to eq 8
end

it "defines variables locally when in block" do
calculator = Keisan::Calculator.new
calculator.evaluate("let x = 7")

expect(calculator.evaluate("{let x = 11; x*2}")).to eq 22
expect(calculator.evaluate("x")).to eq 7
end

it "raises error for single argument when not assignment" do
expect{calculator.evaluate("let x")}.to raise_error(Keisan::Exceptions::InvalidFunctionError)
end

it "works with two arguments for variable assignment" do
calculator.evaluate("let(x, (10+20))")
expect(calculator.evaluate("x").value).to eq 30
end

it "works in sub-expression" do
calculator.evaluate("y = 2*let(x, 3)")
expect(calculator.evaluate("x").value).to eq 3
expect(calculator.evaluate("y").value).to eq 6
end
end

0 comments on commit ff82444

Please sign in to comment.