summaryrefslogtreecommitdiff
path: root/work-in-progress/liblali.h
diff options
context:
space:
mode:
authorDaniel Cerqueira <dan.git@lispclub.com>2025-06-10 20:22:31 +0100
committerDaniel Cerqueira <dan.git@lispclub.com>2025-06-10 20:22:31 +0100
commite20e88b3c9fefc84c4af7f6f047cf34ab2a52888 (patch)
treee7081eaf698dd0c00bcdf10e5bd2ef9907eaf80c /work-in-progress/liblali.h
parent630bc6c0eafab95302f044a642447f9d02800474 (diff)
remove work-in-progress/
Diffstat (limited to 'work-in-progress/liblali.h')
-rw-r--r--work-in-progress/liblali.h337
1 files changed, 0 insertions, 337 deletions
diff --git a/work-in-progress/liblali.h b/work-in-progress/liblali.h
deleted file mode 100644
index 026036a..0000000
--- a/work-in-progress/liblali.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * lali (Lali Another Lisp Implementation)
- *
- * Author: Daniel Cerqueira (dan.git@lispclub.com)
- * Maintainer: Daniel Cerqueira (dan.git@lispclub.com)
- * Version: 0.0
- * Keywords: lali, lisp, implementation, interpreter, lisp1.5,
- * computer programming language
- * Homepage: https://gitlab.com/alexandre1985/lali
- * SPDX-License-Identifier: GPL-3.0-or-later
- *
- * Copyright (C) 2025 Daniel Cerqueira
- *
- * This file is part of lali.
- *
- * lali is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; either version 3 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, see <https://www.gnu.org/licenses/>.
- *
- *
- * lali software is based on tiny-lisp <https://github.com/matp/tiny-lisp/>
- * version from 2016, written by Matthias Pirstitz, which is released to public
- * domain under Unlicense <https://unlicense.org/>.
- */
-
-#ifndef LIBLALI_H
-#define LIBLALI_H
-
-#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
-#define MAP_ANONYMOUS MAP_ANON
-#endif
-
-typedef struct Object Object;
-
-typedef enum Type {
- TYPE_NUMBER,
- TYPE_STRING,
- TYPE_SYMBOL,
- TYPE_CONS,
- TYPE_LAMBDA,
- TYPE_MACRO,
- TYPE_PRIMITIVE,
- TYPE_ENV
-} Type;
-
-struct Object {
- Type type;
- size_t size;
- union {
- struct { double number; }; // number
- struct { char string[sizeof (Object *[3])]; }; // string, symbol
- struct { Object *car, *cdr; }; // cons
- struct { Object *closure, *params, *body, *env; }; // lambda, macro
- struct { int primitive; char *name; }; // primitive
- struct { Object *parent, *vars, *vals; }; // env
- struct { Object *forward; }; // forwarding pointer
- };
-};
-
-extern Object *symbols;
-extern Object *nil;
-extern Object *n;
-extern Object *t;
-extern Object *f;
-
-typedef enum StreamType {
- STREAM_TYPE_STRING,
- STREAM_TYPE_FILE
-} StreamType;
-
-typedef struct Stream {
- StreamType type;
- char *buffer;
- int fd;
- size_t length, capacity;
- off_t offset, size;
-} Stream;
-
-typedef struct Memory {
- size_t capacity, fromOffset, toOffset;
- void *fromSpace, *toSpace;
-} Memory;
-
-extern jmp_buf exceptionEnv;
-
-// EXCEPTION HANDLING /////////////////////////////////////////////////////////
-
-#define exception(...) exceptionWithObject(NULL, __VA_ARGS__)
-
-#ifdef __GNUC__
-void exceptionWithObject(Object *object, char *format, ...)
- __attribute__ ((noreturn, format(printf, 2, 3)));
-#endif
-
-void exceptionWithObject(Object *object, char *format, ...);
-
-// GARBAGE COLLECTION /////////////////////////////////////////////////////////
-
-/* This implements Cheney's copying garbage collector, with which memory is
- * divided into two equal halves (semispaces): from- and to-space. From-space
- * is where new objects are allocated, whereas to-space is used during garbage
- * collection.
- *
- * When garbage collection is performed, objects that are still in use (live)
- * are copied from from-space to to-space. To-space then becomes the new
- * from-space and vice versa, thereby discarding all objects that have not
- * been copied.
- *
- * Our garbage collector takes as input a list of root objects. Objects that
- * can be reached by recursively traversing this list are considered live and
- * will be moved to to-space. When we move an object, we must also update its
- * pointer within the list to point to the objects new location in memory.
- *
- * However, this implies that our interpreter cannot use raw pointers to
- * objects in any function that might trigger garbage collection (or risk
- * causing a SEGV when accessing an object that has been moved). Instead,
- * objects must be added to the list and then only accessed through the
- * pointer inside the list.
- *
- * Thus, whenever we would have used a raw pointer to an object, we use a
- * pointer to the pointer inside the list instead:
- *
- * function: pointer to pointer inside list (Object **)
- * |
- * v
- * list of root objects: pointer to object (Object *)
- * |
- * v
- * semispace: object in memory
- *
- * GC_ROOTS and GC_PARAM are used to pass the list from function to function.
- *
- * GC_TRACE adds an object to the list and declares a variable which points to
- * the objects pointer inside the list.
- *
- * GC_TRACE(gcX, X): add object X to the list and declare Object **gcX
- * to point to the pointer to X inside the list.
- */
-
-#define GC_ROOTS gcRoots
-#define GC_PARAM Object *GC_ROOTS
-
-#define GC_PASTE1(name, id) name ## id
-#define GC_PASTE2(name, id) GC_PASTE1(name, id)
-#define GC_UNIQUE(name) GC_PASTE2(name, __LINE__)
-
-#define GC_TRACE(name, init) \
- Object GC_UNIQUE(GC_ROOTS) = { TYPE_CONS, .car = init, .cdr = GC_ROOTS }; \
- Object **name = &GC_UNIQUE(GC_ROOTS).car; \
- GC_ROOTS = &GC_UNIQUE(GC_ROOTS)
-
-Object *gcMoveObject(Object *object);
-
-void gc(GC_PARAM);
-
-// MEMORY MANAGEMENT //////////////////////////////////////////////////////////
-
-size_t memoryAlign(size_t size, size_t alignment);
-
-Object *memoryAllocObject(Type type, size_t size, GC_PARAM);
-
-// CONSTRUCTING OBJECTS ///////////////////////////////////////////////////////
-
-Object *newObject(Type type, GC_PARAM);
-
-Object *newObjectFrom(Object **from, GC_PARAM);
-
-Object *newNumber(double number, GC_PARAM);
-
-Object *newObjectWithString(Type type, size_t size, GC_PARAM);
-
-Object *newStringWithLength(char *string, size_t length, GC_PARAM);
-
-Object *newString(char *string, GC_PARAM);
-
-Object *newCons(Object **car, Object **cdr, GC_PARAM);
-
-Object *newSymbolWithLength(char *string, size_t length, GC_PARAM);
-
-Object *newSymbol(char *string, GC_PARAM);
-
-Object *newObjectWithClosure(Type type, Object **closure, Object **params, Object **body, Object **env, GC_PARAM);
-
-Object *newLambda(Object **closure, Object **params, Object **body, Object **env, GC_PARAM);
-
-Object *newMacro(Object **closure, Object **params, Object **body, Object **env, GC_PARAM);
-
-Object *newPrimitive(int primitive, char *name, GC_PARAM);
-
-Object *newEnv(Object **func, Object **vals, GC_PARAM);
-
-// STREAM INPUT ///////////////////////////////////////////////////////////////
-
-/* The purpose of the stream functions is to provide an abstraction over file
- * and string inputs. In order to accommodate the REPL, we need to be able to
- * process character special files (such as stdin) character by character and
- * evaluate expressions as they are being entered.
- */
-
-int streamGetc(Stream *stream);
-
-Stream *streamSeek(Stream *stream, int offset);
-
-int streamPeek(Stream *stream);
-
-// READING S-EXPRESSIONS //////////////////////////////////////////////////////
-
-Object *readExpr(Stream *stream, GC_PARAM);
-
-int readNext(Stream *stream);
-
-int initialReadNext(Stream *stream);
-
-int peekForward(Stream *stream, bool shebang);
-
-int peekNext(Stream *stream);
-
-int readWhile(Stream *stream, int (*predicate)(int ch));
-
-Object *readUnary(Stream *stream, char *symbol, GC_PARAM);
-
-Object *readString(Stream *stream, GC_PARAM);
-
-int isSymbolChar(int ch);
-
-Object *readNumberOrSymbol(Stream *stream, GC_PARAM);
-
-Object *reverseList(Object *list);
-
-Object *readList(Stream *stream, GC_PARAM);
-
-
-// WRITING OBJECTS ////////////////////////////////////////////////////////////
-
-void writeObject(Object *object, bool readably, FILE *file);
-
-// ENVIRONMENT ////////////////////////////////////////////////////////////////
-
-/* An environment consists of a pointer to its parent environment (if any) and
- * two parallel lists - vars and vals.
- *
- * Case 1 - vars is a regular list:
- * vars: (a b c), vals: (1 2 3) ; a = 1, b = 2, c = 3
- *
- * Case 2 - vars is a dotted list:
- * vars: (a b . c), vals: (1 2) ; a = 1, b = 2, c = nil
- * vars: (a b . c), vals: (1 2 3) ; a = 1, b = 2, c = (3)
- * vars: (a b . c), vals: (1 2 3 4 5) ; a = 1, b = 2, c = (3 4 5)
- *
- * Case 3 - vars is a symbol:
- * vars: a, vals: nil ; a = nil
- * vars: a, vals: (1) ; a = (1)
- * vars: a, vals: (1 2 3) ; a = (1 2 3)
- *
- * Case 4 - vars and vals are both nil:
- * vars: nil, vals: nil
- */
-
-Object *envLookup(Object *var, Object *env);
-
-Object *envAdd(Object **var, Object **val, Object **env, GC_PARAM);
-
-Object *envSet(Object **var, Object **val, Object **env, GC_PARAM);
-
-// PRIMITIVES /////////////////////////////////////////////////////////////////
-
-Object *primitiveSpace(Object **args, GC_PARAM);
-
-Object *primitiveAtom(Object **args, GC_PARAM);
-
-/* Object *primitiveEq(Object **args, GC_PARAM);
- */
-
-Object *primitiveDif(Object **args, GC_PARAM);
-
-Object *primitiveCar(Object **args, GC_PARAM);
-
-Object *primitiveCdr(Object **args, GC_PARAM);
-
-Object *primitiveCons(Object **args, GC_PARAM);
-
-Object *primitivePrint(Object **args, GC_PARAM);
-
-Object *primitivePrinc(Object **args, GC_PARAM);
-
-Object *primitiveNewline(Object **args, GC_PARAM);
-
-Object *primitiveRead(Object **args, GC_PARAM);
-
-Object *name(Object **args, GC_PARAM);
-
-
-// EVALUATION /////////////////////////////////////////////////////////////////
-
-/* Scheme-style tail recursive evaluation. evalProg, evalProgs, evalCond, and
- * PRIMITIVE_EVAL, return the object in the tail recursive position to be
- * evaluated by evalExpr. Macros are expanded in-place the first time they are
- * evaluated.
- */
-
-Object *evalExpr(Object **object, Object **env, GC_PARAM);
-
-Object *evalSet(Object **args, Object **env, GC_PARAM);
-
-Object *evalProg(Object **args, Object **env, GC_PARAM);
-
-Object *progs1(Object **stop, Object **body, Object **env, GC_PARAM);
-
-Object *evalProgs(Object **args, Object **env, GC_PARAM);
-
-Object *evalCond(Object **args, Object **env, GC_PARAM);
-
-Object *evalFill(Object **args, Object **env, GC_PARAM);
-
-Object *evalLambda(Object **args, Object **env, GC_PARAM);
-
-Object *evalMacro(Object **args, Object **env, GC_PARAM);
-
-Object *expandMacro(Object **macro, Object **args, GC_PARAM);
-
-Object *expandMacroTo(Object **macro, Object **args, Object **cons, GC_PARAM);
-
-Object *evalList(Object **args, Object **env, GC_PARAM);
-
-Object *evalRead(GC_PARAM);
-
-Object *newRootEnv(GC_PARAM);
-
-#endif