Skip to content

Commit

Permalink
lone: extract system structure from interpreter
Browse files Browse the repository at this point in the history
When I started lone I tried to force myself to keep things as simple
as possible in order to maintain focus on the task at hand.
As a result, I wrote code that was tightly coupled on purpose because
I thought I'd get bogged down in library development if I didn't.
Or worse, build system development. Hey, it's certainly happened before.

I believe that approach was instrumental in conjuring up lone lisp
into the realm of existence. I have created a freestanding interpreter
that can successfully run programs. That's no small feat, no matter how
simple and slow it is. Now comes the truly difficult part: making it
useful for something other than running fibonacci calculations.
For that, I need to continuously improve the system, the interpreter,
the language, the modules and everything in-between.
It's truly a lifetime of work.

Before I start walking down that road, it is wise to finally pay back
some of the mounting tech debt in this project. I'll begin by separating
the lone lisp interpreter from the underlying lone system libraries.

Lone was initially conceived as a freestanding lisp interpreter.
As its complexity grew, a library of vital functions was implemented
in order to support basic program operations such as memory allocation
even in the absence of the standard C library. They were meant to be
tightly integrated with the interpreter but their utility increased
to the point they supported the development of tools such as lone-embed.

The utility of the lone system is likely to increase even further
as development of lone continues. My desire to use them to build
general Linux software is also likely to increase. Decoupling the
system functions from the interpreter is therefore desirable.

So I am reorganizing the project in order to make the lone runtime
usable without the lone interpreter. This commit marks the beginning
of the lone system, a library for freestanding Linux development.

The liblinux reborn, better than it ever was.

May this help pave the way for amazing Linux free software.
  • Loading branch information
matheusmoreira committed Jun 30, 2024
1 parent 6a4fdbb commit b424c96
Show file tree
Hide file tree
Showing 123 changed files with 5,133 additions and 4,820 deletions.
7 changes: 4 additions & 3 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ CC := $(CC)
LD ?= ld
LD := $(LD)

CFLAGS ?= -Wall -Wextra -Wpedantic -Wno-unused-function -Wno-unused-parameter -Wno-unknown-attributes
warnings := -Weverything -Wno-unused-function -Wno-unused-parameter -Wno-unknown-attributes -Wno-unsafe-buffer-usage -Wno-padded
CFLAGS ?= $(warnings)
CFLAGS := $(CFLAGS)

LDFLAGS ?=
Expand Down Expand Up @@ -64,7 +65,7 @@ files.sources.tests := $(filter $(directories.source.tests)/%,$(files.sources.al

targets.phony :=
targets.NR.list := $(directories.build)/NR.list
targets.NR.c := $(directories.build.include)/lone/NR.c
targets.NR.c := $(directories.build.include)/lone/lisp/modules/intrinsic/linux/NR.c
targets.NR := $(targets.NR.list) $(targets.NR.c)
targets.objects.lone := $(call source_to_object,$(files.sources.lone))
targets.objects.lone.entry_point := $(directories.build.objects)/lone.o
Expand Down Expand Up @@ -125,7 +126,7 @@ $(directories.build.tools)/%: $(directories.build.objects.tools)/%.o $(targets.o
$(directories.build.tests)/%: $(directories.build.objects.tests)/%.o $(targets.objects.lone) | directories
$(strip $(CC) $(flags.executable) $(CFLAGS.with_overrides) $(LDFLAGS) -o $@ $^)

$(call source_to_object,source/lone/modules/intrinsic/linux.c): $(targets.NR.c)
$(call source_to_object,source/lone/lisp/modules/intrinsic/linux.c): $(targets.NR.c)

$(targets.NR.c): $(targets.NR.list) scripts/NR.generate
scripts/NR.generate < $< > $@
Expand Down
40 changes: 2 additions & 38 deletions include/lone/definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,54 +7,18 @@
#include <linux/elf.h>
#include <asm/bitsperlong.h>

/* ╭────────────────────────────────────────────────────────────────────────╮
│ │
│ bits = 32 | bits = 64 │
│ digits = ceil(bits * log10(2)) = 10 | 20 │
│ │
╰────────────────────────────────────────────────────────────────────────╯ */
#if __BITS_PER_LONG == 64
#define DECIMAL_DIGITS_PER_LONG 20
#define LONE_DECIMAL_DIGITS_PER_LONG 20
#elif __BITS_PER_LONG == 32
#define DECIMAL_DIGITS_PER_LONG 10
#define LONE_DECIMAL_DIGITS_PER_LONG 10
#else
#error "Unsupported architecture"
#endif

#ifndef LONE_BUFFER_SIZE
#define LONE_BUFFER_SIZE 4096
#endif

#ifndef LONE_MEMORY_SIZE
#define LONE_MEMORY_SIZE (1024 * 1024)
#endif

#ifndef LONE_MEMORY_HEAP_VALUE_COUNT
#define LONE_MEMORY_HEAP_VALUE_COUNT 512
#endif

#ifndef LONE_ALIGNMENT
#define LONE_ALIGNMENT 16
#endif

#ifndef LONE_TABLE_LOAD_FACTOR
#define LONE_TABLE_LOAD_FACTOR 0.7
#endif

#ifndef LONE_TABLE_GROWTH_FACTOR
#define LONE_TABLE_GROWTH_FACTOR 2
#endif

#define LONE_PRIMITIVE(name) \
struct lone_value lone_primitive_ ## name \
( \
struct lone_lisp *lone, \
struct lone_value module, \
struct lone_value environment, \
struct lone_value arguments, \
struct lone_value closure \
)

#ifndef PT_LONE
// PT_LONE l o n e
#define PT_LONE 0x6c6f6e65
Expand Down
3 changes: 1 addition & 2 deletions include/lone/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

#include <lone/types.h>

void lone_hash_initialize(struct lone_lisp *lone, struct lone_bytes random);
size_t lone_hash(struct lone_lisp *lone, struct lone_value value);
void lone_hash_initialize(struct lone_system *system, struct lone_bytes random);

#endif /* LONE_HASH_HEADER */
2 changes: 1 addition & 1 deletion include/lone/hash/fnv_1a.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#error "Unsupported architecture"
#endif

void lone_hash_fnv_1a_initialize(struct lone_lisp *lone, struct lone_bytes random);
void lone_hash_fnv_1a_initialize(struct lone_system *system, struct lone_bytes random);

unsigned long
__attribute__((pure))
Expand Down
6 changes: 3 additions & 3 deletions include/lone/lisp.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
#define LONE_LISP_HEADER

#include <lone/types.h>
#include <lone/lisp/types.h>

/* ╭────────────────────────────────────────────────────────────────────────╮
│ │
│ The lone lisp structure represents the lone lisp interpreter. │
│ A pointer to this structure is passed to nearly every function. │
│ It must be initialized before everything else since the memory │
│ allocation system is not functional without it. │
│ It must be initialized before running lone lisp programs. │
│ │
╰────────────────────────────────────────────────────────────────────────╯ */

void lone_lisp_initialize(struct lone_lisp *lone, struct lone_bytes memory, void *stack, struct lone_bytes random);
void lone_lisp_initialize(struct lone_lisp *lone, struct lone_system *system, void *native_stack);

#endif /* LONE_LISP_HEADER */
4 changes: 2 additions & 2 deletions include/lone/lisp/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#ifndef LONE_LISP_CONSTANTS_HEADER
#define LONE_LISP_CONSTANTS_HEADER

#include <lone/types.h>
#include <lone/lisp/types.h>

struct lone_value lone_true(struct lone_lisp *lone);
struct lone_lisp_value lone_lisp_true(struct lone_lisp *lone);

#endif /* LONE_LISP_CONSTANTS_HEADER */
40 changes: 40 additions & 0 deletions include/lone/lisp/definitions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */

#ifndef LONE_LISP_DEFINITIONS_HEADER
#define LONE_LISP_DEFINITIONS_HEADER

#include <lone/definitions.h>

#define LONE_LISP_DECIMAL_DIGITS_PER_INTEGER LONE_DECIMAL_DIGITS_PER_LONG

#ifndef LONE_LISP_BUFFER_SIZE
#define LONE_LISP_BUFFER_SIZE 4096
#endif

#ifndef LONE_LISP_MEMORY_SIZE
#define LONE_LISP_MEMORY_SIZE (1024 * 1024)
#endif

#ifndef LONE_LISP_HEAP_VALUE_COUNT
#define LONE_LISP_HEAP_VALUE_COUNT 512
#endif

#ifndef LONE_LISP_TABLE_LOAD_FACTOR
#define LONE_LISP_TABLE_LOAD_FACTOR 0.7
#endif

#ifndef LONE_LISP_TABLE_GROWTH_FACTOR
#define LONE_LISP_TABLE_GROWTH_FACTOR 2
#endif

#define LONE_LISP_PRIMITIVE(name) \
struct lone_lisp_value lone_lisp_primitive_ ## name \
( \
struct lone_lisp *lone, \
struct lone_lisp_value module, \
struct lone_lisp_value environment, \
struct lone_lisp_value arguments, \
struct lone_lisp_value closure \
)

#endif /* LONE_LISP_DEFINITIONS_HEADER */
34 changes: 17 additions & 17 deletions include/lone/lisp/evaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#ifndef LONE_LISP_EVALUATOR_HEADER
#define LONE_LISP_EVALUATOR_HEADER

#include <lone/types.h>
#include <lone/lisp/types.h>

/* ╭────────────────────────┨ LONE LISP EVALUATOR ┠─────────────────────────╮
│ │
Expand All @@ -29,32 +29,32 @@
│ │
╰────────────────────────────────────────────────────────────────────────╯ */

struct lone_value lone_evaluate(
struct lone_lisp_value lone_lisp_evaluate(
struct lone_lisp *lone,
struct lone_value module,
struct lone_value environment,
struct lone_value value
struct lone_lisp_value module,
struct lone_lisp_value environment,
struct lone_lisp_value value
);

struct lone_value lone_evaluate_all(
struct lone_lisp_value lone_lisp_evaluate_all(
struct lone_lisp *lone,
struct lone_value module,
struct lone_value environment,
struct lone_value list
struct lone_lisp_value module,
struct lone_lisp_value environment,
struct lone_lisp_value list
);

struct lone_value lone_evaluate_in_module(
struct lone_lisp_value lone_lisp_evaluate_in_module(
struct lone_lisp *lone,
struct lone_value module,
struct lone_value value
struct lone_lisp_value module,
struct lone_lisp_value value
);

struct lone_value lone_apply(
struct lone_lisp_value lone_lisp_apply(
struct lone_lisp *lone,
struct lone_value module,
struct lone_value environment,
struct lone_value applicable,
struct lone_value arguments
struct lone_lisp_value module,
struct lone_lisp_value environment,
struct lone_lisp_value applicable,
struct lone_lisp_value arguments
);

#endif /* LONE_LISP_EVALUATOR_HEADER */
10 changes: 10 additions & 0 deletions include/lone/lisp/garbage_collector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */

#ifndef LONE_LISP_GARBAGE_COLLECTOR_HEADER
#define LONE_LISP_GARBAGE_COLLECTOR_HEADER

#include <lone/lisp/types.h>

void lone_lisp_garbage_collector(struct lone_lisp *lone);

#endif /* LONE_LISP_GARBAGE_COLLECTOR_HEADER */
10 changes: 10 additions & 0 deletions include/lone/lisp/hash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */

#ifndef LONE_LISP_HASH_HEADER
#define LONE_LISP_HASH_HEADER

#include <lone/lisp/types.h>

size_t lone_lisp_hash(struct lone_lisp *lone, struct lone_lisp_value value);

#endif /* LONE_LISP_HASH_HEADER */
13 changes: 13 additions & 0 deletions include/lone/lisp/heap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */

#ifndef LONE_LISP_HEAP_HEADER
#define LONE_LISP_HEAP_HEADER

#include <lone/lisp/definitions.h>
#include <lone/lisp/types.h>

void lone_lisp_heap_initialize(struct lone_lisp *lone);
struct lone_lisp_heap_value *lone_lisp_heap_allocate_value(struct lone_lisp *lone);
void lone_lisp_deallocate_dead_heaps(struct lone_lisp *lone);

#endif /* LONE_LISP_HEAP_HEADER */
42 changes: 42 additions & 0 deletions include/lone/lisp/module.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */

#ifndef LONE_LISP_MODULE_HEADER
#define LONE_LISP_MODULE_HEADER

#include <lone/lisp/definitions.h>
#include <lone/lisp/types.h>

/* ╭───────────────────────────┨ LONE / MODULES ┠───────────────────────────╮
│ │
│ Module importing, exporting and loading operations. │
│ │
╰────────────────────────────────────────────────────────────────────────╯ */

struct lone_lisp_value lone_lisp_module_null(struct lone_lisp *lone);
struct lone_lisp_value lone_lisp_module_for_name(struct lone_lisp *lone, struct lone_lisp_value name);
struct lone_lisp_value lone_lisp_module_load(struct lone_lisp *lone, struct lone_lisp_value name);
void lone_lisp_module_load_from_bytes(struct lone_lisp *lone, struct lone_lisp_value module, struct lone_bytes bytes);
void lone_lisp_module_load_null_from_file_descriptor(struct lone_lisp *lone, int file_descriptor);
void lone_lisp_module_load_null_from_standard_input(struct lone_lisp *lone);
void lone_lisp_module_path_push(struct lone_lisp *lone, struct lone_lisp_value directory);
void lone_lisp_module_path_push_c_string(struct lone_lisp *lone, char *directory);
void lone_lisp_module_path_push_va_list(struct lone_lisp *lone, size_t count, va_list directories);
void lone_lisp_module_path_push_all(struct lone_lisp *lone, size_t count, ...);

void lone_lisp_module_export(
struct lone_lisp *lone,
struct lone_lisp_value module,
struct lone_lisp_value symbol
);

void lone_lisp_module_set_and_export(
struct lone_lisp *lone,
struct lone_lisp_value module,
struct lone_lisp_value symbol,
struct lone_lisp_value value
);

LONE_LISP_PRIMITIVE(module_import);
LONE_LISP_PRIMITIVE(module_export);

#endif /* LONE_LISP_MODULE_HEADER */
11 changes: 11 additions & 0 deletions include/lone/lisp/modules/embedded.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */

#ifndef LONE_LISP_MODULES_EMBEDDED_HEADER
#define LONE_LISP_MODULES_EMBEDDED_HEADER

#include <lone/types.h>
#include <lone/lisp/types.h>

void lone_lisp_modules_embedded_load(struct lone_lisp *lone, lone_elf_segment *values);

#endif /* LONE_LISP_MODULES_EMBEDDED_HEADER */
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */

#ifndef LONE_MODULES_INTRINSIC_HEADER
#define LONE_MODULES_INTRINSIC_HEADER
#ifndef LONE_LISP_MODULES_INTRINSIC_HEADER
#define LONE_LISP_MODULES_INTRINSIC_HEADER

#include <lone/types.h>
#include <lone/lisp/types.h>

/* ╭─────────────────────┨ LONE / MODULES / INTRINSIC ┠─────────────────────╮
│ │
│ Initialization for built-in modules with essential functionality. │
│ │
╰────────────────────────────────────────────────────────────────────────╯ */

void lone_modules_intrinsic_initialize(
void lone_lisp_modules_intrinsic_initialize(
struct lone_lisp *lone,
int argument_count,
char **argument_vector,
char **environment,
struct lone_auxiliary_vector *auxiliary_vector
);

#endif /* LONE_MODULES_INTRINSIC_HEADER */
#endif /* LONE_LISP_MODULES_INTRINSIC_HEADER */
33 changes: 33 additions & 0 deletions include/lone/lisp/modules/intrinsic/bytes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */

#ifndef LONE_LISP_MODULES_INTRINSIC_BYTES_HEADER
#define LONE_LISP_MODULES_INTRINSIC_BYTES_HEADER

#include <lone/lisp/definitions.h>
#include <lone/lisp/types.h>

/* ╭────────────────────────────────────────────────────────────────────────╮
│ │
│ Bytes operations. │
│ │
╰────────────────────────────────────────────────────────────────────────╯ */

void lone_lisp_modules_intrinsic_bytes_initialize(struct lone_lisp *lone);

LONE_LISP_PRIMITIVE(bytes_new);

LONE_LISP_PRIMITIVE(bytes_read_u8);
LONE_LISP_PRIMITIVE(bytes_read_s8);
LONE_LISP_PRIMITIVE(bytes_read_u16);
LONE_LISP_PRIMITIVE(bytes_read_s16);
LONE_LISP_PRIMITIVE(bytes_read_u32);
LONE_LISP_PRIMITIVE(bytes_read_s32);

LONE_LISP_PRIMITIVE(bytes_write_u8);
LONE_LISP_PRIMITIVE(bytes_write_s8);
LONE_LISP_PRIMITIVE(bytes_write_u16);
LONE_LISP_PRIMITIVE(bytes_write_s16);
LONE_LISP_PRIMITIVE(bytes_write_u32);
LONE_LISP_PRIMITIVE(bytes_write_s32);

#endif /* LONE_LISP_MODULES_INTRINSIC_BYTES_HEADER */
Loading

0 comments on commit b424c96

Please sign in to comment.