GithubHelp home page GithubHelp logo

lispc's Introduction

lispc

A simple Lisp interpreter written in C. It implements the most basic Lisp special forms (called operators here) as well as a small number of primitive procedures. It is lexically scoped and supports closures.

Building

lispc should build out of the box on any system. Using gcc, simply do

gcc *.c -o lisp -std=c99

Running the resulting executable will start the lispc interpreter. It does not parse files at the moment, and the REPL is very simple.

Language

lispc is a minimalistic Lisp language. Expressions in lispc are either symbols, procedures, numbers or lists. Symbols are used as names in variable bindings, or can be used as identifiers for other purposes. A symbol evaluates to the value it is bound to. Numbers and procedures evaluate to themselves. List evaluation follows two basic rules: If the first element is a symbol and the symbol denotes one of the operators, evaluation rules for the particular operator is followed. If the first element does not denote one of the operators, the list expression is a function call. Every element in the list is evaluated, and the first element, if resulting in a procedure, is called with the rest of the elements as arguments.

Some examples:

Numbers evaluate to themselves:

LISP> 1234
=> 1234

def is an operator, so the following list expression will be an operator call:

LISP> (def k 2)
=> K

The symbol k will after that call refer to the value 2:

LISP> k
=> 2

A list where the first element is not an operator is a function call:

LISP> (+ 1 (* 1 2) 3)
=> 6

Operators

\ (lambda)

(\ (a1 a2 ...) exp) constructs a function whose formal parameters are a1, a2 and so on, and whose expression is exp.

Example:

(\ (x y z) (+ x y z))           ; a function which takes three arguments and sums them
((\ (x y z) (+ x y z)) 1 2 3)   ; create the described procedure and call it with arguments 1, 2 and 3

def

(def a b) introduces a new variable binding where the symbol a is bound tothe value b.

Example:

(def a 5)                       ; define a to be 5
(def square (\ (x) (* x x)))    ; set square to be the function which squares its argument

if

(if test true-exp false-exp) evaluates test. If the result is non-NIL, true-exp is evaluated. Otherwise, false-exp is evaluated.

Example:

(if (= x 2) (+ x 1) 2)          ; evaluates (+ x 1) if x is equal to 2, or evaluates 2 if not

' (quote)

(' exp) simply evaluates to exp. The parser will convert expressions of the form 'x to (' x).

Example:

LISP> (' k)
=> K
LISP> 'k
=> K

set!

(set! a b) changes the value what a refers to, to the value b.

let

(let ((a1 b1) (a2 b2) ...) exp) introduces local bindings of the symbol a1 to the value b1, the symbol a2 to the value b2, and so on. With these bindings, the exp expression is evaluated. The bindings only exist during the evaluation of exp. Already existant bindings outside the let scope will be shadowed by these bindings.

Example:

(let ((x 2) (y 3))
  (+ x y))                ; x and y are only bound in this expression

do or :

(do exp1 exp2 ...) evaluates the expressions exp1, exp2, ... in order, and uses the last evaluated value as its value.

Example:

(do (print 'hi)
  (print 'there) 
  1234)

This will print "HI THERE" on the screen, and the expression will evaluate to 1234.

Primitives

Generic functions

The standard library defines the functions new-generic and implement for using generic functions.

(new-generic name) creates a new generic function called name and returns a procedure which can call it.

(implement name fn type) defines a specific implementation of the generic function. name is the symbol of the generic function, fn is the implementing procedure, and type is a list or a symbol denoting the argument types the implementation handles. If type is a single symbol, the implementation is assumed to take a variable number of arguments, and every argument has to match this type. If type is a list, its items denote the argument types in order.

Example

The function + might be useful to overload for certain types. The standard library implements + for integers as follows:

(def + (new-generic '+))
(implement '+ _+ 'integer)

Here, _+ denotes the built in primitive procedure for adding integers. The symbolic type argument makes this implementation accept a variable number of arguments, all of integer type.

To add a new implementation, for example for a type matrix, we can do

(implement '+ add-matrix '(matrix matrix))

Here, the type argument is a list of two elements, meaning that this implementation will take two arguments, both of type matrix. The function add-matrix must be a function taking at least two such arguments.

lispc's People

Contributors

jaffe- avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

lispc's Issues

Error compiling with clang

Hi!
I enjoyed the project! Great job! ๐Ÿ‘

Just wanted to mention that we get

lisp.c:219:5: error: call to undeclared function 'strip_spaces'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declarat
ion]
    strip_spaces(expression);
    ^

running gcc *.c -o lisp -std=c99 on

> clang -v
Apple clang version 15.0.0 (clang-1500.1.0.2.5)
Target: arm64-apple-darwin23.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

Adding a header-file for parser.h and including it in lisp.c fixed this. ๐Ÿ™‚

license?

hi! this is awesome, but was wondering if you could add a license to this?

I'd love to be able to use it for a quick demo, but am wary without a license being added.

thanks much!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.