Skip to content

Commit

Permalink
Merge pull request #26 from CFiggers/dev
Browse files Browse the repository at this point in the history
v0.0.7
  • Loading branch information
CFiggers authored Aug 12, 2024
2 parents 3ea0bd9 + 62328c5 commit 204e22c
Show file tree
Hide file tree
Showing 9 changed files with 521 additions and 279 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@
All notable changes to this project will be documented in this file.
Format for entires is <version-string> - release date.

## 0.0.7 - 2024-08-11

- Core loop
- More explicit `(os/exit 0)` instead of implicit process exit
- Logging
- Overhaul logging module and include significantly more logging statements throughout
- Completion
- Simplify `binding-type` lookup
- Bug Fixes
- Attempting to index on null ds in `on-document-definition`
- Catch error when attempting to write to `janetlsp.log.txt` fails
- Diagnostics/Completion: Maintain separate eval-envs for each document uri instead of overwriting shared eval results
- Testing
- Fix tests throughout
- Progress on Integration testing
- Misc
- Formatting tweaks
- Capture current commit in version outputs
- Catch and handle errors from `handle-message` instead of crashing

## 0.0.6 - 2024-07-31

- Core Functionality
Expand Down
114 changes: 71 additions & 43 deletions src/doc.janet
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
(import ./logging)

(defn make-module-entry [x]
(comment logging/log (string/format "make-module-entry on %m" x))
(logging/info (string/format "make-module-entry on %m" x) [:hover] 1)
(let [bind-type (cond
(x :redef) (type (in (x :ref) 0))
(x :ref) (string :var " (" (type (in (x :ref) 0)) ")")
Expand All @@ -29,6 +29,20 @@
"No documentation found.\n"))))

(deftest "test make-module-entry: string/trim"
(test (dyn (symbol "string/trim"))
@{:doc "(string/trim str &opt set)\n\nTrim leading and trailing whitespace from a byte sequence. If the argument `set` is provided, consider only characters in `set` to be whitespace."
:source-map ["src/core/string.c" 602 1]
:value @string/trim})
(test (make-module-entry (dyn (symbol "string/trim")))
````cfunction
src/core/string.c on line 602, column 1
```janet
(string/trim str &opt set)
```
Trim leading and trailing whitespace from a byte sequence. If the argument `set` is provided, consider only characters in `set` to be whitespace.
````)
(test-stdout (print (make-module-entry (dyn (symbol "string/trim")))) ````
cfunction
src/core/string.c on line 602, column 1
Expand All @@ -40,7 +54,19 @@
Trim leading and trailing whitespace from a byte sequence. If the argument `set` is provided, consider only characters in `set` to be whitespace.
````))

(deftest "test make-module-entry: length"
(deftest "test make-module-entry: length"
(test (dyn (symbol "length"))
@{:doc "(length ds)\n\nReturns the length or count of a data structure in constant time as an integer. For structs and tables, returns the number of key-value pairs in the data structure."
:value @length})
(test (make-module-entry (dyn (symbol "length")))
````function
```janet
(length ds)
```
Returns the length or count of a data structure in constant time as an integer. For structs and tables, returns the number of key-value pairs in the data structure.
````)
(test-stdout (print (make-module-entry (dyn (symbol "length")))) ````
function
Expand Down Expand Up @@ -78,9 +104,10 @@

(defn get-signature
"Look up the signature of a symbol in a given environment."
[sym]
(comment logging/log (string/format "get-signature tried %m" ((dyn :eval-env) sym)))
(if-let [x ((dyn :eval-env) sym)]
[sym env]
(assert (not (nil? env)) "get-signature: env is nil")
(logging/info (string/format "get-signature tried %m" (env sym)) [:hover] 1)
(if-let [x (env sym)]
(-> (string/split "\n" (x :doc))
(array/slice nil 1)
(first))
Expand All @@ -93,54 +120,59 @@
(if (has-value? '[break def do fn if quasiquote quote
set splice unquote upscope var while] sym)
(string "(" sym " ... )")
(print "symbol " sym " not found."))))
(logging/info (string/format "Symbol %m not found" sym) [:hover]))))

(defn my-doc*
"Get the documentation for a symbol in a given environment."
[sym env]
(comment logging/log (string/format "my-doc* tried: %m" ((dyn :eval-env) sym)))
(if-let [x ((dyn :eval-env) sym)]
(assert env "my-doc*: env is nil")
(logging/info (string/format "env is: %m" env) [:hover] 1)
(logging/info (string/format "my-doc* tried: %m" (env sym)) [:hover] 1)
(if-let [x (env sym)]
(make-module-entry x)
(if (has-value? '[break def do fn if quasiquote quote
set splice unquote upscope var while] sym)
(make-special-form-entry sym)
(do
(def module-find-fiber (fiber/new |(module/find (string sym)) :e (dyn :eval-env)))
(logging/info "Not a symbol or a special form, seeking module" [:hover] 1)
(logging/info (string/format "Regular module/find returns: %m" (module/find (string sym))) [:hover])
(def module-find-fiber (fiber/new |(module/find (string sym)) :e env))
(def mff-return (resume module-find-fiber))
(logging/info (string/format "mff-return is: %m" mff-return) [:hover] 1)
(def [fullpath mod-kind]
(if (= :error (fiber/status module-find-fiber))
nil
mff-return))

# (logging/log (string/format ":eval-env has this in module/cache: %m" ((dyn :eval-env) 'module/cache)))
(logging/info (string/format "env has this in module/cache: %m" (env 'module/cache)) [:hover] 2)

# (logging/log (string/format "module-find-fiber got %m for %m" mff-return sym))
(def module-cache-fiber (fiber/new |(in module/cache fullpath) :e (dyn :eval-env)))
(logging/info (string/format "module-find-fiber got %m for %m" mff-return sym) [:hover] 1)
(def module-cache-fiber (fiber/new |(in module/cache fullpath) :e env))
(def mcf-return (resume module-cache-fiber))
(cond
(= :error (fiber/status module-cache-fiber)) (print "symbol " sym " not found.")
(= :error (fiber/status module-cache-fiber)) (logging/err (string/format "symbol %m not found." sym) [:hover])
mcf-return (make-module-entry {:module true
:kind mod-kind
:source-map [fullpath nil nil]
:doc (in mcf-return :doc)})
(print "symbol " sym " not found."))))))
(logging/info (string/format "symbol %m not found." sym) [:hover]))))))

(deftest "testing my-doc*: string/trim"
(setdyn :eval-env (make-env root-env))
(test-stdout (print (my-doc* 'string/trim (dyn :eval-env))) ````
cfunction
src/core/string.c on line 602, column 1
```janet
(string/trim str &opt set)
```
Trim leading and trailing whitespace from a byte sequence. If the argument `set` is provided, consider only characters in `set` to be whitespace.
````))
(def env (make-env root-env))
(test (my-doc* 'string/trim env)
````cfunction
src/core/string.c on line 602, column 1
```janet
(string/trim str &opt set)
```
Trim leading and trailing whitespace from a byte sequence. If the argument `set` is provided, consider only characters in `set` to be whitespace.
````))

(deftest "testing my-doc*: length"
(setdyn :eval-env (make-env root-env))
(test-stdout (print (my-doc* 'length (dyn :eval-env))) ````
(def env (make-env root-env))
(test-stdout (print (my-doc* 'length env)) ````
function
```janet
Expand All @@ -151,8 +183,8 @@
````))

(deftest "testing my-doc*: set"
(setdyn :eval-env (make-env root-env))
(test-stdout (print (my-doc* 'set (dyn :eval-env))) `
(def env (make-env root-env))
(test-stdout (print (my-doc* 'set env)) `
special form
(set ...)
Expand All @@ -161,28 +193,24 @@
`))

(deftest "testing my-doc*: test-def"
(setdyn :eval-env (make-env root-env))
(test-stdout (print (my-doc* 'test-def (dyn :eval-env))) `
symbol test-def not found.
`))
(def env (make-env root-env))
(test (my-doc* 'test-def env)
nil))

(deftest "testing my-doc*: wackythingthatdoesntexist"
(setdyn :eval-env (make-env root-env))
(test-stdout (print (my-doc* (symbol "wackythingthatdoesntexist") (dyn :eval-env))) `
symbol wackythingthatdoesntexist not found.
`))
(def env (make-env root-env))
(test (my-doc* (symbol "wackythingthatdoesntexist") env)
nil))

(deftest "testing my-doc*: module entry"
(setdyn :eval-env (make-env root-env))
(def import-fiber (fiber/new |(import spork/path) :e (dyn :eval-env)))
(def env (make-env root-env))
(def import-fiber (fiber/new |(import spork/path) :e env))
(def if-result (resume import-fiber))
(if (= :error (fiber/status import-fiber))
(error "fiber errored")
(merge (dyn :eval-env) (fiber/getenv import-fiber)))
(merge env (fiber/getenv import-fiber)))

(test-stdout (print (my-doc* (symbol "spork/path") (dyn :eval-env))) `
(test-stdout (print (my-doc* (symbol "spork/path") env)) `
module (source)
/usr/local/lib/janet/spork/path.janet
Expand Down
116 changes: 62 additions & 54 deletions src/eval.janet
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
(thunk))))))

(defn eval-buffer [str &opt filename]
(logging/info (string/format "`eval-buffer` received filename: `%s`" (or filename "none")) [:evaluation] 1)
(logging/info (string/format "`eval-buffer` received str: `%s`" str) [:evaluation] 2)

(default filename "eval.janet")
(var state (string str))
(defn chunks [buf parser]
Expand All @@ -61,84 +64,89 @@
(when ret
(buffer/push-string buf str)
(buffer/push-string buf "\n")))

(setdyn :eval-env (make-env root-env))

(def fresh-env (make-env root-env))

(each path (or (dyn :unique-paths) @[])
(cond
(string/has-suffix? ".janet" path) (array/push ((fresh-env 'module/paths) :value) [path :source])
(string/has-suffix? ".so" path) (array/push ((fresh-env 'module/paths) :value) [path :native])
(string/has-suffix? ".jimage" path) (array/push ((fresh-env 'module/paths) :value) [path :jimage])))


(def eval-fiber
(fiber/new
|(do (var returnval @[])
(try (run-context {:chunks chunks
:on-compile-error (fn compile-error [msg errf where line col]
(array/push returnval {:message msg
:location [line col]}))
:on-parse-error (fn parse-error [p x]
(array/push returnval {:message (parser/error p)
:location (parser/where p)}))
:evaluator flycheck-evaluator
:fiber-flags :i
:source filename})
([err]
(array/push returnval {:message err
:location [0 0]})))
returnval) :e (dyn :eval-env)))
|(do (var returnval @[])
(try (run-context {:chunks chunks
:on-compile-error (fn compile-error [msg errf where line col]
(array/push returnval {:message msg
:location [line col]}))
:on-parse-error (fn parse-error [p x]
(array/push returnval {:message (parser/error p)
:location (parser/where p)}))
:evaluator flycheck-evaluator
:fiber-flags :i
:source filename})
([err]
(array/push returnval {:message err
:location [0 0]})))
returnval) :e fresh-env))
(def eval-fiber-return (resume eval-fiber))
eval-fiber-return)
(logging/info (string/format "`eval-buffer` is returning: %m" eval-fiber-return) [:evaluation] 2)
[eval-fiber-return fresh-env])

# tests

(deftest "test eval-buffer: (+ 2 2)"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "(+ 2 2)") @[]))
(test (eval-buffer "(+ 2 2)" "test.janet") [@[] @{:current-file "test.janet"}]))

(deftest "test eval-buffer: (2)"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "(2)")
@[{:location [1 1]
:message "2 expects 1 argument, got 0"}]))
(test (eval-buffer "(2)" "test.janet")
[@[{:location [1 1]
:message "2 expects 1 argument, got 0"}]
@{:current-file "test.janet"}]))

(deftest "test eval-buffer: (+ 2 2"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "(+ 2 2")
@[{:location [2 0]
:message "unexpected end of source, ( opened at line 1, column 1"}]))
(test (eval-buffer "(+ 2 2" "test.janet")
[@[{:location [2 0]
:message "unexpected end of source, ( opened at line 1, column 1"}]
@{:current-file "test.janet"}]))

# check for side effects
(deftest "test eval-buffer: (pp 42)"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "(pp 42)") @[]))
(test (eval-buffer "(pp 42)") [@[] @{:current-file "eval.janet"}]) "test.janet")

(deftest "test eval-buffer: ()"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "()")
@[{:location [0 0]
:message "expected integer key for tuple in range [0, 0), got 0"}]))
(test (eval-buffer "()" "test.janet")
[@[{:location [0 0]
:message "expected integer key for tuple in range [0, 0), got 0"}]
@{:current-file "test.janet"}]))

(deftest "import with no argument should give a parse error"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "(import )")
@[{:location [1 1]
:message "macro arity mismatch, expected at least 1, got 0"}]))
(test (eval-buffer "(import )" "test.janet")
[@[{:location [1 1]
:message "macro arity mismatch, expected at least 1, got 0"}]
@{:current-file "test.janet"}]))

(deftest "import with no matching module should give a parse error"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "(import randommodulethatdoesntexist)")
@[{:location [0 0]
:message "could not find module randommodulethatdoesntexist:\n /usr/local/lib/janet/randommodulethatdoesntexist.jimage\n /usr/local/lib/janet/randommodulethatdoesntexist.janet\n /usr/local/lib/janet/randommodulethatdoesntexist/init.janet\n /usr/local/lib/janet/randommodulethatdoesntexist.so"}]))
(test (eval-buffer "(import randommodulethatdoesntexist)" "test.janet")
[@[{:location [0 0]
:message "could not find module randommodulethatdoesntexist:\n /usr/local/lib/janet/randommodulethatdoesntexist.jimage\n /usr/local/lib/janet/randommodulethatdoesntexist.janet\n /usr/local/lib/janet/randommodulethatdoesntexist/init.janet\n /usr/local/lib/janet/randommodulethatdoesntexist.so"}]
@{:current-file "test.janet"}]))

(deftest "does not error because string/trim is a cfunction"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "(string/trim )") @[]))
(test (eval-buffer "(string/trim )") [@[] @{:current-file "eval.janet"}]) "test.janet")

(deftest "should give a parser error 2"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "(freeze )")
@[{:location [1 1]
:message "<function freeze> expects at least 1 argument, got 0"}]))
(test (eval-buffer "(freeze )" "test.janet")
[@[{:location [1 1]
:message "<function freeze> expects at least 1 argument, got 0"}]
@{:current-file "test.janet"}]))

(deftest "multiple compiler errors"
(setdyn :eval-env (make-env root-env))
(test (eval-buffer "(freeze ) (import )")
@[{:location [1 1]
:message "<function freeze> expects at least 1 argument, got 0"}
{:location [1 11]
:message "macro arity mismatch, expected at least 1, got 0"}]))
(test (eval-buffer "(freeze ) (import )" "test.janet")
[@[{:location [1 1]
:message "<function freeze> expects at least 1 argument, got 0"}
{:location [1 11]
:message "macro arity mismatch, expected at least 1, got 0"}]
@{:current-file "test.janet"}]))
Loading

0 comments on commit 204e22c

Please sign in to comment.