Skip to content

Commit

Permalink
Fixed function definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcsparker committed Feb 27, 2012
1 parent d719927 commit 02e61a8
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 22 deletions.
18 changes: 6 additions & 12 deletions lib/kalc/ast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -159,29 +159,23 @@ def eval(context)
end

class FunctionDefinition
attr_reader :name
attr_reader :argument_list
attr_reader :body

def initialize(name, argument_list, body)
@name = name
@argument_list = argument_list
@body = body
end

def eval(context)
context.add_function(@name.to_sym, lambda { |parent_context, *argument_list|
context.add_function(@name.to_sym, lambda { |parent_context, *args|
dup_body = @body.dup
cxt = Environment.new(parent_context)

argument_list.each_with_index do |arg, idx|
cxt.add_variable(argument_list[idx].value, arg.eval(cxt))
args.each_with_index do |arg, idx|
cxt.add_variable(@argument_list[idx].value, arg.eval(cxt))
end

@body.eval(cxt)
dup_body.eval(cxt)
})
context.get_function(@name)
nil
end
end

end
end
6 changes: 3 additions & 3 deletions lib/kalc/grammar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ def self.operators(operators={})
}

rule(:function_definition_expression) {
(str('DEF ') >> identifier.as(:name) >>
paren_argument_list.as(:argument_list) >>
left_brace >> function_body.as(:body) >> right_brace).as(:function_definition) |
(str('DEFINE') >> spaces? >> identifier.as(:name) >>
paren_argument_list.as(:argument_list) >>
left_brace >> function_body.as(:body) >> right_brace).as(:function_definition) |
expressions.as(:expressions)
}

Expand Down
20 changes: 13 additions & 7 deletions lib/kalc/interpreter.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# Code inspired by https://github.com/txus/schemer

require 'pp'

module Kalc
class Interpreter

attr_reader :env

def initialize(ast = nil)

@ast = ast

def initialize
@env = Environment.new do |env|

env.add_function(:IF, lambda { |cxt, cond, if_true, if_false|
Expand Down Expand Up @@ -85,12 +84,19 @@ def initialize(ast = nil)
})
end

env.add_function(:P, lambda { |cxt, *output|
p output
})

env.add_function(:PP, lambda { |cxt, *output|
pp output
})

end
end

def run(ast = nil)
@ast = ast if ast
@ast.eval(@env)
def run(ast)
ast.eval(@env)
end
end
end

0 comments on commit 02e61a8

Please sign in to comment.