application/octet-stream
•
3.79 KB
•
105 lines
; Nujel - Copyright (C) 2020-2021 - Benjamin Vincent Schulenburg
; This project uses the MIT license, a copy should be included under /LICENSE
[def test-context "Nujel Standalone"]
[defn file/eval [path environment]
"Evaluate a Nujel source file in the current context"
[when-not environment [set! environment root-closure]]
[eval-in environment [cons 'do [read [file/read path]]]]]
[defn file/compile [path environment]
"Compile a Nujel source file into optimized object code"
[def source [cons 'do [read [file/read path]]]]
[def object-code [compile* source [or environment [environment*]]]]
[file/write [if object-code [string/write object-code] ""]
[cat [path/without-extension path] ".no"]]
[return object-code]]
[defn file/compile/module [path environment base-dir]
"Compile a Nujel source file into optimized object code"
[def module-name [string->keyword [path/without-extension [string/cut path [length base-dir]]]]]
[def source `[defmodule ~module-name [def *module* ~module-name] ~@[read [file/read path]]]]
[def object-code [compile* source [or environment [environment*]]]]
[file/write [if object-code [string/write object-code] ""]
[cat [path/without-extension path] ".no"]]
[return object-code]]
[defn file/compile/argv []
[def path [car [last-pair repl/args]]]
[def module [index-of path "_modules/"]]
[if [>= module 0]
[file/compile/module path #nil [string/cut path 0 [+ module 9]]]
[file/compile path]]]
[defn file/test/module/run [tests module-name]
[require :test]
[doseq [expr tests]
[test/run-test! [eval [cadr expr]]
`[do [require ~module-name] ~@[cddr expr]]]]]
[defn valid-test-form? [form]
[== [car form] 'deftest]]
[defn file/test/module [path base-dir]
"Test a module by running all contained tests"
[def rel-path [string/cut path [length base-dir]]]
[when [== [char-at rel-path 0] #\/]
[set! rel-path [string/cut rel-path 1]]]
[def module-name [string->keyword [path/without-extension rel-path]]]
[require :test]
[test/init!]
[-> [read [file/read path]]
[filter valid-test-form?]
[file/test/module/run module-name]]
[test/finish! [ansi-blue module-name]]]
[defn file/test/directory [base-dir]
"Compile a Nujel source file into optimized object code"
[-> [directory/read-recursive base-dir]
[flatten]
[sort]
[filter [path/ext?! "nuj"]]
[map [fn [path] [file/test/module path base-dir]]]
[sum]]]
[defn load [filename]
[try [fn [err]
[display/error err]
#f]
[file/eval filename]
[pfmtln "Loaded {filename}"]
#t]]
[defn file/file? [filename]
[ref [file/stat filename] :regular-file?]]
[defn file/dir? [filename]
[ref [file/stat filename] :directory?]]
[defn directory/read-relative [path]
[map [directory/read path]
[fn [a]
[cat path "/" a]]]]
[defn directory/read-recursive [path]
[flatten [map [directory/read-relative path]
[fn [A] [if [file/dir? A]
[directory/read-recursive A]
A]]]]]
[defn popen/trim [cmd]
"Run CMD using popen and return the trimmed stdout"
[trim [cdr [popen cmd]]]]
[def +root-working-dir+ [path/working-directory]]
[defn file/module-loader [name]
[def module-path [fmt "{+root-working-dir+}/modules/{}.nuj" [keyword->string name]]]
[def source [file/read module-path]]
[when-not source [return #nil]]
[def expr [list 'module [cons do [read source]]]]
[def mod [eval expr]]
[return mod]]
[module/add-loader file/module-loader]