From 043a96a6b7cf55f7ef58fb5ebf8ad87b7d50b571 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Mon, 18 Oct 2021 12:31:20 +0200 Subject: Add header files for all modules --- src/bootstrap/environment.c | 21 ++----------- src/bootstrap/environment.h | 34 ++++++++++++++++++++ src/bootstrap/errors.c | 31 +----------------- src/bootstrap/errors.h | 38 ++++++++++++++++++++++ src/bootstrap/gc.c | 67 ++++++--------------------------------- src/bootstrap/gc.h | 69 ++++++++++++++++++++++++++++++++++++++++ src/bootstrap/lexer.c | 38 ++-------------------- src/bootstrap/lexer.h | 66 ++++++++++++++++++++++++++++++++++++++ src/bootstrap/main.c | 22 +++++-------- src/bootstrap/objects.c | 66 ++------------------------------------ src/bootstrap/objects.h | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/bootstrap/parser.c | 9 +----- src/bootstrap/parser.h | 22 +++++++++++++ src/bootstrap/primitives.c | 4 +-- src/bootstrap/primitives.h | 60 +++++++++++++++++++++++++++++++++++ src/bootstrap/read_line.c | 3 +- src/bootstrap/read_line.h | 10 ++++++ src/bootstrap/singletons.c | 17 ++++++++++ src/bootstrap/string_view.c | 5 +-- src/bootstrap/string_view.h | 21 +++++++++++++ 20 files changed, 445 insertions(+), 235 deletions(-) create mode 100644 src/bootstrap/environment.h create mode 100644 src/bootstrap/errors.h create mode 100644 src/bootstrap/gc.h create mode 100644 src/bootstrap/lexer.h create mode 100644 src/bootstrap/objects.h create mode 100644 src/bootstrap/parser.h create mode 100644 src/bootstrap/primitives.h create mode 100644 src/bootstrap/read_line.h create mode 100644 src/bootstrap/singletons.c create mode 100644 src/bootstrap/string_view.h (limited to 'src') diff --git a/src/bootstrap/environment.c b/src/bootstrap/environment.c index d5e954b..3fe8be1 100644 --- a/src/bootstrap/environment.c +++ b/src/bootstrap/environment.c @@ -1,21 +1,6 @@ -typedef struct EnvEntry { - Object *symbol; - Object *value; -} EnvEntry; - -typedef struct Environment { - struct Environment *parent; - EnvEntry *buf; - size_t size; - size_t cap; - bool marked; -} Environment; - -static Environment *global_env; - -#define ENV_BUF_CAP 8 - -Environment *alloc_env(void); +#include "environment.h" +#include "gc.h" +#include "errors.h" Environment * env_create(Environment *parent) { diff --git a/src/bootstrap/environment.h b/src/bootstrap/environment.h new file mode 100644 index 0000000..cc13921 --- /dev/null +++ b/src/bootstrap/environment.h @@ -0,0 +1,34 @@ +#ifndef BDL_ENVIRONMENT_H +#define BDL_ENVIRONMENT_H + +#include "objects.h" + +typedef struct EnvEntry { + Object *symbol; + Object *value; +} EnvEntry; + +typedef struct Environment { + struct Environment *parent; + EnvEntry *buf; + size_t size; + size_t cap; + bool marked; +} Environment; + +Environment * env_create(Environment *parent); +void env_add_symbol(Environment *env, Object *symbol, Object *value); +Object * env_lookup(Environment *env, Object *symbol); +Object * env_update(Environment *env, Object *symbol, Object *value); +ssize_t env_index_current(Environment *env, Object *symbol); +void env_add_or_update_current(Environment *env, Object *symbol, Object *value); +Environment * env_extend(Environment *parent, Environment *extra); + +#define MAKE_ENV_VAR(ENV,STR,VAR) \ + (env_add_symbol((ENV), MAKE_SYM(STR), (VAR))) +#define MAKE_ENV_PROC(ENV,STR,FUN) \ + (env_add_symbol((ENV), MAKE_SYM(STR), make_procedure(FUN))) + +#define ENV_BUF_CAP 8 + +#endif // BDL_ENVIRONMENT_H diff --git a/src/bootstrap/errors.c b/src/bootstrap/errors.c index c1d2879..d957cfa 100644 --- a/src/bootstrap/errors.c +++ b/src/bootstrap/errors.c @@ -1,32 +1,4 @@ -typedef enum ErrorType { - ERR_TYPE_LEXER, - ERR_TYPE_PARSER, - ERR_TYPE_RUNTIME, -} ErrorType; - -typedef enum ErrorValue { - ERR_UNKNOWN = 0, - ERR_UNMATCHED_STRING, - ERR_UNBALANCED_PAREN, - ERR_NOT_IMPLEMENTED, - ERR_EOF_REACHED, - ERR_UNKNOWN_TOKEN, - ERR_UNKNOWN_OBJ_TYPE, - ERR_NOT_A_SYMBOL, - ERR_SYMBOL_NOT_FOUND, - ERR_OBJ_NOT_CALLABLE, - ERR_NOT_ENOUGH_ARGS, - ERR_TOO_MANY_ARGS, - ERR_WRONG_ARG_TYPE, - ERR_DIVISION_BY_ZERO, -} ErrorValue; - -typedef struct Error { - ErrorType type; - ErrorValue value; - size_t line; - size_t col; -} Error; +#include "errors.h" static const char* error_msgs[] = { [ERR_UNKNOWN] = "error: something unexpected happened", @@ -45,7 +17,6 @@ static const char* error_msgs[] = { [ERR_DIVISION_BY_ZERO] = "error: division by zero", }; -#define ERR_MAX_NUMBER 16 static Error errors[ERR_MAX_NUMBER]; static size_t errors_n = 0; static bool supress_errors = false; diff --git a/src/bootstrap/errors.h b/src/bootstrap/errors.h new file mode 100644 index 0000000..7916f4a --- /dev/null +++ b/src/bootstrap/errors.h @@ -0,0 +1,38 @@ +#ifndef BDL_ERRORS_H +#define BDL_ERRORS_H + +typedef enum ErrorType { + ERR_TYPE_LEXER, + ERR_TYPE_PARSER, + ERR_TYPE_RUNTIME, +} ErrorType; + +typedef enum ErrorValue { + ERR_UNKNOWN = 0, + ERR_UNMATCHED_STRING, + ERR_UNBALANCED_PAREN, + ERR_NOT_IMPLEMENTED, + ERR_EOF_REACHED, + ERR_UNKNOWN_TOKEN, + ERR_UNKNOWN_OBJ_TYPE, + ERR_NOT_A_SYMBOL, + ERR_SYMBOL_NOT_FOUND, + ERR_OBJ_NOT_CALLABLE, + ERR_NOT_ENOUGH_ARGS, + ERR_TOO_MANY_ARGS, + ERR_WRONG_ARG_TYPE, + ERR_DIVISION_BY_ZERO, +} ErrorValue; + +typedef struct Error { + ErrorType type; + ErrorValue value; + size_t line; + size_t col; +} Error; + +void error_push(Error error); + +#define ERR_MAX_NUMBER 16 + +#endif // BDL_ERRORS_H diff --git a/src/bootstrap/gc.c b/src/bootstrap/gc.c index 11a1f5a..473930a 100644 --- a/src/bootstrap/gc.c +++ b/src/bootstrap/gc.c @@ -1,48 +1,4 @@ -// Stack of root nodes. -typedef struct RootNodes { - Object **buf; - size_t size; - size_t cap; -} RootNodes; - -// Stack of active environments. -typedef struct ActiveEnvs { - Environment **buf; - size_t size; - size_t cap; -} ActiveEnvs; - -typedef struct Environments { - Environment *buf; - size_t size; - size_t cap; -} Environments; - -typedef struct FreeList { - size_t *buf; - size_t size; - size_t cap; - size_t position; -} FreeList; - -typedef struct GC { - RootNodes roots; - Environments envs; - Object *objects; - size_t obj_cap; - FreeList free_objects; - FreeList free_envs; - ActiveEnvs active_envs; -} GC; - -#define GC_OBJS_CAP 1024 * 1024 -#define GC_ROOTS_CAP 1024 -#define GC_ENVS_CAP 1024 * 4 - -static GC gc; - -void mark_and_sweep(void); -void dump_gc(void); +#include "gc.h" Environment * alloc_env(void) { @@ -115,9 +71,9 @@ init_gc(void) { .cap = GC_ENVS_CAP, }, .active_envs = (ActiveEnvs){ - .buf = malloc(GC_ROOTS_CAP * sizeof(Environment*)), + .buf = malloc(GC_ACTIVE_ENVS_CAP * sizeof(Environment*)), .size = 0, - .cap = GC_ROOTS_CAP, + .cap = GC_ACTIVE_ENVS_CAP, }, }; @@ -131,13 +87,6 @@ init_gc(void) { } } -Object * -get_obj(size_t offset) { - return &gc.objects[offset]; -} - -void mark_obj(Object *obj); - void mark_environment(Environment *env) { if (env == NULL || env->marked) { @@ -190,11 +139,15 @@ mark_and_sweep(void) { if (!obj->marked) { // Free heap allocated memory for this object if needed. if (obj->type == OBJ_TYPE_SYMBOL) { - free(obj->symbol); + if (obj->symbol != NULL) { + free(obj->symbol); + } obj->symbol = NULL; obj->symbol_n = 0; } else if (obj->type == OBJ_TYPE_STRING) { - free(obj->string); + if (obj->symbol != NULL) { + free(obj->string); + } obj->string = NULL; obj->string_n = 0; } @@ -280,7 +233,7 @@ alloc_object(ObjectType type) { } size_t slot = gc.free_objects.buf[gc.free_objects.position++]; gc.free_objects.size--; - Object *obj = get_obj(slot); + Object *obj = &gc.objects[slot]; obj->type = type; obj->marked = false; return obj; diff --git a/src/bootstrap/gc.h b/src/bootstrap/gc.h new file mode 100644 index 0000000..038c820 --- /dev/null +++ b/src/bootstrap/gc.h @@ -0,0 +1,69 @@ +#ifndef BDL_GC_H +#define BDL_GC_H + +#include "objects.h" +#include "environment.h" + +// Stack of root nodes. +typedef struct RootNodes { + Object **buf; + size_t size; + size_t cap; +} RootNodes; + +// Stack of active environments. +typedef struct ActiveEnvs { + Environment **buf; + size_t size; + size_t cap; +} ActiveEnvs; + +typedef struct Environments { + Environment *buf; + size_t size; + size_t cap; +} Environments; + +typedef struct FreeList { + size_t *buf; + size_t size; + size_t cap; + size_t position; +} FreeList; + +typedef struct GC { + RootNodes roots; + Environments envs; + Object *objects; + size_t obj_cap; + FreeList free_objects; + FreeList free_envs; + ActiveEnvs active_envs; +} GC; + +void init_gc(void); + +// Allocation functions for objects and environments. +Object * alloc_object(ObjectType type); +Environment * alloc_env(void); + +// Root and environment protector functions. +void push_root(Object *obj); +Object * pop_root(void); +void push_active_env(Environment *env); +Environment * pop_active_env(void); + +// Mark and sweep algorithm functions. +void mark_environment(Environment *env); +void mark_obj(Object *obj); +void mark_and_sweep(void); + +// Debugging function to print out the contentes of some GC fields. +void dump_gc(void); + +#define GC_OBJS_CAP 1024 * 1024 +#define GC_ROOTS_CAP 1024 +#define GC_ACTIVE_ENVS_CAP 2 +#define GC_ENVS_CAP 1024 * 4 + +#endif // BDL_GC_H diff --git a/src/bootstrap/lexer.c b/src/bootstrap/lexer.c index ee387dd..05324eb 100644 --- a/src/bootstrap/lexer.c +++ b/src/bootstrap/lexer.c @@ -1,29 +1,4 @@ -typedef enum TokenType { - TOKEN_UNKNOWN = 0, - TOKEN_LPAREN, - TOKEN_RPAREN, - TOKEN_QUOTE, - TOKEN_TRUE, - TOKEN_FALSE, - TOKEN_NIL, - TOKEN_FIXNUM, - TOKEN_SYMBOL, - TOKEN_STRING, - TOKEN_EOF, -} TokenType; - -typedef struct Token { - TokenType type; - StringView value; - size_t line; - size_t column; -} Token; - -typedef struct Tokens { - Token *buf; - size_t size; - size_t cap; -} Tokens; +#include "lexer.h" void print_token(Token tok) { @@ -69,8 +44,6 @@ print_token(Token tok) { printf("\n"); } -#define TOK_BUF_CAP 256 - void push_token(Tokens *tokens, Token tok) { if (tokens->buf == NULL) { @@ -84,13 +57,6 @@ push_token(Tokens *tokens, Token tok) { tokens->buf[tokens->size++] = tok; } -typedef struct Scanner { - StringView current; - size_t line_number; - size_t col_number; - size_t offset; -} Scanner; - char scan_next(Scanner *scanner) { char c = sv_next(&scanner->current); @@ -157,7 +123,7 @@ is_delimiter(char c) { } TokenType -find_primitive_type(StringView value) { +find_primitive_type(const StringView value) { bool is_fixnum = true; for (size_t i = 0; i < value.n; i++) { char c = value.start[i]; diff --git a/src/bootstrap/lexer.h b/src/bootstrap/lexer.h new file mode 100644 index 0000000..129fd9a --- /dev/null +++ b/src/bootstrap/lexer.h @@ -0,0 +1,66 @@ +#ifndef BDL_LEXER_H +#define BDL_LEXER_H + +typedef enum TokenType { + TOKEN_UNKNOWN = 0, + TOKEN_LPAREN, + TOKEN_RPAREN, + TOKEN_QUOTE, + TOKEN_TRUE, + TOKEN_FALSE, + TOKEN_NIL, + TOKEN_FIXNUM, + TOKEN_SYMBOL, + TOKEN_STRING, + TOKEN_EOF, +} TokenType; + +typedef struct Token { + TokenType type; + StringView value; + size_t line; + size_t column; +} Token; + +typedef struct Tokens { + Token *buf; + size_t size; + size_t cap; +} Tokens; + +typedef struct Scanner { + StringView current; + size_t line_number; + size_t col_number; + size_t offset; +} Scanner; + +// Print a token to standard output for debugging purposes. +void print_token(Token tok); + +// Push a token to the token list. +void push_token(Tokens *tokens, Token tok); + +// Same functionality as the ScanView pairs, but keeping track of line and +// column numbers. +char scan_next(Scanner *scanner); +char scan_peek(const Scanner *scanner); + +// Check if the current scanner still have characters left. +bool scan_has_next(const Scanner *scanner); + +// Advance the scanner until we ran out of whitespace. +void skip_whitespace(Scanner *scanner); + +// Check if a given character is a delimiter. +bool is_delimiter(char c); + +// Extract the token type from the current string. +TokenType find_primitive_type(const StringView value); + +// Generate a list of tokens from the given string. +Tokens tokenize(const StringView *sv); + +#define TOK_BUF_CAP 256 + +#endif // BDL_LEXER_H diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c index 2d24f92..cfad9f1 100755 --- a/src/bootstrap/main.c +++ b/src/bootstrap/main.c @@ -6,25 +6,17 @@ #include #include -#include "string_view.c" -#include "read_line.c" +#include "singletons.c" + +#include "environment.c" #include "errors.c" +#include "gc.c" #include "lexer.c" #include "objects.c" #include "parser.c" -#include "environment.c" -#include "gc.c" #include "primitives.c" - -// -// Utility macros. -// - -#define MAKE_SYM(STR) make_symbol((StringView){(STR), sizeof(STR) - 1}) -#define MAKE_ENV_VAR(ENV,STR,VAR) \ - (env_add_symbol((ENV), MAKE_SYM(STR), (VAR))) -#define MAKE_ENV_PROC(ENV,STR,FUN) \ - (env_add_symbol((ENV), MAKE_SYM(STR), make_procedure(FUN))) +#include "read_line.c" +#include "string_view.c" void init(void) { @@ -113,7 +105,7 @@ process_source(const StringView *source) { .current = 0, }; while (has_next_token(&visitor) && peek_token(&visitor).type != TOKEN_EOF) { - // check the stack before parsing + // Check the root node stack size before parsing size_t root_stack_size = gc.roots.size; Object *root = parse_tree(&visitor); gc.roots.size = root_stack_size; diff --git a/src/bootstrap/objects.c b/src/bootstrap/objects.c index 09076db..359329b 100644 --- a/src/bootstrap/objects.c +++ b/src/bootstrap/objects.c @@ -1,70 +1,10 @@ -typedef enum ObjectType { - OBJ_TYPE_FIXNUM, - OBJ_TYPE_BOOL, - OBJ_TYPE_NIL, - OBJ_TYPE_SYMBOL, - OBJ_TYPE_STRING, - OBJ_TYPE_PAIR, - OBJ_TYPE_PROCEDURE, - OBJ_TYPE_LAMBDA, - OBJ_TYPE_ERR, -} ObjectType; - -struct Environment; - -typedef struct Object { - ObjectType type; - bool marked; - union { - // OBJ_TYPE_FIXNUM - ssize_t fixnum; - - // OBJ_TYPE_STRING - struct { - char *string; - size_t string_n; - }; - - // OBJ_TYPE_PAIR - struct { - struct Object *car; - struct Object *cdr; - }; - - // OBJ_TYPE_SYMBOL - struct { - char *symbol; - size_t symbol_n; - }; - - // OBJ_TYPE_PROCEDURE - struct Object *(*proc)(struct Environment *env, struct Object *args); - - // OBJ_TYPE_LAMBDA - struct { - struct Object *params; - struct Object *body; - struct Environment *env; - }; - }; -} Object; - -// -// Singletons. -// - -static Object *obj_nil; -static Object *obj_true; -static Object *obj_false; -static Object *obj_err; -static Object *obj_quote; +#include "gc.h" +#include "objects.h" // // Constructors. // -Object * alloc_object(ObjectType); - Object * make_fixnum(ssize_t num) { Object *obj = alloc_object(OBJ_TYPE_FIXNUM); @@ -116,8 +56,6 @@ append_string(Object *obj, const StringView sv) { obj->string_n += sv.n; } -void display(Object *root); - void display_pair(Object *root) { display(root->car); diff --git a/src/bootstrap/objects.h b/src/bootstrap/objects.h new file mode 100644 index 0000000..56821eb --- /dev/null +++ b/src/bootstrap/objects.h @@ -0,0 +1,77 @@ +#ifndef BDL_OBJECTS_H +#define BDL_OBJECTS_H + +#include "string_view.h" + +typedef enum ObjectType { + OBJ_TYPE_FIXNUM, + OBJ_TYPE_BOOL, + OBJ_TYPE_NIL, + OBJ_TYPE_SYMBOL, + OBJ_TYPE_STRING, + OBJ_TYPE_PAIR, + OBJ_TYPE_PROCEDURE, + OBJ_TYPE_LAMBDA, + OBJ_TYPE_ERR, +} ObjectType; + +struct Environment; + +typedef struct Object { + ObjectType type; + bool marked; + union { + // OBJ_TYPE_FIXNUM + ssize_t fixnum; + + // OBJ_TYPE_STRING + struct { + char *string; + size_t string_n; + }; + + // OBJ_TYPE_PAIR + struct { + struct Object *car; + struct Object *cdr; + }; + + // OBJ_TYPE_SYMBOL + struct { + char *symbol; + size_t symbol_n; + }; + + // OBJ_TYPE_PROCEDURE + struct Object *(*proc)(struct Environment *env, struct Object *args); + + // OBJ_TYPE_LAMBDA + struct { + struct Object *params; + struct Object *body; + struct Environment *env; + }; + }; +} Object; + +// Object constructors. +Object * make_fixnum(ssize_t num); +Object * make_procedure(Object *(*proc)(struct Environment *, struct Object *args)); +Object * make_pair(Object *car, Object *cdr); +Object * make_symbol(StringView sv); +Object * make_string(void); +void append_string(Object *obj, const StringView sv); + +// Object representation. +void display(Object *root); +void display_pair(Object *root); + +// Object comparison. +bool obj_eq(Object *a, Object* b); + +// Utility macros. +#define DEBUG_OBJ(MSG,OBJ) printf((MSG)); display(OBJ); printf("\n"); +#define PRINT_OBJ(OBJ) display(OBJ); printf("\n"); +#define MAKE_SYM(STR) make_symbol((StringView){(STR), sizeof(STR) - 1}) + +#endif // BDL_OBJECTS_H diff --git a/src/bootstrap/parser.c b/src/bootstrap/parser.c index 77ece9d..5b0033a 100644 --- a/src/bootstrap/parser.c +++ b/src/bootstrap/parser.c @@ -1,7 +1,4 @@ -typedef struct Visitor { - Tokens tokens; - size_t current; -} Visitor; +#include "parser.h" Token peek_token(const Visitor *visitor) { @@ -18,8 +15,6 @@ has_next_token(const Visitor *visitor) { return visitor->current < visitor->tokens.size; } -void push_root(Object*); - Object * parse_fixnum(Token tok) { ssize_t num = 0; @@ -38,8 +33,6 @@ parse_fixnum(Token tok) { return obj; } -Object * parse_tree(Visitor *vs); - Object * parse_list(Visitor *vs) { Token tok = peek_token(vs); diff --git a/src/bootstrap/parser.h b/src/bootstrap/parser.h new file mode 100644 index 0000000..3bd17ef --- /dev/null +++ b/src/bootstrap/parser.h @@ -0,0 +1,22 @@ +#ifndef BDL_PARSER_H +#define BDL_PARSER_H + +typedef struct Visitor { + Tokens tokens; + size_t current; +} Visitor; + +// Mimics the functionality in the Scanner functions, but for entire tokens. +Token next_token(Visitor *visitor); +Token peek_token(const Visitor *visitor); +bool has_next_token(const Visitor *visitor); + +// Parse a token into a fixnum object. +Object * parse_fixnum(Token tok); + +// Recursive descent parser. If an object is not a list the parsing is handled +// by the parse_tree function. +Object * parse_list(Visitor *vs); +Object * parse_tree(Visitor *vs); + +#endif // BDL_PARSER_H diff --git a/src/bootstrap/primitives.c b/src/bootstrap/primitives.c index 0c2a17d..0f1498d 100644 --- a/src/bootstrap/primitives.c +++ b/src/bootstrap/primitives.c @@ -1,5 +1,4 @@ -#define DEBUG_OBJ(MSG,OBJ) printf((MSG)); display(OBJ); printf("\n"); -static Object *proc_if; +#include "primitives.h" Object * eval(Environment *env, Object *root) { @@ -153,6 +152,7 @@ eval_lambda: .value = ERR_UNKNOWN_OBJ_TYPE, }); return obj_err; + eval_success: if (recursion_active) { // Remove stack protector. diff --git a/src/bootstrap/primitives.h b/src/bootstrap/primitives.h new file mode 100644 index 0000000..f874b17 --- /dev/null +++ b/src/bootstrap/primitives.h @@ -0,0 +1,60 @@ +#ifndef BDL_PRIMITIVES_H +#define BDL_PRIMITIVES_H + +// Function evaluation. +Object * eval(Environment *env, Object *root); + +// Evaluation functions. +Object * proc_quote(Environment *env, Object *obj); +Object * proc_eval(Environment *env, Object *obj); + +// Arithmetic. +Object * proc_sum(Environment *env, Object *obj); +Object * proc_sub(Environment *env, Object *obj); +Object * proc_mul(Environment *env, Object *obj); +Object * proc_div(Environment *env, Object *obj); +Object * proc_mod(Environment *env, Object *obj); + +// Printing. +Object * proc_display(Environment *env, Object *obj); +Object * proc_print(Environment *env, Object *obj); +Object * proc_newline(Environment *env, Object *obj); + +// Type checking. +Object * proc_is_boolean(Environment *env, Object *obj); +Object * proc_is_nil(Environment *env, Object *obj); +Object * proc_is_symbol(Environment *env, Object *obj); +Object * proc_is_string(Environment *env, Object *obj); +Object * proc_is_fixnum(Environment *env, Object *obj); +Object * proc_is_pair(Environment *env, Object *obj); +Object * proc_is_procedure(Environment *env, Object *obj); +Object * proc_is_error(Environment *env, Object *obj); + +// Logical operations. +Object * proc_not(Environment *env, Object *obj); +Object * proc_and(Environment *env, Object *obj); +Object * proc_or(Environment *env, Object *obj); +Object * proc_cond(Environment *env, Object *obj); +Object * proc_num_less_than(Environment *env, Object *obj); +Object * proc_num_greater_than(Environment *env, Object *obj); +Object * proc_num_lesseq_than(Environment *env, Object *obj); +Object * proc_num_greatereq_than(Environment *env, Object *obj); +Object * proc_num_equal(Environment *env, Object *obj); +Object * proc_equal(Environment *env, Object *obj); + +// List operations. +Object * proc_car(Environment *env, Object *obj); +Object * proc_cdr(Environment *env, Object *obj); +Object * proc_cons(Environment *env, Object *obj); +Object * proc_list(Environment *env, Object *obj); + +// Environment/variable manipulation. +Object * proc_define(Environment *env, Object *obj); +Object * proc_set(Environment *env, Object *obj); +Object * proc_lambda(Environment *env, Object *obj); +Object * proc_fun(Environment *env, Object *obj); + +// Runtinme configuration. +Object * proc_supress_errors(Environment *env, Object *obj); + +#endif // BDL_PRIMITIVES_H diff --git a/src/bootstrap/read_line.c b/src/bootstrap/read_line.c index 603bfee..03146ad 100644 --- a/src/bootstrap/read_line.c +++ b/src/bootstrap/read_line.c @@ -1,4 +1,5 @@ -#define RL_BUF_SIZE 1024 +#include "read_line.h" + static char readline_buf[RL_BUF_SIZE]; StringView diff --git a/src/bootstrap/read_line.h b/src/bootstrap/read_line.h new file mode 100644 index 0000000..160bce0 --- /dev/null +++ b/src/bootstrap/read_line.h @@ -0,0 +1,10 @@ +#ifndef BDL_READ_LINE_H +#define BDL_READ_LINE_H + +#include "string_view.h" + +StringView read_line(void); + +#define RL_BUF_SIZE 1024 + +#endif // BDL_READ_LINE_H diff --git a/src/bootstrap/singletons.c b/src/bootstrap/singletons.c new file mode 100644 index 0000000..eb9c397 --- /dev/null +++ b/src/bootstrap/singletons.c @@ -0,0 +1,17 @@ +#include "environment.h" +#include "gc.h" +#include "objects.h" + +// Global garbage collector singleton. +static GC gc; + +// Special singleton Objects. +static Object *obj_nil; +static Object *obj_true; +static Object *obj_false; +static Object *obj_err; +static Object *obj_quote; +static Object *proc_if; + +// Global environment. +static Environment *global_env; diff --git a/src/bootstrap/string_view.c b/src/bootstrap/string_view.c index 13ba9e0..39fabe9 100644 --- a/src/bootstrap/string_view.c +++ b/src/bootstrap/string_view.c @@ -1,7 +1,4 @@ -typedef struct StringView { - char *start; - size_t n; -} StringView; +#include "string_view.h" char sv_next(StringView *sv) { diff --git a/src/bootstrap/string_view.h b/src/bootstrap/string_view.h new file mode 100644 index 0000000..42273ab --- /dev/null +++ b/src/bootstrap/string_view.h @@ -0,0 +1,21 @@ +#ifndef BDL_STRINGVIEW_H +#define BDL_STRINGVIEW_H + +typedef struct StringView { + char *start; + size_t n; +} StringView; + +// Consume a character in the stream. +char sv_next(StringView *sv); + +// Check what is the current character in the stream. +char sv_peek(const StringView *sv); + +// Compare if the arguments are the same. +bool sv_equal(const StringView *a, const StringView *b); + +// Write a character to the given output stream. +void sv_write(const StringView *sv, FILE *file); + +#endif // BDL_STRINGVIEW_H -- cgit v1.2.1