(import /src/base :as b)
(import /src/scanner :as s)
(import /src/parser :as p)
(import /src/validate :as v)
(import /src/interpreter :as i)
(import /src/errors :as e)

(def pkg (do 
  (def pre-ctx @{:^parent {"base" b/base}})
  (def pre-src (slurp "prelude.ld"))
  (def pre-scanned (s/scan pre-src :prelude))
  (def pre-parsed (p/parse pre-scanned))
  (def parse-errors (pre-parsed :errors))
  (when (any? parse-errors) (each err parse-errors (e/parse-error err)) (break :error))
  (def pre-validated (v/valid pre-parsed pre-ctx))
  (def validation-errors (pre-validated :errors))
  (when (any? validation-errors) (each err validation-errors (e/validation-error err)) (break :error))
  (try 
   (i/interpret (pre-parsed :ast) pre-ctx)
   ([err] (e/runtime-error err) :error))))

(def ctx (do
  (def ctx @{})
  (each [k v] (pairs pkg)
    (set (ctx (string k)) v))
  (set (ctx "^name") nil)
  (set (ctx "^type") nil)
  ctx))

(def post/src (slurp "postlude.ld"))

(def post/ast (do
  (def post-ctx @{:^parent ctx})
  (def post-scanned (s/scan post/src :postlude))
  (def post-parsed (p/parse post-scanned))
  (def parse-errors (post-parsed :errors))
  (when (any? parse-errors) (each err parse-errors (e/parse-error err)) (break :error))
  (def post-validated (v/valid post-parsed post-ctx))
  (def validation-errors (post-validated :errors))
  (when (any? validation-errors) (each err validation-errors (e/validation-error err)) (break :error))
  (post-parsed :ast)))

