Module: Halunke::Runtime

Defined in:
lib/halunke/runtime/hweb.rb,
lib/halunke/runtime/harray.rb,
lib/halunke/runtime/hclass.rb,
lib/halunke/runtime/hstdio.rb,
lib/halunke/runtime/hnumber.rb,
lib/halunke/runtime/hobject.rb,
lib/halunke/runtime/hregexp.rb,
lib/halunke/runtime/hstring.rb,
lib/halunke/runtime/hfunction.rb,
lib/halunke/runtime/hdictionary.rb,
lib/halunke/runtime/hnative_object.rb,
lib/halunke/runtime/hunassigned_bareword.rb

Defined Under Namespace

Classes: HClass, HFunction, HNativeObject, HObject

Constant Summary collapse

HWeb =
HClass.new(
  "Web",
  [],
  {
    "run on" => HFunction.new([:self, :app, :host_port], lambda { |context|
      require "rackup"

      host, port = context["host_port"].ruby_value.split(":")

      # TODO: Body, Headers
      Rackup::Handler::WEBrick.run(lambda { |env|
        henv = context["Dictionary"].create_instance({
          context["String"].create_instance("request_method") => context["String"].create_instance(env["REQUEST_METHOD"]),
          context["String"].create_instance("path") => context["String"].create_instance(env["PATH_INFO"]),
          context["String"].create_instance("query") => context["String"].create_instance(env["QUERY_STRING"])
        })
        result = context["app"].receive_message(context, "call", [henv]).ruby_value

        status = result[0].ruby_value

        headers = {}
        result[1].ruby_value.each_pair do |key, value|
          headers[key.ruby_value] = value.ruby_value
        end

        body = result[2].ruby_value.map(&:ruby_value)

        [status.to_i, headers, body]
      }, Host: host, Port: port)

      env["host_port"]
    }),
    "run" => HFunction.new([:self, :app], lambda { |context|
      host_port = HString.create_instance("0.0.0.0:#{ENV['PORT']}")
      context["self"].receive_message(context, "run on", [context["app"], host_port])
    })
  },
  {},
  true
)
HArray =
HClass.new(
  "Array",
  [],
  {
    "@ else" => HFunction.new([:self, :index, :fallback], lambda { |context|
      context["self"].ruby_value[context["index"].ruby_value] || context["fallback"]
    }),
    "=" => HFunction.new([:self, :other], lambda { |context|
      return context["false"] if context["self"].ruby_value.length != context["other"].ruby_value.length

      context["self"].ruby_value.zip(context["other"].ruby_value).map do |a, b|
        a.receive_message(context.parent, "=", [b])
      end.reduce(context["true"]) do |memo, value|
        memo.receive_message(context, "and", [value])
      end
    }),
    "map" => HFunction.new([:self, :fn], lambda { |context|
      return HArray.create_instance(context["self"].ruby_value.map do |x|
        context["fn"].receive_message(context, "call", [HArray.create_instance([x])])
      end)
    }),
    "reduce with" => HFunction.new([:self, :fn, :initial], lambda { |context|
      context["self"].ruby_value.reduce(context["initial"]) do |memo, current|
        context["fn"].receive_message(context, "call", [HArray.create_instance([memo, current])])
      end
    }),
    "find else" => HFunction.new([:self, :search_fn, :fallback], lambda { |context|
      context["self"].ruby_value.find(-> { context["fallback"] }) do |element|
        context["search_fn"].receive_message(context, "call", [HArray.create_instance([element])]) == context["true"]
      end
    }),
    "to_boolean" => HFunction.new([:self], lambda { |context|
      context["true"]
    }),
    "to_string" => HFunction.new([:self], lambda { |context|
      inspected_members = context["self"].ruby_value.map do |member|
        member.receive_message(context, "to_string", []).ruby_value
      end
      HString.create_instance("#{inspected_members.join("\n")}")
    }),
    "inspect" => HFunction.new([:self], lambda { |context|
      inspected_members = context["self"].ruby_value.map { |member| member.inspect(context) }
      HString.create_instance("[#{inspected_members.join(' ')}]")
    })
  },
  {},
  true
)
HStdio =
HClass.new(
  "Stdio",
  [],
  {
    "puts" => HFunction.new([:self, :obj], lambda { |context|
      str = context["obj"].receive_message(context, "to_string", [])
      puts str.ruby_value
      str
    }),
    "examine" => HFunction.new([:self, :obj], lambda { |context|
      str = context["obj"].receive_message(context, "inspect", [])
      puts str.ruby_value
      context["obj"]
    })
  },
  {},
  true
)
HNumber =
HClass.new(
  "Number",
  [],
  {
    "+" => HFunction.new([:self, :other], lambda { |context|
      HNumber.create_instance(context["self"].ruby_value + context["other"].ruby_value)
    }),
    "-" => HFunction.new([:self, :other], lambda { |context|
      HNumber.create_instance(context["self"].ruby_value - context["other"].ruby_value)
    }),
    "/" => HFunction.new([:self, :other], lambda { |context|
      HNumber.create_instance(context["self"].ruby_value / context["other"].ruby_value)
    }),
    "*" => HFunction.new([:self, :other], lambda { |context|
      HNumber.create_instance(context["self"].ruby_value * context["other"].ruby_value)
    }),
    "**" => HFunction.new([:self, :other], lambda { |context|
      HNumber.create_instance(context["self"].ruby_value ** context["other"].ruby_value)
    }),
    "<" => HFunction.new([:self, :other], lambda { |context|
      if context["self"].ruby_value < context["other"].ruby_value
        context["true"]
      else
        context["false"]
      end
    }),
    ">" => HFunction.new([:self, :other], lambda { |context|
      if context["self"].ruby_value > context["other"].ruby_value
        context["true"]
      else
        context["false"]
      end
    }),
    "=" => HFunction.new([:self, :other], lambda { |context|
      if context["self"].ruby_value == context["other"].ruby_value
        context["true"]
      else
        context["false"]
      end
    }),
    "to_boolean" => HFunction.new([:self], lambda { |context|
      context["true"]
    }),
    "to_string" => HFunction.new([:self], lambda { |context|
      float_value = context["self"].ruby_value.to_f
      float_value = float_value.to_i if float_value.to_i == float_value
      HString.create_instance(float_value.to_s)
    }),
    "inspect" => HFunction.new([:self], lambda { |context|
      context["self"].receive_message(context, "to_string", [])
    })
  },
  {},
  true
)
HRegexp =
HClass.new(
  "Regexp",
  [],
  {
    "to_boolean" => HFunction.new([:self], lambda { |context|
      context["true"]
    }),
    "to_string" => HFunction.new([:self], lambda { |context|
      HString.create_instance(context["self"].ruby_value.inspect)
    }),
    "inspect" => HFunction.new([:self], lambda { |context|
      HString.create_instance(context["self"].ruby_value.inspect)
    })
  },
  {
    "new" => HFunction.new([:self, :attr], lambda { |context|
      str = (context["attr"].ruby_value.find do |key, _value|
        key.ruby_value == "string"
      end)[1].ruby_value

      HRegexp.create_instance(Regexp.new(str))
    }),
    "from" => HFunction.new([:self, :str], lambda { |context|
      context["self"].receive_message(
        context,
        "new",
        [HDictionary.create_instance({HString.create_instance("string") => context["str"]})]
      )
    })
  },
  true
)
HString =
HClass.new(
  "String",
  [],
  {
    "reverse" => HFunction.new([:self], lambda { |context|
      HString.create_instance(context["self"].ruby_value.reverse)
    }),
    "replace with" => HFunction.new([:self, :searchword, :replacement], lambda { |context|
      result = context["self"].ruby_value.gsub(
        context["searchword"].ruby_value,
        context["replacement"].ruby_value
      )
      HString.create_instance(result)
    }),
    "match" => HFunction.new([:self, :regexp], lambda { |context|
      match_data = context["self"].ruby_value.match(context["regexp"].ruby_value)
      h = {}
      unless match_data.nil?
        match_data.named_captures.each_pair do |key, value|
          h[HString.create_instance(key)] = HString.create_instance(value)
        end
        match_data.to_a.each_with_index do |value, key|
          h[HString.create_instance(key)] = HString.create_instance(value)
        end
      end
      HDictionary.create_instance(h, source_code_position: NullSourceCodePosition.new)
    }),
    "scan" => HFunction.new([:self, :regexp], lambda { |context|
      result = context["self"].ruby_value.scan(context["regexp"].ruby_value)

      HArray.create_instance(result.map do |r|
        if r.class == Array
          HArray.create_instance(r.map { |x| HString.create_instance(x) })
        else
          HString.create_instance(r)
        end
      end)
    }),
    "=" => HFunction.new([:self, :other], lambda { |context|
      if context["self"].ruby_value == context["other"].ruby_value
        context["true"]
      else
        context["false"]
      end
    }),
    "+" => HFunction.new([:self, :other], lambda { |context|
      HString.create_instance(context["self"].ruby_value + context["other"].ruby_value)
    }),
    "to_boolean" => HFunction.new([:self], lambda { |context|
      context["true"]
    }),
    "to_string" => HFunction.new([:self], lambda { |context|
      context["self"]
    }),
    "inspect" => HFunction.new([:self], lambda { |context|
      HString.create_instance(context["self"].ruby_value.inspect)
    })
  },
  {},
  true
)
HDictionary =
HClass.new(
  "Dictionary",
  [],
  {
    "@ else" => HFunction.new([:self, :search, :fallback], lambda { |context|
      result = context["self"].ruby_value.find do |key, _value|
        key.receive_message(context, "=", [context["search"]]).inspect(context) == "true"
      end
      result ? result[1] : context["fallback"]
    }),
    "merge" => HFunction.new([:self, :other], lambda { |context|
      HDictionary.create_instance(context["self"].ruby_value.merge(context["other"].ruby_value))
    }),
    "to_boolean" => HFunction.new([:self], lambda { |context|
      context["true"]
    }),
    "to_string" => HFunction.new([:self], lambda { |context|
      x = []
      context["self"].ruby_value.each_pair do |key, value|
        key_s = key.receive_message(context, "to_string", [])
        value_s = value.receive_message(context, "to_string", [])
        x.push("#{key_s.ruby_value} #{value_s.ruby_value}")
      end
      HString.create_instance(x.join("\n"))
    }),
    "inspect" => HFunction.new([:self], lambda { |context|
      x = []
      context["self"].ruby_value.each_pair do |key, value|
        x.push(key.inspect(context))
        x.push(value.inspect(context))
      end
      HString.create_instance("@[#{x.join(' ')}]")
    })
  },
  {
    "from" => HFunction.new([:self, :array], lambda { |context|
      context["self"].create_instance(context["array"].ruby_value.map(&:ruby_value).to_h)
    })
  },
  true
)
HUnassignedBareword =
HClass.new(
  "UnassignedBareword",
  [],
  {
    "=" => HFunction.new([:self, :other], lambda { |context|
      bareword_name = context["self"].ruby_value

      begin
        context.parent[bareword_name] = context["other"]
      rescue
        assigned_value = context.parent[context["self"].ruby_value].inspect(context)
        raise HBarewordAlreadyAssigned.new("Bareword '#{bareword_name} is already assigned to #{assigned_value}. In Halunke, you can only assign once.", context["self"].source_code_position)
      end
      context["true"]
    }),
    "inspect" => HFunction.new([:self], lambda { |context|
      HString.create_instance("'#{context["self"].ruby_value}")
    })
  },
  {},
  true
)