<commit_before>(ns clojure-ruby.evaluate)

(declare evaluate)

(defn evaluate-body [system body]
  (mapv (partial evaluate system) body))

(defn ruby-msg [system obj method-name args]
  (if-let [meth (get-in obj [:methods method-name])]
    (apply meth system obj args)
    (throw (ex-info "Method lookup failed" {:object obj, :method method-name}))))

(defmulti evaluate-one (fn [vars stmt] (first stmt)))

(defmethod evaluate-one :assignment [system stmt]
  (let [[_ name val] stmt
        val (evaluate system val)]
    (swap! (:variables system) assoc name val)))

(defmethod evaluate-one :reference [system stmt]
  (let [[_ name] stmt]
    (if-let [var (get @(:variables system) name)]
      var
      (if-let [meth (get @(:methods system) name)]
        (evaluate-body system meth)
        (throw (ex-info "Cannot find variable or method" {:name name}))))))

(defmethod evaluate-one :method-call [system stmt]
  (let [[_ obj method & args] stmt
        obj (evaluate system obj)
        args (map (partial evaluate system) args)]
    (ruby-msg system obj method args)))

(defmethod evaluate-one :number [system stmt]
  (let [[_ val] stmt
        {:keys [create-number]} system]
    (create-number (Long. val))))

(defmethod evaluate-one :string [system stmt]
  (let [[_ val] stmt
        {:keys [create-string]} system]
    (create-string val)))

(defmethod evaluate-one :if [system stmt]
 (let [[_ & branches] stmt
       {:keys [as-host-boolean]} system]
   (loop [branches branches]
     (if-let [[branch & branches] branches]
       (let [[_ predicate & body] branch]
         (if (as-host-boolean (evaluate system predicate))
           (evaluate-body system body)
           (recur branches)))))))

(defmethod evaluate-one :while [system stmt]
  (let [[_ predicate & body] stmt
        {:keys [as-host-boolean]} system]
    (while (as-host-boolean (evaluate system predicate))
      (evaluate-body system body))))

(defmethod evaluate-one :until [system stmt]
  (let [[_ predicate & body] stmt
        {:keys [as-host-boolean]} system]
    (while (not (as-host-boolean (evaluate system predicate)))
      (evaluate-body system body))))

(defmethod evaluate-one :case [system stmt]
  (let [[_ predicate & whens] stmt
        predicate (evaluate system predicate)
        {:keys [as-host-boolean]} system]
    (loop [whens whens]
      (if-let [[when & whens] (seq whens)]
        (let [[_ matcher & body] when
              matcher (evaluate system matcher)]
          (if (as-host-boolean (ruby-msg system predicate "===" [matcher]))
            (evaluate-body system body)
            (recur whens)))))))

(defmethod evaluate-one :method-def [system stmt]
  (let [[_ name args & body] stmt]
    (swap! (:methods system) assoc name body)))

(defn evaluate [system stmt]
  (try
    (evaluate-one system stmt)
    (catch Exception e
      (throw (ex-info "Evaluation failed" {:statement stmt} e)))))

(defn evaluate-all [create-string create-number as-host-boolean initial-variables stmts]
  (let [system {:variables (atom initial-variables)
                :methods (atom {})
                :create-string create-string
                :create-number create-number
                :as-host-boolean as-host-boolean}]
    (doseq [stmt stmts]
      (evaluate system stmt))))
<commit_msg>Store Ruby-defined methods directly on the object<commit_after>(ns clojure-ruby.evaluate)

(declare evaluate)

(defn evaluate-body [system body]
  (mapv (partial evaluate system) body))

(defn method-lookup [obj method-name]
  (get-in obj [:methods method-name]))

(defn ruby-msg [system obj method-name args]
  (if-let [meth (method-lookup obj method-name)]
    (if (fn? meth)
      (apply meth system obj args)
      (evaluate-body system meth))
    (throw (ex-info "Method lookup failed" {:object obj, :method method-name}))))

(defmulti evaluate-one (fn [vars stmt] (first stmt)))

(defmethod evaluate-one :assignment [system stmt]
  (let [[_ name val] stmt
        val (evaluate system val)]
    (swap! (:variables system) assoc name val)))

(defmethod evaluate-one :reference [system stmt]
  (let [[_ name] stmt]
    (if-let [var (get @(:variables system) name)]
      var
      (let [self (get @(:variables system) "self")]
        (if (method-lookup self name)
          (ruby-msg system self name [])
          (throw (ex-info "Cannot find variable or method" {:name name})))))))

(defmethod evaluate-one :method-call [system stmt]
  (let [[_ obj method & args] stmt
        obj (evaluate system obj)
        args (map (partial evaluate system) args)]
    (ruby-msg system obj method args)))

(defmethod evaluate-one :number [system stmt]
  (let [[_ val] stmt
        {:keys [create-number]} system]
    (create-number (Long. val))))

(defmethod evaluate-one :string [system stmt]
  (let [[_ val] stmt
        {:keys [create-string]} system]
    (create-string val)))

(defmethod evaluate-one :if [system stmt]
 (let [[_ & branches] stmt
       {:keys [as-host-boolean]} system]
   (loop [branches branches]
     (if-let [[branch & branches] branches]
       (let [[_ predicate & body] branch]
         (if (as-host-boolean (evaluate system predicate))
           (evaluate-body system body)
           (recur branches)))))))

(defmethod evaluate-one :while [system stmt]
  (let [[_ predicate & body] stmt
        {:keys [as-host-boolean]} system]
    (while (as-host-boolean (evaluate system predicate))
      (evaluate-body system body))))

(defmethod evaluate-one :until [system stmt]
  (let [[_ predicate & body] stmt
        {:keys [as-host-boolean]} system]
    (while (not (as-host-boolean (evaluate system predicate)))
      (evaluate-body system body))))

(defmethod evaluate-one :case [system stmt]
  (let [[_ predicate & whens] stmt
        predicate (evaluate system predicate)
        {:keys [as-host-boolean]} system]
    (loop [whens whens]
      (if-let [[when & whens] (seq whens)]
        (let [[_ matcher & body] when
              matcher (evaluate system matcher)]
          (if (as-host-boolean (ruby-msg system predicate "===" [matcher]))
            (evaluate-body system body)
            (recur whens)))))))

(defmethod evaluate-one :method-def [system stmt]
  (let [[_ name args & body] stmt]
    (swap! (:variables system) assoc-in ["self" :methods name] body)))

(defn evaluate [system stmt]
  (try
    (evaluate-one system stmt)
    (catch Exception e
      (throw (ex-info "Evaluation failed" {:statement stmt} e)))))

(defn evaluate-all [create-string create-number as-host-boolean initial-variables stmts]
  (let [system {:variables (atom initial-variables)
                :create-string create-string
                :create-number create-number
                :as-host-boolean as-host-boolean}]
    (doseq [stmt stmts]
      (evaluate system stmt))))

{'fraction_non_alphanumeric': 0.13955542470189902, 'fraction_numerical': 0.0, 'mean_word_length': 3.012994683992912, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2987707', 'n_tokens_mistral': 2162, 'n_tokens_neox': 2077, 'n_words': 678}