class Aster::Environment

Attributes

stderr[R]
stdout[R]

Public Class Methods

new(parent = nil) click to toggle source
# File lib/aster/environment.rb, line 7
def initialize(parent = nil)
  @parent = parent
  @env = {}
  @stdout, @stderr = "", ""

  define_base_environment if parent.nil?
end

Public Instance Methods

[](k) click to toggle source
# File lib/aster/environment.rb, line 19
def [](k)
  @env[k.to_sym] || @parent && @parent[k.to_sym]
end
[]=(k, v) click to toggle source
# File lib/aster/environment.rb, line 23
def []=(k, v)
  @env[k.to_sym] = v
end
child() click to toggle source
# File lib/aster/environment.rb, line 15
def child
  self.class.new(self)
end
define_function(name, args, commands = nil, &block) click to toggle source
# File lib/aster/environment.rb, line 32
def define_function(name, args, commands = nil, &block)
  self[name] = Function.new(args, commands, &block)
end
define_macro(name, &block) click to toggle source
# File lib/aster/environment.rb, line 36
def define_macro(name, &block)
  self[name] = Macro.new self, block
end
eval(script) click to toggle source
# File lib/aster/environment.rb, line 27
def eval(script)
  tree = Parser.new.parse script
  eval_tree tree
end

Private Instance Methods

define_base_environment() click to toggle source
# File lib/aster/environment.rb, line 42
def define_base_environment
  define_function :echo, [:_list_] do |arguments|
    @stdout << arguments.join(' ')
  end

  define_function :equal, [:a, :b] do |(a, b)|
    a.to_s == b.to_s ? "yes" : "no"
  end

  define_function :add, [:_list_] do |arguments|
    arguments.inject(0){|r, s| s.to_i + r}.to_s
  end

end
eval_argument(arg) click to toggle source
# File lib/aster/environment.rb, line 93
def eval_argument(arg)
  if arg.is_a?(Command)
    eval_command(arg)
  elsif arg.is_a?(Variable)
    self[arg.name]
  else
    arg
  end
end
eval_arguments(arguments) click to toggle source
# File lib/aster/environment.rb, line 103
def eval_arguments(arguments)
  arguments.map{|arg| eval_argument arg}
end
eval_command(command) click to toggle source
# File lib/aster/environment.rb, line 58
def eval_command(command)
  case command.function_name
  when :function
    fun, *args = command.arguments
    
    self.define_function(
      fun,
      args,
      command.sub_commands
    )
  when :if
    cond_value = eval_argument command.arguments.first
    eval_tree command.sub_commands if is_true?(cond_value)
  when :set
    var, value, _ = command.arguments
    self[var] = eval_argument value
  when :not
    cond_value = eval_arguments([command.arguments.first]).first
    is_true?(cond_value) ? "no" : "yes"
  else
    case function_or_macro = self[command.function_name]
    when Function
      eval_function(
        function_or_macro, 
        eval_arguments(command.arguments), 
        self.child
      )
    when Macro
      eval_macro(function_or_macro, command)
    else
      # ?            binding.pry
    end
  end
end
eval_function(function, arguments, env) click to toggle source
# File lib/aster/environment.rb, line 126
def eval_function(function, arguments, env)
  # bind arguments to new env
  function.arguments.each_with_index do |a, i|
    env[a] = arguments[i]
  end

  if function.commands
    env.send :eval_tree, function.commands
  elsif function.block
    function.block.call arguments
  else
    raise
  end        
end
eval_macro(macro, command) click to toggle source
# File lib/aster/environment.rb, line 117
def eval_macro(macro, command)
  command_or_commands = macro.function(command)
  if command_or_commands.is_a?(Array)
    eval_tree command_or_commands
  else
    eval_command command_or_commands
  end
end
eval_tree(tree) click to toggle source
# File lib/aster/environment.rb, line 111
def eval_tree(tree)
  tree.map do |command|
    res = eval_command command
  end.last
end
is_true?(val) click to toggle source
# File lib/aster/environment.rb, line 107
def is_true?(val)
  val && val.strip == "yes"
end