Skip to content

Commit

Permalink
feat: adding list constructor and list operations
Browse files Browse the repository at this point in the history
  • Loading branch information
BRonen committed Apr 7, 2024
1 parent 76ce920 commit b30b775
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 11 deletions.
55 changes: 45 additions & 10 deletions src/bronen/kekwisp.clj
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(ns bronen.kekwisp)
(ns bronen.kekwisp
(:require [clojure.core.reducers :as r]))

(defn quote? [s] (and (not= s \")
(not= s \))
Expand Down Expand Up @@ -90,7 +91,11 @@
; Evaluation

(def default-context
{"print" (fn [v] {:token "print" :value v})
{"list" (fn [v] {:token "list" :value v})
"map" (fn [v] {:token "map" :value v})
"get" (fn [v] {:token "get" :value v})
"fold" (fn [v] {:token "fold" :value v})
"print" (fn [v] {:token "print" :value v})
"def" (fn [v] {:token "definition" :value v})
"fn" (fn [v] {:token "function" :value v})
"do" (fn [v] {:token "do" :value v})
Expand All @@ -113,14 +118,44 @@
[values ctx]
(let [f (evaluate (first values) ctx)]
(case (:token f)
"callable" ((:value f) (map #(evaluate % ctx) (drop 1 values)))
"sum" (apply + (map #(evaluate % ctx) (drop 1 values)))
"subtraction" (apply - (map #(evaluate % ctx) (drop 1 values)))
"multiplication" (apply * (map #(evaluate % ctx) (drop 1 values)))
"division" (apply / (map #(evaluate % ctx) (drop 1 values)))
"print" (let [result (doall (map #(evaluate % ctx) (drop 1 values)))] (println result) result)
"do" (last (doall (map #(evaluate % ctx) (drop 1 values))))
"conditional" (if (evaluate (nth values 1)) (evaluate (nth values 2)) (evaluate (nth values 3)))
"callable" ((:value f) (map #(evaluate % ctx)
(drop 1 values)))
"map" (let [f (-> values (nth 1) (evaluate ctx) :value)]
{:token "list"
:value (map #(f [%])
(-> values (nth 2) (evaluate ctx) :value))})
"fold" (let [f (-> values (nth 1) (evaluate ctx) :value)]
(r/fold (fn
([] (-> values (nth 2) (evaluate ctx)))
([acc v] (f [acc v])))
(-> values (nth 3) (evaluate ctx) :value)))
"get" (let [i (-> values (nth 2) (evaluate ctx))]
(-> values
(nth 1)
:value
(#(drop 1 %))
(nth i)
(evaluate ctx)))
"list" {:token "list"
:value (map #(evaluate % ctx)
(drop 1 values))}
"sum" (apply + (map #(evaluate % ctx)
(drop 1 values)))
"subtraction" (apply - (map #(evaluate % ctx)
(drop 1 values)))
"multiplication" (apply * (map #(evaluate % ctx)
(drop 1 values)))
"division" (apply / (map #(evaluate % ctx)
(drop 1 values)))
"print" (let [result (doall (map #(evaluate % ctx)
(drop 1 values)))]
(println result)
result)
"do" (last (doall (map #(evaluate % ctx)
(drop 1 values))))
"conditional" (if (evaluate (nth values 1))
(evaluate (nth values 2))
(evaluate (nth values 3)))
"definition" (do (swap! ctx #(conj % {(:value (nth values 1))
(evaluate (nth values 2))}))
(when (nth values 3 false) (evaluate (nth values 3) ctx)))
Expand Down
69 changes: 68 additions & 1 deletion test/bronen/kekwisp_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,71 @@
(parse)
(first)
(#(evaluate % ctx)))
444)))))
444))))
(testing "Should evaluate lists calls"
(let [ctx (atom {})]
(is (= (-> "(list 1 2 3)"
(lexer)
(parse)
(first)
(#(evaluate % ctx)))
{:token "list" :value [1 2 3]})))
(let [ctx (atom {})]
(is (= (-> "(list (list 1 2 3) 4 5 6)"
(lexer)
(parse)
(first)
(#(evaluate % ctx)))
{:token "list" :value [{:token "list" :value [1 2 3]} 4 5 6]})))
(testing "Should evaluate lists calls"
(let [ctx (atom {})]
(is (= (-> "(list 1 2 3)"
(lexer)
(parse)
(first)
(#(evaluate % ctx)))
{:token "list" :value [1 2 3]})))
(let [ctx (atom {})]
(is (= (-> "(list (list 1 2 3) 4 5 6)"
(lexer)
(parse)
(first)
(#(evaluate % ctx)))
{:token "list" :value [{:token "list" :value [1 2 3]} 4 5 6]}))))
(testing "Should evaluate map calls"
(let [ctx (atom {})]
(is (= (-> "(map (fn (a) 8) (list 1 2 3))"
(lexer)
(parse)
(first)
(#(evaluate % ctx)))
{:token "list" :value [8 8 8]}))
(is (= (-> "(map (fn (a) (* a 2)) (list 1 2 3))"
(lexer)
(parse)
(first)
(#(evaluate % ctx)))
{:token "list" :value [2 4 6]}))))
(testing "Should evaluate fold calls"
(let [ctx (atom {})]
(is (= (-> "(fold (fn (acc v) (+ acc v)) 0 (list 1 2 3))"
(lexer)
(parse)
(first)
(#(evaluate % ctx)))
6)))
(let [ctx (atom {})]
(is (= (-> "(fold (fn (acc v) (+ acc v)) 0 (map (fn (v) (* v 2)) (list 1 2 3)))"
(lexer)
(parse)
(first)
(#(evaluate % ctx)))
12))))
(testing "Should evaluate get calls"
(let [ctx (atom {})]
(is (= (-> "(get (list 1 2 3) 2)"
(lexer)
(parse)
(first)
(#(evaluate % ctx)))
3))))))

0 comments on commit b30b775

Please sign in to comment.