• Stars
    star
    172
  • Rank 221,201 (Top 5 %)
  • Language
    C++
  • License
    Apache License 2.0
  • Created almost 4 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A lisp👽 written in C++

👻wisp

A lisp👽 written in C++

Why write a lisp?

Lisp is one of those niche, beautiful languages that people only use for two specific purposes:

  1. Write a lisp interpreter
  2. To illustrate that code is data!!

So why add to the list of infinite lisp interpreters?

The answer is simple: I'm bored out of my mind in quarantine. If you were looking to find out why this particular lisp is special, you're fresh out of luck.

But isn't the fact that it's a lisp enough?

Lisp

yes.

Syntax and Special Forms

Like every other lisp, this language uses s-expressions for code syntax and data syntax. So, for example, the s-expression (print 5) is both a valid code snippet, and a valid list containing the items print and 5.

When the data (print 5) is evaluated by the interpreter, it evaluates print and 5, and then applies print to 5.

Here's the result.

>>> (print 5)
5
 => 5

That's super cool! But what if we want to define our own functions? We can use the builtin function defun!

; define a function `fact` that takes an argument `n`
(defun fact (n)
  (if (<= n 1)
     1
     (* n (fact (- n 1)))
   ))

Thats awesome! But did you notice anything different about the defun function? It doesn't evaluate its arguments. If the atom fact were evaluated, it would throw an error like so:

>>> fact
error: the expression `fact` failed in scope { } with message "atom not defined"

This is known as a special form, where certain functions "quote" their arguments. We can quote things ourselves too, but the language automatically quotes arguments to special forms itself.

If you want to "quote" a value yourself, you can do it like this.

; quote the s-expression (1 2 3) so it's not evaluated
>>> (print '(1 2 3))
(1 2 3)
 => (1 2 3)

As you can see, quote negates an evaluation. For example, whenever the expression ''a is evaluated, it becomes 'a. This can be useful for when you want to write long lists of data or variable names without wanting to evaluate them as code.

Special Form Argument Evaluations Purpose
(if cond a b) if only evaluates its cond argument. If cond is truthy (non-zero), then a is evaluated. Otherwise, b is evaluated. This special form is the main method of control flow.
(do a b c ...) do takes a list of s-expressions and evaluates them in the order they were given (in the current scope), and then returns the result of the last s-expression. This special form allows lambda functions to have multi-step bodies.
(scope a b c ...) scope takes a list of s-expressions and evaluates them in the order they were given in a new scope, and then returns the result of the last s-expression. This special form allows the user to evaluate blocks of code in new scopes.
(defun name params body) defun evaluates none of its arguments. This special form allows the user to conveniently define functions.
(define name value) define evaluates the value argument, which is then assigned to name in the current scope. This special form allows the user to bind atoms to values in a scope.
(lambda params body) lambda evaluates none of its arguments. This special form allows the user to define anonymous functions.
(quote x) quote evaluates none of its arguments. This is equivalent to the 'expr syntactic sugar.
(for x list ...) for evaluates only its list argument. for iterates through the list storing each element in x, and then evaluating all of the rest of the values in the for body. It then returns the last value evaluated.
(while cond ...) while evaluates only its cond argument. while evaluates its condition expression every iteration before running. If it is true, it continues to evaluate every expression in the while body. It then returns the last value evaluated.

Examples

Here are some example math-y functions to wrap your head around.

; quicksort
(defun qs (l)
    (if (<= (len l) 1)
        l
        (do
            (define pivot (first l))
            (+
                (qs (filter (lambda (n) (> pivot n)) l))
                (list pivot)
                (qs (tail (filter (lambda (n) (<= pivot n)) l)))
            ))
    ))

; decrement a number
(defun dec (n) (- n 1))
; increment a number
(defun inc (n) (+ n 1))
; not a bool
(defun not (x) (if x 0 1))

; negate a number
(defun neg (n) (- 0 n))

; is a number positive?
(defun is-pos? (n) (> n 0))
; is a number negative?
(defun is-neg? (n) (< n 0))

Usage

Using and compiling wisp

Dependencies

Compile with your C++ compiler of choice. This is compatible with all standard versions of C++ since ANSI C++.

$ git clone https://github.com/adam-mcdaniel/wisp
$ cd wisp
$ g++ wisp.cpp -o wisp

Using the binary

Run wisp in interactive mode:

$ ./wisp
>>> (print "Hello world!")
Hello world!
 => "Hello world!"

Interpret a file:

$ ./wisp "examples/hello_world.lisp"
Hello world!
$ ./wisp -f "examples/hello_world.lisp"
Hello world!

Interpret from command line argument:

$ ./wisp -c '(print "Hello world!")'
Hello world!

More Repositories

1

oakc

A portable programming language with a compact intermediate representation
Rust
697
star
2

dune

A shell🐚 by the beach🏖️!
Rust
682
star
3

chess-engine

A dependency-free chess engine♟️ library built to run anywhere.
Rust
379
star
4

free

An esoteric programming language with an unusual compiler backend
Rust
320
star
5

atom

Shell scripting that will knock your socks off
Rust
258
star
6

harbor

A language that ports⚓: examining the limits of compilation⚙️.
Rust
80
star
7

sage

A programming language that's wise beyond its bytes!🌱🌿🪴
Rust
32
star
8

smpl

A superset of brainfuck with dynamic memory management.
C++
23
star
9

maroon-lang

A (nearly) pure functional programming language.
Rust
22
star
10

tsar

Tsar programming language
Rust
13
star
11

honeycomb

A portable parser combinator library that does not require a runtime
Rust
10
star
12

game-of-life

A game of life🔬 simulator on an infinite♾️ plane
Rust
8
star
13

qalc

A very unstable and terrible language for quickly writing calculator programs
Rust
5
star
14

xasm

A cross platform, compiled and dynamically typed programming / intermediate language
Rust
5
star
15

sight

A library for Vision Processing
Python
5
star
16

lasm

A tiny and portable assembly language for complex compilers
Rust
4
star
17

program-evolution

Evolutionary algorithms applied to SKI combinator calclus and a Turing-machine-based architecture
Python
3
star
18

rusty-ci

A tool to generate buildbot projects from a YAML file
Rust
3
star
19

wisp-bootstrap

A bootstrapped lisp compiler
Common Lisp
3
star
20

battaliants

A roguelike ant-catching game written for a hackathon
GDScript
3
star
21

calendar

A tiny calendar program
Nim
2
star
22

pink-lang

A high level programming language that compiles to native
C++
2
star
23

blame-tracker

Accuse guilty developers!
Python
2
star
24

cable-lang-cxx

A fast dynamically typed language interoperable with C++
C++
2
star
25

adam-mcdaniel.github.io

My site📖
HTML
2
star
26

hlvm

A high level virtual machine library that can be used to easily make powerful programming languages
Rust
2
star
27

finn-assembler

The assembler for the Finn IR implemented using my HLVM in Rust
Rust
2
star
28

sage-chess

A chess engine written in my programming language, Sage🌱
C
2
star
29

xasm-vm

All of the implementations of virtual machines for the Xasm intermediate representation
1
star
30

Octaculus

Octaculus - 8-way directional gesture detection using machine learning and light dependent resistors
Jupyter Notebook
1
star
31

toki-pona-dataset

Dataset for Toki Pona constructed language
Jupyter Notebook
1
star
32

periwinkle

Language inspired by Python, Rust, and C++
Python
1
star
33

hlvm_runtime

The runtime library for HLVM
Rust
1
star
34

xassembler

The assembler for XASM
Rust
1
star
35

Dynamite

An interpreted programming language with speed and extensibility in mind.
Go
1
star
36

dune-old

A cross platform shell built with my ideals in mind
Rust
1
star
37

comment

Strip multiple types of comments
Rust
1
star
38

ski

SKI combinator calculus implemented in rust
Rust
1
star
39

xmachine

A fast, cross platform virtual machine implemented in Rust without the Standard Library.
Rust
1
star
40

adams-bot

A mini me for my Discord server!
C
1
star
41

adam-mcdaniel

My profile📝
1
star
42

rapture

A library to write installation programs / a tool to install programs. Meant to be to the future backend of rusty-ci.
Rust
1
star
43

xgopher

Golang Xasm virtual machine implementation
Go
1
star
44

lite

A tiny text editor📝 with syntax highlighting🎨, undo/redo🧰, and a language for customizing the editor🏗️
Rust
1
star
45

resume

My Resume
1
star
46

vpn

A VPN implemented over TLS/SSL written in C
C
1
star
47

gc-rust

A rust library to implement reference counting garbage collection
Rust
1
star
48

ramify

A functional programming language with builtin parallelism
Rust
1
star
49

music-generator

A tool to generate a lead sheet in a specified key given a certain number of choruses and verses.
Rust
1
star