Compare commits
No commits in common. "move-notice" and "main" have entirely different histories.
move-notic
...
main
133
README.md
133
README.md
|
@ -1,3 +1,134 @@
|
|||
<!--
|
||||
|
||||
Please keep this document correctly word-wrapped at 70 columns and
|
||||
with no trailing whitespace or blank lines at the end! Merge requests
|
||||
with modifications to this document will be not be accepted until it
|
||||
is formatted correctly! ~~abb
|
||||
|
||||
-->
|
||||
|
||||
# Drim
|
||||
|
||||
Drim is now hosted at [[https://codeberg.org/gkgoat/drim]].
|
||||
Drim is a programming language designed to have the very high-level
|
||||
ergonomics and provable correctness of a purely functional language,
|
||||
while maintaining speed using strictly-controlled, deterministic
|
||||
memory management. The language is capable of compiling to C (and
|
||||
possibly other languages in the future), allowing for maximum
|
||||
portability without having to write a new backend for the compiler for
|
||||
every possible target; also, the compiler and tooling will eventually
|
||||
be rewritten in Drim to allow for maximum portability.
|
||||
|
||||
Syntactically, the language primarily resembles a mixture between
|
||||
standard ML and Rust; the language always ignores whitespace.
|
||||
|
||||
Drim is licensed under the GNU General Public License, version 3 or
|
||||
later. See the `LICENSE` file for details.
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
// Calculates the nth fibonacci number.
|
||||
def fibonacci (n: U32) : U32 = match n {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
n => fibonacci (n - 2) + fibonacci (n - 1),
|
||||
};
|
||||
|
||||
// Prompts the user for a number n, and prints the Fibonacci numbers up
|
||||
// to n.
|
||||
def fibPrompt = do {
|
||||
print "Enter a number: ";
|
||||
num <- read <$> getLine;
|
||||
sequence_ (print . fibonacci <$> (0 .. num));
|
||||
};
|
||||
|
||||
// Program entry point.
|
||||
def main : IO ()
|
||||
= fibPrompt;
|
||||
```
|
||||
|
||||
Note that type annotations are always optional; here they're given for
|
||||
`fibonacci` and `main` for illustrative purposes, but omitted for
|
||||
`fibPrompt` (for which the compiler infers the return type `IO ()`).
|
||||
|
||||
## Tools
|
||||
|
||||
This repository contains the following tools:
|
||||
- `drimc-rs`, the Stage-1 Drim compiler, written in Rust. This can be
|
||||
used as a binary with a fairly standard compiler CLI, or as a
|
||||
library for use in other Rust programs.
|
||||
|
||||
The following tools do not exist yet, but are planned:
|
||||
- `drimc`, the main Drim compiler written in Drim. This program
|
||||
supports a superset of the behavior of `drimc-rs`, and exposes a
|
||||
library that can be used by other Drim programs in addition to a the
|
||||
compiler CLI.
|
||||
- `drim`, the interactive Drim interpreter, a wrapper around `drimc`.
|
||||
- `drimd`, the Language Server Protocol (LSP) server for Drim code
|
||||
support in editors, supporting definition peeking and lookup,
|
||||
renaming variables and modules, etc.
|
||||
- `drimfmt`, the standard formatter for Drim code; all Drim code used
|
||||
in this repository must be formatted with `drimfmt`, and its use is
|
||||
recommended for other projects.
|
||||
- `drimdoc`, the documentation generator.
|
||||
- `drim-mode`, an Emacs mode for editing Drim code, supporting syntax
|
||||
highlighting, automatic indentation, some basic keybindings for
|
||||
common tasks, Emacs-side LSP integration for communicating with
|
||||
`drimd`, and a collection of `yasnippet` snippets for inserting
|
||||
common Drim constructs.
|
||||
- `drim-vsc`, Visual Studio Code plugins and tools for editing
|
||||
AlexScript code.
|
||||
- `drim-vim`, tools and configuration files for optimizing Vim
|
||||
and Neovim for editing Drim code.
|
||||
|
||||
## Language features
|
||||
|
||||
The language is mostly influenced by Rust and Haskell: it has strict
|
||||
safety requirements and borrow-checked memory management like that of
|
||||
Rust, but its syntax and type system are similar to those of Haskell.
|
||||
|
||||
Some features the language will most likely have:
|
||||
- All functions are pure by default; side effects are chained together
|
||||
using an `IO` monad.
|
||||
- Despite the language's purity, expressions will be strictly
|
||||
evaluated to provide more programmer control.
|
||||
- Different monads represent different levels of safety, and can be
|
||||
converted using functions marked as `UNSAFE`. The intention is that
|
||||
code can be audited by manually checking that all the `UNSAFE`
|
||||
transformations are sound, and code that contains no `UNSAFE`
|
||||
function calls are guaranteed to satisfy varying definitions of
|
||||
soundness:
|
||||
- The `IO` monad represents computations that might have side
|
||||
effects on the real world. If a computation of type `IO` is known
|
||||
by the programmer to not have side effects on the real world, then
|
||||
it can be converted to a pure computation using the standard
|
||||
library function `UNSAFE_assertPure : IO a -> a`.
|
||||
- The `MemoryUnsafe` monad represents computations that might read
|
||||
from or write to memory that is not allocated correctly: for
|
||||
example, `readPtr`, which reads from a raw pointer, is of type
|
||||
`MemoryUnsafe a` because the pointer is not known to be valid. If
|
||||
a computation has been confirmed to be safe by the programmer, it
|
||||
can be converted to an `IO` computation using
|
||||
`UNSAFE_assertMemorySafe : MemoryUnsafe a -> IO a`.
|
||||
- Further safety monads may be added in the future.
|
||||
- The language achieves good performance by guaranteeing a number of
|
||||
optimizations:
|
||||
- Since the language uses a linear type system, garbage collection
|
||||
is not done; instead, values are stored on the stack unless
|
||||
explicitly declared to be on the heap, and heap-stored values are
|
||||
cleaned up at deterministic points as calculated at compile time.
|
||||
- Functions of type `Fn t -> t` are optimized into functions that
|
||||
operate on pointers to `t`, i.e., notionally, `Fn (*mut t) -> ()`,
|
||||
where `*mut t` is a mutable pointer to a type `t`.
|
||||
- Types that contain an optional, non-null pointer like `Option (Box
|
||||
a)`, `Option (Ref a)`, etc., are optimized into nullable pointers.
|
||||
- Since the language has no loops, the compiler guarantees
|
||||
optimization of tail-call recursion to loops on all functions, as
|
||||
is standard in functional languages.
|
||||
|
||||
## Compilation
|
||||
|
||||
When invoked with no flags, Drim by default compiles source code
|
||||
directly to code that is valid C and C++, then calls the system C
|
||||
compiler to generate an object file, then calls the system linker to
|
||||
generate an executable file.
|
||||
|
|
Loading…
Reference in a new issue