Skip to content

Latest commit

 

History

History
90 lines (80 loc) · 3.18 KB

lang.md

File metadata and controls

90 lines (80 loc) · 3.18 KB

🌽

Milho (corn in portuguese) is a toy dialect of Lisp written as a way to learn more about compilers. There are implementations in rust and go

Primitives

  • Number

5 ;; Number
1/5 ;; Numbers can also be fractional
5/1 ;; 5/1 is the same as 5. Actually, 5 is implemented as 5/1 underneath 
  • Boolean
True ;; true
False ;; false
  • String
"Strings are written with double quotes."
  • Nil
Nil ;;
  • Identitifer
memes ;; Identifiers are defined like this
<oi> ;; they can start with anything you want, except numbers
m3M3$_irados ;; after that, they can hold pretty much anything
  • Lists
'(2 3) ;; Lists are defined by putting anything between parenthesis.
(+ 2 3) => 5;; When you evaluate a list, it runs the first element as a function with the remaining elements as arguments.
(cons + '(2 3)) ;; We have all of your typical LISP list functions
() ;; Empty spaces evaluate to Nil
  • Error
(make-error 404 "Not found");; Erros cannot be created out of nowhere. You can, though, create your own errors using the make-error builtin
(make-error "oops, I broke" 20);; Notice that the first argument needs to be a number, and the second, a string. Otherwise you'll get an error, but not the one you're expecting. :p

Defining your things :P

  • Variables

(def a 5) ;; Variables are declared with the def built-in
(def things-i-like '( "memes" "basimga" "xd" )) ;; And they can hold pretty much everything ;)

(let (x 2 y 5) (sub x y)) ;; Local variables are defined like this.
=> -3 This odd positions are the identifiers, the even are the values.
  • Functions

(defn      ;; functions are declared with the defn built-in
  sum      ;; its first argument is the name of your function
  ( a b )  ;; the second one is a list with the name of your parameters  
  (+ a b)  ;; and the third is your function per se
) 

(defn sub ;; You can define multi-arity functions like this.
  (( x ) (negate x)) ;; And then your function will work according to the number of parameters
  (( x +rest ) (append-list (+ x) (map negate rest))) ;; They can even be variadics
) ;; But be careful: you can only have one body per number of params, and one variadic

(fn ( x ) (* 2 x)) ;; Anonymous functions are defined like this
  • Macros

(defmacro         ;; You can define macros with the defmacro keyword
  add             ;; Macros are just like functions, except their arguments are not evaluated
  (+rest)         ;; before the macro is expanded, and then ran
  (cons + rest)   ;; This means that this is the same as (rest1 + rest2 + rest 3 ...)
)                 ;; A function with the same body would evaluate to the list (.__add__ rest1 rest2 rest3...)

Dealing with errors

(def res (make-error 404 "Not found"))

(if (is-error res) ;; Errors can be checked with the is-error builtin
  (print "Oops, I broke")
  (print "Oh well, I'm working")
)

(get-error-message res) ;; You can access your error's message with the get-error-message bultin
(get-error-code res) ;; Or access the code with get-error-code