Giter Club home page Giter Club logo

micro-lisp's Introduction

Micro Lisp

Objective: implement a small Lisp/Scheme language in as little C code as possible.

This is a hobby project for educational purposes, it has bugs and may fail without warning. Pull requests and improvements welcome

The interpreter supports lambda, e.g.

  ((lambda (x) (cons x (quote 1))) (quote 7))
  (7 . 1)

Note that lambda does not capture free variables (variables that are not passed as arguments and refer to an outer scope). Free variables will resolve to their assigned values in the environment when the body of the lambda is evaluated.

The special forms if and quote behave in a typical way:

  (if (quote t) (quote 7) (quote 0))
  7

The only types are symbols and pairs.

Non-quoted symbols are looked up in the environment. If they have no associated value the result is null; in fact, zero. Because there is no numeric type a number e.g. 7 will be treated like any other symbol and looked up in the environment. Note in the examples above how numbers are quoted to prevent that.

The built-in primitives in the environment are: car, cdr, cons, eq?, pair?, read, write.

Also provided is apply which takes a function and a single list argument:

  (apply write (quote ((hello world))))
  (hello world)
  (quote t)

Lists can be built up by consing:

  (apply write (cons (cons (quote hello) (cons (quote world) null)) null))
  (hello world)
  (quote t)

Read Eval Print Loop

A REPL is implemented in micro-lisp itself. To try it out in a terminal:

  cat repl.lisp - | ./micro-lisp

To exit, press 'control c' to terminate the process.

Note the - argument to cat to pipe stdin through, otherwise micro-lisp will receive end-of-file.

The source code for the REPL is in repl.lisp. It implements eval and provides an environment which resolves symbols to the primitive functions in the underlying micro-lisp interpreter.

Debugging with GDB

A .gdbinit file sets the target, breakpoints and runs the executable. Simply run gdb.

Pull requests welcome.

asciicast

micro-lisp's People

Contributors

carld avatar cellularmitosis avatar islam0mar avatar johnlunney avatar rain-1 avatar xyproto avatar

Stargazers

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

Watchers

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

micro-lisp's Issues

funopen issue

Hello,
I know it could sound weird, but how could be possible to rewrite the eval_string function without using funopen?
I totally rewrote the source code in K&R style, porting mlisp89 to a CPM/80 using Aztec C compiler.
I got two issues, at the linking time: the first one with strdup (easily fixed), the other one with funopen, but I think it's quite hard to implement.
So if you could give me a hint, it would great.
thanks

print_obj() has curious if-statement

At

if (is_pair(cdr(ob))) { printf(" "); print_obj(cdr(ob), 0); }
we have a section of code that reads:

    if (cdr(ob) != 0) {
      if (is_pair(cdr(ob))) {  printf(" "); print_obj(cdr(ob), 0);  }
    }

That inner is_pair() looks like a possible mistake -- the prior line ensures that this if-statement only gets evaluated if cdr(ob) is non-nil, but in that case, how could is_pair(cdb(ob)) ever be false? In micro-lisp, the CDR is always a (possibly-empty) list, is it not?

Even if it were possible for the CDR to be a non-list, wouldn't you want an else statement for this if, to print something else when that's the case?

Tests fail on 64-bit Ubuntu 17.10

As the title says. I get several warnings from gcc 7.2.0, but they appear harmless. Could it be due to the 64-bit environment, where pointers are larger than plain ints? I haven't looked closer yet...

Parenthesize variable use inside macros

#define is_space(x)  (x == ' ' || x == '\n')
#define is_parens(x) (x == '(' || x == ')')

Should be

#define is_space(x)  ((x) == ' ' || (x) == '\n')
#define is_parens(x) ((x) == '(' || (x) == ')')

Otherwise, C's operator precedence applies for the == operator and whatever operations x evaluates to.

Requires <stdint.h>

On gcc (GCC) 7.2.0 from ArchLinux standard repositories (core/gcc), it fails to compile as written.

uintptr_t is not defined without the stdint.h header. Including that header allowed the program to compile without errors.

Alignment & pointer tagging discussion in blog post

to an 8-bit boundary, it means that when memory is allocated itā€™s address will be a multiple of 8. For example the next 8 bit boundary for the address 0x100200230 is 0x100200238

Shouldn't this be talking about 8-byte alignment rather than 8-bit alignment? 8 bytes is the 64-bit word size that C compilers use these days.

afl-fuzz: Segmentation fault

For giggles I'm putting this micro-lisp through American Fuzzy Lop (afl-fuzz). It seems rather resilient šŸ‘

It found what it calls a "hang" case though. If you put a single character in a file, the parser will fault. E.g a file with just 0x7F or 0xED it will lead to a Segmentation fault.

Do with it whatever you like :)

examples/format.lisp is missing?

Thank you so much for publishing this project!

I ran test.sh and found a problem:

examples/format.lisp -> hello 21553 test world
#t
cat: examples/format.lisp: No such file or directory
Test FAIL

Sure enough, there is no format.lisp file in the examples/ directory.

A few questions

There seem to be two seperate projects in this repository; 1) micro-lisp in 162 lines of C and
2) Micro Scheme in 560 lines of 6.

The examples seem to relate to Micro Scheme rather than Micro Lisp.

Would it be possible to update the README file to make it clear how these two implementations relate to each other.

Thanks
Hugh

C89 version segfaults

$ ./mlisp89
Segmentation fault (core dumped)
(lldb) bt
* thread #1, name = 'mlisp89', stop reason = signal SIGSEGV: invalid address (fault address: 0x557582a0)
  * frame #0: 0x00007ffff7b6e467 libc.so.6`__strncmp_sse42 + 151
    frame #1: 0x000055555555514e mlisp89`intern(sym="write") at mlisp89.c:67
    frame #2: 0x0000555555554879 mlisp89`main(argc=<unavailable>, argv=<unavailable>) at mlisp89.c:167
    frame #3: 0x00007ffff7a40f4a libc.so.6`__libc_start_main + 234
    frame #4: 0x0000555555554dfa mlisp89`_start + 42

Pointer tagging cast using long

Pointers and long are not necessarily the same size (on 64-bit Windows long is 32-bit). It might be a good idea to use uintptr_t if available, or check that the size of the integer matches that of a pointer.

cannot lookup: null

Hello,

I ran into an issue when running the REPL with mlisp89:

$ cat repl.lisp - | ./mlisp89
cannot lookup: null
(+ 1 1)
$ echo $?
1

I tried adding null to the "environment", but it didn't seem to work. Do I need to implement support for this directly in eval?

The `-ansi` flag makes all tests fail

This is on 64-bit Arch Linux with gcc 7.2.0:

gcc -Wall -pedantic -ansi -g -o micro-lisp micro-lisp.c
micro-lisp.c: In function ā€˜internā€™:
micro-lisp.c:49:18: warning: implicit declaration of function ā€˜strdupā€™; did you mean ā€˜strcmpā€™? [-Wimplicit-function-declaration]
   symbols = cons(strdup(sym), symbols);
                  ^~~~~~
                  strcmp
micro-lisp.c:49:18: warning: passing argument 1 of ā€˜consā€™ makes pointer from integer without a cast [-Wint-conversion]
micro-lisp.c:38:8: note: expected ā€˜void *ā€™ but argument is of type ā€˜intā€™
 List * cons(void *_car, void *_cdr) {
        ^~~~
micro-lisp.c: In function ā€˜apply_primitiveā€™:
micro-lisp.c:103:11: warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
   return ((List * (*) (List *)) primfn)  ( args );
           ^
micro-lisp.c: In function ā€˜mainā€™:
micro-lisp.c:144:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
   List *env = cons (cons(intern("car"), cons((void *)fcar, 0)),
                                              ^
micro-lisp.c:145:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("cdr"), cons((void *)fcdr, 0)),
                                              ^
micro-lisp.c:146:47: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("cons"), cons((void *)fcons, 0)),
                                               ^
micro-lisp.c:147:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("eq?"), cons((void *)feq, 0)),
                                              ^
micro-lisp.c:148:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("pair?"), cons((void *)fpair, 0)),
                                                ^
micro-lisp.c:149:50: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("symbol?"), cons((void *)fatom, 0)),
                                                  ^
micro-lisp.c:150:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("null?"), cons((void *)fnull, 0)),
                                                ^
micro-lisp.c:151:47: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("read"), cons((void *)freadobj, 0)),
                                               ^
micro-lisp.c:152:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("write"), cons((void *)fwriteobj, 0)),
                                                ^
wc micro-lisp.c
 159  769 5595 micro-lisp.c
./test.sh
(car (quote (1 2 3 4))) -> 1
Test FAIL
(cdr (quote (1 2 3 4))) -> (2 3 4)
Test FAIL
(cons (quote 1) (cons (quote 2) null)) -> (1 2)
Test FAIL
((lambda (x) (cons x (cons (quote 1) null))) (quote 7)) -> (7 1)
Test FAIL
(pair? (quote (1 2 3))) -> (quote t)
Test FAIL
(eq? (quote hello) (quote hello)) -> (quote t)
Test FAIL
(eq? (quote hello) (quote world)) -> null
Test FAIL
(pair? (cons (quote hello) (quote world))) -> (quote t)
Test FAIL
(pair? (quote hello)) -> null
Test FAIL
((1 (x) (cons x (quote 1))) 2) -> null
Test FAIL
1 -> null
Test FAIL
((lambda (x) (write x)) (quote hello)) -> hello
Test FAIL
(write (quote (cons (quote 1) (quote 2)))) -> (cons (quote 1) (quote 2))
Test FAIL
(cons (quote 1) (cons (quote 2) (cons (quote 3) (cons (quote 4) null)))) -> (1 2 3 4)
Test FAIL
(quote (1 2 3 4)) -> (1 2 3 4)
Test FAIL
(cons (quote 1) (cons (quote 2) null)) -> (1 2)
Test FAIL
(write (cons (quote (hello world)) null)) -> ((hello world))
Test FAIL
((lambda (x y) (cons y (cons x null))) (quote 67) (quote 89)) -> (89 67)
Test FAIL
assoc.lisp -> lisp
Test FAIL
apply.lisp -> (fn 1 2 3 4)
Test FAIL
apply2.lisp -> (fn (1 2 3 4))
Test FAIL
reverse.lisp -> (9 8 7 6 5 4 3 2 1)
Test FAIL
hello -> carl
Test FAIL
(quote (write hello)) -> (write hello)
Test FAIL
(write (cons (quote hello) (cons (quote world) null))) -> (hello world)
Test FAIL
(apply write (cons (quote hello) (cons (quote world) null))) -> (hello world)
Test FAIL
Passed 0 of 26

When removing the -ansi flag in the Makefile, some of the tests passes:

gcc -Wall -pedantic -g -o micro-lisp micro-lisp.c
micro-lisp.c: In function ā€˜apply_primitiveā€™:
micro-lisp.c:103:11: warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
   return ((List * (*) (List *)) primfn)  ( args );
           ^
micro-lisp.c: In function ā€˜mainā€™:
micro-lisp.c:144:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
   List *env = cons (cons(intern("car"), cons((void *)fcar, 0)),
                                              ^
micro-lisp.c:145:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("cdr"), cons((void *)fcdr, 0)),
                                              ^
micro-lisp.c:146:47: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("cons"), cons((void *)fcons, 0)),
                                               ^
micro-lisp.c:147:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("eq?"), cons((void *)feq, 0)),
                                              ^
micro-lisp.c:148:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("pair?"), cons((void *)fpair, 0)),
                                                ^
micro-lisp.c:149:50: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("symbol?"), cons((void *)fatom, 0)),
                                                  ^
micro-lisp.c:150:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("null?"), cons((void *)fnull, 0)),
                                                ^
micro-lisp.c:151:47: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("read"), cons((void *)freadobj, 0)),
                                               ^
micro-lisp.c:152:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("wrigcc -Wall -pedantic -g -o micro-lisp micro-lisp.c
micro-lisp.c: In function ā€˜apply_primitiveā€™:
micro-lisp.c:103:11: warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
   return ((List * (*) (List *)) primfn)  ( args );
           ^
micro-lisp.c: In function ā€˜mainā€™:
micro-lisp.c:144:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
   List *env = cons (cons(intern("car"), cons((void *)fcar, 0)),
                                              ^
micro-lisp.c:145:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("cdr"), cons((void *)fcdr, 0)),
                                              ^
micro-lisp.c:146:47: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("cons"), cons((void *)fcons, 0)),
                                               ^
micro-lisp.c:147:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("eq?"), cons((void *)feq, 0)),
                                              ^
micro-lisp.c:148:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("pair?"), cons((void *)fpair, 0)),
                                                ^
micro-lisp.c:149:50: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("symbol?"), cons((void *)fatom, 0)),
                                                  ^
micro-lisp.c:150:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("null?"), cons((void *)fnull, 0)),
                                                ^
micro-lisp.c:151:47: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("read"), cons((void *)freadobj, 0)),
                                               ^
micro-lisp.c:152:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("write"), cons((void *)fwriteobj, 0)),
                                                ^
wc micro-lisp.c
 159  769 5595 micro-lisp.c
./test.sh
(car (quote (1 2 3 4))) -> 1
Test FAIL
(cdr (quote (1 2 3 4))) -> (2 3 4)
Test FAIL
(cons (quote 1) (cons (quote 2) null)) -> (1 2)
Test FAIL
((lambda (x) (cons x (cons (quote 1) null))) (quote 7)) -> (7 1)
Test FAIL
(pair? (quote (1 2 3))) -> (quote t)
Test OK
(eq? (quote hello) (quote hello)) -> (quote t)
Test OK
(eq? (quote hello) (quote world)) -> null
Test OK
(pair? (cons (quote hello) (quote world))) -> (quote t)
Test FAIL
(pair? (quote hello)) -> null
Test OK
((1 (x) (cons x (quote 1))) 2) -> null
Test OK
1 -> null
Test OK
((lambda (x) (write x)) (quote hello)) -> hello
Test OK
(write (quote (cons (quote 1) (quote 2)))) -> (cons (quote 1) (quote 2))
Test OK
(cons (quote 1) (cons (quote 2) (cons (quote 3) (cons (quote 4) null)))) -> (1 2 3 4)
Test FAIL
(quote (1 2 3 4)) -> (1 2 3 4)
Test OK
(cons (quote 1) (cons (quote 2) null)) -> (1 2)
Test FAIL
(write (cons (quote (hello world)) null)) -> ((hello world))
Test FAIL
((lambda (x y) (cons y (cons x null))) (quote 67) (quote 89)) -> (89 67)
Test FAIL
assoc.lisp -> lisp
Test FAIL
apply.lisp -> (fn 1 2 3 4)
Test FAIL
apply2.lisp -> (fn (1 2 3 4))
Test FAIL
reverse.lisp -> (9 8 7 6 5 4 3 2 1)
Test FAIL
hello -> carl
Test FAIL
(quote (write hello)) -> (write hello)
Test FAIL
(write (cons (quote hello) (cons (quote world) null))) -> (hello world)
Test FAIL
(apply write (cons (quote hello) (cons (quote world) null))) -> (hello world)
Test FAIL
Passed 9 of 26te"), cons((void *)fwriteobj, 0)),
                                                ^
wc micro-lisp.c
 159  769 5595 micro-lisp.c
./test.sh
(car (quote (1 2 3 4))) -> 1
Test FAIL
(cdr (quote (1 2 3 4))) -> (2 3 4)
Test FAIL
(cons (quote 1) (cons (quote 2) null)) -> (1 2)
Test FAIL
((lambda (x) (cons x (cons (quote 1) null))) (quote 7)) -> (7 1)
Test FAIL
(pair? (quote (1 2 3))) -> (quote t)
Test OK
(eq? (quote hello) (quote hello)) -> (quote t)
Test OK
(eq? (quote hello) (quote world)) -> null
Test OK
(pair? (cons (quote hello) (quote world))) -> (quote t)
Test FAIL
(pair? (quote hello)) -> null
Test OK
((1 (x) (cons x (quote 1))) 2) -> null
Test OK
1 -> null
Test OK
((lambda (x) (write x)) (quote hello)) -> hello
Test OK
(write (quote (cons (quote 1) (quote 2)))) -> (cons (quote 1) (quote 2))
Test OK
(cons (quote 1) (cons (quote 2) (cons (quote 3) (cons (quote 4) null)))) -> (1 2 3 4)
Test FAIL
(quote (1 2 3 4)) -> (1 2 3 4)
Test OK
(cons (quote 1) (cons (quote 2) null)) -> (1 2)
Test FAIL
(write (cons (quote (hello world)) null)) -> ((hello world))
Test FAIL
((lambda (x y) (cons y (cons x null))) (quote 67) (quote 89)) -> (89 67)
Test FAIL
assoc.lisp -> lisp
Test FAIL
apply.lisp -> (fn 1 2 3 4)
Test FAIL
apply2.lisp -> (fn (1 2 3 4))
Test FAIL
reverse.lisp -> (9 8 7 6 5 4 3 2 1)
Test FAIL
hello -> carl
Test FAIL
(quote (write hello)) -> (write hello)
Test FAIL
(write (cons (quote hello) (cons (quote world) null))) -> (hello world)
Test FAIL
(apply write (cons (quote hello) (cons (quote world) null))) -> (hello world)
Test FAIL
Passed 9 of 26

When also adding -O2, in addition to having removed -ansi, all tests pass:

gcc -Wall -pedantic -O2 -g -o micro-lisp micro-lisp.c
micro-lisp.c: In function ā€˜apply_primitiveā€™:
micro-lisp.c:103:11: warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
   return ((List * (*) (List *)) primfn)  ( args );
           ^
micro-lisp.c: In function ā€˜mainā€™:
micro-lisp.c:144:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
   List *env = cons (cons(intern("car"), cons((void *)fcar, 0)),
                                              ^
micro-lisp.c:145:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("cdr"), cons((void *)fcdr, 0)),
                                              ^
micro-lisp.c:146:47: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("cons"), cons((void *)fcons, 0)),
                                               ^
micro-lisp.c:147:46: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("eq?"), cons((void *)feq, 0)),
                                              ^
micro-lisp.c:148:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("pair?"), cons((void *)fpair, 0)),
                                                ^
micro-lisp.c:149:50: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("symbol?"), cons((void *)fatom, 0)),
                                                  ^
micro-lisp.c:150:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("null?"), cons((void *)fnull, 0)),
                                                ^
micro-lisp.c:151:47: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("read"), cons((void *)freadobj, 0)),
                                               ^
micro-lisp.c:152:48: warning: ISO C forbids conversion of function pointer to object pointer type [-Wpedantic]
               cons (cons(intern("write"), cons((void *)fwriteobj, 0)),
                                                ^
wc micro-lisp.c
 159  769 5595 micro-lisp.c
./test.sh
(car (quote (1 2 3 4))) -> 1
Test OK
(cdr (quote (1 2 3 4))) -> (2 3 4)
Test OK
(cons (quote 1) (cons (quote 2) null)) -> (1 2)
Test OK
((lambda (x) (cons x (cons (quote 1) null))) (quote 7)) -> (7 1)
Test OK
(pair? (quote (1 2 3))) -> (quote t)
Test OK
(eq? (quote hello) (quote hello)) -> (quote t)
Test OK
(eq? (quote hello) (quote world)) -> null
Test OK
(pair? (cons (quote hello) (quote world))) -> (quote t)
Test OK
(pair? (quote hello)) -> null
Test OK
((1 (x) (cons x (quote 1))) 2) -> null
Test OK
1 -> null
Test OK
((lambda (x) (write x)) (quote hello)) -> hello
Test OK
(write (quote (cons (quote 1) (quote 2)))) -> (cons (quote 1) (quote 2))
Test OK
(cons (quote 1) (cons (quote 2) (cons (quote 3) (cons (quote 4) null)))) -> (1 2 3 4)
Test OK
(quote (1 2 3 4)) -> (1 2 3 4)
Test OK
(cons (quote 1) (cons (quote 2) null)) -> (1 2)
Test OK
(write (cons (quote (hello world)) null)) -> ((hello world))
Test OK
((lambda (x y) (cons y (cons x null))) (quote 67) (quote 89)) -> (89 67)
Test OK
assoc.lisp -> lisp
Test OK
apply.lisp -> (fn 1 2 3 4)
Test OK
apply2.lisp -> (fn (1 2 3 4))
Test OK
reverse.lisp -> (9 8 7 6 5 4 3 2 1)
Test OK
hello -> carl
Test OK
(quote (write hello)) -> (write hello)
Test OK
(write (cons (quote hello) (cons (quote world) null))) -> (hello world)
Test OK
(apply write (cons (quote hello) (cons (quote world) null))) -> (hello world)
Test OK
Passed 26 of 26

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.