Skip to content

Commit f51507e

Browse files
committed
Garbage collection now working.
1 parent dde4a9c commit f51507e

File tree

5 files changed

+22
-16
lines changed

5 files changed

+22
-16
lines changed

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ A dumb lisp interpreter, made for practice.
1515
- [(lambda (arg-a arg-b ...) stmnt-a stmnt-b ...)](#lambda-arg-a-arg-b--stmnt-a-stmnt-b-)
1616
- [Arithmatic Operators (+, -, /, *)](#arithmatic-operators-----)
1717
- [Comparison Operators (=, <, >)](#comparison-operators---)
18-
- [TODO](#todo)
1918

2019
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
2120

2221
## Features
2322
- A libreadline-based REPL
2423
- Create `lambda` functions with closures
2524
- Create macros
25+
- Garbage collection using the Boehm GC
2626
- It's dumb
2727

2828
## Built-in Functions
@@ -58,6 +58,3 @@ A dumb lisp interpreter, made for practice.
5858
### Arithmatic Operators (+, -, /, *)
5959

6060
### Comparison Operators (=, <, >)
61-
62-
## TODO
63-
- Garbage collection

src/builtins.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <assert.h>
55
#include <string.h>
66

7+
#include "gc.h"
8+
79
/* HELPER FUNCTIONS */
810

911
static int len(expr *list) {
@@ -416,7 +418,7 @@ expr *builtin_strcat(scope *scope, expr *arguments) {
416418
assert(a != NULL && a->type == STRING_EXPR);
417419
assert(b != NULL && b->type == STRING_EXPR);
418420

419-
char *newstring = malloc(strlen(a->string_value) + strlen(b->string_value) + 1);
421+
char *newstring = GC_MALLOC_ATOMIC(strlen(a->string_value) + strlen(b->string_value) + 1);
420422
strcpy(newstring, a->string_value);
421423
strcat(newstring, b->string_value);
422424

@@ -436,7 +438,7 @@ expr *builtin_substr(scope *scope, expr *arguments) {
436438
assert(start->int_value >= 0 && start->int_value <= strlen(string->string_value));
437439
assert(n->int_value >= 0 && start->int_value + n->int_value <= strlen(string->string_value));
438440

439-
char *newstring = malloc(n->int_value + 1);
441+
char *newstring = GC_MALLOC_ATOMIC(n->int_value + 1);
440442
strncpy(newstring, string->string_value + start->int_value, n->int_value);
441443
newstring[n->int_value] = '\0';
442444

src/expression.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
#include "assert.h"
66
#include "emitter.h"
77

8+
#include "gc.h"
9+
810
static inline expr *make_expr() {
9-
expr *e = malloc(sizeof(expr));
10-
memset(e, 0, sizeof(expr));
11+
expr *e = GC_MALLOC(sizeof(expr));
1112
return e;
1213
}
1314

src/lexer.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <ctype.h>
66
#include "stringpool.h"
77

8+
#include "gc.h"
9+
810
void create_file_lexer(lexing_context *ctx, const char *filename) {
911
ctx->filename = filename;
1012
ctx->lineno = 1;
@@ -54,12 +56,12 @@ static void advance_until_newline(lexing_context *ctx) {
5456

5557
// Read a string literal, ending on a close-quote
5658
const char *read_string(lexing_context *ctx) {
57-
char literal[MAX_LITERAL_SIZE];
59+
char buffer[MAX_LITERAL_SIZE];
5860
int position = 0;
5961
while (true) {
6062
int c = get_char(ctx);
6163
if (c == '\"') {
62-
literal[position] = '\0';
64+
buffer[position] = '\0';
6365
break;
6466
}
6567

@@ -81,10 +83,12 @@ const char *read_string(lexing_context *ctx) {
8183
}
8284
}
8385

84-
literal[position] = c;
86+
buffer[position] = c;
8587
++position;
8688
}
87-
return strdup(literal);
89+
char *literal = GC_MALLOC_ATOMIC(strlen(buffer) + 1);
90+
strcpy(literal, buffer);
91+
return literal;
8892
}
8993

9094
bool is_validsymbolchar(char c) {
@@ -137,7 +141,7 @@ bool is_letter(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
137141
bool is_alphanumeric(char c) { return is_letter(c) || is_digit(c); }
138142

139143
void unget_token(lexing_context *ctx, token_t *token) {
140-
token_t *new_token = malloc(sizeof(token_t));
144+
token_t *new_token = GC_MALLOC(sizeof(token_t));
141145
memcpy(new_token, token, sizeof(token_t));
142146
new_token->next = ctx->stack;
143147
ctx->stack = new_token;
@@ -149,7 +153,7 @@ void get_next_token(lexing_context *ctx, token_t *token) {
149153
token_t *next_tok = ctx->stack;
150154
ctx->stack = next_tok->next;
151155
memcpy(token, next_tok, sizeof(token_t));
152-
free(next_tok);
156+
GC_FREE(next_tok);
153157
return;
154158
}
155159

src/scope.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include "stdlib.h"
44
#include "string.h"
55

6+
#include "gc.h"
7+
68
struct expr *scope_lookup(struct scope *scope, const char *symbol) {
79
for (struct scope *curr = scope; curr != NULL; curr = curr->parent) {
810
struct expr *e = scope_probe(curr, symbol);
@@ -22,14 +24,14 @@ struct expr *scope_probe(struct scope *scope, const char *symbol) {
2224
}
2325

2426
struct scope *scope_create(struct scope *parent) {
25-
struct scope *scope = malloc(sizeof(struct scope));
27+
struct scope *scope = GC_MALLOC(sizeof(struct scope));
2628
scope->parent = parent;
2729
scope->mappings = NULL;
2830
return scope;
2931
}
3032

3133
void scope_add_mapping(struct scope *scope, const char *symbol, struct expr *value) {
32-
struct mapping *m = malloc(sizeof(struct mapping));
34+
struct mapping *m = GC_MALLOC(sizeof(struct mapping));
3335
m->symbol = symbol;
3436
m->value = value;
3537

0 commit comments

Comments
 (0)