Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
mcdearman committed Jun 23, 2024
1 parent cd43c7e commit 1666ea7
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 282 deletions.
10 changes: 9 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 0 additions & 25 deletions examples/lust.scm
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,3 @@
(String.get (Map.get lexer src) (Map.get lexer pos))
:nil))

(def (next-token lexer)
(match (peek-char lexer)
(:nil (token :eof (span (Map.get lexer pos) (Map.get lexer pos))))
(ch (if (whitespace? ch)
(do
(while (whitespace? (peek-char lexer))
(Map.update lexer pos (fn (x) (+ x 1))))
(next-token lexer))
(if (digit? ch)
(do
(let start (Map.get lexer pos))
(while (digit? (peek-char lexer))
(Map.update lexer pos (fn (x) (+ x 1))))
(token :number (span start (Map.get lexer pos))))

(if (is-alpha? ch)
(do
(let start (Map.get lexer pos))
(while (is-alphanumeric? (peek-char lexer))
(Map.update lexer pos (fn (x) (+ x 1))))
(token :identifier (span start (Map.get lexer pos))))

(do
(Map.update lexer pos (fn (x) (+ x 1)))
(token :unknown (span (Map.get lexer pos) (Map.get lexer pos))))))))))
250 changes: 99 additions & 151 deletions examples/mvp.scm
Original file line number Diff line number Diff line change
@@ -1,162 +1,110 @@
;; Lust is a simple Lisp-like language based on the idea of term rewriting.
;; It is a functional language with a simple syntax and semantics.
;; Terms are rewritten using pattern matching and substitution.
;; The language is dynamically typed and has first-class functions.

;; Special Forms:
;; - def: define a variable
;; - let: bind variables in a scope
;; - match: pattern match a term
;; - list: create a list
;; - set: create a set
;; - map: create a map
;; - array: create an array
;; - byte-array: create a byte array
;; - apply: apply a function to a list of arguments
;; - eval: evaluate a term
;; - read: read a term from a string
;; - fn: create a lambda function
;; - and: short-circuiting logical and
;; - or: short-circuiting logical or
;; - quote: prevent evaluation of a term
;; - quasiquote: prevent evaluation of a term, except for unquoted terms
;; - unquote: evaluate a term in a quasiquote
;; - unquote-splicing: evaluate a term in a quasiquote and splice the result
;; - module: define a module

;; def declarations
(def x 42)

(def (fib n)
(if (<= n 1)
n
(+ (fib (- n 1)) (fib (- n 2)))))

(def (fib n)
(if (<= n 1)
n
(+ (fib (- n 1)) (fib (- n 2)))))

(def (fib-iter n)
(let loop ((a 0) (b 1) (i n))
(if (= i 0)
a
(loop b (+ a b) (- i 1)))))

;; def fib_iter n =
;; let loop a b i =
;; if i = 0 then a
;; else loop b (a + b) (i - 1)
;; in loop 0 1 n

(def (fib-iter n)
(letf (loop a b i)
(if (= i 0)
a
(loop b (+ a b) (- i 1)))
(loop 0 1 n)))

;; this could also be done with a `match` expression
(def (fib n)
(match n
(0 0)
(1 1)
(n (+ (fib (- n 1)) (fib (- n 2))))))

;; call the `fib` function
(fib 10)

;; Note: The pattern matching in the `fib` function is not the same as in other languages.
;; You might think `(fib 0)` would be syntax sugar for binding `n` to `0` in the `fib` function.
;; However, it is actually binding the whole term `(fib 0)` to `0` in the `fib` function.
;; This is equivalent to telling the runtime that it can replace `(fib 0)` with `0`.

;; let expressions
(let ((x 1) (y 2)) (+ x y))

;; fn expressions
(let ((x 1)
((foo y) (+ x y)))
(foo 2))


;; quote expressions
(quote (1 2 3))
'(1 2 3)
;; > '(1 2 3)
;; (1 2 3)

;; quasiquote/unquote expressions
(quasiquote (1 2 (unquote (+ 1 2)) 4))
`(1 2 ,(+ 1 2) 4)

;; lambda expressions
(fn (x) (+ x 1))
;; lambda call
((fn (x) (+ x 1)) 2)

;; and expressions (short-circuiting)
(and (< 1 2) (> 2 1))

;; or expressions (short-circuiting)
(or (< 1 2) (> 2 1))

;; not expressions
(not (< 1 2))

;; list expressions
[1 2 (+ 1 2) 4]

;; this is equivalent to
(List.new 1 2 (+ 1 2) 4)

;; maps
{:a 1 :b 2}

;; this is equivalent to
(Map.new :a 1 :b 2)

;; Maps that use keyword symbols as keys are called records.
;; Keywords are symbols that evaluate to themselves they
;; are used to represent named arguments and are often
;; used as keys in maps.
:foo
; => :foo

;; map update
(Map.insert {:a 1 :b 2} :a 3)

;; map access
(Map.get {:a 1 :b 2} :a)
(def m {:a 1 :b 2})
(m.a)

;; map remove
(Map.remove {:a 1 :b 2} :a)

;; sets
#{1 2 3}

;; this is equivalent to
(Set.new 1 2 3)

;; Macros are rules for transforming terms at compile time.
;; They are used to define new syntax and to optimize code.
;; Macros are defined using the `macro` special form.
(macro (if cond then else)
`(match ,cond
(#t ,then)
(#f ,else)))

;; Reader macros are rules for transforming terms at read time.
;; They are used to define new syntax and to optimize code.
;; The most common reader macro is the quote reader macro.
;; Quote can be defined as a reader macro using the `reader` special form
;; and template matching.
(reader-macro (quote stream)
(match stream
("'{term}" (quote term))))

;; module declarations
(module Vector
(def (new) {:data []})
(def (new &xs) {:data xs}))

(def (fib n)
(match n
(0 0)
(1 1)
(n (+ (fib (- n 1)) (fib (- n 2))))))

;; Built-in Functions:
;; - +: add numbers
;; - -: subtract numbers
;; - *: multiply numbers
;; - /: divide numbers
;; - %: modulo
;; - =: equality
;; - <: less than
;; - >: greater than
;; - <=: less than or equal to
;; - >=: greater than or equal to
;; - head: get the first element of a list
;; - tail: get the rest of the elements of a list
;; - empty?: check if a list is empty
;; - pair: create a pair

;; Built-in data types:
;; - Num
;; - Real
;; - Rational
;; - BigRational
;; - Int
;; - BigInt
;; - Nat
;; - BigNat
;; - Byte
;; - Boolean
;; - List
;; - Set
;; - Map
;; - Array
;; - ByteArray
;; - Symbol
;; - Char
;; - String

(def x 10)
x
; => 10

; Function definition
(def (add x y) (+ x y))

; Function call
(add 1 2)
; => 3

; Let binding
(let ((x 10) (y 20)) (+ x y))
; => 30

; List creation
(list 1 2 3)

; Lambda function
((fn (x) (+ x 1)) 1)

; Logical and
(and true false)
; => false

; Logical or
(or true false)
; => true

; Quote
(quote (+ 1 2)) ; or
'(+ 1 2)
; => (+ 1 2)

; Quasiquote/unquote
`(1 2 ,(+ 1 2))
; => (1 2 3)

; Unquote-splicing
`(1 2 ,@(list 3 4))
; => (1 2 3 4)

; Symbol
'symbol
; => symbol

; Keyword symbol
:keyword
; => :keyword

; byte array
(byte-array 1 2 3) ; or
#u8(1 2 3)
; => #u8(1 2 3)

Loading

0 comments on commit 1666ea7

Please sign in to comment.