build a doc file, bring in some other documentation

This commit is contained in:
Scott Richmond 2025-07-07 00:10:37 -04:00
parent 79720ba833
commit 49bb50ada1
11 changed files with 173 additions and 154 deletions

View File

@ -1039,7 +1039,7 @@ fn self {
() -> base :process (:self)
}
fn send {
fn send! {
"Sends a message to the specified process and returns the message."
(pid as :keyword, msg) -> {
base :process (:send, pid, msg)
@ -1052,7 +1052,7 @@ fn link! {
(pid as :keyword) -> base :process (:link, pid)
}
fn spawn! {
fn spawn {
"Spawns a process. Takes a 0-argument (nullary) function that will be executed as the new process. Returns a keyword process ID (pid) of the newly spawned process."
(f as :fn) -> {
let new_pid = base :process (:spawn, f)
@ -1061,7 +1061,7 @@ fn spawn! {
}
}
fn fledge! {
fn fledge {
"Spawns a process and then immediately unlinks from it. Takes a 0-argument (nullary) function that will be executed as the new process. Returns a keyword process ID (pid) of the newly fledged process."
(f as :fn) -> base :process (:spawn, f)
}
@ -1088,7 +1088,7 @@ fn monitor! {
else nil
}
fn flush! {
fn flush {
"Clears the current process's mailbox and returns all the messages."
() -> base :process (:flush)
}
@ -1098,7 +1098,7 @@ fn sleep! {
(ms as :number) -> base :process (:sleep, ms)
}
fn await! {
fn await {
"Parks the current process until it receives an exit signal from the passed process. Returns the result of a successful execution or panics if the awaited process panics. If the other process is not alive, returns `nil`."
(pid as :keyword) -> if monitor! (pid)
then receive {
@ -1127,7 +1127,7 @@ fn hibernate! {
() -> receive { _ -> hibernate! () }
}
fn heed! {
fn heed {
"Parks the current process until it receives a reply, and returns whatever is replied. Causes a panic if it gets anything other than a `(:reply, result)` tuple."
() -> receive {
(:reply, result) -> result
@ -1164,7 +1164,7 @@ fn request_fetch! {
}
fn fetch {
"Requests the contents of the URL passed in. Returns a result tuple of `(:ok, {contents})` or `(:err, {status code})`."
"Requests the contents of the URL passed in. Returns a result tuple of (:ok, <contents>) or (:err, <status code>)."
(url) -> {
let pid = self ()
spawn! (fn () -> request_fetch! (pid, url))
@ -1402,7 +1402,7 @@ fn turtle_listener () -> {
turtle_listener ()
}
fn spawn_turtle! {
fn spawn_turtle {
"Spawns a new turtle in a new process. Methods on the turtle process mirror those of turtle graphics functions in prelude. Returns the pid of the new turtle."
() -> {
let pid = spawn! (fn () -> turtle_listener ())
@ -1498,106 +1498,73 @@ fn llist {
}
&&& keyboard input
fn key_pressed? {
fn key_down? {
"Returns true ie the key is currently pressed. Keys are indicated by strings. For non-alphanumeric keys, consult the documentation to get key codes."
(key as :string) -> do keys_down > unbox > contains? (key, _)
}
#{
& completed actor functions
self
send
spawn! & <- is no longer a special form
yield!
sleep!
alive?
flush!
& wip actor functions
link!
monitor!
await!
heed!
unlink!
hibernate!
spawn_turtle!
key_pressed?
& shared memory w/ rust
& `box`es are actually way cool
console
input
fetch_outbox
abs & math
add & math
alive? & processes
angle & math
any? & types and values
append & lists
assert! & errors
assoc & dicts
at & tuples, strings, lists
atan/2 & math
await & processes
back! & turtle graphics
background! & turtle graphics
between? & math
bg! & turtle graphics
bk! & turtle graphics
bool & bools
bool? & bools
box? & boxes
butlast & list, tuple, string
car & llist
cdr & llist
ceil & math
chars & strings
clear! & turtle graphics
coll? & dicts, tuples, lists
colors & turtle graphics
colours & turtle graphics
concat & list string
cons & llist
console & buffers
contains? & list, tuple, string
cos & math
count & list, tuple, string
dec & math
deg/rad &math
deg/turn &math
dict & dicts
dict? & dicts
dissoc & dicts
dist & math
div & math
div/0 & math
div/safe & math
doc! & io
downcase & string
each! & list
empty? & list string dict tuple
eq? & values
err & result
err? & result
even? & math
false? & bool
fd! & turtles
fetch &
fetch_inbox
keys_down
& a fetch fn
fetch
& await user input
read_input
abs
abs
add
angle
any?
append
assert!
assoc
& assoc?
at
atan/2
back!
background!
between?
bg!
bk!
bool
bool?
box?
butlast
car
cdr
ceil
chars
clear!
coll?
colors
colours
concat
condense
cons
console
contains?
cos
count
dec
deg/rad
deg/turn
dict
dict?
dissoc
dist
div
div/0
div/safe
doc!
downcase
each!
empty?
eq?
err
err?
even?
false?
fd!
fetch_outbox
filter
first
first
first
floor
flush
fn?
fold
foldr
@ -1609,21 +1576,27 @@ fn key_pressed? {
has?
heading
heading/vector
heed
hibernate!
hideturtle!
home!
inc
indexed?
index_of
indexed?
indices_of
input
inv
inv/0
inv/safe
join
keep
key_down?
keys
keys_down
keyword?
last
left!
link!
list
list?
llist
@ -1635,6 +1608,7 @@ fn key_pressed? {
mod
mod/0
mod/safe
monitor!
mult
neg
neg?
@ -1665,6 +1639,7 @@ fn key_pressed? {
random
random_int
range
read_input
report!
rest
right!
@ -1672,15 +1647,20 @@ fn key_pressed? {
round
rt!
second
self
send!
sentence
setheading!
show
showturtle!
sin
sleep!
slice
slice_n
some
some?
spawn
spawn_turtle
split
sqrt
sqrt/safe
@ -1703,6 +1683,7 @@ fn key_pressed? {
turtle_state
type
unbox
unlink!
unwrap!
unwrap_or
upcase
@ -1711,5 +1692,6 @@ fn key_pressed? {
values
words
ws?
yield!
zero?
}

View File

@ -1,7 +1,7 @@
# A base library for Ludus
# Only loaded in the prelude
(import /src/scanner :as s)
(import /janet/scanner :as s)
(defn bool [x] (if (= :^nil x) nil x))

View File

@ -1,5 +1,5 @@
(import /src/base :as base)
(import /src/prelude :as prelude)
(import /janet/base :as base)
(import /janet/prelude :as prelude)
(defn map-values [f dict]
(from-pairs (map (fn [[k v]] [k (f v)]) (pairs dict))))
@ -23,20 +23,21 @@
(string/join (map toc-entry sorted-names) "&nbsp;&nbsp;&nbsp; "))
(def topics {
"math" ["abs" "add" "angle" "atan/2" "between?" "ceil" "cos" "dec" "deg/rad" "deg/turn" "dist" "div" "div/0" "div/safe" "even?" "floor" "gt?" "gte?" "heading/vector" "inc" "inv" "inv/0" "inv/safe" "lt?" "lte?" "max" "min" "mod" "mod/0" "mod/safe" "mult" "neg" "neg?" "odd?" "pi" "pos?" "rad/deg" "rad/turn" "random" "random_int" "range" "round" "sin" "sqrt" "sqrt/safe" "square" "sub" "sum_of_squares" "tan" "tau" "to_number" "turn/deg" "turn/rad" "zero?"]
"boolean" ["and" "bool" "bool?" "false?" "not" "or" "true?"]
"dicts" ["any?" "assoc" "assoc?" "coll?" "count" "dict" "dict?" "diff" "dissoc" "empty?" "get" "keys" "random" "update" "values"]
"lists" ["any?" "append" "at" "butlast" "coll?" "concat" "count" "each!" "empty?" "filter" "first" "fold" "join" "keep" "last" "list" "list?" "map" "ordered?" "random" "range" "rest" "second" "sentence" "slice"]
"math" ["abs" "add" "angle" "atan/2" "between?" "ceil" "cos" "dec" "deg/rad" "deg/turn" "dist" "div" "div/0" "div/safe" "even?" "floor" "gt?" "gte?" "heading/vector" "inc" "inv" "inv/0" "inv/safe" "lt?" "lte?" "max" "min" "mod" "mod/0" "mod/safe" "mult" "neg" "neg?" "odd?" "pi" "pos?" "pow" "rad/deg" "rad/turn" "random" "random_int" "range" "round" "sin" "sqrt" "sqrt/safe" "square" "sub" "sum_of_squares" "tan" "tau" "to_number" "turn/deg" "turn/rad" "zero?"]
"bools" ["and" "bool" "bool?" "false?" "not" "or" "true?"]
"dicts" ["any?" "assoc" "coll?" "count" "dict" "dict?" "diff" "dissoc" "empty?" "get" "has?" "keys" "random" "update" "values"]
"lists" ["any?" "append" "at" "butlast" "coll?" "concat" "count" "each!" "empty?" "filter" "first" "fold" "index_of" "indexed?" "indices_of" "join" "keep" "last" "list" "list?" "map" "random" "range" "rest" "second" "sentence" "slice"]
"llists" ["car" "cdr" "cons" "llist"]
"sets" ["any?" "append" "coll?" "concat" "contains?" "count" "empty?" "omit" "random" "set" "set?"]
# "sets" ["any?" "append" "coll?" "concat" "contains?" "count" "empty?" "omit" "random" "set" "set?"]
"tuples" ["any?" "at" "coll?" "count" "empty?" "first" "last" "ordered?" "rest" "second" "tuple?"]
"strings" ["any?" "chars" "chars/safe" "concat" "count" "downcase" "empty?" "join" "sentence" "show" "slice" "split" "string" "string?" "strip" "to_number" "trim" "upcase" "words"]
"types and values" ["assoc?" "bool?" "box?" "coll?" "dict?" "eq?" "fn?" "keyword?" "list?" "neq?" "nil?" "number?" "ordered?" "set?" "show" "some" "some?" "string?" "tuple?" "type"]
"boxes and state" ["box?" "unbox" "store!" "update!"]
"strings" ["any?" "at" "chars" "chars/safe" "concat" "count" "downcase" "empty?" "join" "sentence" "show" "slice" "slice_n" "split" "string" "string?" "strip" "to_number" "trim" "upcase" "words"]
"types and values" ["bool?" "box?" "coll?" "dict?" "eq?" "fn?" "indexed?" "keyword?" "list?" "nil?" "number?" "set?" "show" "some" "some?" "string?" "tuple?" "type"]
"boxes" ["box?" "unbox" "store!" "update!"]
"results" ["err" "err?" "ok" "ok?" "unwrap!" "unwrap_or"]
"errors" ["assert!"]
"turtle graphics" ["back!" "background!" "bk!" "clear!" "colors" "fd!" "forward!" "goto!" "heading" "heading/vector" "hideturtle!" "home!" "left!" "loadstate!" "lt!" "pc!" "pd!" "pencolor" "pencolor!" "pendown!" "pendown?" "penup!" "penwidth" "penwidth!" "position" "pu!" "pw!" "render_turtle!" "reset_turtle!" "right!" "rt!" "setheading!" "showturtle!" "turtle_state"]
"environment and i/o" ["doc!" "print!" "report!" "state"]
"turtle graphics" ["back!" "background!" "bk!" "clear!" "colors" "fd!" "forward!" "goto!" "heading" "heading/vector" "hideturtle!" "home!" "left!" "loadstate!" "lt!" "pc!" "pd!" "pencolor" "pencolour" "pencolor!" "pencolour!" "pendown!" "pendown?" "penup!" "penwidth" "penwidth!" "position" "pu!" "pw!" "render_turtle!" "reset_turtle!" "right!" "rt!" "setheading!" "showturtle!" "spawn_turtle" "turtle_state"]
"environment and i/o" ["console" "doc!" "fetch_inbox" "fetch_outbox" "input" "key_down?" "keys_down" "print!" "read_input" "report!"]
"processes" ["alive?" "await" "fledge" "flush" "heed" "hibernate!" "monitor" "self" "send!" "sleep!" "spawn" "unlink!" "yield!"]
})
(defn capitalize [str]

View File

@ -1,4 +1,4 @@
(import /src/base :as b)
(import /janet/base :as b)
(defn- get-line [source line]
((string/split "\n" source) (dec line)))

View File

@ -1,6 +1,6 @@
# A tree walk interpreter for ludus
(import /src/base :as b)
(import /janet/base :as b)
(var interpret nil)
(var match-pattern nil)

View File

@ -2,14 +2,14 @@
# devised in order to run under wasm
# takes a string, returns a string with a json object
# (try (os/cd "janet") ([_] nil)) # for REPL
(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)
(import /src/base :as b)
(import /src/prelude :as prelude)
(import /src/json :as j)
(import /janet/scanner :as s)
(import /janet/parser :as p)
(import /janet/validate :as v)
(import /janet/interpreter :as i)
(import /janet/errors :as e)
(import /janet/base :as b)
(import /janet/prelude :as prelude)
(import /janet/json :as j)
(defn ludus [source]
# if we can't load prelude, bail

View File

@ -1,7 +1,7 @@
### A recursive descent parser for Ludus
### We still need to scan some things
(import /src/scanner :as s)
(import /janet/scanner :as s)
# stash janet type
(def janet-type type)
@ -698,6 +698,25 @@
@{:type :match :data [to-match clauses] :token origin})
([err] err)))
(defn- receive [parser]
(def origin (current parser))
(def ast {:type :receive :data @[] :token origin})
(def clauses @[])
(expect parser :receive)
(advance parser)
(try
(do
(def open-brace (current parser))
(expect parser :lbrace) (advance parser)
(accept-many parser :newline)
(while (not (check parser :rbrace))
(when (check parser :eof)
(error {:type :error :token open-brace :msg "unclosed brace"}))
(array/push clauses (match-clause parser)))
(advance parser)
@{:type :receive :data [clauses] :token origin})
([err] err)))
# {pattern} = {nonbinding} {terminators}
(defn- with-clause [parser]
(try
@ -973,7 +992,7 @@
(def body (nonbinding parser))
{:type :test :data [desc body] :token origin})
### loops and repeates
### loops and repeats
(defn- loopp [parser]
(def origin (current parser))
(expect parser :loop) (advance parser)
@ -1031,9 +1050,10 @@
:startdict (dict parser)
:startset (sett parser)
:word (word-expr parser)
:pkg-name (pkg-name parser)
# :pkg-name (pkg-name parser)
:recur (recur parser)
:panic (panicc parser)
:do (doo parser)
(panic parser (string "expected simple expression, got " (type curr)))
)
)
@ -1072,6 +1092,7 @@
:when (whenn parser)
:match (matchh parser)
:with (withh parser)
:receive (receive parser)
# do
:do (doo parser)
@ -1114,12 +1135,13 @@
:startdict (dict parser)
:startset (sett parser)
:word (word-expr parser)
:pkg-name (pkg-name parser)
# :pkg-name (pkg-name parser)
:recur (recur parser)
:if (iff parser)
:when (whenn parser)
:match (matchh parser)
:with (withh parser)
:receive (receive parser)
# :with (withh parser)
:do (doo parser)
:lbrace (block parser)
:loop (loopp parser)

View File

@ -1,20 +1,20 @@
(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)
(import /janet/base :as b)
(import /janet/scanner :as s)
(import /janet/parser :as p)
(import /janet/validate :as v)
(import /janet/interpreter :as i)
(import /janet/errors :as e)
(def pkg (do
(def pre-ctx @{:^parent {"base" b/base}})
(def pre-src (slurp "../assets/prelude.ld"))
(def pre-src (slurp "./assets/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))
# (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))))
@ -27,16 +27,16 @@
(set (ctx "^type") nil)
ctx))
(def post/src (slurp "postlude.ld"))
# (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)))
# (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)))

View File

@ -9,20 +9,21 @@
"false" :false ## impl -> literal word
"fn" :fn ## impl
"if" :if ## impl
"import" :import ## impl
# "import" :import ## impl
"let" :let ## impl
"loop" :loop ## impl
"match" :match ## impl
"nil" :nil ## impl -> literal word
"ns" :ns ## impl
# "ns" :ns ## impl
"panic!" :panic ## impl (should _not_ be a function)
"pkg" :pkg
# "pkg" :pkg
"receive" :receive
"recur" :recur ## impl
"repeat" :repeat ## impl
"test" :test
# "test" :test
"then" :then ## impl
"true" :true ## impl -> literal word
"use" :use ## wip
# "use" :use ## wip
"when" :when ## impl, replaces cond
"with" :with ## impl
})

View File

@ -286,6 +286,13 @@ Deferred until a later iteration of Ludus:
(match-clauses validator clauses)
validator)
(defn- receive [validator]
(def ast (validator :ast))
(def [clauses] (ast :data))
(match-clauses validator clauses)
validator)
(defn- declare [validator fnn]
(def status (validator :status))
(def declared (get status :declared @{}))
@ -758,6 +765,7 @@ Deferred until a later iteration of Ludus:
:loop (loopp validator)
:recur (recur validator)
:box (box validator)
:receive (receive validator)
(error (string "unknown node type " type)))))
(set validate validate*)

View File

@ -38,3 +38,8 @@ release:
serve:
live-server pkg
# build the documentation
doc:
janet janet/doc.janet
-rm doc/prelude.md
mv prelude.md doc/