Fixes in lambda/function definitions (body args). Cleanup of examples and decumentation. Added convenience methods for JS interop, lists and objects.
This commit is contained in:
parent
8d23e5264e
commit
0cebbe52cb
60
README.txt
60
README.txt
@ -59,11 +59,16 @@ To save an image in memory, open an image file with Ronin, or drag an image file
|
|||||||
|
|
||||||
Library
|
Library
|
||||||
|
|
||||||
|
Files
|
||||||
|
|
||||||
- (open name ~scale) Imports a graphic file with format.
|
- (open name ~scale) Imports a graphic file with format.
|
||||||
- (import name ~shape) Imports a graphic file with format.
|
- (import name ~shape) Imports a graphic file with format.
|
||||||
- (export ~format ~quality) Exports a graphic file with format.
|
- (export ~format ~quality) Exports a graphic file with format.
|
||||||
- (files) Returns the list of loaded files.
|
- (files) Returns the list of loaded files.
|
||||||
- (print string) Exports string to file.
|
- (print string) Exports string to file.
|
||||||
|
|
||||||
|
Shapes
|
||||||
|
|
||||||
- (pos ~x ~y) Returns a position shape.
|
- (pos ~x ~y) Returns a position shape.
|
||||||
- (line ax ay bx by) Returns a line shape.
|
- (line ax ay bx by) Returns a line shape.
|
||||||
- (size w h) Returns a size shape.
|
- (size w h) Returns a size shape.
|
||||||
@ -74,6 +79,9 @@ Library
|
|||||||
- (poly ...pos) Returns a poly shape.
|
- (poly ...pos) Returns a poly shape.
|
||||||
- (text x y p t ~a ~f) Returns a text shape.
|
- (text x y p t ~a ~f) Returns a text shape.
|
||||||
- (svg x y d) Returns a svg shape.
|
- (svg x y d) Returns a svg shape.
|
||||||
|
|
||||||
|
Canvas operations
|
||||||
|
|
||||||
- (color r g b ~a) Returns a color object.
|
- (color r g b ~a) Returns a color object.
|
||||||
- (hsl h s l ~a) returns a HSL color object
|
- (hsl h s l ~a) returns a HSL color object
|
||||||
- (resize ~w) Resizes the canvas to target w and h, returns the rect.
|
- (resize ~w) Resizes the canvas to target w and h, returns the rect.
|
||||||
@ -92,6 +100,9 @@ Library
|
|||||||
- (clear ~rect) Clears a rect.
|
- (clear ~rect) Clears a rect.
|
||||||
- (gradient line ~colors 'black']) Defines a gradient color.
|
- (gradient line ~colors 'black']) Defines a gradient color.
|
||||||
- (guide shape color) Draws a shape on the guide layer.
|
- (guide shape color) Draws a shape on the guide layer.
|
||||||
|
|
||||||
|
Pixel operations
|
||||||
|
|
||||||
- (pixels fn ~q ~rect)
|
- (pixels fn ~q ~rect)
|
||||||
- (saturation pixel q) Change the saturation of pixels.
|
- (saturation pixel q) Change the saturation of pixels.
|
||||||
- (contrast pixel q) Change the contrast of pixels.
|
- (contrast pixel q) Change the contrast of pixels.
|
||||||
@ -100,8 +111,14 @@ Library
|
|||||||
- (multiply pixel q) Change the color balance of pixels.
|
- (multiply pixel q) Change the color balance of pixels.
|
||||||
- (normalize pixel q) Normalize the color of pixels with another color.
|
- (normalize pixel q) Normalize the color of pixels with another color.
|
||||||
- (lum color) Return the luminance of a color.
|
- (lum color) Return the luminance of a color.
|
||||||
|
|
||||||
|
Strings
|
||||||
|
|
||||||
- (concat ...items) Concat multiple strings.
|
- (concat ...items) Concat multiple strings.
|
||||||
- (split string char) Split string at character.
|
- (split string char) Split string at character.
|
||||||
|
|
||||||
|
Math
|
||||||
|
|
||||||
- (add ...args) Adds values.
|
- (add ...args) Adds values.
|
||||||
- (sub ...args) Subtracts values.
|
- (sub ...args) Subtracts values.
|
||||||
- (mul ...args) Multiplies values.
|
- (mul ...args) Multiplies values.
|
||||||
@ -125,38 +142,71 @@ Library
|
|||||||
- (PI)
|
- (PI)
|
||||||
- (TWO_PI)
|
- (TWO_PI)
|
||||||
- (random ...args)
|
- (random ...args)
|
||||||
|
|
||||||
|
Logic
|
||||||
|
|
||||||
- (gt a b) Returns true if a is greater than b, else false.
|
- (gt a b) Returns true if a is greater than b, else false.
|
||||||
- (lt a b) Returns true if a is less than b, else false.
|
- (lt a b) Returns true if a is less than b, else false.
|
||||||
- (eq a b) Returns true if a is equal to b, else false.
|
- (eq a b) Returns true if a is equal to b, else false.
|
||||||
- (and ...args) Returns true if all conditions are true.
|
- (and ...args) Returns true if all conditions are true.
|
||||||
- (or a b ...rest) Returns true if at least one condition is true.
|
- (or a b ...rest) Returns true if at least one condition is true.
|
||||||
|
- (not a) Negation. Returns true if a is false. Returns false if a is true.
|
||||||
|
- (while fn action) While loop. Execute action for as long as fn is true.
|
||||||
|
|
||||||
|
Language
|
||||||
|
- (let name value)
|
||||||
|
- (def name value)
|
||||||
|
- (defn fname ~(...fnparams) ...instructions)
|
||||||
|
- (λ (...args) ...instructions)
|
||||||
|
- (if (condition) ...instruction-when-true ~...instruction-when-false)
|
||||||
|
|
||||||
|
Lists
|
||||||
|
|
||||||
- (each arr fn) Run a function for each element in a list.
|
- (each arr fn) Run a function for each element in a list.
|
||||||
- (map arr fn) Run a function on each element in a list.
|
- (map arr fn) Run a function on each element in a list.
|
||||||
- (filter arr fn) Remove from list, when function returns false.
|
- (filter arr fn) Remove from list, when function returns false.
|
||||||
- (reduce arr fn acc)
|
- (reduce arr fn acc)
|
||||||
- (len item) Returns the length of a list.
|
- (len item) Returns the length of a list.
|
||||||
|
- (cons arr ...items) Returns a new array with the items appended.
|
||||||
|
- (push arr ...items) Appends the items into the existing list.
|
||||||
|
- (pop arr) Pop the last item from the list and return the item.
|
||||||
- (first arr) Returns the first item of a list.
|
- (first arr) Returns the first item of a list.
|
||||||
- (last arr) Returns the last
|
- (last arr) Returns the last
|
||||||
- (rest [_ ...arr])
|
- (rest [_ ...arr]) Returns all arguments except the first
|
||||||
- (range start end ~step)
|
- (range start end ~step) Returns a list of numbers counting from start to end. Step defaults to 1.
|
||||||
|
|
||||||
|
Objects (maps)
|
||||||
|
|
||||||
- (get item key) Gets an object's parameter with name.
|
- (get item key) Gets an object's parameter with name.
|
||||||
- (set item ...args) Sets an object's parameter with name as value.
|
- (set item ...args) Sets an object's parameter with name as value.
|
||||||
- (of h ...keys) Gets object parameters with names.
|
- (of h ...keys) Gets object parameters with names.
|
||||||
|
- (object ...entries) Creates an object with provided entries.
|
||||||
- (keys item) Returns a list of the object's keys
|
- (keys item) Returns a list of the object's keys
|
||||||
- (values item) Returns a list of the object's values
|
- (values item) Returns a list of the object's values
|
||||||
- (convolve kernel ~rect)
|
|
||||||
|
Convolution filters
|
||||||
|
|
||||||
|
- (convolve kernel ~rect) Apply convolution filter with given kernel on an area.
|
||||||
- (blur) Returns the blur kernel.
|
- (blur) Returns the blur kernel.
|
||||||
- (sharpen) Returns the sharpen kernel.
|
- (sharpen) Returns the sharpen kernel.
|
||||||
- (edge) Returns the edge kernel.
|
- (edge) Returns the edge kernel.
|
||||||
|
|
||||||
|
Points
|
||||||
|
|
||||||
- (offset a b) Offsets pos a with pos b, returns a.
|
- (offset a b) Offsets pos a with pos b, returns a.
|
||||||
- (distance a b) Get distance between positions.
|
- (distance a b) Get distance between positions.
|
||||||
|
|
||||||
|
Utilities
|
||||||
|
|
||||||
- (echo ...args) Print arguments to interface.
|
- (echo ...args) Print arguments to interface.
|
||||||
- (debug arg) Print arguments to console.
|
- (debug arg) Print arguments to console.
|
||||||
- (time ~rate) Returns timestamp in milliseconds.
|
- (time ~rate) Returns timestamp in milliseconds.
|
||||||
- (js) Javascript interop.
|
- (js) Javascript interop. Returns window object.
|
||||||
- (on event f) Triggers on event.
|
- (on event f) Triggers on event.
|
||||||
- (test name a b)
|
- (test name a b) Unit test. Checks if a is equal to b, logs results to console.
|
||||||
- (benchmark fn) Logs time taken to execute a function.
|
- (benchmark fn) Logs time taken to execute a function.
|
||||||
|
- (get-theme) Returns an object with current theme colors.
|
||||||
|
- (get-frame) Returns a shape object describing the current canvas.
|
||||||
|
|
||||||
Extras
|
Extras
|
||||||
|
|
||||||
|
@ -35,9 +35,9 @@
|
|||||||
|
|
||||||
;
|
;
|
||||||
(defn redraw ()
|
(defn redraw ()
|
||||||
(
|
|
||||||
(clear)
|
(clear)
|
||||||
(rec 300)))
|
(rec 300))
|
||||||
|
|
||||||
;
|
;
|
||||||
(on "animate" redraw)
|
(on "animate" redraw)
|
@ -3,6 +3,9 @@
|
|||||||
;
|
;
|
||||||
(clear)
|
(clear)
|
||||||
|
|
||||||
|
(def frame
|
||||||
|
(get-frame))
|
||||||
|
|
||||||
;
|
;
|
||||||
(def gradient-line
|
(def gradient-line
|
||||||
(line frame:c 0 frame:c frame:h))
|
(line frame:c 0 frame:c frame:h))
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
(clear)
|
(clear)
|
||||||
|
|
||||||
|
(def frame
|
||||||
|
(get-frame))
|
||||||
|
|
||||||
|
|
||||||
; times
|
; times
|
||||||
|
|
||||||
@ -26,13 +29,13 @@
|
|||||||
; position on a circle from angle
|
; position on a circle from angle
|
||||||
|
|
||||||
(defn circle-pos
|
(defn circle-pos
|
||||||
(cx cy r a) {:x
|
(cx cy r a) (object "x"
|
||||||
(add cx
|
(add cx
|
||||||
(mul r
|
(mul r
|
||||||
(cos a))) :y
|
(cos a))) "y"
|
||||||
(add cy
|
(add cy
|
||||||
(mul r
|
(mul r
|
||||||
(sin a)))})
|
(sin a)))))
|
||||||
|
|
||||||
|
|
||||||
; draw
|
; draw
|
||||||
@ -42,10 +45,10 @@
|
|||||||
(
|
(
|
||||||
(stroke
|
(stroke
|
||||||
(line cx cy
|
(line cx cy
|
||||||
(:x
|
(get
|
||||||
(circle-pos cx cy r a))
|
(circle-pos cx cy r a) "x")
|
||||||
(:y
|
(get
|
||||||
(circle-pos cx cy r a))) "white" 2)))
|
(circle-pos cx cy r a) "y")) "white" 2)))
|
||||||
|
|
||||||
;
|
;
|
||||||
(defn draw-star
|
(defn draw-star
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
(def theme
|
(def theme
|
||||||
(get-theme))
|
(get-theme))
|
||||||
|
(def frame
|
||||||
|
(get-frame))
|
||||||
|
|
||||||
; ex: theme:f_high
|
; ex: theme:f_high
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
(clear)
|
(clear)
|
||||||
|
|
||||||
|
(def theme
|
||||||
|
(get-theme))
|
||||||
|
|
||||||
|
(def frame
|
||||||
|
(get-frame))
|
||||||
|
|
||||||
(defn branch
|
(defn branch
|
||||||
(v)
|
(v)
|
||||||
(if
|
(if
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
(clear)
|
(clear)
|
||||||
|
|
||||||
|
(def theme
|
||||||
|
(get-theme))
|
||||||
|
|
||||||
(transform:move 150 150)
|
(transform:move 150 150)
|
||||||
|
|
||||||
(fill
|
(fill
|
||||||
|
168
examples/events/webmidi.lisp
Normal file
168
examples/events/webmidi.lisp
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
;A simple MIDI visualiser
|
||||||
|
;showing activity per note
|
||||||
|
;and channel.
|
||||||
|
|
||||||
|
(clear)
|
||||||
|
|
||||||
|
(def theme
|
||||||
|
(get-theme))
|
||||||
|
|
||||||
|
(resize 1200 600)
|
||||||
|
|
||||||
|
(def maxcirclesize 50)
|
||||||
|
|
||||||
|
(def mincirclesize 20)
|
||||||
|
|
||||||
|
(def circlexdist 40)
|
||||||
|
|
||||||
|
(def circleydist 30)
|
||||||
|
|
||||||
|
(def notes
|
||||||
|
(object 0 "A" 1 "A#" 2 "B" 3 "C" 4 "C#" 5 "D" 6 "D#" 7 "E" 8 "F" 9 "F#" 10 "G" 11 "G#"))
|
||||||
|
|
||||||
|
(def sharpnotes
|
||||||
|
(object 1 "A#" 4 "C#" 6 "D#" 9 "F#" 11 "G#"))
|
||||||
|
|
||||||
|
(def frame
|
||||||
|
(get-frame))
|
||||||
|
|
||||||
|
(def jswindow
|
||||||
|
(js))
|
||||||
|
|
||||||
|
(defn isblackkey
|
||||||
|
(num)
|
||||||
|
(def distfromA0
|
||||||
|
(sub num 21))
|
||||||
|
(def semitonenum
|
||||||
|
(mod distfromA0 12))
|
||||||
|
(not
|
||||||
|
(eq
|
||||||
|
(get sharpnotes semitonenum) undefined)))
|
||||||
|
|
||||||
|
(defn circlebynotenum
|
||||||
|
(num)
|
||||||
|
(circle
|
||||||
|
(mul
|
||||||
|
(sub num 47) circlexdist)
|
||||||
|
(if
|
||||||
|
(isblackkey num) circleydist
|
||||||
|
(mul 2.5 circleydist)) mincirclesize))
|
||||||
|
|
||||||
|
(def reactivecircles
|
||||||
|
(reduce
|
||||||
|
(range 48 76)
|
||||||
|
(λ
|
||||||
|
(acc num index)
|
||||||
|
(set acc num
|
||||||
|
(circlebynotenum num)))
|
||||||
|
(object)))
|
||||||
|
|
||||||
|
(def channelcircles
|
||||||
|
(map
|
||||||
|
(range 0 15)
|
||||||
|
(λ
|
||||||
|
(num)
|
||||||
|
(circle
|
||||||
|
(add
|
||||||
|
(mul num circlexdist 1.25) circlexdist) 200 mincirclesize))))
|
||||||
|
|
||||||
|
(defn js-exec
|
||||||
|
(obj fname listargs)
|
||||||
|
(def boundfunction
|
||||||
|
(js-bind
|
||||||
|
(get obj fname) obj))
|
||||||
|
(def result
|
||||||
|
(apply boundfunction
|
||||||
|
(if
|
||||||
|
(eq listargs undefined) () listargs))) result)
|
||||||
|
|
||||||
|
(defn midimsghandler
|
||||||
|
(midiMessage)
|
||||||
|
(def eventType
|
||||||
|
(get
|
||||||
|
(:data midiMessage) "0"))
|
||||||
|
;zero based
|
||||||
|
(def channelNum
|
||||||
|
(logand eventType 15))
|
||||||
|
;ignore clock in debug to keep things cleaner
|
||||||
|
(if
|
||||||
|
(not
|
||||||
|
(eq eventType 248))
|
||||||
|
(debug "incoming MIDI:" "CH" channelNum
|
||||||
|
(:data midiMessage)))
|
||||||
|
(def noteNum
|
||||||
|
(get
|
||||||
|
(:data midiMessage) "1"))
|
||||||
|
(def noteVelocity
|
||||||
|
(get
|
||||||
|
(:data midiMessage) "2"))
|
||||||
|
(set
|
||||||
|
(get channelcircles channelNum) "r"
|
||||||
|
(add mincirclesize
|
||||||
|
(mul
|
||||||
|
(sub maxcirclesize mincirclesize)
|
||||||
|
(div noteVelocity 100))))
|
||||||
|
(set
|
||||||
|
(or
|
||||||
|
(get reactivecircles noteNum)()) "r"
|
||||||
|
(add mincirclesize
|
||||||
|
(mul
|
||||||
|
(sub maxcirclesize mincirclesize)
|
||||||
|
(div noteVelocity 100)))))
|
||||||
|
|
||||||
|
(defn midiokhandler
|
||||||
|
(midiAccess)
|
||||||
|
(def midiInputs
|
||||||
|
(js-exec
|
||||||
|
(:inputs midiAccess) "values"))
|
||||||
|
(eachof midiInputs
|
||||||
|
(λ
|
||||||
|
(input id)
|
||||||
|
(debug "Setting listener on"
|
||||||
|
(:name input)
|
||||||
|
(:manufacturer input))
|
||||||
|
(set input "onmidimessage" midimsghandler))))
|
||||||
|
|
||||||
|
(defn midierrhandler
|
||||||
|
(err)
|
||||||
|
(debug "midierrhandler" err))
|
||||||
|
|
||||||
|
(js-exec
|
||||||
|
(js-exec
|
||||||
|
(:navigator jswindow) "requestMIDIAccess") "then"
|
||||||
|
(list midiokhandler midierrhandler))
|
||||||
|
|
||||||
|
(defn drawcircle
|
||||||
|
(arglist)
|
||||||
|
(def notenum
|
||||||
|
(first arglist))
|
||||||
|
(def i
|
||||||
|
(last arglist))
|
||||||
|
(if
|
||||||
|
(gt
|
||||||
|
(:r i) mincirclesize)
|
||||||
|
(set i "r"
|
||||||
|
(sub
|
||||||
|
(:r i) 0.6)))
|
||||||
|
(fill i
|
||||||
|
(if
|
||||||
|
(isblackkey notenum)
|
||||||
|
(theme:f_med)
|
||||||
|
(theme:f_low))))
|
||||||
|
|
||||||
|
(defn redraw ()
|
||||||
|
(clear)
|
||||||
|
(each
|
||||||
|
(entries reactivecircles) drawcircle)
|
||||||
|
(each channelcircles
|
||||||
|
(λ
|
||||||
|
(s i)
|
||||||
|
(fill s theme:b_high)
|
||||||
|
(fill
|
||||||
|
(text
|
||||||
|
(sub s:cx mincirclesize)
|
||||||
|
(add s:cy mincirclesize 18) 18
|
||||||
|
(concat "CH" i)) theme:b_inv 2))))
|
||||||
|
|
||||||
|
;
|
||||||
|
(on "animate" redraw)
|
3
examples/not-implemented-yet/README.md
Normal file
3
examples/not-implemented-yet/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Not implemented (yet)
|
||||||
|
|
||||||
|
This set of examples shows the limitations of Ronin's LISP.
|
44
examples/not-implemented-yet/object-symbols.lisp
Normal file
44
examples/not-implemented-yet/object-symbols.lisp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
;To inspect the results of these tests,
|
||||||
|
;open your browser's debugging tools
|
||||||
|
;
|
||||||
|
(usually F12)
|
||||||
|
and navigate to the
|
||||||
|
;JavaScript console.
|
||||||
|
(clear)
|
||||||
|
|
||||||
|
(def mydog
|
||||||
|
(object "color" "gold" "coat" "long" :speed "quick" :health "good"))
|
||||||
|
|
||||||
|
(debug mydog)
|
||||||
|
|
||||||
|
(test "My dog's color is"
|
||||||
|
(get mydog "color") "gold")
|
||||||
|
|
||||||
|
(test "My dog's coat is"
|
||||||
|
(get mydog "coat") "long")
|
||||||
|
|
||||||
|
(test "My dog's speed is"
|
||||||
|
(get mydog "speed") "quick")
|
||||||
|
|
||||||
|
;the last one passes only because :health
|
||||||
|
;in the set instruction above
|
||||||
|
;resolves to undefined - and
|
||||||
|
;technically you can have one object value
|
||||||
|
;for key=undefined
|
||||||
|
(test "My dog's health is"
|
||||||
|
(get mydog :health) "good")
|
||||||
|
|
||||||
|
;You can, however, use obj:param syntax to
|
||||||
|
;get properties of objects.
|
||||||
|
;A shorthand for
|
||||||
|
(get obj "param")
|
||||||
|
.
|
||||||
|
;
|
||||||
|
(test "Get color" mydog:color "gold")
|
||||||
|
|
||||||
|
;Also,
|
||||||
|
(:coat mydog)
|
||||||
|
|
||||||
|
;is another shorthand.
|
||||||
|
(test "Get coat shorthand function"
|
||||||
|
(:coat mydog) "long")
|
@ -2,17 +2,31 @@
|
|||||||
|
|
||||||
(clear)
|
(clear)
|
||||||
|
|
||||||
(defn glitch
|
(import $path
|
||||||
(rec)
|
|
||||||
(if (gt rec 1)
|
|
||||||
(
|
|
||||||
(translate
|
|
||||||
(rect (random 400) (random 400) (random 10) (random 10))
|
|
||||||
(pos (random 400) (random 400)))
|
|
||||||
(glitch (sub rec 1)))))
|
|
||||||
|
|
||||||
(import
|
|
||||||
"../static/crystal.jpg"
|
|
||||||
(rect 0 0 400 400))
|
(rect 0 0 400 400))
|
||||||
|
|
||||||
|
(defn translate
|
||||||
|
(source-rect dest-pos)
|
||||||
|
(
|
||||||
|
(paste
|
||||||
|
(copy source-rect)
|
||||||
|
(rect dest-pos:x dest-pos:y source-rect:w source-rect:h))))
|
||||||
|
|
||||||
|
(defn glitch
|
||||||
|
(rec)
|
||||||
|
(if
|
||||||
|
(gt rec 1)
|
||||||
|
(
|
||||||
|
(translate
|
||||||
|
(rect
|
||||||
|
(random 1 400)
|
||||||
|
(random 1 400)
|
||||||
|
(random 1 10)
|
||||||
|
(random 1 10))
|
||||||
|
(pos
|
||||||
|
(random 1 400)
|
||||||
|
(random 1 400)))
|
||||||
|
(glitch
|
||||||
|
(sub rec 1)))))
|
||||||
|
|
||||||
(glitch 500)
|
(glitch 500)
|
@ -1,6 +1,12 @@
|
|||||||
; Normalize photo colors
|
; Normalize photo colors
|
||||||
|
|
||||||
(open $path 0.5)
|
(open $path 0.5)
|
||||||
|
|
||||||
|
;(pick (rect 0 0 100 100)) will return the average color
|
||||||
|
;of 100x100px rectangle.
|
||||||
|
;without extra arguments,
|
||||||
|
;pick grabs the whole canvas by default,
|
||||||
|
;and calculates the average color.
|
||||||
(def average-color
|
(def average-color
|
||||||
(pick))
|
(pick))
|
||||||
(pixels normalize average-color)
|
(pixels normalize average-color)
|
@ -1,4 +1,4 @@
|
|||||||
; saturate image
|
; saturate image
|
||||||
(open "../static/crystal.jpg")
|
(open $path)
|
||||||
(pixels
|
(pixels saturation 12
|
||||||
(frame) saturation 12)
|
(get-frame))
|
@ -2,7 +2,7 @@
|
|||||||
; drag an image on the window
|
; drag an image on the window
|
||||||
(open $path)
|
(open $path)
|
||||||
;
|
;
|
||||||
(pixels
|
(pixels saturation 0
|
||||||
(rect 100 100 400 400) saturation 0)
|
(rect 100 100 400 400))
|
||||||
(pixels
|
(pixels contrast 0.5
|
||||||
(rect 300 300 400 400) contrast 0.5)
|
(rect 300 300 400 400))
|
@ -6,7 +6,7 @@
|
|||||||
(if
|
(if
|
||||||
(gt rec 0)
|
(gt rec 0)
|
||||||
(
|
(
|
||||||
(import "../static/crystal.jpg"
|
(import $path
|
||||||
(rect
|
(rect
|
||||||
(random 200)
|
(random 200)
|
||||||
(random 200)
|
(random 200)
|
||||||
|
@ -18,63 +18,10 @@
|
|||||||
(pick
|
(pick
|
||||||
(guide
|
(guide
|
||||||
(rect $xy unit unit))))
|
(rect $xy unit unit))))
|
||||||
(def color-2
|
(echo color-1)
|
||||||
(pick
|
|
||||||
(guide
|
|
||||||
(rect $xy unit unit))))
|
|
||||||
(def color-3
|
|
||||||
(pick
|
|
||||||
(guide
|
|
||||||
(rect $xy unit unit))))
|
|
||||||
(def color-4
|
|
||||||
(pick
|
|
||||||
(guide
|
|
||||||
(rect $xy unit unit))))
|
|
||||||
(def color-5
|
|
||||||
(pick
|
|
||||||
(guide
|
|
||||||
(rect $xy unit unit))))
|
|
||||||
(def color-6
|
|
||||||
(pick
|
|
||||||
(guide
|
|
||||||
(rect $xy unit unit))))
|
|
||||||
(def color-7
|
|
||||||
(pick
|
|
||||||
(guide
|
|
||||||
(rect $xy unit unit))))
|
|
||||||
(def color-8
|
|
||||||
(pick
|
|
||||||
(guide
|
|
||||||
(rect $xy unit unit))))
|
|
||||||
|
|
||||||
; display
|
; display
|
||||||
|
|
||||||
(fill
|
(fill
|
||||||
(circle
|
(circle
|
||||||
(mul 20 2) pos-row-1 18) color-1)
|
(mul 20 2) pos-row-1 18) color-1)
|
||||||
(fill
|
|
||||||
(circle
|
|
||||||
(mul 20 4) pos-row-1 18) color-2)
|
|
||||||
(fill
|
|
||||||
(circle
|
|
||||||
(mul 20 6) pos-row-1 18) color-3)
|
|
||||||
(fill
|
|
||||||
(circle
|
|
||||||
(mul 20 8) pos-row-1 18) color-4)
|
|
||||||
(fill
|
|
||||||
(circle
|
|
||||||
(mul 20 3) pos-row-2 18) color-5)
|
|
||||||
(fill
|
|
||||||
(circle
|
|
||||||
(mul 20 5) pos-row-2 18) color-6)
|
|
||||||
(fill
|
|
||||||
(circle
|
|
||||||
(mul 20 7) pos-row-2 18) color-7)
|
|
||||||
(fill
|
|
||||||
(circle
|
|
||||||
(mul 20 9) pos-row-2 18) color-8)
|
|
||||||
;
|
|
||||||
(def res
|
|
||||||
(add color-1:hex ":" color-2:hex ":" color-3:hex ":" color-4:hex ":" color-5:hex ":" color-6:hex ":" color-7:hex ":" color-8:hex))
|
|
||||||
(echo
|
|
||||||
(add res ":" res))
|
|
@ -1,4 +1,4 @@
|
|||||||
(resize 600 200)
|
(resize 600 800)
|
||||||
|
|
||||||
(clear)
|
(clear)
|
||||||
|
|
||||||
@ -14,6 +14,9 @@
|
|||||||
(guide
|
(guide
|
||||||
(line 0 100 600 100)) colors))
|
(line 0 100 600 100)) colors))
|
||||||
|
|
||||||
|
;collect colors to prepared list,
|
||||||
|
;in particular points from the gradient
|
||||||
|
;marked by the guides
|
||||||
(each picked-colors
|
(each picked-colors
|
||||||
(λ
|
(λ
|
||||||
(color id)
|
(color id)
|
||||||
@ -25,5 +28,33 @@
|
|||||||
(mul id
|
(mul id
|
||||||
(div 600 9)) 100)))))))
|
(div 600 9)) 100)))))))
|
||||||
|
|
||||||
|
;show picked colors as swatches
|
||||||
|
(each picked-colors
|
||||||
|
(λ
|
||||||
|
(color id)
|
||||||
|
(
|
||||||
|
;swatch circle
|
||||||
|
(fill
|
||||||
|
(circle
|
||||||
|
20 (add (mul id
|
||||||
|
(div 600 9)) 300) 18) color)
|
||||||
|
"black")))
|
||||||
|
|
||||||
|
;show picked colors as text
|
||||||
|
(each picked-colors
|
||||||
|
(λ
|
||||||
|
(color id)
|
||||||
|
(
|
||||||
|
(fill
|
||||||
|
(text
|
||||||
|
12 (add (mul id
|
||||||
|
(div 600 9)) 300 5) 24
|
||||||
|
(concat id ": "
|
||||||
|
(get
|
||||||
|
(get picked-colors
|
||||||
|
(concat "" id)) "hex"))) "black"))))
|
||||||
|
|
||||||
|
;get the first color in different formats
|
||||||
(echo
|
(echo
|
||||||
(get picked-colors:1 "hex"))
|
(get picked-colors:0 "hex")
|
||||||
|
(get picked-colors:0 "rgba"))
|
@ -7,5 +7,8 @@
|
|||||||
(add
|
(add
|
||||||
(mul index 40) 50) 40 name) "red"))
|
(mul index 40) 50) 40 name) "red"))
|
||||||
|
|
||||||
|
;this will display the list of loaded files.
|
||||||
|
;drag a few pictures into Ronin, then eval
|
||||||
|
;this script again.
|
||||||
(each
|
(each
|
||||||
(files) print-file)
|
(files) print-file)
|
@ -3,6 +3,8 @@
|
|||||||
;
|
;
|
||||||
(clear)
|
(clear)
|
||||||
|
|
||||||
|
(def frame (get-frame))
|
||||||
|
|
||||||
;
|
;
|
||||||
(def gradient-line
|
(def gradient-line
|
||||||
(line frame:c 0 frame:c frame:h))
|
(line frame:c 0 frame:c frame:h))
|
||||||
|
134
examples/tests/lists.lisp
Normal file
134
examples/tests/lists.lisp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
(test "Native last call - list of numbers"
|
||||||
|
(last
|
||||||
|
(1 2 3)) 3)
|
||||||
|
|
||||||
|
(test "Native last call - list of numbers, 1 element"
|
||||||
|
(last
|
||||||
|
(1)) 1)
|
||||||
|
|
||||||
|
(test "Native last call - list of numbers, no elements"
|
||||||
|
(last ()) undefined)
|
||||||
|
|
||||||
|
(test "Native last call - list of strings, 1 element"
|
||||||
|
(last
|
||||||
|
("abc")) "abc")
|
||||||
|
|
||||||
|
(test "Native last call - list of strings, many elements"
|
||||||
|
(last
|
||||||
|
("ala" "bla" "cla")) "cla")
|
||||||
|
|
||||||
|
;functions defined as defn/lambda args bodyinstrs...
|
||||||
|
|
||||||
|
(defn lastfn
|
||||||
|
(listarg) (debug "some other instruction")
|
||||||
|
(last listarg))
|
||||||
|
|
||||||
|
(test "Proxied last call - list of numbers"
|
||||||
|
(lastfn
|
||||||
|
(1 2 3)) 3)
|
||||||
|
|
||||||
|
(test "Proxied last call - list of numbers, 1 element"
|
||||||
|
(lastfn
|
||||||
|
(1)) 1)
|
||||||
|
|
||||||
|
(test "Proxied last call - list of numbers, no elements"
|
||||||
|
(lastfn ()) undefined)
|
||||||
|
|
||||||
|
(test "Proxied last call - list of strings, 1 element"
|
||||||
|
(lastfn
|
||||||
|
("abc")) "abc")
|
||||||
|
|
||||||
|
(test "Proxied last call - list of strings, many elements"
|
||||||
|
(lastfn
|
||||||
|
("ala" "bla" "cla")) "cla")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(test "Lambda last call - list of numbers"
|
||||||
|
((λ
|
||||||
|
(listarg) (debug "some other instruction")
|
||||||
|
(last listarg))
|
||||||
|
(1 2 3)) 3)
|
||||||
|
|
||||||
|
(test "Lambda last call - list of numbers, 1 element"
|
||||||
|
((λ
|
||||||
|
(listarg) (debug "some other instruction")
|
||||||
|
(last listarg))
|
||||||
|
(1)) 1)
|
||||||
|
|
||||||
|
(test "Lambda last call - list of numbers, no elements"
|
||||||
|
((λ
|
||||||
|
(listarg) (debug "some other instruction")
|
||||||
|
(last listarg)) ()) undefined)
|
||||||
|
|
||||||
|
(test "Lambda last call - list of strings, 1 element"
|
||||||
|
((λ
|
||||||
|
(listarg) (debug "some other instruction")
|
||||||
|
(last listarg))
|
||||||
|
("abc")) "abc")
|
||||||
|
|
||||||
|
(test "Lambda last call - list of strings, many elements"
|
||||||
|
((λ
|
||||||
|
(listarg) (debug "some other instruction")
|
||||||
|
(last listarg))
|
||||||
|
("ala" "bla" "cla")) "cla")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;functions defined as defn/lambda args bodyinstr
|
||||||
|
|
||||||
|
(defn lastfn2
|
||||||
|
(listarg)
|
||||||
|
(last listarg))
|
||||||
|
|
||||||
|
(test "Proxied last call - list of numbers"
|
||||||
|
(lastfn2
|
||||||
|
(1 2 3)) 3)
|
||||||
|
|
||||||
|
(test "Proxied last call - list of numbers, 1 element"
|
||||||
|
(lastfn2
|
||||||
|
(1)) 1)
|
||||||
|
|
||||||
|
(test "Proxied last call - list of numbers, no elements"
|
||||||
|
(lastfn2 ()) undefined)
|
||||||
|
|
||||||
|
(test "Proxied last call - list of strings, 1 element"
|
||||||
|
(lastfn2
|
||||||
|
("abc")) "abc")
|
||||||
|
|
||||||
|
(test "Proxied last call - list of strings, many elements"
|
||||||
|
(lastfn2
|
||||||
|
("ala" "bla" "cla")) "cla")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(test "Lambda last call - list of numbers"
|
||||||
|
((λ
|
||||||
|
(listarg)
|
||||||
|
(last listarg))
|
||||||
|
(1 2 3)) 3)
|
||||||
|
|
||||||
|
(test "Lambda last call - list of numbers, 1 element"
|
||||||
|
((λ
|
||||||
|
(listarg)
|
||||||
|
(last listarg))
|
||||||
|
(1)) 1)
|
||||||
|
|
||||||
|
(test "Lambda last call - list of numbers, no elements"
|
||||||
|
((λ
|
||||||
|
(listarg)
|
||||||
|
(last listarg)) ()) undefined)
|
||||||
|
|
||||||
|
(test "Lambda last call - list of strings, 1 element"
|
||||||
|
((λ
|
||||||
|
(listarg)
|
||||||
|
(last listarg))
|
||||||
|
("abc")) "abc")
|
||||||
|
|
||||||
|
(test "Lambda last call - list of strings, many elements"
|
||||||
|
((λ
|
||||||
|
(listarg)
|
||||||
|
(last listarg))
|
||||||
|
("ala" "bla" "cla")) "cla")
|
70
index.html
70
index.html
@ -148,14 +148,16 @@ function Lain (lib = {}) {
|
|||||||
const identifier = input[1].value
|
const identifier = input[1].value
|
||||||
if (context.scope[identifier]) { console.warn('Lain', `Redefining function: ${identifier}`) }
|
if (context.scope[identifier]) { console.warn('Lain', `Redefining function: ${identifier}`) }
|
||||||
const fnParams = input[2].type === TYPES.string && input[3] ? input[3] : input[2]
|
const fnParams = input[2].type === TYPES.string && input[3] ? input[3] : input[2]
|
||||||
const fnBody = input[2].type === TYPES.string && input[4] ? input[4] : input[3]
|
const fnBodyFirstIndex = input[2].type === TYPES.string && input[4] ? 4 : 3
|
||||||
|
const fnBody = input.slice(fnBodyFirstIndex)
|
||||||
context.scope[identifier] = function () {
|
context.scope[identifier] = function () {
|
||||||
const lambdaArguments = arguments
|
const lambdaArguments = arguments
|
||||||
const lambdaScope = fnParams.reduce(function (acc, x, i) {
|
const lambdaScope = fnParams.reduce(function (acc, x, i) {
|
||||||
acc[x.value] = lambdaArguments[i]
|
acc[x.value] = lambdaArguments[i]
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
return interpret(fnBody, new Context(lambdaScope, context))
|
let result = interpret(fnBody, new Context(lambdaScope, context))
|
||||||
|
return getReturnValue(result)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
λ: function (input, context) {
|
λ: function (input, context) {
|
||||||
@ -165,13 +167,20 @@ function Lain (lib = {}) {
|
|||||||
acc[x.value] = lambdaArguments[i]
|
acc[x.value] = lambdaArguments[i]
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
return interpret(input[2], new Context(lambdaScope, context))
|
let result = interpret(input.slice(2), new Context(lambdaScope, context))
|
||||||
|
return getReturnValue(result)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
if: function (input, context) {
|
if: function (input, context) {
|
||||||
return interpret(input[1], context) ? interpret(input[2], context) : input[3] ? interpret(input[3], context) : []
|
return interpret(input[1], context) ? interpret(input[2], context) : input[3] ? interpret(input[3], context) : []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const getReturnValue = function (interpretResult) {
|
||||||
|
if(!interpretResult || !(interpretResult instanceof Array) || !interpretResult.length){
|
||||||
|
return interpretResult
|
||||||
|
}
|
||||||
|
return interpretResult[interpretResult.length - 1]
|
||||||
|
}
|
||||||
const interpretList = function (input, context) {
|
const interpretList = function (input, context) {
|
||||||
if (input.length > 0 && input[0].value in special) {
|
if (input.length > 0 && input[0].value in special) {
|
||||||
return special[input[0].value](input, context)
|
return special[input[0].value](input, context)
|
||||||
@ -1185,6 +1194,21 @@ function Library (client) {
|
|||||||
}
|
}
|
||||||
return Math.random()
|
return Math.random()
|
||||||
}
|
}
|
||||||
|
this.logand = (a, b) => {
|
||||||
|
return a & b
|
||||||
|
}
|
||||||
|
this.logior = (a, b) => {
|
||||||
|
return a | b
|
||||||
|
}
|
||||||
|
this.logxor = (a, b) => {
|
||||||
|
return a ^ b
|
||||||
|
}
|
||||||
|
this.lognot = (a) => {
|
||||||
|
return ~ a
|
||||||
|
}
|
||||||
|
this.ash = (a, b) => {
|
||||||
|
return a << b
|
||||||
|
}
|
||||||
this.gt = (a, b) => { // Returns true if a is greater than b, else false.
|
this.gt = (a, b) => { // Returns true if a is greater than b, else false.
|
||||||
return a > b
|
return a > b
|
||||||
}
|
}
|
||||||
@ -1211,20 +1235,29 @@ function Library (client) {
|
|||||||
}
|
}
|
||||||
return args[args.length - 1]
|
return args[args.length - 1]
|
||||||
}
|
}
|
||||||
this.not = (a) => {
|
this.not = (a) => { //Negation. Returns true if a is false. Returns false if a is true.
|
||||||
return !a
|
return !a
|
||||||
}
|
}
|
||||||
this.while = (fn, action) => {
|
this.while = (fn, action) => { //While loop. Execute action for as long as fn is true.
|
||||||
while (fn()) {
|
while (fn()) {
|
||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.apply = (fn, argslist) => {
|
||||||
|
let result = fn(...argslist);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
this.each = (arr, fn) => { // Run a function for each element in a list.
|
this.each = (arr, fn) => { // Run a function for each element in a list.
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i = 0; i < arr.length; i++) {
|
||||||
const arg = arr[i]
|
const arg = arr[i]
|
||||||
fn(arg, i)
|
fn(arg, i)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.eachof = (arr, fn) => {
|
||||||
|
for(let elem of arr){
|
||||||
|
fn(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
this.map = (arr, fn) => { // Returns a new list with fn applied to each value.
|
this.map = (arr, fn) => { // Returns a new list with fn applied to each value.
|
||||||
return arr.map(fn);
|
return arr.map(fn);
|
||||||
}
|
}
|
||||||
@ -1242,7 +1275,10 @@ function Library (client) {
|
|||||||
this.len = (item) => { // Returns the length of a list.
|
this.len = (item) => { // Returns the length of a list.
|
||||||
return item.length
|
return item.length
|
||||||
}
|
}
|
||||||
this.cons = (arr, ...items) => { // Retruns a new array with the items appended.
|
this.list = (...items) => { // Returns a new array with the items
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
this.cons = (arr, ...items) => { // Returns a new array with the items appended to arr.
|
||||||
return arr.concat(items)
|
return arr.concat(items)
|
||||||
}
|
}
|
||||||
this.push = (arr, ...items) => { // Appends the items into the existing list.
|
this.push = (arr, ...items) => { // Appends the items into the existing list.
|
||||||
@ -1260,10 +1296,10 @@ function Library (client) {
|
|||||||
this.last = (arr) => { // Returns the last
|
this.last = (arr) => { // Returns the last
|
||||||
return arr[arr.length - 1]
|
return arr[arr.length - 1]
|
||||||
}
|
}
|
||||||
this.rest = ([_, ...arr]) => {
|
this.rest = ([_, ...arr]) => { // Returns all arguments except the first
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
this.range = (start, end, step = 1) => {
|
this.range = (start, end, step = 1) => { //Returns a list of numbers counting from start to end. Step defaults to 1.
|
||||||
const arr = []
|
const arr = []
|
||||||
if (step > 0) {
|
if (step > 0) {
|
||||||
for (let i = start; i <= end; i += step) {
|
for (let i = start; i <= end; i += step) {
|
||||||
@ -1277,7 +1313,7 @@ function Library (client) {
|
|||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
this.get = (item, key) => { // Gets an object's parameter with name.
|
this.get = (item, key) => { // Gets an object's parameter with name.
|
||||||
return item && key ? item[key] : null
|
return item && (key !== null && key !== undefined) ? item[key] : null
|
||||||
}
|
}
|
||||||
this.set = (item, ...args) => { // Sets an object's parameter with name as value.
|
this.set = (item, ...args) => { // Sets an object's parameter with name as value.
|
||||||
for (let i = 0; i < args.length; i += 2) {
|
for (let i = 0; i < args.length; i += 2) {
|
||||||
@ -1305,6 +1341,9 @@ function Library (client) {
|
|||||||
this.values = (item) => { // Returns a list of the object's values
|
this.values = (item) => { // Returns a list of the object's values
|
||||||
return Object.values(item)
|
return Object.values(item)
|
||||||
}
|
}
|
||||||
|
this.entries = (item) => { // Returns a list of the object's properties, each in array of [key, value]
|
||||||
|
return Object.entries(item);
|
||||||
|
}
|
||||||
this.convolve = (kernel, rect = this['get-frame']()) => {
|
this.convolve = (kernel, rect = this['get-frame']()) => {
|
||||||
const sigma = kernel.flat().reduce((a, x) => (a + x))
|
const sigma = kernel.flat().reduce((a, x) => (a + x))
|
||||||
const kw = kernel[0].length; const kh = kernel.length
|
const kw = kernel[0].length; const kh = kernel.length
|
||||||
@ -1357,9 +1396,9 @@ function Library (client) {
|
|||||||
client.log(args)
|
client.log(args)
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
this.debug = (arg) => { // Print arguments to console.
|
this.debug = (...args) => { // Print arguments to console.
|
||||||
console.log(arg)
|
console.log(...args)
|
||||||
return arg
|
return args
|
||||||
}
|
}
|
||||||
this.time = (rate = 1) => { // Returns timestamp in milliseconds.
|
this.time = (rate = 1) => { // Returns timestamp in milliseconds.
|
||||||
return (Date.now() * rate)
|
return (Date.now() * rate)
|
||||||
@ -1367,10 +1406,13 @@ function Library (client) {
|
|||||||
this.js = () => { // Javascript interop.
|
this.js = () => { // Javascript interop.
|
||||||
return window
|
return window
|
||||||
}
|
}
|
||||||
|
this['js-bind'] = (fn, thisArg, ...args) => {
|
||||||
|
return fn.bind(thisArg, ...args)
|
||||||
|
}
|
||||||
this.on = (event, f) => { // Triggers on event.
|
this.on = (event, f) => { // Triggers on event.
|
||||||
client.bind(event, f)
|
client.bind(event, f)
|
||||||
}
|
}
|
||||||
this.test = (name, a, b) => {
|
this.test = (name, a, b) => { //nit test. Checks if a is equal to b, logs results to console.
|
||||||
if (`${a}` !== `${b}`) {
|
if (`${a}` !== `${b}`) {
|
||||||
console.warn('failed ' + name, a, b)
|
console.warn('failed ' + name, a, b)
|
||||||
} else {
|
} else {
|
||||||
@ -1387,7 +1429,7 @@ function Library (client) {
|
|||||||
this['get-theme'] = () => { // Get theme values.
|
this['get-theme'] = () => { // Get theme values.
|
||||||
return client.theme.active
|
return client.theme.active
|
||||||
}
|
}
|
||||||
this['get-frame'] = () => { // Get theme values.
|
this['get-frame'] = () => { // Get frame shape.
|
||||||
return client.surface.getFrame()
|
return client.surface.getFrame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,15 +40,21 @@ function Lain (lib = {}) {
|
|||||||
defn: function (input, context) {
|
defn: function (input, context) {
|
||||||
const identifier = input[1].value
|
const identifier = input[1].value
|
||||||
if (context.scope[identifier]) { console.warn('Lain', `Redefining function: ${identifier}`) }
|
if (context.scope[identifier]) { console.warn('Lain', `Redefining function: ${identifier}`) }
|
||||||
|
|
||||||
const fnParams = input[2].type === TYPES.string && input[3] ? input[3] : input[2]
|
const fnParams = input[2].type === TYPES.string && input[3] ? input[3] : input[2]
|
||||||
const fnBody = input[2].type === TYPES.string && input[4] ? input[4] : input[3]
|
const fnBodyFirstIndex = input[2].type === TYPES.string && input[4] ? 4 : 3
|
||||||
|
const fnBody = input.slice(fnBodyFirstIndex)
|
||||||
|
|
||||||
context.scope[identifier] = function () {
|
context.scope[identifier] = function () {
|
||||||
const lambdaArguments = arguments
|
const lambdaArguments = arguments
|
||||||
const lambdaScope = fnParams.reduce(function (acc, x, i) {
|
const lambdaScope = fnParams.reduce(function (acc, x, i) {
|
||||||
acc[x.value] = lambdaArguments[i]
|
acc[x.value] = lambdaArguments[i]
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
return interpret(fnBody, new Context(lambdaScope, context))
|
|
||||||
|
let result = interpret(fnBody, new Context(lambdaScope, context))
|
||||||
|
//lisp returns the return value of the last executed function, not a list of all results of all functions.
|
||||||
|
return getReturnValue(result)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
λ: function (input, context) {
|
λ: function (input, context) {
|
||||||
@ -58,7 +64,10 @@ function Lain (lib = {}) {
|
|||||||
acc[x.value] = lambdaArguments[i]
|
acc[x.value] = lambdaArguments[i]
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
return interpret(input[2], new Context(lambdaScope, context))
|
|
||||||
|
let result = interpret(input.slice(2), new Context(lambdaScope, context))
|
||||||
|
//lisp returns the return value of the last executed function, not a list of all results of all functions.
|
||||||
|
return getReturnValue(result)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
if: function (input, context) {
|
if: function (input, context) {
|
||||||
@ -66,6 +75,15 @@ function Lain (lib = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getReturnValue = function (interpretResult) {
|
||||||
|
//lisp returns the return value of the last executed function,
|
||||||
|
//not a list of all results of all functions.
|
||||||
|
if(!interpretResult || !(interpretResult instanceof Array) || !interpretResult.length){
|
||||||
|
return interpretResult
|
||||||
|
}
|
||||||
|
return interpretResult[interpretResult.length - 1]
|
||||||
|
}
|
||||||
|
|
||||||
const interpretList = function (input, context) {
|
const interpretList = function (input, context) {
|
||||||
if (input.length > 0 && input[0].value in special) {
|
if (input.length > 0 && input[0].value in special) {
|
||||||
return special[input[0].value](input, context)
|
return special[input[0].value](input, context)
|
||||||
|
@ -382,6 +382,28 @@ function Library (client) {
|
|||||||
return Math.random()
|
return Math.random()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Binary
|
||||||
|
|
||||||
|
this.logand = (a, b) => {
|
||||||
|
return a & b
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logior = (a, b) => {
|
||||||
|
return a | b
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logxor = (a, b) => {
|
||||||
|
return a ^ b
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lognot = (a) => {
|
||||||
|
return ~ a
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ash = (a, b) => {
|
||||||
|
return a << b
|
||||||
|
}
|
||||||
|
|
||||||
// Logic
|
// Logic
|
||||||
|
|
||||||
this.gt = (a, b) => { // Returns true if a is greater than b, else false.
|
this.gt = (a, b) => { // Returns true if a is greater than b, else false.
|
||||||
@ -415,18 +437,22 @@ function Library (client) {
|
|||||||
return args[args.length - 1]
|
return args[args.length - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
this.not = (a) => {
|
this.not = (a) => { //Negation. Returns true if a is false. Returns false if a is true.
|
||||||
return !a
|
return !a
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arrays
|
this.while = (fn, action) => { //While loop. Execute action for as long as fn is true.
|
||||||
|
|
||||||
this.while = (fn, action) => {
|
|
||||||
while (fn()) {
|
while (fn()) {
|
||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Arrays
|
||||||
|
this.apply = (fn, argslist) => {
|
||||||
|
let result = fn(...argslist);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
this.each = (arr, fn) => { // Run a function for each element in a list.
|
this.each = (arr, fn) => { // Run a function for each element in a list.
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i = 0; i < arr.length; i++) {
|
||||||
const arg = arr[i]
|
const arg = arr[i]
|
||||||
@ -434,6 +460,12 @@ function Library (client) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.eachof = (arr, fn) => {
|
||||||
|
for(let elem of arr){
|
||||||
|
fn(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.map = (arr, fn) => { // Returns a new list with fn applied to each value.
|
this.map = (arr, fn) => { // Returns a new list with fn applied to each value.
|
||||||
return arr.map(fn);
|
return arr.map(fn);
|
||||||
}
|
}
|
||||||
@ -455,7 +487,11 @@ function Library (client) {
|
|||||||
return item.length
|
return item.length
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cons = (arr, ...items) => { // Retruns a new array with the items appended.
|
this.list = (...items) => { // Returns a new array with the items
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cons = (arr, ...items) => { // Returns a new array with the items appended to arr.
|
||||||
return arr.concat(items)
|
return arr.concat(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,11 +514,11 @@ function Library (client) {
|
|||||||
return arr[arr.length - 1]
|
return arr[arr.length - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rest = ([_, ...arr]) => {
|
this.rest = ([_, ...arr]) => { // Returns all arguments except the first
|
||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|
||||||
this.range = (start, end, step = 1) => {
|
this.range = (start, end, step = 1) => { //Returns a list of numbers counting from start to end. Step defaults to 1.
|
||||||
const arr = []
|
const arr = []
|
||||||
if (step > 0) {
|
if (step > 0) {
|
||||||
for (let i = start; i <= end; i += step) {
|
for (let i = start; i <= end; i += step) {
|
||||||
@ -499,7 +535,7 @@ function Library (client) {
|
|||||||
// Objects
|
// Objects
|
||||||
|
|
||||||
this.get = (item, key) => { // Gets an object's parameter with name.
|
this.get = (item, key) => { // Gets an object's parameter with name.
|
||||||
return item && key ? item[key] : null
|
return item && (key !== null && key !== undefined) ? item[key] : null
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set = (item, ...args) => { // Sets an object's parameter with name as value.
|
this.set = (item, ...args) => { // Sets an object's parameter with name as value.
|
||||||
@ -533,6 +569,10 @@ function Library (client) {
|
|||||||
return Object.values(item)
|
return Object.values(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.entries = (item) => { // Returns a list of the object's properties, each in array of [key, value]
|
||||||
|
return Object.entries(item);
|
||||||
|
}
|
||||||
|
|
||||||
// Convolve
|
// Convolve
|
||||||
|
|
||||||
this.convolve = (kernel, rect = this['get-frame']()) => {
|
this.convolve = (kernel, rect = this['get-frame']()) => {
|
||||||
@ -575,6 +615,8 @@ function Library (client) {
|
|||||||
[-1, -1, -1]]
|
[-1, -1, -1]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Points
|
||||||
|
|
||||||
this.offset = (a, b) => { // Offsets pos a with pos b, returns a.
|
this.offset = (a, b) => { // Offsets pos a with pos b, returns a.
|
||||||
a.x += b.x
|
a.x += b.x
|
||||||
a.y += b.y
|
a.y += b.y
|
||||||
@ -585,6 +627,8 @@ function Library (client) {
|
|||||||
return Math.sqrt(((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y)))
|
return Math.sqrt(((a.x - b.x) * (a.x - b.x)) + ((a.y - b.y) * (a.y - b.y)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
|
||||||
this.print = (value) => {
|
this.print = (value) => {
|
||||||
client.source.write('ronin-print', 'txt', value, 'text/plain')
|
client.source.write('ronin-print', 'txt', value, 'text/plain')
|
||||||
return value
|
return value
|
||||||
@ -595,9 +639,9 @@ function Library (client) {
|
|||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
this.debug = (arg) => { // Print arguments to console.
|
this.debug = (...args) => { // Print arguments to console.
|
||||||
console.log(arg)
|
console.log(...args)
|
||||||
return arg
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
this.time = (rate = 1) => { // Returns timestamp in milliseconds.
|
this.time = (rate = 1) => { // Returns timestamp in milliseconds.
|
||||||
@ -608,11 +652,24 @@ function Library (client) {
|
|||||||
return window
|
return window
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a new function that
|
||||||
|
// Useful when executing JS functions that need a strict `this` context.
|
||||||
|
//
|
||||||
|
// An example:
|
||||||
|
// `(get (get (js) "navigator") "requestMIDIAccess")` in Ronin
|
||||||
|
// should be equivalent to `window.navigator.requestMIDIAccess` in JS.
|
||||||
|
// Executing such retrieved JS method will crash though - as the method
|
||||||
|
// needs an internal `this` context - in exemplary case, window.navigator.
|
||||||
|
//
|
||||||
|
this['js-bind'] = (fn, thisArg, ...args) => {
|
||||||
|
return fn.bind(thisArg, ...args)
|
||||||
|
}
|
||||||
|
|
||||||
this.on = (event, f) => { // Triggers on event.
|
this.on = (event, f) => { // Triggers on event.
|
||||||
client.bind(event, f)
|
client.bind(event, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.test = (name, a, b) => {
|
this.test = (name, a, b) => { //nit test. Checks if a is equal to b, logs results to console.
|
||||||
if (`${a}` !== `${b}`) {
|
if (`${a}` !== `${b}`) {
|
||||||
console.warn('failed ' + name, a, b)
|
console.warn('failed ' + name, a, b)
|
||||||
} else {
|
} else {
|
||||||
@ -634,7 +691,7 @@ function Library (client) {
|
|||||||
return client.theme.active
|
return client.theme.active
|
||||||
}
|
}
|
||||||
|
|
||||||
this['get-frame'] = () => { // Get theme values.
|
this['get-frame'] = () => { // Get frame shape.
|
||||||
return client.surface.getFrame()
|
return client.surface.getFrame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user