Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Compile-time reflection #108

Merged
merged 9 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ jobs:
- name: Install Tree-sitter (with runtime)
run: |
npm install -g tree-sitter-cli
curl -fsSL https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.22.6.tar.gz | tar -xz
curl -fsSL https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.23.0.tar.gz | tar -xz
cd tree-sitter-*
make
sudo make install
Expand Down Expand Up @@ -115,7 +115,7 @@ jobs:
- name: Install Tree-sitter (with runtime)
run: |
npm install -g tree-sitter-cli
curl -fsSL https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.22.6.tar.gz | tar -xz
curl -fsSL https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.23.0.tar.gz | tar -xz
cd tree-sitter-*
make
sudo make install
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Install Tree-sitter (with runtime)
run: |
npm install -g tree-sitter-cli
curl -fsSL https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.22.6.tar.gz | tar -xz
curl -fsSL https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.23.0.tar.gz | tar -xz
cd tree-sitter-*
make -j8
sudo make install
Expand Down
76 changes: 42 additions & 34 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@ members = [

[profile.coverage]
inherits = "dev"

[profile.profiling]
inherits = "release"
debug = true
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ RUN mkdir -p /etc/apt/keyrings && \
RUN cargo install tree-sitter-cli

WORKDIR /alumina/deps
RUN curl -fsSL https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.22.6.tar.gz | tar -xz
RUN curl -fsSL https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.23.0.tar.gz | tar -xz
RUN cd tree-sitter-* && make -j8 && make install && ldconfig
RUN curl -fsSL https://github.com/ianlancetaylor/libbacktrace/archive/master.tar.gz | tar -xz
RUN cd libbacktrace-* && ./configure && make -j8 && make install
Expand Down
5 changes: 2 additions & 3 deletions MISSING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
- Better error messages for why recursive functions can't be inlined (rather than just "Unpopulated symbol")
- stack overflow in codegen stage because infinite size recursive structs are not rejected during monomorphization
- could be a similar issue with protocols, though these are more coservative vis-a-vis recursion
- Whole ZST and divergence handling might still be buggy, in particular, uninitialized variables of `!` type might be problematic since lowering is quite liberal with making temporary name bindings for various stuff.
- It might be fine now, it's been a while since I last ran into a ZST bug
- if tentative monomorphization fails (e.g. error), but type inference still succeeds, we are left with unpopulated symbols
- this is now especially an issue with `when` expressions which do tentative mono during proto bound checking
- This is a big problem, unfortunately there is no easy solution with the current `mono` architecture
Expand All @@ -20,7 +18,6 @@
- Right now there is not even a good error message to say that this is not supported, just a cryptic "unbound placeholder" during mono
- Recursive local functions lead to stack overflow as mono monomorphizes them over and over again. The local item handling for functions was designed for lambdas that cannot be recursive (without indirection)
- Macros cannot define local items or use anonymous function. This is quite bad and should be fixed.
- Promoting all variables to function scope is a bit of a unique feature of Alumina and I like it (comes in quite handy for autoref - can take an address of any rvalue and defer), but it may inhibit some optimizations downstream.
- `if opt.is_some { opt.inner }` and `if res.is_ok() { res.unwrap() }` do not spark joy. Full pattern matching is overkill, but this is very common and
deserves a better idiom.
- a coherent story for operator overloading
Expand Down Expand Up @@ -90,6 +87,8 @@
- full Hindley-Milner type inference. Global type inference will pretty much require a full rewrite of `mono`, so whis would be a massive project, but it would also be super awesome to have
- Type inference gaps are a big pain point right now, especially since there are so many places where adding a type hint is not even possible (e.g. when chaining methods).
- some sort of type-checking of pre-monomorphized functions might be useful. they can have pretty blatant errors inside that would fail to compile no matter what the type parameters are, but you don't know until you actually try to use it.
- ... (et cetera) as a tuple splat operator (types and expressions)
- attributes in reflection

## Tooling

Expand Down
22 changes: 11 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ else ifdef FAST_DEBUG
CARGO_TARGET_DIR = target/release
CFLAGS += -g0
ALUMINA_FLAGS += --debug
else ifdef PROFILING
BUILD_DIR = $(BUILD_ROOT)/profiling
CARGO_FLAGS += --profile profiling
CARGO_TARGET_DIR = target/profiling
CFLAGS += -g3 -fPIE -rdynamic -O3
ALUMINA_FLAGS += --debug
else ifdef COVERAGE
CC ?= clang
BUILD_DIR = $(BUILD_ROOT)/coverage
Expand All @@ -34,7 +40,7 @@ endif

LDFLAGS ?= -lm
ifndef STD_BACKTRACE
ALUMINA_FLAGS += --cfg use_libbacktrace
ALUMINA_FLAGS += --cfg libbacktrace
LDFLAGS += -lbacktrace
endif
ifndef NO_THREADS
Expand All @@ -49,7 +55,7 @@ else
endif

ifdef TIMINGS
ALUMINA_FLAGS += --timings
ALUMINA_FLAGS += -Ztimings
endif

# Convert a list of source files to a list of <module>=<file> pairs. mod.alu files are treated
Expand Down Expand Up @@ -255,7 +261,7 @@ install: $(ALUMINA_BOOT) $(SYSROOT_FILES)
alumina-boot: $(ALUMINA_BOOT)
ln -sf $(ALUMINA_BOOT) $@

.PHONY: test-std test-examples test-alumina-boot test-libraries test-lang test
.PHONY: test-std test-alumina-boot test-libraries test-lang test

test-std: alumina-boot $(STDLIB_TESTS)
$(STDLIB_TESTS) $(TEST_FLAGS)
Expand Down Expand Up @@ -293,24 +299,18 @@ quick: $(BUILD_DIR)/quick
BENCH_CMD = ./tools/bench.py -n$(if $(TIMES),$(TIMES),20) $(if $(MARKDOWN),--markdown,)

bench-std: $(ALUMINA_BOOT) $(SYSROOT_FILES)
$(BENCH_CMD) $(ALUMINA_BOOT) $(ALUMINA_FLAGS) --sysroot $(SYSROOT) --timings --cfg test --cfg test_std --output /dev/null
$(BENCH_CMD) $(ALUMINA_BOOT) $(ALUMINA_FLAGS) --sysroot $(SYSROOT) -Ztimings --cfg test --cfg test_std --output /dev/null

bench-std-cached: $(ALU_TEST_STD_DEPS)
@ if [ -z "$(CACHE_AST)" ]; then \
echo "ERROR: CACHE_AST=1 is not set"; \
exit 1; \
fi
$(BENCH_CMD) $(ALUMINA_BOOT) $(ALUMINA_FLAGS_TEST_STD) --timings --cfg test --cfg test_std --output /dev/null
$(BENCH_CMD) $(ALUMINA_BOOT) $(ALUMINA_FLAGS_TEST_STD) -Ztimings --cfg test --cfg test_std --output /dev/null

bench-std-cc: $(STDLIB_TESTS).c $(MINICORO)
$(BENCH_CMD) $(CC) $(CFLAGS) -o/dev/null $^ $(LDFLAGS)

$(BUILD_DIR)/flamegraph.svg: $(ALUMINA_BOOT) $(SYSROOT_FILES)
CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph \
-o $@ -- $(ALUMINA_FLAGS) --sysroot $(SYSROOT) --timings --cfg test --cfg test_std --output /dev/null

flamegraph: $(BUILD_DIR)/flamegraph.svg

## ------------------------------ Diag tests ----------------------------

DIAG_CMD = ./tools/diag.py
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Non-exhaustive list of distinguishing features:
- [Compile-time constant evaluation](./examples/constants.alu) (including loops, function calls, etc.)
- [Unified call syntax](https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax) for functions and macros in scope
- [Defer expressions](./examples/defer_and_move.alu)
- [Reflection](./examples/reflection.alu)

Alumina is heavily inspired by Rust, especially in terms of syntax and standard library API. Unlike Rust, however, Alumina is not memory-safe and it requires manual memory management.

Expand Down Expand Up @@ -126,13 +127,14 @@ Finished:
- [TCP/IP sockets](https://docs.alumina-lang.net/std/net)
- [random number generation](https://docs.alumina-lang.net/std/random)
- [unit testing framework](https://docs.alumina-lang.net/test)
- [reflection](https://docs.alumina-lang.net/std/typing)

To be done:

- Standard library is only usable on Unixes (tested on Linux, macOS and Android)
- Compiler driver (something like Rust's `cargo`)
- A good story for third-party libraries (something like `crates.io` maybe?)
- Various rough edges and missing features
- Various rough edges, bugs and missing features

Full list of missing features, open questions, bugs and ideas for the future is in [MISSING.md](./MISSING.md)

Expand Down Expand Up @@ -173,7 +175,7 @@ Additionally, to compile the tools, such as `alumina-doc`, these prerequisites a
sudo make install
# sudo ldconfig
```
- [`libbacktrace`](https://github.com/ianlancetaylor/libbacktrace/) is an optional dependency for nice stack backtraces on panics. If disabled, pass `STD_BACKTRACE=1` when builting `aluminac` to use the libc's backtrace function instead.
- [`libbacktrace`](https://github.com/ianlancetaylor/libbacktrace/) is an optional dependency for nice stack backtraces on panics. If disabled, pass `STD_BACKTRACE=1` when building `aluminac` to use the libc's backtrace function instead.
```bash
git clone https://github.com/ianlancetaylor/libbacktrace
cd libbacktrace
Expand Down
Loading
Loading