summaryrefslogtreecommitdiff
path: root/lambda-calcul/clojure/src/lccl
diff options
context:
space:
mode:
Diffstat (limited to 'lambda-calcul/clojure/src/lccl')
-rw-r--r--lambda-calcul/clojure/src/lccl/app.clj30
-rw-r--r--lambda-calcul/clojure/src/lccl/fwk/middlewares.clj15
-rw-r--r--lambda-calcul/clojure/src/lccl/lc/ast.clj7
-rw-r--r--lambda-calcul/clojure/src/lccl/lc/evaluator.clj28
-rw-r--r--lambda-calcul/clojure/src/lccl/main.clj36
5 files changed, 116 insertions, 0 deletions
diff --git a/lambda-calcul/clojure/src/lccl/app.clj b/lambda-calcul/clojure/src/lccl/app.clj
new file mode 100644
index 0000000..522d8bf
--- /dev/null
+++ b/lambda-calcul/clojure/src/lccl/app.clj
@@ -0,0 +1,30 @@
+(ns lccl.app
+ (:require [reitit.ring :as ring-reitit]
+ [reitit.coercion.malli]
+ [reitit.ring.malli]
+ [reitit.dev.pretty :as pretty]
+ [reitit.ring.middleware.muuntaja :as muuntaja]
+ [muuntaja.core :as m]))
+
+(defn eval
+ [request]
+ (let [sexpr (slurp (:body request))]
+ (println "Demande d'évaluation de l'expression :" sexpr)
+ {:status 200, :body sexpr}))
+
+(defn api-handler
+ []
+ (ring-reitit/ring-handler
+ (ring-reitit/router
+ [["/eval" {:post eval}]]
+
+ {:exception pretty/exception
+ :data {
+ :muuntaja m/instance
+ :middleware [muuntaja/format-response-middleware]}})))
+
+(defn app-handler
+ []
+ (ring-reitit/routes (api-handler)))
+
+
diff --git a/lambda-calcul/clojure/src/lccl/fwk/middlewares.clj b/lambda-calcul/clojure/src/lccl/fwk/middlewares.clj
new file mode 100644
index 0000000..973cffc
--- /dev/null
+++ b/lambda-calcul/clojure/src/lccl/fwk/middlewares.clj
@@ -0,0 +1,15 @@
+(ns lccl.fwk.middlewares
+ (:require [ring.middleware.reload :as reload]))
+
+; https://bogoyavlensky.com/blog/auto-reloading-ring/
+(defn reloading-ring-handler
+ "Reload ring handler on each request."
+ [f]
+ (let [reload! (#'reload/reloader ["src"] true)]
+ (fn
+ ([request]
+ (reload!)
+ ((f) request))
+ ([request respond raise]
+ (reload!)
+ ((f) request respond raise))))) \ No newline at end of file
diff --git a/lambda-calcul/clojure/src/lccl/lc/ast.clj b/lambda-calcul/clojure/src/lccl/lc/ast.clj
new file mode 100644
index 0000000..58bad11
--- /dev/null
+++ b/lambda-calcul/clojure/src/lccl/lc/ast.clj
@@ -0,0 +1,7 @@
+(ns lccl.lc.ast)
+
+(defrecord Var [name])
+(defrecord Abs [arg body])
+(defrecord App [left right])
+
+(def IDENTITY (->Abs "x" (->Var "x")))
diff --git a/lambda-calcul/clojure/src/lccl/lc/evaluator.clj b/lambda-calcul/clojure/src/lccl/lc/evaluator.clj
new file mode 100644
index 0000000..70e972e
--- /dev/null
+++ b/lambda-calcul/clojure/src/lccl/lc/evaluator.clj
@@ -0,0 +1,28 @@
+(ns lccl.lc.evaluator
+ (:import [lccl.lc.ast Var Abs App])
+ (:require [lccl.lc.ast :refer [->Abs ->App]]))
+
+(declare substitute)
+
+(defmulti evaluate (fn [term] [(type term)]))
+(defmethod evaluate [Var] ([term] term))
+(defmethod evaluate [Abs] ([term] term))
+(defmethod evaluate [App]
+ ([term]
+ (let [left (-> term :left)]
+ (condp = (type left)
+ Abs (substitute (:body left) (:arg left) (:right term))
+ term))))
+
+(defmulti substitute (fn [body arg val] [(type body)]))
+(defmethod substitute [Var]
+ ([body arg val]
+ (if (= (:name body) arg) val body)))
+(defmethod substitute [Abs]
+ ([body arg val]
+ (if (= (:arg body) arg)
+ body
+ (->Abs (:arg body) (substitute (:body body) arg val)))))
+(defmethod substitute [App]
+ ([body arg val]
+ (->App (substitute (:left body) arg val) (substitute (:right body) arg val))))
diff --git a/lambda-calcul/clojure/src/lccl/main.clj b/lambda-calcul/clojure/src/lccl/main.clj
new file mode 100644
index 0000000..071d7c6
--- /dev/null
+++ b/lambda-calcul/clojure/src/lccl/main.clj
@@ -0,0 +1,36 @@
+(ns lccl.main
+ (:require [ring.adapter.jetty :as ring-jetty]
+ [clj-http.client :as client]
+ [lccl.app :as app]
+ [lccl.fwk.middlewares :as middlewares])
+ (:gen-class))
+
+(def TEAM_NAME "LCCL")
+(def SELF_PORT 8888)
+(def SELF_URL (str "http://127.0.0.1:" SELF_PORT))
+(def TESTER_URL "http://127.0.0.1:8080")
+
+(defn run-http-server!
+ [{:keys [dev-mode? server-options]}]
+ (let [create-handler-fn #(app/app-handler)
+ handler* (if dev-mode?
+ (middlewares/reloading-ring-handler create-handler-fn)
+ (create-handler-fn))]
+ (ring-jetty/run-jetty handler* server-options)
+ (println "Evaluateur à l'écoute sur le port" (:port server-options))))
+
+(defn- run! [{dev-mode? :dev-mode?}]
+ (run-http-server! {:dev-mode? dev-mode?
+ :server-options {:join? false :port SELF_PORT}})
+ (let [response (client/post (str TESTER_URL "/register")
+ {:body (str "{\"url\": \"" SELF_URL "/eval\", \"name\": \"" TEAM_NAME "\"}")
+ :content-type :json
+ :accept :json})]
+ (println "Résultat de l'enregistrement : " (:body response))))
+
+(defn -main
+ [& _]
+ (run! {:dev-mode? false}))
+
+(comment
+ (run! {:dev-mode? true}))