Clean up some stuff, add ebnf grammar, fail to get quil working
This commit is contained in:
commit
3a7f86e401
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -19,4 +19,4 @@ pom.xml.asc
|
|||
**/.DS_Store
|
||||
/sandbox
|
||||
ludus.sublime-workspace
|
||||
ludus
|
||||
/ludus
|
|
@ -4,8 +4,15 @@
|
|||
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
|
||||
:url "https://www.eclipse.org/legal/epl-2.0/"}
|
||||
:dependencies [[org.clojure/clojure "1.11.1"]
|
||||
<<<<<<< HEAD
|
||||
[babashka/fs "0.1.6"]
|
||||
[quil "4.0.0-SNAPSHOT"]]
|
||||
||||||| 1c2ab51
|
||||
[babashka/fs "0.1.6"]]
|
||||
=======
|
||||
[babashka/fs "0.1.6"]
|
||||
[quil "4.0.0-SNAPSHOT-1"]]
|
||||
>>>>>>> 55d76f6854bf67119873d98e2c9c18d8390ab90a
|
||||
:plugins [[lein-cljfmt "0.8.0"]]
|
||||
:repl-options {:init-ns ludus.core}
|
||||
:main ludus.core
|
||||
|
|
32
src/ludus/draw.clj
Normal file
32
src/ludus/draw.clj
Normal file
|
@ -0,0 +1,32 @@
|
|||
(ns ludus.draw
|
||||
(:require [quil.core :as q]
|
||||
[quil.middleware :as m]))
|
||||
|
||||
(defn setup []
|
||||
(q/frame-rate 60)
|
||||
(q/color-mode :hsb)
|
||||
{:color 0 :angle 0})
|
||||
|
||||
(defn update-state [state]
|
||||
{:color (mod (+ (:color state) 0.7) 255)
|
||||
:angle (+ (:angle state) 0.1)})
|
||||
|
||||
(defn draw-state [state]
|
||||
(q/background 240)
|
||||
(q/fill (:color state) 255 255)
|
||||
(let [angle (:angle state)
|
||||
x (* 150 (q/cos angle))
|
||||
y (* 150 (q/sin angle))]
|
||||
(q/with-translation [(/ (q/width) 2)
|
||||
(/ (q/height) 2)]
|
||||
(q/ellipse x y 100 100))))
|
||||
|
||||
(defn ludus-draw []
|
||||
(q/defsketch sketch
|
||||
:title "Hello Ludus"
|
||||
:size [500 500]
|
||||
:setup setup
|
||||
:update update-state
|
||||
:draw draw-state
|
||||
:features []
|
||||
:middleware [m/fun-mode]))
|
135
src/ludus/ludus.ebnf
Normal file
135
src/ludus/ludus.ebnf
Normal file
|
@ -0,0 +1,135 @@
|
|||
(*
|
||||
ludus.ebnf
|
||||
|
||||
An Instaparse-style EBNF grammer for Ludus.
|
||||
*)
|
||||
|
||||
script = <wsnl?> toplevel <ws?> {<terminator> <ws?> toplevel <ws?>} <wsnl?>
|
||||
|
||||
terminator = (";" | <{comment}> "\n")+
|
||||
|
||||
ws = (" " | "\t" | "\r")+
|
||||
|
||||
wsnl = (ws | <{comment}> "\n")+
|
||||
|
||||
reserved = "cond" | "let" | "if" | "then" | "else" | "nil" | "true" | "false" | "as" | "match" | "with" | "NaN" | "recur"
|
||||
|
||||
comment = "&" not_nl*
|
||||
|
||||
not_nl = #"[^\n]"
|
||||
|
||||
toplevel = expression | import | test | ns
|
||||
|
||||
test = <"test" ws> string <ws> expression
|
||||
|
||||
import = <"import" ws> string <ws "as" ws> name
|
||||
|
||||
ns = <"ns" ws> name <ws? "{" wsnl?> entries <wsnl? "}">
|
||||
|
||||
entries = [(name | entry) {<separator> [(name | entry)]}]
|
||||
|
||||
expression = if | cond | let | tuple | atom | synthetic | block | match | fn | do | loop | dict | struct | list | ref | spawn | send | receive | repeat
|
||||
|
||||
(* TODO: is this right? *)
|
||||
repeat = <"repeat" ws> (number | name) <ws> fn_clause
|
||||
|
||||
spawn = <"spawn" ws> expression
|
||||
|
||||
receive = <"receive" ws? "{" wsnl?> match_clause {terminator <ws?> [match_clause]} <wsnl? "}">
|
||||
|
||||
ref = <"ref" ws> name <ws? "=" ws?> expression
|
||||
|
||||
loop = <"loop" ws> tuple <ws "with" ws> (fn_clause
|
||||
| (<"{" wsnl?> fn_clause {terminator <ws?> [fn_clause]} <wsnl? "}">))
|
||||
|
||||
do = <"do" ws> expression {<pipe> expression}
|
||||
|
||||
pipe = wsnl? "|>" wsnl?
|
||||
|
||||
fn = lambda | named | complex
|
||||
|
||||
lambda = <"fn" ws?> fn_clause
|
||||
|
||||
named = <"fn" ws?> name <ws> fn_clause
|
||||
|
||||
complex = <"fn" ws?> name <ws?> "{" <wsnl?> string? <wsnl> fn_clause {terminator <ws?> [fn_clause]} <wsnl? "}">
|
||||
|
||||
fn_clause = tuple_pattern <arrow> expression
|
||||
|
||||
match = <"match" ws> expression <ws "with" ws? "{" wsnl?> match_clause {terminator <ws?> [match_clause]} <wsnl? "}">
|
||||
|
||||
match_clause = pattern constraint? <arrow> expression
|
||||
|
||||
constraint = <"when" ws> expression
|
||||
|
||||
let = <"let" ws> pattern <ws "=" wsnl> expression
|
||||
|
||||
pattern = tuple_pattern | atom | placeholder | "else" | splattern
|
||||
|
||||
tuple_pattern = <"(" wsnl?> [pattern {<separator> [pattern]}] <{separator} ws? ")">
|
||||
|
||||
struct_pattern = <"@{" wsnl?> [(name | pattern_entry | splattern) {<separator> [(name | pattern_entry | splattern)]}] <{separator} ws? "}">
|
||||
|
||||
dict_pattern = <"#{" wsnl?> [(name | pattern_entry | splattern) {<separator> [(name | pattern_entry | splattern)]}] <{separator} ws? "}">
|
||||
|
||||
pattern_entry = keyword <ws> pattern
|
||||
|
||||
splattern = <"..."> name | ignored | placeholder
|
||||
|
||||
block = <"{" wsnl?> expression {<terminator ws?> expression <ws?>} <wsnl? "}">
|
||||
|
||||
cond = "cond" <ws> expression <ws? "{" wsnl?> cond_clause {terminator <ws?> [cond_clause]} <wsnl? "}">
|
||||
|
||||
cond_clause = expression <arrow> expression
|
||||
|
||||
arrow = <ws? "->" wsnl?>
|
||||
|
||||
if = <"if" ws> expression <wsnl "then" ws> expression <wsnl> <"else" ws> expression
|
||||
|
||||
synthetic = (name | keyword | recur) ((<ws?> (args | keyword))+)
|
||||
|
||||
recur = <"recur">
|
||||
|
||||
separator = <ws?> ("," | "\n") <ws?>
|
||||
|
||||
args = <"(" ws? {separator}> [arg_expr {<separator> [arg_expr]}] <{separator} ws? ")">
|
||||
|
||||
arg_expr = expression | placeholder
|
||||
|
||||
placeholder = <"_">
|
||||
|
||||
tuple = <"(" wsnl?> [expression {<separator> [expression]}] <{separator} ws? ")">
|
||||
|
||||
list = <"[" wsnl?> [(expression | splat) {<separator> [(expression | splat)]}] <{separator} ws? "]">
|
||||
|
||||
struct = <"@{" wsnl?> [(name | entry) {<separator> [(name | entry)]}] <{separator} ws? "}">
|
||||
|
||||
dict = <"#{" wsnl?> [(name | entry | splat) {<separator> [(name | entry | splat)]}] <{separator} ws? "}">
|
||||
|
||||
entry = keyword <ws> expression
|
||||
|
||||
splat = <"..."> name
|
||||
|
||||
atom = name | ignored | keyword | number | string | boolean | nil
|
||||
|
||||
boolean = true | false
|
||||
|
||||
true = <"true">
|
||||
|
||||
false = <"false">
|
||||
|
||||
nil = <"nil">
|
||||
|
||||
string = <'"'> {escaped_quote | nonquote} <'"'>
|
||||
|
||||
escaped_quote = "\\" '\"'
|
||||
nonquote = #'[^"]'
|
||||
|
||||
keyword = #":[a-zA-Z][a-zA-Z0-9\/\-_!\*\?]*"
|
||||
ignored = #"_[a-z][a-zA-Z0-9\/\-_!\*\?]*"
|
||||
|
||||
name = !reserved #"[a-z][a-zA-Z0-9\/\-_!\*\?]*"
|
||||
|
||||
(* TODO: Debug this to reject things starting with 0, eg 012. *)
|
||||
number = #"\-?[1-9][0-9]*" | #"\-?(0|[1-9][0-9]*).[0-9]+" | ["-"] "0" | "NaN"
|
||||
|
|
@ -2,8 +2,7 @@
|
|||
(:require
|
||||
[ludus.data :as data]
|
||||
[ludus.show :as show]
|
||||
[ludus.draw :as d]
|
||||
))
|
||||
[ludus.draw :as d]))
|
||||
|
||||
;; TODO: make eq, and, or special forms that short-circuit
|
||||
;; Right now, they evaluate all their args
|
||||
|
@ -95,6 +94,10 @@
|
|||
::data/type ::data/clj
|
||||
:body get})
|
||||
|
||||
(def draw {:name "draw"
|
||||
::data/type ::data/clj
|
||||
:body draw/ludus-draw})
|
||||
|
||||
(def draw {:name "draw"
|
||||
::data/type ::data/clj
|
||||
:body d/draw})
|
||||
|
|
Loading…
Reference in New Issue
Block a user