better_panics #15
|
@ -1,7 +1,7 @@
|
|||
(ns ludus.error
|
||||
(:require [clojure.string :as string]))
|
||||
|
||||
(defn get-line [source {:keys [line]}]
|
||||
(defn get-line [source line]
|
||||
(let [lines (string/split-lines source)
|
||||
the_line (nth lines (dec line))]
|
||||
the_line))
|
||||
|
@ -21,22 +21,26 @@
|
|||
|
||||
(defn scan-error [] :TODO)
|
||||
|
||||
(defn parse-error [source {:keys [trace token]}]
|
||||
(let [line (get-line source token)
|
||||
(defn parse-error [{:keys [trace token]}]
|
||||
(let [source (:source token)
|
||||
input (:input token)
|
||||
line-num (:line token)
|
||||
line (get-line source line-num)
|
||||
line-num (:line token)
|
||||
prefix (str line-num ": ")
|
||||
underline (get-underline source token (count prefix))
|
||||
expected (first trace)
|
||||
got (:type token)
|
||||
message (str "Ludus found a parsing error on line " line-num ".\nExpected: " expected "\nGot: " got "\n")
|
||||
message (str "Ludus found a parsing error on line " line-num " in " input ".\nExpected: " expected "\nGot: " got "\n")
|
||||
]
|
||||
(str message "\n" prefix line "\n" underline)
|
||||
)
|
||||
)
|
||||
|
||||
(defn run-error [source {:keys [line message]}]
|
||||
(if line
|
||||
(str "Ludus panicked on line " line ":\n" (get-line source {:line line}) "\n" message)
|
||||
(str "Ludus panicked!\n" message)
|
||||
))
|
||||
(defn run-error [{:keys [message token line]}]
|
||||
(let [source (:source token) input (:input token)]
|
||||
(if line
|
||||
(str "Ludus panicked!: " message "\nOn line " line " in " input "\n" (get-line source line))
|
||||
(str "Ludus panicked!\n" message)
|
||||
)))
|
||||
|
||||
|
|
|
@ -915,11 +915,11 @@
|
|||
(into {} (map-keys kw->str) ns))
|
||||
|
||||
(def ludus-prelude
|
||||
(let [scanned (scanner/scan prelude/prelude)
|
||||
(let [scanned (scanner/scan prelude/prelude "prelude")
|
||||
parsed (p/apply-parser g/script (:tokens scanned))
|
||||
; _ (println "Parse status: " (:status parsed))
|
||||
; _ (if (= :err (:status parsed))
|
||||
; (throw (ex-info (error/parse-error prelude/prelude parsed) {})))
|
||||
; (throw (ex-info (error/parse-error parsed) {})))
|
||||
base-ctx (volatile! {::parent (volatile! {"base" base/base})})
|
||||
interpreted (interpret-ast parsed base-ctx)
|
||||
namespace (dissoc interpreted ::data/type ::data/name ::data/struct)
|
||||
|
@ -980,6 +980,7 @@
|
|||
;(pp/pprint (ex-data e))
|
||||
;(throw e)
|
||||
{::data/error true
|
||||
:token (get-in (ex-data e) [:ast :token])
|
||||
:line (get-in (ex-data e) [:ast :token :line])
|
||||
:message (ex-message e)}
|
||||
))))
|
||||
|
@ -991,12 +992,13 @@
|
|||
(interpret-ast parsed base-ctx)
|
||||
(catch Throwable e
|
||||
{::data/error true
|
||||
:token (get-in (ex-data e) [:ast :token])
|
||||
:line (get-in (ex-data e) [:ast :token :line])
|
||||
:message (ex-message e)}))))
|
||||
|
||||
|
||||
;; repl
|
||||
(do
|
||||
(comment
|
||||
|
||||
(println "***********")
|
||||
|
||||
|
@ -1004,7 +1006,7 @@
|
|||
panic! (:oh, :no)
|
||||
")
|
||||
|
||||
(def tokens (-> source scanner/scan :tokens))
|
||||
(def tokens (-> source (scanner/scan "test input") :tokens))
|
||||
|
||||
(def ast (p/apply-parser g/script tokens))
|
||||
|
||||
|
|
|
@ -31,12 +31,12 @@
|
|||
#?(:clj value :cljs (clj->js value)))
|
||||
|
||||
(defn run [source]
|
||||
(let [user_scanned (s/scan source)
|
||||
(let [user_scanned (s/scan source "user input")
|
||||
user_tokens (:tokens user_scanned)
|
||||
user_parsed (p/apply-parser g/script user_tokens)
|
||||
user_result (i/interpret-safe source user_parsed {})
|
||||
result_str (show/show user_result)
|
||||
post_scanned (s/scan pre/postlude)
|
||||
post_scanned (s/scan pre/postlude "postlude")
|
||||
post_tokens (:tokens post_scanned)
|
||||
post_parsed (p/apply-parser g/script post_tokens)
|
||||
post_result (i/interpret-safe source post_parsed {})
|
||||
|
@ -48,22 +48,24 @@
|
|||
(clean-out {:errors (:errors user_tokens)})
|
||||
|
||||
(= :err (:status user_parsed))
|
||||
(clean-out {:errors [(error/parse-error source user_parsed)]})
|
||||
(clean-out {:errors [(error/parse-error user_parsed)]})
|
||||
|
||||
(::data/error user_result)
|
||||
(clean-out (assoc (ld->clj post_result) :errors [(error/run-error source user_result)]))
|
||||
(clean-out (assoc (ld->clj post_result) :errors [(error/run-error user_result)]))
|
||||
|
||||
:else
|
||||
(clean-out clj_result)
|
||||
)
|
||||
))
|
||||
|
||||
(do
|
||||
(comment
|
||||
(def source "
|
||||
|
||||
(def source "panic! :oops")
|
||||
a b c
|
||||
|
||||
(def tokens (s/scan source))
|
||||
")
|
||||
|
||||
(-> source run :errors println)
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -897,10 +897,10 @@ fn unwrap_or {
|
|||
|
||||
fn assert! {
|
||||
"Asserts a condition: returns the value if the value is truthy, panics if the value is falsy. Takes an optional message."
|
||||
(value) -> if value then value else panic! string ("Assert failed", value)
|
||||
(value, message) -> if value
|
||||
(value) -> if value then value else panic! string ("Assert failed:", value)
|
||||
(msg, value) -> if value
|
||||
then value
|
||||
else panic! string ("Assert failed:", message, value)
|
||||
else panic! string ("Assert failed: ", msg, " with ", value)
|
||||
}
|
||||
|
||||
&&& Turtle & other graphics
|
||||
|
|
|
@ -51,8 +51,9 @@
|
|||
|
||||
(defn- new-scanner
|
||||
"Creates a new scanner."
|
||||
[source]
|
||||
[source input]
|
||||
{:source source
|
||||
:input input
|
||||
:length (count source)
|
||||
:errors []
|
||||
:start 0
|
||||
|
@ -135,7 +136,9 @@
|
|||
(current-lexeme scanner)
|
||||
literal
|
||||
(:line scanner)
|
||||
(:start scanner)))))
|
||||
(:start scanner)
|
||||
(:source scanner)
|
||||
(:input scanner)))))
|
||||
|
||||
;; TODO: errors should also be in the vector of tokens
|
||||
;; The goal is to be able to be able to hand this to an LSP?
|
||||
|
@ -146,7 +149,9 @@
|
|||
(current-lexeme scanner)
|
||||
nil
|
||||
(:line scanner)
|
||||
(:start scanner))
|
||||
(:start scanner)
|
||||
(:source scanner)
|
||||
(:input scanner))
|
||||
err-token (assoc token :message msg)]
|
||||
(-> scanner
|
||||
(update :errors conj err-token)
|
||||
|
@ -240,7 +245,7 @@
|
|||
comm (str char)]
|
||||
(let [char (current-char scanner)]
|
||||
(if (= \newline char)
|
||||
(update scanner :line inc)
|
||||
scanner
|
||||
(recur (advance scanner) (str comm char))))))
|
||||
|
||||
(defn- scan-token [scanner]
|
||||
|
@ -322,8 +327,8 @@
|
|||
(defn- next-token [scanner]
|
||||
(assoc scanner :start (:current scanner)))
|
||||
|
||||
(defn scan [source]
|
||||
(loop [scanner (new-scanner source)]
|
||||
(defn scan [source input]
|
||||
(loop [scanner (new-scanner source input)]
|
||||
(if (at-end? scanner)
|
||||
(let [scanner (add-token (add-token scanner :break) :eof)]
|
||||
{:tokens (:tokens scanner)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
(ns ludus.token)
|
||||
|
||||
(defn token
|
||||
[type text literal line start]
|
||||
[type text literal line start source input]
|
||||
{:type type
|
||||
:lexeme text
|
||||
:literal literal
|
||||
:line line
|
||||
:source source
|
||||
:input input
|
||||
:start start})
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
51828
|
Loading…
Reference in New Issue
Block a user