halunke 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -1
- data/examples/hello.hal +19 -0
- data/examples/web.hal +20 -0
- data/exe/halunke +11 -7
- data/halunke.gemspec +2 -0
- data/lib/halunke/grammar.y +16 -32
- data/lib/halunke/interpreter.rb +56 -2
- data/lib/halunke/lexer.rb +95 -80
- data/lib/halunke/lexer.rl +7 -3
- data/lib/halunke/nodes.rb +24 -25
- data/lib/halunke/parser.rb +97 -112
- data/lib/halunke/runtime.rb +11 -222
- data/lib/halunke/runtime/false.hal +18 -0
- data/lib/halunke/runtime/harray.rb +30 -0
- data/lib/halunke/runtime/hclass.rb +96 -0
- data/lib/halunke/runtime/hdictionary.rb +26 -0
- data/lib/halunke/runtime/hfunction.rb +27 -0
- data/lib/halunke/runtime/hnative_object.rb +21 -0
- data/lib/halunke/runtime/hnumber.rb +41 -0
- data/lib/halunke/runtime/hobject.rb +30 -0
- data/lib/halunke/runtime/hstdout.rb +16 -0
- data/lib/halunke/runtime/hstring.rb +35 -0
- data/lib/halunke/runtime/hunassigned_bareword.rb +19 -0
- data/lib/halunke/runtime/hweb.rb +40 -0
- data/lib/halunke/runtime/true.hal +18 -0
- data/lib/halunke/version.rb +1 -1
- metadata +31 -2
    
        data/lib/halunke/runtime.rb
    CHANGED
    
    | @@ -1,222 +1,11 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
                  HObject.new(self, ruby_value)
         | 
| 13 | 
            -
                end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
                def lookup(message)
         | 
| 16 | 
            -
                  @runtime_methods.fetch(message)
         | 
| 17 | 
            -
                rescue KeyError
         | 
| 18 | 
            -
                  raise "Class #{@name} has no method to respond to message '#{message}'"
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
              end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
              class HObject
         | 
| 23 | 
            -
                attr_reader :ruby_value
         | 
| 24 | 
            -
             | 
| 25 | 
            -
                def initialize(runtime_class, ruby_value = nil)
         | 
| 26 | 
            -
                  @runtime_class = runtime_class
         | 
| 27 | 
            -
                  @ruby_value = ruby_value
         | 
| 28 | 
            -
                end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                def receive_message(context, message_name, message_value)
         | 
| 31 | 
            -
                  m = @runtime_class.lookup(message_name)
         | 
| 32 | 
            -
                  m.call(context, [self].concat(message_value))
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                def inspect(context)
         | 
| 36 | 
            -
                  receive_message(context, "inspect", []).ruby_value
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
              end
         | 
| 39 | 
            -
             | 
| 40 | 
            -
              class HFunction
         | 
| 41 | 
            -
                def initialize(signature, fn)
         | 
| 42 | 
            -
                  @signature = signature
         | 
| 43 | 
            -
                  @fn = fn
         | 
| 44 | 
            -
                end
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                # TODO: This is a little bit of duplication that could probably be cleaned up by making functions proper objects
         | 
| 47 | 
            -
                def receive_message(context, message_name, message_value)
         | 
| 48 | 
            -
                  raise "Class Function has no method to respond to message '#{message_name}'" unless message_name == "call"
         | 
| 49 | 
            -
                  call(context, message_value[0].ruby_value)
         | 
| 50 | 
            -
                end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                def call(parent_context, args)
         | 
| 53 | 
            -
                  context = parent_context.create_child
         | 
| 54 | 
            -
                  @signature.zip(args).each do |name, value|
         | 
| 55 | 
            -
                    context[name.to_s] = value
         | 
| 56 | 
            -
                  end
         | 
| 57 | 
            -
                  @fn.call(context)
         | 
| 58 | 
            -
                end
         | 
| 59 | 
            -
              end
         | 
| 60 | 
            -
             | 
| 61 | 
            -
              class HContext
         | 
| 62 | 
            -
                def initialize(parent_context = nil)
         | 
| 63 | 
            -
                  @parent_context = parent_context
         | 
| 64 | 
            -
                  @context = {}
         | 
| 65 | 
            -
                end
         | 
| 66 | 
            -
             | 
| 67 | 
            -
                def []=(name, value)
         | 
| 68 | 
            -
                  @context[name] = value
         | 
| 69 | 
            -
                end
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                def [](name)
         | 
| 72 | 
            -
                  @context.fetch(name)
         | 
| 73 | 
            -
                rescue KeyError
         | 
| 74 | 
            -
                  raise "Undefined bareword '#{name}'" if @parent_context.nil?
         | 
| 75 | 
            -
                  @parent_context[name]
         | 
| 76 | 
            -
                end
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                def parent
         | 
| 79 | 
            -
                  @parent_context
         | 
| 80 | 
            -
                end
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                def key?(name)
         | 
| 83 | 
            -
                  @context.key?(name)
         | 
| 84 | 
            -
                end
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                def create_child
         | 
| 87 | 
            -
                  HContext.new(self)
         | 
| 88 | 
            -
                end
         | 
| 89 | 
            -
             | 
| 90 | 
            -
                def self.root_context
         | 
| 91 | 
            -
                  context = new
         | 
| 92 | 
            -
             | 
| 93 | 
            -
                  context["Number"] = HNumber
         | 
| 94 | 
            -
                  context["String"] = HString
         | 
| 95 | 
            -
                  context["Array"] = HArray
         | 
| 96 | 
            -
                  context["UnassignedBareword"] = HUnassignedBareword
         | 
| 97 | 
            -
                  context["True"] = HTrue
         | 
| 98 | 
            -
                  context["False"] = HFalse
         | 
| 99 | 
            -
                  context["true"] = HTrue.create_instance
         | 
| 100 | 
            -
                  context["false"] = HFalse.create_instance
         | 
| 101 | 
            -
             | 
| 102 | 
            -
                  context
         | 
| 103 | 
            -
                end
         | 
| 104 | 
            -
              end
         | 
| 105 | 
            -
             | 
| 106 | 
            -
              HNumber = HClass.new(
         | 
| 107 | 
            -
                "Number",
         | 
| 108 | 
            -
                "+" => HFunction.new([:self, :other], lambda { |context|
         | 
| 109 | 
            -
                  HNumber.create_instance(context["self"].ruby_value + context["other"].ruby_value)
         | 
| 110 | 
            -
                }),
         | 
| 111 | 
            -
                "<" => HFunction.new([:self, :other], lambda { |context|
         | 
| 112 | 
            -
                  if context["self"].ruby_value < context["other"].ruby_value
         | 
| 113 | 
            -
                    HTrue.create_instance
         | 
| 114 | 
            -
                  else
         | 
| 115 | 
            -
                    HFalse.create_instance
         | 
| 116 | 
            -
                  end
         | 
| 117 | 
            -
                }),
         | 
| 118 | 
            -
                ">" => HFunction.new([:self, :other], lambda { |context|
         | 
| 119 | 
            -
                  if context["self"].ruby_value > context["other"].ruby_value
         | 
| 120 | 
            -
                    HTrue.create_instance
         | 
| 121 | 
            -
                  else
         | 
| 122 | 
            -
                    HFalse.create_instance
         | 
| 123 | 
            -
                  end
         | 
| 124 | 
            -
                }),
         | 
| 125 | 
            -
                "=" => HFunction.new([:self, :other], lambda { |context|
         | 
| 126 | 
            -
                  if context["self"].ruby_value == context["other"].ruby_value
         | 
| 127 | 
            -
                    HTrue.create_instance
         | 
| 128 | 
            -
                  else
         | 
| 129 | 
            -
                    HFalse.create_instance
         | 
| 130 | 
            -
                  end
         | 
| 131 | 
            -
                }),
         | 
| 132 | 
            -
                "inspect" => HFunction.new([:self], lambda { |context|
         | 
| 133 | 
            -
                  float_value = context["self"].ruby_value.to_f
         | 
| 134 | 
            -
                  float_value = float_value.to_i if float_value.to_i == float_value
         | 
| 135 | 
            -
                  HString.create_instance(float_value.to_s)
         | 
| 136 | 
            -
                })
         | 
| 137 | 
            -
              )
         | 
| 138 | 
            -
             | 
| 139 | 
            -
              HString = HClass.new(
         | 
| 140 | 
            -
                "String",
         | 
| 141 | 
            -
                "reverse" => HFunction.new([:self], lambda { |context|
         | 
| 142 | 
            -
                  HString.create_instance(context["self"].ruby_value.reverse)
         | 
| 143 | 
            -
                }),
         | 
| 144 | 
            -
                "replace with" => HFunction.new([:self, :searchword, :replacement], lambda { |context|
         | 
| 145 | 
            -
                  result = context["self"].ruby_value.gsub(
         | 
| 146 | 
            -
                    context["searchword"].ruby_value,
         | 
| 147 | 
            -
                    context["replacement"].ruby_value
         | 
| 148 | 
            -
                  )
         | 
| 149 | 
            -
                  HString.create_instance(result)
         | 
| 150 | 
            -
                }),
         | 
| 151 | 
            -
                "=" => HFunction.new([:self, :other], lambda { |context|
         | 
| 152 | 
            -
                  if context["self"].ruby_value == context["other"].ruby_value
         | 
| 153 | 
            -
                    HTrue.create_instance
         | 
| 154 | 
            -
                  else
         | 
| 155 | 
            -
                    HFalse.create_instance
         | 
| 156 | 
            -
                  end
         | 
| 157 | 
            -
                }),
         | 
| 158 | 
            -
                "inspect" => HFunction.new([:self], lambda { |context|
         | 
| 159 | 
            -
                  HString.create_instance(context["self"].ruby_value.inspect)
         | 
| 160 | 
            -
                })
         | 
| 161 | 
            -
              )
         | 
| 162 | 
            -
             | 
| 163 | 
            -
              HArray = HClass.new(
         | 
| 164 | 
            -
                "Array",
         | 
| 165 | 
            -
                "inspect" => HFunction.new([:self], lambda { |context|
         | 
| 166 | 
            -
                  inspected_members = context["self"].ruby_value.map { |member| member.inspect(context) }
         | 
| 167 | 
            -
                  HString.create_instance("[#{inspected_members.join(' ')}]")
         | 
| 168 | 
            -
                }),
         | 
| 169 | 
            -
                "=" => HFunction.new([:self, :other], lambda { |context|
         | 
| 170 | 
            -
                  return HFalse.create_instance if context["self"].ruby_value.length != context["other"].ruby_value.length
         | 
| 171 | 
            -
             | 
| 172 | 
            -
                  context["self"].ruby_value.zip(context["other"].ruby_value).map do |a, b|
         | 
| 173 | 
            -
                    a.receive_message(context.parent, "=", [b])
         | 
| 174 | 
            -
                  end.reduce(HTrue.create_instance) do |memo, value|
         | 
| 175 | 
            -
                    memo.receive_message(context, "and", [value])
         | 
| 176 | 
            -
                  end
         | 
| 177 | 
            -
                })
         | 
| 178 | 
            -
              )
         | 
| 179 | 
            -
             | 
| 180 | 
            -
              HUnassignedBareword = HClass.new(
         | 
| 181 | 
            -
                "UnassignedBareword",
         | 
| 182 | 
            -
                "=" => HFunction.new([:self, :other], lambda { |context|
         | 
| 183 | 
            -
                  context.parent[context["self"].ruby_value] = context["other"]
         | 
| 184 | 
            -
                  HTrue.create_instance
         | 
| 185 | 
            -
                }),
         | 
| 186 | 
            -
                "inspect" => HFunction.new([:self], lambda { |context|
         | 
| 187 | 
            -
                  HString.create_instance("'#{context["self"].ruby_value}")
         | 
| 188 | 
            -
                })
         | 
| 189 | 
            -
              )
         | 
| 190 | 
            -
             | 
| 191 | 
            -
              HTrue = HClass.new(
         | 
| 192 | 
            -
                "True",
         | 
| 193 | 
            -
                "and" => HFunction.new([:self, :other], lambda { |context|
         | 
| 194 | 
            -
                  context["other"]
         | 
| 195 | 
            -
                }),
         | 
| 196 | 
            -
                "or" => HFunction.new([:self, :other], lambda { |context|
         | 
| 197 | 
            -
                  context["self"]
         | 
| 198 | 
            -
                }),
         | 
| 199 | 
            -
                "then else" => HFunction.new([:self, :true_branch, :false_branch], lambda { |context|
         | 
| 200 | 
            -
                  context["true_branch"].receive_message(context, "call", [HArray.create_instance([])])
         | 
| 201 | 
            -
                }),
         | 
| 202 | 
            -
                "inspect" => HFunction.new([:self], lambda {|context|
         | 
| 203 | 
            -
                  HString.create_instance("true")
         | 
| 204 | 
            -
                })
         | 
| 205 | 
            -
              )
         | 
| 206 | 
            -
             | 
| 207 | 
            -
              HFalse = HClass.new(
         | 
| 208 | 
            -
                "False",
         | 
| 209 | 
            -
                "and" => HFunction.new([:self, :other], lambda { |context|
         | 
| 210 | 
            -
                  context["self"]
         | 
| 211 | 
            -
                }),
         | 
| 212 | 
            -
                "or" => HFunction.new([:self, :other], lambda { |context|
         | 
| 213 | 
            -
                  context["other"]
         | 
| 214 | 
            -
                }),
         | 
| 215 | 
            -
                "then else" => HFunction.new([:self, :true_branch, :false_branch], lambda { |context|
         | 
| 216 | 
            -
                  context["false_branch"].receive_message(context, "call", [HArray.create_instance([])])
         | 
| 217 | 
            -
                }),
         | 
| 218 | 
            -
                "inspect" => HFunction.new([:self], lambda {|context|
         | 
| 219 | 
            -
                  HString.create_instance("false")
         | 
| 220 | 
            -
                })
         | 
| 221 | 
            -
              )
         | 
| 222 | 
            -
            end
         | 
| 1 | 
            +
            require "halunke/runtime/hclass"
         | 
| 2 | 
            +
            require "halunke/runtime/hobject"
         | 
| 3 | 
            +
            require "halunke/runtime/hnative_object"
         | 
| 4 | 
            +
            require "halunke/runtime/hfunction"
         | 
| 5 | 
            +
            require "halunke/runtime/hnumber"
         | 
| 6 | 
            +
            require "halunke/runtime/hstring"
         | 
| 7 | 
            +
            require "halunke/runtime/harray"
         | 
| 8 | 
            +
            require "halunke/runtime/hdictionary"
         | 
| 9 | 
            +
            require "halunke/runtime/hunassigned_bareword"
         | 
| 10 | 
            +
            require "halunke/runtime/hstdout"
         | 
| 11 | 
            +
            require "halunke/runtime/hweb"
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            (Class new 'False
         | 
| 2 | 
            +
              methods @[
         | 
| 3 | 
            +
                "and" { |'self 'other|
         | 
| 4 | 
            +
                  self
         | 
| 5 | 
            +
                }
         | 
| 6 | 
            +
                "or" { |'self 'other|
         | 
| 7 | 
            +
                  other
         | 
| 8 | 
            +
                }
         | 
| 9 | 
            +
                "then else" { |'self 'true_branch 'false_branch|
         | 
| 10 | 
            +
                  (false_branch call [])
         | 
| 11 | 
            +
                }
         | 
| 12 | 
            +
                "inspect" { |'self 'other|
         | 
| 13 | 
            +
                  "false"
         | 
| 14 | 
            +
                }
         | 
| 15 | 
            +
              ]
         | 
| 16 | 
            +
            )
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            ('false = (False new))
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            module Halunke
         | 
| 2 | 
            +
              module Runtime
         | 
| 3 | 
            +
                HArray = HClass.new(
         | 
| 4 | 
            +
                  "Array",
         | 
| 5 | 
            +
                  [],
         | 
| 6 | 
            +
                  {
         | 
| 7 | 
            +
                    "inspect" => HFunction.new([:self], lambda { |context|
         | 
| 8 | 
            +
                      inspected_members = context["self"].ruby_value.map { |member| member.inspect(context) }
         | 
| 9 | 
            +
                      HString.create_instance("[#{inspected_members.join(' ')}]")
         | 
| 10 | 
            +
                    }),
         | 
| 11 | 
            +
                    "=" => HFunction.new([:self, :other], lambda { |context|
         | 
| 12 | 
            +
                      return context["false"] if context["self"].ruby_value.length != context["other"].ruby_value.length
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                      context["self"].ruby_value.zip(context["other"].ruby_value).map do |a, b|
         | 
| 15 | 
            +
                        a.receive_message(context.parent, "=", [b])
         | 
| 16 | 
            +
                      end.reduce(context["true"]) do |memo, value|
         | 
| 17 | 
            +
                        memo.receive_message(context, "and", [value])
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
                    }),
         | 
| 20 | 
            +
                    "map" => HFunction.new([:self, :fn], lambda { |context|
         | 
| 21 | 
            +
                      return HArray.create_instance(context["self"].ruby_value.map do |x|
         | 
| 22 | 
            +
                        context["fn"].receive_message(context, "call", [HArray.create_instance([x])])
         | 
| 23 | 
            +
                      end)
         | 
| 24 | 
            +
                    })
         | 
| 25 | 
            +
                  },
         | 
| 26 | 
            +
                  {},
         | 
| 27 | 
            +
                  true
         | 
| 28 | 
            +
                )
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,96 @@ | |
| 1 | 
            +
            module Halunke
         | 
| 2 | 
            +
              module Runtime
         | 
| 3 | 
            +
                class HClass
         | 
| 4 | 
            +
                  attr_reader :name
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def initialize(name, allowed_attributes, instance_methods, class_methods, native)
         | 
| 7 | 
            +
                    @name = name
         | 
| 8 | 
            +
                    @allowed_attributes = allowed_attributes
         | 
| 9 | 
            +
                    @instance_methods = instance_methods
         | 
| 10 | 
            +
                    @class_methods = class_methods
         | 
| 11 | 
            +
                    @native = native
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                  class << self
         | 
| 15 | 
            +
                    def receive_message(context, message_name, message_value)
         | 
| 16 | 
            +
                      case message_name
         | 
| 17 | 
            +
                      when "new attributes methods class_methods"
         | 
| 18 | 
            +
                        name = determine_name(message_value[0])
         | 
| 19 | 
            +
                        allowed_attributes = determine_allowed_attributes(message_value[1])
         | 
| 20 | 
            +
                        instance_methods = determine_methods(message_value[2])
         | 
| 21 | 
            +
                        class_methods = determine_methods(message_value[3])
         | 
| 22 | 
            +
                      when "new attributes methods"
         | 
| 23 | 
            +
                        name = determine_name(message_value[0])
         | 
| 24 | 
            +
                        allowed_attributes = determine_allowed_attributes(message_value[1])
         | 
| 25 | 
            +
                        instance_methods = determine_methods(message_value[2])
         | 
| 26 | 
            +
                        class_methods = {}
         | 
| 27 | 
            +
                      when "new methods"
         | 
| 28 | 
            +
                        name = determine_name(message_value[0])
         | 
| 29 | 
            +
                        allowed_attributes = []
         | 
| 30 | 
            +
                        instance_methods = determine_methods(message_value[1])
         | 
| 31 | 
            +
                        class_methods = {}
         | 
| 32 | 
            +
                      else
         | 
| 33 | 
            +
                        raise "Class Class has no method to respond to message '#{message_name}'"
         | 
| 34 | 
            +
                      end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      context[name] = HClass.new(name, allowed_attributes, instance_methods, class_methods, false)
         | 
| 37 | 
            +
                    end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    private
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    def determine_name(hstring)
         | 
| 42 | 
            +
                      hstring.ruby_value
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    def determine_allowed_attributes(harray)
         | 
| 46 | 
            +
                      harray.ruby_value.map(&:ruby_value)
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    def determine_methods(hdictionary)
         | 
| 50 | 
            +
                      instance_methods = {}
         | 
| 51 | 
            +
                      hdictionary.ruby_value.each_pair do |method_name, fn|
         | 
| 52 | 
            +
                        instance_methods[method_name.ruby_value] = fn
         | 
| 53 | 
            +
                      end
         | 
| 54 | 
            +
                      instance_methods
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  def receive_message(context, message_name, message_value)
         | 
| 59 | 
            +
                    if message_name == "new"
         | 
| 60 | 
            +
                      create_instance(message_value[0])
         | 
| 61 | 
            +
                    elsif @class_methods.keys.include? message_name
         | 
| 62 | 
            +
                      m = @class_methods[message_name]
         | 
| 63 | 
            +
                      m.receive_message(context, "call", [HArray.create_instance([self].concat(message_value))])
         | 
| 64 | 
            +
                    else
         | 
| 65 | 
            +
                      raise "Class #{@name} has no method to respond to message '#{message_name}'"
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  def allowed_attribute?(attribute_name)
         | 
| 70 | 
            +
                    @allowed_attributes.include? attribute_name
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  def create_instance(value = nil)
         | 
| 74 | 
            +
                    if native?
         | 
| 75 | 
            +
                      HNativeObject.new(self, value)
         | 
| 76 | 
            +
                    else
         | 
| 77 | 
            +
                      HObject.new(self, value ? value.ruby_value : {})
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                  end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  def lookup(message)
         | 
| 82 | 
            +
                    @instance_methods.fetch(message)
         | 
| 83 | 
            +
                  rescue KeyError
         | 
| 84 | 
            +
                    raise "Class #{@name} has no method to respond to message '#{message}'"
         | 
| 85 | 
            +
                  end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  def inspect(_context)
         | 
| 88 | 
            +
                    "#<Class #{@name}>"
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                  def native?
         | 
| 92 | 
            +
                    @native
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
              end
         | 
| 96 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            module Halunke
         | 
| 2 | 
            +
              module Runtime
         | 
| 3 | 
            +
                HDictionary = HClass.new(
         | 
| 4 | 
            +
                  "Dictionary",
         | 
| 5 | 
            +
                  [],
         | 
| 6 | 
            +
                  {
         | 
| 7 | 
            +
                    "inspect" => HFunction.new([:self], lambda { |context|
         | 
| 8 | 
            +
                      x = []
         | 
| 9 | 
            +
                      context["self"].ruby_value.each_pair do |key, value|
         | 
| 10 | 
            +
                        x.push(key.inspect(context))
         | 
| 11 | 
            +
                        x.push(value.inspect(context))
         | 
| 12 | 
            +
                      end
         | 
| 13 | 
            +
                      HString.create_instance("@[#{x.join(' ')}]")
         | 
| 14 | 
            +
                    }),
         | 
| 15 | 
            +
                    "@ else" => HFunction.new([:self, :search, :fallback], lambda { |context|
         | 
| 16 | 
            +
                      result = context["self"].ruby_value.find do |key, _value|
         | 
| 17 | 
            +
                        key.receive_message(context, "=", [context["search"]]).inspect(context) == "true"
         | 
| 18 | 
            +
                      end
         | 
| 19 | 
            +
                      result ? result[1] : context["fallback"]
         | 
| 20 | 
            +
                    })
         | 
| 21 | 
            +
                  },
         | 
| 22 | 
            +
                  {},
         | 
| 23 | 
            +
                  true
         | 
| 24 | 
            +
                )
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            module Halunke
         | 
| 2 | 
            +
              module Runtime
         | 
| 3 | 
            +
                class HFunction
         | 
| 4 | 
            +
                  def initialize(signature, fn)
         | 
| 5 | 
            +
                    @signature = signature
         | 
| 6 | 
            +
                    @fn = fn
         | 
| 7 | 
            +
                  end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def receive_message(parent_context, message_name, message_value)
         | 
| 10 | 
            +
                    raise "Class Function has no method to respond to message '#{message_name}'" unless message_name == "call"
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                    context = parent_context.create_child
         | 
| 13 | 
            +
                    args = message_value[0].ruby_value
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                    @signature.zip(args).each do |name, value|
         | 
| 16 | 
            +
                      context[name.to_s] = value
         | 
| 17 | 
            +
                    end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                    @fn.call(context)
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def inspect(_context)
         | 
| 23 | 
            +
                    "#<Function (#{@signature.length})>"
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            module Halunke
         | 
| 2 | 
            +
              module Runtime
         | 
| 3 | 
            +
                class HNativeObject
         | 
| 4 | 
            +
                  attr_reader :ruby_value
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  def initialize(runtime_class, ruby_value = nil)
         | 
| 7 | 
            +
                    @runtime_class = runtime_class
         | 
| 8 | 
            +
                    @ruby_value = ruby_value
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def receive_message(context, message_name, message_value)
         | 
| 12 | 
            +
                    m = @runtime_class.lookup(message_name)
         | 
| 13 | 
            +
                    m.receive_message(context, "call", [HArray.create_instance([self].concat(message_value))])
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  def inspect(context)
         | 
| 17 | 
            +
                    receive_message(context, "inspect", []).ruby_value
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         |