Skip to content

Latest commit

 

History

History
313 lines (242 loc) · 5.79 KB

README.md

File metadata and controls

313 lines (242 loc) · 5.79 KB

Gitpod Ready-to-Code Codacy Badge Codacy Badge

Lengine, another Lisp Engine

Compiler is now available!! Checkout compiler's README.md!!

Documentation is in progress: Documentation

Table of contents

  • Compiled at Scala 2.12.10
  • SBT should be installed

Execute Code

# SBT should be installed in your local machine
$ git clone https://github.com/gkm2164/lengine
$ ./install.sh
$ ./lengine [filename]?

# ex) run lisp code
$ ./lengine ./examples/testCode.lisp

# ex) run REPL
$ ./lengine
 

REPL

$ sbt run
lengine > (println (+ 3 5))
8
res0 => ()
  • To quit REPL,
lengine > (quit)

You can test List type also

lengine > (println (cons 3 (cons 5 nil)))
(3 5)
res0 => ()
lengine > (println (tail (cons 3 (cons 5 nil))))
(5)
res1 => ()
...

Compiler

$ ./install.sh
$ ./lenginec hello.lisp --className Hello

Sample Code

  • refer to examples folder
;;; map list with 2 adder
(import "libs/sequence")

(def nums (list 1 2 3 4 5))
(map nums (lambda (x) (+ x 2))
  • Data types
;;; integer
0
#2r100 ;;; binary number 100
#xabcd ;;; hex number abcd
#18rabcdefgh ;; base 18 number abcdefgh
#2r-100 ;;; negative number for binary 100

;;; Float number
0.0
-0.35

;;; Ratio number
3/5
-3/5

;;; Complex Number
#C(30 20)   ;;; 30 + 20i
#C(3/5 1/4) ;;; (3/5) + (1/4)i
#C(0.3 2.4) ;;; 0.3 + 2.4i

;;; Character
#\a         ;;; a
#\A         ;;; A
#\c         ;;; c
#\Backspace ;;; \b
#\Linefeed  ;;; \n
#\Page      ;;; \p
#\Return    ;;; \r
#\Rubout    ;;; like \b

;;; String
"Hello World!"
"\"This is escape example for double quote!\""

;;; Object
{
  :id 1
  :name "Gyeongmin Go"
  :email "gkm2164@gmail.com"
}
  • Function definition
;;; Define function
;;; (fn [name] [symbols] [body])
;;; ex) adder takes a and b
(fn add (a b) (+ a b))


;;; Function override
(fn add (a b) (+ a b))
(fn add (a b c) (+ (+ a b) c))

;;; Function pattern match
(fn fact (acc 0) acc)
(fn fact (acc n) (fact (* acc n) (- n 1)))
(println (fact 5)) ;;; 120
  • Define value
;;; Define variable
;;; (def [name] [body])
;;; ex) set x to be 3
(def x 3)
x

;;; ex) define lazy symbol
(def 'x (+ 3 3))

;;; and you can use with
'x
  • Lambda
;;; Lambda as value
;;; (lambda [args] [body])
;;; ex) Lambda which takes 2 variable and add them
(lambda (a b) (+ a b))

;;; same as fn...
(def add (lambda (a b) (+ a b)))
;;; == (fn add (+ a b))
  • do statement
;;; Do stmt
;;; (do stmts*)
(do (println 3)
    (println 4)
    (println 5)
    return 0)
;;; print 3 4 5 line by line and return 0
  • loop statement
;;; Loop stmt with for comprehension
;;; (loop [for-stmt]+ [body])
;;; -- for stmt
;;; for [symbol] in [list]
;;; ex)

(loop for x in [1 2 3 4 5]
      (do (println x)
          (+ x 1)))
;;; == [2 3 4 5 6]

(loop for x in [1 2 3 4 5]
      for y in [2 3 4 5 6]
      (+ x y))
  • Introduce local variable
;;; introduct local variable
;;; (let ([name] [value]) [body])
;;; ex) define variable x and use it in that scope
(import "libs/sequence")  ;;; below example code require sequence library 

(let (name (read-line "Type your name: "))
  (println (concat "Hello, " name "!")))
  • List
;;; use list as value
;;; (list values*)
;;; ex) List for 1 2 3 4 5
(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 nil)))))
(list 1 2 3 4 5)
[1 2 3 4 5]
;;; List type of List(1, 2, 3, 4, 5)
  • operators
;;; boolean operators
(and true true) ;;; == true
(and false true) ;;; == false
(>= 3 0) ;;; == true
(or (>= 3 0) (<= 0 1)) ;;; == true
;;; and, or, =(equal), /=(not equal), >=, <=, >, <

;;; not allowed
(and true 3) ;;; ???
  • Object refer
;;;
({:hello 1} :hello) ;;; == 1
  • Import library
;;; Import library
;;; (import [path])
(import "libs/sequence") ;;; import sequence operations
;;; test
(map (list 1 2 3 4 5) (lambda (x) (+ x 1)))
;;; == (list 2 3 4 5 6)
  • REPL history
;;; See history or use the history
;;; (history [index of history]?)
;;; ex) see history result
(history)        ;;; command history is also accumulated to history
0: (+ 3 5)       ;;; examples
1: (println 3)


;;; run 
(history 0)
res3 => 8
  • Having fun with Sequence!
lengine > (import "libs/sequence")  ;;; will import bunch of sequence related functions
lengine > (range 1 5)
res1 => [1 2 3 4 5]: List
lengine > (map res1 inc)
res2 => [2 3 4 5 6]: List
lengine > (take 3 res2)
res3 => [2 3 4]: List
lengine > (drop 2 res3)
res4 => [4]: List

Feature

  • Char Type
  • Namespace
  • Stream
  • ByteCode generation
  • Loop with only condition
  • Macro implementation

Friend Projects

  • KAND: Compilable LISP, type system enhanced, and could be run on Java Virtual Machine