Tiny statically-typed (embeddable) language.
- Language to replace Lua where more stable performance and control is needed.
- Language to replace C with language of similar control, but better possibility of code organization (packages or namespaces).
- Language that maps APIs and paradigms to the script with zero friction.
Project is not being made in isolation, it is made as a direct requirement of Runt project. Runt needs this for it's configuration, command customization and extensions.
- Go -- Love syntax and a feature set of Go (minus garbage collection)
- WebAssembly -- Love most of the design, VM takes big chunk of notes from this.
- Quake3 VM -- Love idea of compiling VM to x64 at runtime, VM/x64 takes notes from this.
- Bitwise's Ion -- Ideas and knowledge stolen with love.
Implementation:
- Embeddable.
- STB-style libaries.
- Minimal binary size.
- No cstdlib dependency.
- No LLVM dependency.
Language:
- Simple Go-inspired syntax.
- Type inference.
- No built-in memory management.
- Packages.
- Most of what C does.
- Bring your own library code.
- Compile time execution.
Project is planned to be split to STB-style modules:
ri.h- Library
- Lexing, Parsing, Resolution, Validation.
- Take string, output AST or error.
ri-to-vm.h- Library
- Take RiAST, output RiVM module blob.
ri-vm.h- Library
- Take RiVM blob, run it.
Standalone programs:
ri-to-c.c- Program
- Take RiAST, output C file(s).
- Run compiler.
- Run executable.
The work is split to phases:
- Phase 1 AST: Basics (current)
- Lexer, parser and resolver basics
- All statements
- Simple scalar types
- Draft VM compilation
- Phase 2 AST: Compound types
- Enum
- Pointer
- Struct
- Union
- Initializers
- Phase 3 AST: Slices
- C arrays with count
- Packages
- Phase 4 VM: Compilation and Execution
- Compiling to VM
- Integration with Runt using simple AST interpreter for initializers.
- Later:
- Compiling VM to x64
- Compiling to C
The list will grow as I go.
- Built-in types
-
int8 -
uint8 -
int16 -
uint16 -
int32 -
uint32 -
int64 -
uint64 -
float32 -
float64 -
bool - Complex type(s)
complex64complex128
- SSE type(s)
- Pointers
- Function pointers
- Struct
- Union
- Enum
- Slices
[]type
-
- Constants
- Untyped constant literal
- Integer
- Real
- Boolean
- String
- Initializers
- Nil
- Typed named constants
- Untyped named constants
- Untyped constant literal
- Comments
- Line comments
- Block comments
- Function declaration
-
function <name> (<inputs>) (<outputs>) { ... } -
function <name> (<inputs>) <type-spec> -
function <name> (<inputs>) - Convenience syntax for function arguments of same type (
a, b int32)
-
- Function prototype declaration
-
function <name> (<inputs>) (<outputs>)
-
- Function type
-
function (<inputs>) (<outputs>) -
function (<inputs>) <type-spec> -
function (<inputs>)
-
- Call
-
<name>(<arguments>) - Type checking.
-
- If statement
-
if <pre-st>; <condition> { ... } -
if <condition> { ... } -
if ... { ... } else { ... } -
if ... { ... } else if ... - Type checking.
-
- For statement
-
for <pre-st>; <condition>; <post-st> { ... } -
for <pre-st>; ; <post-st> { ... } -
for <pre-st>; ; { ... } -
for ; <condition>; { ... } -
for ; ; { ... } -
for <condition> { ... } -
{ break } -
{ continue } - Type checking.
-
- Switch statement
-
switch <pre-st>; <expr> { ... } -
case <const>: -
default -
breakorfallthrough?
-
- Goto statement
-
goto <label> -
label:
-
- Arithmetic expressions
-
-a -
+a -
--a(L, TBD) -
++a(L, TBD) -
a--(L, TBD) -
a++(L, TBD) -
a + b -
a - b -
a * b -
a / b -
a % b -
a = b -
a += b -
a -= b -
a *= b -
a /= b
-
- Bitwise expressions
-
~n -
a ^ b -
a & b -
a | b -
a << b -
a >> b -
a &= b -
a |= b -
a ^= b
-
- Comparison expressions
-
a < b -
a > b -
a <= b -
a >= b -
a == b -
a != b
-
- Boolean expressions
-
!n -
a && b -
a || b
-
- ASTNode/Type checking
Language details to be determined.
- No semicolons
- REQUIREMENT: No whitespace significance (cannot be determined by new-line characters).
- Semicolon after
returncan be determined by whether function has an output argument. - Semicolon after function input arguments where a return type without parens might occur is problematic.
func (a int32);? int32;?- Make return value to be required (introducing
void)? - Make return value to be always wrapped in parens?
func (a int32) (int32)?
- Multiple function output arguments
- In C implemented as non-const pointer parameters.
- Really wanted only for error reporting.
- Zero, one or two outputs only?
- Single output with one additional implicit
erroroutput?
- Prefix and postfix
++and--operators as statements or expressions?- These are technically
x += 1, so assignment which is a statement.
- These are technically
- Named function output argument(s)
- Will attempt.
- Strings
-
[]char8,[]char16,[]char32slices - No zero-termination guarantee.
- No
string + stringbullshit. - How to deal with zero-terminated strings for C APIs compatibility?
-
- Boolean types
- For now, we're going with what Go does: We're going with 8-bit bool, in order to protect type safety and support explicit casting.
intcannot be cast tobool, you need to doi != 0boolcannot be cast toint, you need to doif b { i == 1 }boolis not supported by arithmetic operations.- Some of these might change though after proper testing.
- The cast from bool to int is quite safe.
- Problem is that some arithmetic operations with bool make sense in order to do branchless calculations.
- For now, we're going with what Go does: We're going with 8-bit bool, in order to protect type safety and support explicit casting.
- Go interfaces
- Code in root?
- Module is function?
- Module has root code as
mainfunction? - Pros:
- Good for scripting.
- Good for module initialization.
- Cons:
- Incompatible with C's
#include(initialization has to be called manually)
- Incompatible with C's
- Context as silent argument?