Back to Prismjs

Prism Arturo

examples/prism-arturo.html

latest8.6 KB
Original Source

Full example

; this is a comment
; this is another comment

;---------------------------------
; VARIABLES & VALUES
;---------------------------------

; numbers
a1: 2
a2: 3.14
a3: to :complex [1 2.0] ; 1.0+2.0i

; strings
c1: "this is a string"
c2: {
    this is a multiline string
    that is indentation-agnostic
}
c3: {:
    this is 
        a verbatim
            multiline string
                which will remain exactly
                    as the original
:}

; characters
ch: `c`

; blocks/arrays
d: [1 2 3]

; dictionaries
e: #[
    name: "John"
    surname: "Doe"
    age: 34
    likes: [pizza spaghetti]
]

; yes, functions are values too
f: function [x][
    2 * x
]

; colors - right, you can directly define them as well!
g1: #red
g2: #0077BF

; dates
h: now ; 2021-05-03T17:10:48+02:00

; logical values
i1: true
i2: false
i3: maybe

;---------------------------------
; BASIC OPERATORS
;---------------------------------

; simple arithmetic
1 + 1 ; => 2
8 - 1 ; => 7
4.2 - 1.1 ; => 3.1
10 * 2 ; => 20
35 / 4 ; => 8
35 // 4 ; => 8.75
2 ^ 5 ; => 32
5 % 3 ; => 2

; bitwise operators
and 3 5 ; => 1
or 3 5 ; => 7
xor 3 5 ; => 6

; pre-defined constants
pi ; => 3.141592653589793
epsilon ; => 2.718281828459045
null ; => null
true ; => true
false ; => false

;---------------------------------
; COMPARISON OPERATORS
;---------------------------------

; equality
1 = 1 ; => true
2 = 1 ; => false

; inequality
1 <> 1 ; => false
2 <> 1 ; => true

; more comparisons
1 < 10 ; => true
1 =< 10 ; => true
10 =< 10 ; => true
1 > 10 ; => false
1 >= 10 ; => false
11 >= 10 ; => true

;---------------------------------
; CONDITIONALS
;---------------------------------

; logical operators
and? true true ; => true
and? true false ; => false
or? true false ; => true
or? false false ; => false

and? [1=2][2<3] ; => false 
                    ; (the second block will not be evaluated)

; simple if statements
if 2 > 1 [print "yes!"] ; yes!
if 3 <> 2 -> print "true!" ; true!

; if/else statements
if? 2 > 3 -> print "2 is greater than 3"
else -> print "2 is not greater than 3" ; 2 is not greater than 3

; switch statements
switch 2 > 3 -> print "2 is greater than 3"
                -> print "2 is not greater than 3" ; 2 is not greater than 3

a: (2 > 3)["yes"]["no"] ; a: "no"
a: (2 > 3)? -> "yes" -> "no" ; a: "no" (exactly the same as above)

; case/when statements
case [1]
    when? [>2] -> print "1 is greater than 2. what?!"
    when? [<0] -> print "1 is less than 0. nope..."
    else -> print "here we are!" ; here we are!

;---------------------------------
; LOOPS
;---------------------------------

; with `loop`
arr: [1 4 5 3]
loop arr 'x [
    print ["x =" x]
]
; x = 1
; x = 4
; x = 5
; x = 3

; with loop and custom index
loop.with:'i arr 'x [
    print ["item at position" i "=>" x]
]
; item at position 0 => 1
; item at position 1 => 4
; item at position 2 => 5
; item at position 3 => 3

; using ranges
loop 1..3 'x -> ; since it's a single statement
    print x ; there's no need for [block] notation
                        ; we can wrap it up using the `->` syntactic sugar

loop `a`..`c` 'ch ->
    print ch
; a
; b
; c

; picking multiple items
loop 1..10 [x y] ->
    print ["x =" x ", y =" y]
; x = 1 , y = 2 
; x = 3 , y = 4 
; x = 5 , y = 6 
; x = 7 , y = 8 
; x = 9 , y = 10 

; looping through a dictionary
dict: #[name: "John", surname: "Doe", age: 34]
loop dict [key value][
    print [key "->" value]
]
; name -> John 
; surname -> Doe 
; age -> 34 

; while loops
i: new 0
while [i<3][
    print ["i =" i]
    inc 'i
]
; i = 0
; i = 1
; i = 2

;---------------------------------
; STRINGS
;---------------------------------

; case
a: "tHis Is a stRinG"
print upper a ; THIS IS A STRING
print lower a ; this is a string
print capitalize a ; THis Is a stRinG

; concatenation
a: "Hello " ++ "World!" ; a: "Hello World!"

; strings as an array
split "hello" ; => [h e l l o]
split.words "hello world" ; => [hello world]

print first "hello" ; h
print last "hello" ; o

; conversion
to :string 123 ; => "123"
to :integer "123" ; => 123

; joining strings together
join ["hello" "world"] ; => "helloworld"
join.with:"-" ["hello" "world"] ; => "hello-world"

; string interpolation
x: 2
print ~"x = |x|" ; x = 2

; interpolation with `print`
print ["x =" x] ; x = 2
                            ; (`print` works by calculating the given block
                            ; and joining the different values as strings
                            ; with a single space between them)

; templates
print render.template {
    <||= switch x=2 [ ||>
        Yes, x = 2
    <||][||>
        No, x is not 2
    <||]||> 
} ; Yes, x = 2

; matching
prefix? "hello" "he" ; => true
suffix? "hello" "he" ; => false

contains? "hello" "ll" ; => true
contains? "hello" "he" ; => true
contains? "hello" "x" ; => false

in? "ll" "hello" ; => true 
in? "x" "hello" ; => false

;---------------------------------
; BLOCKS
;---------------------------------

; calculate a block
arr: [1 1+1 1+1+1]
@arr ; => [1 2 3]

; execute a block
sth: [print "Hello world"] ; this is perfectly valid,
                            ; could contain *anything*
                            ; and will not be executed...

do sth ; Hello world
                            ; (...until we tell it to)

; array indexing
arr: ["zero" "one" "two" "three"]
print first arr ; zero
print arr\0 ; zero
print last arr ; three
print arr\3 ; three

x: 2
print get arr x ; two
print arr\[x] ; two

; setting an array element
arr\0: "nada"
set arr 2 "dos"
print arr ; nada one dos three

; adding elements to an array
arr: new []
'arr ++ "one"
'arr ++ "two"
print arr ; one two

; remove elements from an array
arr: new ["one" "two" "three" "four"]
'arr -- "two" ; arr: ["one" "three" "four"]
remove 'arr .index 0 ; arr: ["three" "four"]

; getting the size of an array
arr: ["one" 2 "three" 4]
print size arr ; 4

; getting a slice of an array
print slice ["one" "two" "three" "four"] 0 1 ; one two

; check if array contains a specific element
print contains? arr "one" ; true
print contains? arr "five" ; false

; sorting array
arr: [1 5 3 2 4]
sort arr ; => [1 2 3 4 5]
sort.descending arr ; => [5 4 3 2 1]

; mapping values
map 1..10 [x][2*x] ; => [2 4 6 8 10 12 14 16 18 20]
map 1..10 'x -> 2*x ; same as above
map 1..10 => [2*&] ; same as above
map 1..10 => [2*] ; same as above

; selecting/filtering array values
select 1..10 [x][odd? x] ; => [1 3 5 7 9]
select 1..10 => odd? ; same as above

filter 1..10 => odd? ; => [2 4 6 8 10]
                            ; (now, we leave out all odd numbers - 
                            ; while select keeps them)

; misc operations
arr: ["one" 2 "three" 4]
reverse arr ; => [4 "three" 2 "one"]
shuffle arr ; => [2 4 "three" "one"]
unique [1 2 3 2 3 1] ; => [1 2 3]
permutate [1 2 3] ; => [[1 2 3] [1 3 2] [3 1 2] [2 1 3] [2 3 1] [3 2 1]]
take 1..10 3 ; => [1 2 3]
repeat [1 2] 3 ; => [1 2 1 2 1 2]

;---------------------------------
; FUNCTIONS
;---------------------------------

; declaring a function
f: function [x][2*x]
f: function [x]-> 2*x ; same as above
f: $[x]->2*x ; same as above (only using the `$` alias 
                            ; for the `function`... function)

; calling a function
f 10 ; => 20

; returning a value
g: function [x][
    if x < 2 -> return 0

    res: 0
    loop 0..x 'z [
        res: res + z
    ]
    return res
]

;---------------------------------
; CUSTOM TYPES
;---------------------------------

; defining a custom type
define :person [ ; define a new custom type "Person"
    name ; with fields: name, surname, age
    surname
    age 
][ 
    ; with custom post-construction initializer
    init: [
        this\name: capitalize this\name
    ]

    ; custom print function
    print: [
        render "NAME: |this\name|, SURNAME: |this\surname|, AGE: |this\age|"
    ]

    ; custom comparison operator
    compare: 'age
]

; create a method for our custom type
sayHello: function [this][
    ensure -> is? :person this

    print ["Hello" this\name]
]

; create new objects of our custom type
a: to :person ["John" "Doe" 34] ; let's create 2 "Person"s
b: to :person ["jane" "Doe" 33] ; and another one

; call pseudo-inner method
sayHello a ; Hello John                       
sayHello b ; Hello Jane

; access object fields
print ["The first person's name is:" a\name] ; The first person's name is: John
print ["The second person's name is:" b\name] ; The second person's name is: Jane

; changing object fields
a\name: "Bob"                                   
sayHello a ; Hello Bob

; verifying object type
print type a ; :person
print is? :person a ; true

; printing objects
print a ; NAME: John, SURNAME: Doe, AGE: 34

; sorting user objects (using custom comparator)
sort @[a b] ; Jane..., John...
sort.descending @[a b] ; John..., Jane...