From f6c8cac5c77f75766dbdbbb6d130a8d1835e2d68 Mon Sep 17 00:00:00 2001 From: Matthias Schuetz Date: Sun, 24 Feb 2008 23:58:15 +0000 Subject: [PATCH] basic lisp interpreter in c git-svn-id: https://shell.noname-ev.de/svn/lisp/tinylisp@5 f9497395-c7e6-438d-86fc-c13047f9afa0 --- Makefile | 18 +++++++++++++ base.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ base.h | 26 ++++++++++++++++++ lisp_scanner.rl | 21 +++++++++++++++ list.c | 5 ++++ list.h | 5 ++++ symbol_table.c | 36 +++++++++++++++++++++++++ symbol_table.h | 19 ++++++++++++++ test_scanner.c | 5 ++++ tinylisp.c | 14 ++++++++++ 10 files changed, 219 insertions(+) create mode 100644 Makefile create mode 100644 base.c create mode 100644 base.h create mode 100644 lisp_scanner.rl create mode 100644 list.c create mode 100644 list.h create mode 100644 symbol_table.c create mode 100644 symbol_table.h create mode 100644 test_scanner.c create mode 100644 tinylisp.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a060040 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +flex: + flex lisp_scanner.rl + +.c.o: + $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $< + +tinylisp: tinylisp.o symbol_table.o base.o + $(CC) -o tinylisp tinylisp.o symbol_table.o base.o + + +run: tinylisp + ./tinylisp + +clean: + rm tinylisp *.o + +test: flex test_scanner.o lex.yy.o + gcc -o test_scanner test_scanner.o lex.yy.o /opt/local/lib/libfl.a diff --git a/base.c b/base.c new file mode 100644 index 0000000..f57b61a --- /dev/null +++ b/base.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include "base.h" +#include "symbol_table.h" + +struct object * car(struct cons_cell * cc){ + return cc->car; +} + +struct object * cdr(struct cons_cell * cc){ + return cc->cdr; +} + +bool atom_p(struct object * o){ + return o!=nil && o->atom_p; +} + +struct object * cons(struct object * o1, struct object * o2){ + struct object * o = (struct object *) malloc(sizeof(struct object)); + o->atom_p = false; + struct cons_cell * cc = (struct cons_cell *) malloc(sizeof(struct cons_cell)); + o->data = cc; + cc->car = o1; + cc->cdr = o2; + return o; +} + +struct object * quote(char * s){ + return st_insert(s); +} + +void print_cons(struct cons_cell * cc); +void print_atom(atom a); + +void print(struct object * o){ + if (o==nil) { + printf("nil"); + return; + } + + if (o->atom_p) + print_atom((atom) o->data); + else + print_cons((struct cons_cell *) o->data); +} + +void print_cons(struct cons_cell * cc){ + printf("("); + print(car(cc)); + + if (atom_p(cdr(cc))) { + printf(" . "); + print(cdr(cc)); + } else { + + } + + printf(")"); +} + +void print_atom(atom a){ + printf("%s", st_id_to_name(a)); +} + +struct obj * read(){ + char *s; + while(s = (char *)yylex()) +} + diff --git a/base.h b/base.h new file mode 100644 index 0000000..1e3ad5a --- /dev/null +++ b/base.h @@ -0,0 +1,26 @@ +#ifndef __TINYLISP_H +#define __TINYLISP_H + +#include + +typedef int atom; + +#define nil NULL + +struct object { + bool atom_p; + void * data; +}; + +struct cons_cell { + struct object * car; + struct object * cdr; +}; + +struct object * car(struct cons_cell * cc); +struct object * cdr(struct cons_cell * cc); +struct object * quote(char * s); +struct object * cons(struct object * o1, struct object * o2); +void print(struct object * o); + +#endif diff --git a/lisp_scanner.rl b/lisp_scanner.rl new file mode 100644 index 0000000..6a5902f --- /dev/null +++ b/lisp_scanner.rl @@ -0,0 +1,21 @@ +%{ + +%} + +digit [0-9] +blank [ \t] +name1 [A-Za-z] +name2 [A-Za-z_0-9] + +%% + +{name1}{name2}* { return (char *)yytext; } + + +"(" {return (char *)yytext;} +")" {return (char *)yytext;} + +"\n" { } + +{blank}+ ; +%% diff --git a/list.c b/list.c new file mode 100644 index 0000000..e3cf161 --- /dev/null +++ b/list.c @@ -0,0 +1,5 @@ +#include "list.h" + +void * car(struct cons_cell * cons_cell){ + return cons_cell->car +} diff --git a/list.h b/list.h new file mode 100644 index 0000000..7e8721a --- /dev/null +++ b/list.h @@ -0,0 +1,5 @@ +#ifndef __LIST_H +#define __LIST_H + + +#endif diff --git a/symbol_table.c b/symbol_table.c new file mode 100644 index 0000000..ae53fd9 --- /dev/null +++ b/symbol_table.c @@ -0,0 +1,36 @@ +#include +#include "symbol_table.h" + +static struct symbol_table st; + +struct object * st_insert(char * name){ + struct object * o; + if ((o = st_lookup(name)) != NULL) + return o; + + struct symbol * sym = &st.symbols[st.size]; + o = &sym->object; + o->atom_p = true; + o->data = (void *)st.size; + + int length = strlen(name); + strncpy(sym->name, name, length); + + st.size++; + return o; +} + +struct object * st_lookup(char * name){ + int i; + for (i=0; i%s<\n", sym); +} diff --git a/tinylisp.c b/tinylisp.c new file mode 100644 index 0000000..dcf249e --- /dev/null +++ b/tinylisp.c @@ -0,0 +1,14 @@ +#include +#include "base.h" +#include "symbol_table.h" + +int main(int argc, char **argv){ + st_insert("nil"); + st_insert("t"); + struct object * list; + list = cons(quote("a"), cons(quote("b"), cons(quote("c"), nil))); + print(cons(quote("a"), quote("b"))); puts(""); + print(list); + return 0; +} +