Skip to content

Commit f27befe

Browse files
committed
Will REPL until quit called
1 parent aa16334 commit f27befe

File tree

6 files changed

+85
-7
lines changed

6 files changed

+85
-7
lines changed

build

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
yacc -d parser.y
22
lex parser.l
3-
cc lex.yy.c y.tab.c type.c nil.c atoms.c pair.c stack.c exception.c dictionary.c function.c standard_library.c interpreter.c repl.c -ll -ly -o lisp
3+
cc lex.yy.c y.tab.c type.c nil.c atoms.c pair.c stack.c exception.c dictionary.c function.c exit.c standard_library.c interpreter.c repl.c -ll -ly -o lisp

exit.c

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include "exit.h"
2+
#include "type.h"
3+
#include <stdlib.h>
4+
5+
static void exit_code_writer(void *, Printf);
6+
7+
void declare_exit_code(void) {
8+
declare(free, exit_code_writer);
9+
}
10+
11+
Object *exit_code(int code) {
12+
int *cell = (int *)malloc(sizeof(int));
13+
*cell = code;
14+
return wrap(exit_code_type, cell);
15+
}
16+
17+
int is_exit_code(Object *object) {
18+
return is_a(exit_code_type, object);
19+
}
20+
21+
static void exit_code_writer(void *code, Printf printer) {
22+
printer("%d", *(int *)code);
23+
}

exit.h

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef EXIT_HEADER
2+
#define EXIT_HEADER
3+
4+
#include "type.h"
5+
6+
Type *exit_code_type;
7+
8+
void declare_exit_code(void);
9+
Object *exit_code(int);
10+
int is_exit_code(Object *);
11+
12+
#endif

interpreter.c

+14
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@
22
#include "nil.h"
33
#include "atoms.h"
44
#include "pair.h"
5+
#include "exit.h"
56
#include "function.h"
67
#include "dictionary.h"
78
#include "standard_library.h"
89

910
static Dictionary *dictionary;
1011
static Object *eval_call(Object *, Object *, ErrorHandler, Dictionary *);
12+
static Object *eval_identifier(Object *, ErrorHandler, Dictionary *);
1113
static Object *execute(Callable, Object *, ErrorHandler, Dictionary *);
1214

1315
void create_interpreter(void) {
1416
declare_nil();
1517
declare_atoms();
1618
declare_pair();
1719
declare_functions();
20+
declare_exit_code();
1821
dictionary = create_dictionary();
1922
declare_standard_library(dictionary);
2023
}
@@ -33,6 +36,8 @@ Object *eval(Object *object, ErrorHandler error, Dictionary *dictionary) {
3336
Object *result = eval_call(clone(car(object)), clone(cdr(object)), error, dictionary);
3437
destroy(object);
3538
return result;
39+
} else if (is_identifier(object)) {
40+
return eval_identifier(object, error, dictionary);
3641
} else {
3742
return object;
3843
}
@@ -63,6 +68,15 @@ static Object *eval_call(Object *identifier, Object *arguments, ErrorHandler err
6368
return apply(function, arguments, error, dictionary);
6469
}
6570

71+
static Object *eval_identifier(Object *identifier, ErrorHandler error, Dictionary *dictionary) {
72+
Object *found;
73+
if (! (found = find(dictionary, (char *)value(identifier)))) {
74+
return error("Unkown identifier", identifier);
75+
} else {
76+
return clone(found);
77+
}
78+
}
79+
6680
static Object *execute(Callable built_in, Object *arguments, ErrorHandler error, Dictionary *dictionary) {
6781
return (*built_in)(arguments, error, dictionary);
6882
}

repl.c

+26-6
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,47 @@
22
#include "nil.h"
33
#include "pair.h"
44
#include "exception.h"
5+
#include "exit.h"
56
#include "interpreter.h"
67
#include <stdio.h>
78

89
extern void create_reader(void);
910
extern void free_reader(void);
1011
extern Object *read(void);
1112

13+
static int exit_status = 0;
14+
static int request_exit = 0;
15+
static void will_exit(int);
16+
static int exiting(void);
1217
static void print(Object *value);
1318
static void print_error(char *, Object *);
1419

1520
int main(int argc, char **argv) {
1621
create_interpreter();
1722
create_reader();
18-
Try {
19-
print(eval(read(), throw_exception, top_level()));
20-
} Catch {
21-
print_error(exception_message(), (Object *)exception_information());
22-
}
23+
do {
24+
Try {
25+
print(eval(read(), throw_exception, top_level()));
26+
} Catch {
27+
if (is_exit_code((Object *)exception_information())) {
28+
will_exit(*(int *)value((Object *)exception_information()));
29+
} else {
30+
print_error(exception_message(), (Object *)exception_information());
31+
}
32+
}
33+
} while (! exiting());
2334
free_reader();
2435
free_interpreter();
25-
return 0;
36+
return exit_status;
37+
}
38+
39+
static void will_exit(int exit_code) {
40+
request_exit = 1;
41+
exit_status = exit_code;
42+
}
43+
44+
static int exiting(void) {
45+
return request_exit;
2646
}
2747

2848
static void print(Object *value) {

standard_library.c

+9
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,24 @@
55
#include "nil.h"
66
#include "atoms.h"
77
#include "pair.h"
8+
#include "exit.h"
89

10+
static Object *quit(Object *, ErrorHandler, Dictionary *);
911
static Object *set(Object *, ErrorHandler, Dictionary *);
1012
static Object *plus(Object *, ErrorHandler, Dictionary *);
1113

1214
void declare_standard_library(Dictionary *dictionary) {
15+
add(dictionary, "quit", built_in(quit));
1316
add(dictionary, "set", built_in(set));
1417
add(dictionary, "+", built_in(plus));
1518
}
1619

20+
static Object *quit(Object *object, ErrorHandler error, Dictionary *dictionary) {
21+
Object *code = exit_code(is_number(object) ? (int)value(object) : 0);
22+
destroy(object);
23+
return error("Quitting", code);
24+
}
25+
1726
static Object *set(Object *arguments, ErrorHandler error, Dictionary *dictionary) {
1827
char *identifier = value(car(arguments));
1928
add(dictionary, identifier, clone(cdr(arguments)));

0 commit comments

Comments
 (0)