start = program / id program = scope / assignment / operation / string / number scope = space '(' space 'let' space as:assignment+ space ar:start* space pr:program* space ')' {return { operator: 'let', expressions: [as, ar, pr] } } operation = space '(' space o:operator space exp:start* space ')' space { return {operator: o, expressions: exp }} operator = '>'/'<'/'+'/'-'/'*'/'='/'if'/'let'/'print'/id assignment = space '[' space i:id space s:string space ']' space { return { operator: 'assignment', expressions: [i, s]}; } string = space quote str:(mandatory_space/letter)+ quote space { return str.join("") ; } id = r:raw_id { return {operator: 'var', expressions: r } } raw_id = t:text+ { return t.join(""); } letter = [^" \n] text = [a-zA-Z-] number = d:digit+ space { return +(d.join('')); } digit = [0123456789.-] space = [ \n]* / !. { return undefined } mandatory_space = [ \n]+ / !. { return undefined } quote = ["']

Numbers

67 -17 22.3 -0.3

Strings

"Hello, World!"

Identifiers

These are used for variable names. How do you parse them into somehting different from a string? foo bar some-identifier

Operations

(+ 1 2) (- 1 2) (* 1 2) (+ 1 2 3 4 5) (< 5 6) (< 5 6 8 20 34) (+ 5 6 (+ 8 20) 34) (print "Hello, World!") (print "hey" "you") (= (+ 1 2) (+ 3 4))

Nesting

(< (+ 1 2) 6) (< (+ 1 2) (+ 8 (* 3 (+ 8 (* 3 (+ 8 (* 3 4))))))) (if (< 20 10) 55 22) (if (< 20 10) (print "less!") (print "more!"))

Scope

(let [name "SFPC"] (print name) (print "pie")) (let [name "SFPC"] [tiger "elephant"] (print name) (print "pie") (print tiger)) (let [name "SFPC"] (let [tiger "elephant"] (print name)) 1) (let [name "SFPC"] (let [tiger "elephant"] (print name)) "1") (let [name "SFPC"] (let [tiger "elephant"] (print tiger) (print name)) (print tiger) (print name))