157 lines
4.4 KiB
Markdown
157 lines
4.4 KiB
Markdown
# The Core Language
|
|
|
|
Core is an experimental systems programming language and compiler I built as one of my first "full" language projects.
|
|
|
|
It is intentionally kept here as a learning artifact: useful to read, fun to tinker with, and definitely not production-ready.
|
|
|
|
## What this project is
|
|
|
|
- A compiler written in C++
|
|
- A language with `.core` source files
|
|
- A C code generator backend (Core -> C)
|
|
- A small standard-module set in `modules/`
|
|
- A collection of examples in `examples/`
|
|
|
|
The compiler aims for simple syntax, explicit behavior, and debuggable output.
|
|
|
|
## Current status
|
|
|
|
- Archived hobby project / historical snapshot
|
|
- Works in many cases, but has known bugs and rough edges
|
|
- Best viewed as a language implementation study, not a stable toolchain
|
|
- I have made modifications over time and have not recently re-verified a clean build, so the project may not build out of the box
|
|
|
|
If you are new to compilers, this repo can still be valuable as a real-world "first serious compiler" codebase.
|
|
|
|
## Language highlights
|
|
|
|
- Static typing with strict checks
|
|
- Untyped compile-time constants (with big-int support in constant evaluation)
|
|
- Order-independent declarations
|
|
- Modules via `#import`
|
|
- Conditional loading (for example OS-specific modules)
|
|
- Slices, arrays, structs, unions, enums
|
|
- Multiple return values
|
|
- Operator overloading
|
|
- Runtime type information (`Type`, `GetTypeInfo`, `Any`)
|
|
|
|
## Tiny syntax taste
|
|
|
|
```core
|
|
#import "Multimedia.core"
|
|
|
|
main :: (): int
|
|
StartMultimedia(title = "Hello people!")
|
|
for UpdateMultimedia()
|
|
if Mu.key[Key.Escape].down
|
|
Mu.quit = true
|
|
|
|
for y := 0, y < Mu.window.y, y += 1
|
|
for x := 0, x < Mu.window.x, x += 1
|
|
Mu.screen[x + y * Mu.window.x] = 0xFFFFFF00
|
|
|
|
return 0
|
|
```
|
|
|
|
For more examples, see:
|
|
|
|
- `examples/language_basics.core`
|
|
- `examples/arrays_and_slices.core`
|
|
- `examples/operator_overloading.core`
|
|
- `examples/runtime_type_information.core`
|
|
|
|
## Compiler pipeline
|
|
|
|
At a high level:
|
|
|
|
1. Lex + parse `.core` source into AST
|
|
2. Resolve symbols and types
|
|
3. Generate C code (`generated_main.c`)
|
|
4. Optionally compile generated C with `clang`
|
|
|
|
One design goal was debugger friendliness, so generated C includes line synchronization for stepping through source.
|
|
|
|
## Building the compiler
|
|
|
|
### Windows
|
|
|
|
```bat
|
|
build.bat
|
|
```
|
|
|
|
This builds the compiler executable in `build/`.
|
|
|
|
### Linux
|
|
|
|
`build_unix.sh` exists, but the repo layout changed over time. If it fails, build manually:
|
|
|
|
```bash
|
|
clang src/language/core_main.cpp -O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o core.out
|
|
```
|
|
|
|
## Running it
|
|
|
|
Compile one source file to C:
|
|
|
|
```bash
|
|
./core.out examples/language_basics.core
|
|
```
|
|
|
|
or on Windows:
|
|
|
|
```bat
|
|
build\main.exe examples\language_basics.core
|
|
```
|
|
|
|
This produces `generated_main.c`.
|
|
|
|
Then compile the generated C yourself (example):
|
|
|
|
```bash
|
|
clang generated_main.c -Wall -Wno-unused-function -Wno-parentheses-equality -g -o a.out
|
|
```
|
|
|
|
There is also a test mode:
|
|
|
|
```bash
|
|
./core.out -testing
|
|
```
|
|
|
|
which iterates through `examples/` (and `tests/` if present), compiles, and runs them.
|
|
|
|
## Repository map
|
|
|
|
- `src/language/` - compiler front/mid/back-end implementation
|
|
- `src/base/` - memory, strings, containers, utilities
|
|
- `src/os/` - OS abstraction layer (Windows/Linux)
|
|
- `modules/` - language modules and platform bindings
|
|
- `examples/` - sample Core programs
|
|
- `tools/meta.py` - meta tables used to generate token/keyword boilerplate
|
|
|
|
## Known rough edges
|
|
|
|
- Project paths changed over time; some scripts may need adjustment
|
|
- Windows support is more mature than Linux in some areas
|
|
- No polished package manager or full modern tooling around the language
|
|
- Feature set is incomplete (for example, no finished generics system)
|
|
|
|
## Why keep this repo public?
|
|
|
|
Because complete-but-imperfect projects are useful. This codebase captures:
|
|
|
|
- early language design decisions
|
|
- practical compiler architecture tradeoffs
|
|
- how a transpile-to-C strategy can speed up experimentation
|
|
|
|
If you are building your own language, you may find useful ideas here (and just as many cautionary tales).
|
|
|
|
## Learning resources that inspired this project
|
|
|
|
- https://bitwise.handmade.network/
|
|
- https://hero.handmade.network/episode/code/day206/
|
|
- https://www.youtube.com/watch?v=TH9VCN6UkyQ&list=PLmV5I2fxaiCKfxMBrNsU1kgKJXD3PkyxO
|
|
- A Retargetable C Compiler: Design and Implementation (Fraser/Hanson)
|
|
- https://github.com/c3lang/c3c
|
|
- https://go.dev/blog/constants
|
|
- https://github.com/gingerbill/odin
|