zig/README.md

192 lines
6.3 KiB
Markdown

# zig lang
An experiment in writing a low-level programming language with the intent to
replace C. Zig intends to be a small language, yet powerful enough to write
readable, safe, optimal, and concise code to solve any computing problem.
## Goals
* Ability to run arbitrary code at compile time and generate code.
* Completely compatible with C libraries with no wrapper necessary.
* Creating a C library should be a primary use case. Should be easy to export
an auto-generated .h file.
* Generics such as containers.
* Do not depend on libc unless explicitly imported.
* First class error code support.
* Include documentation generator.
* Eliminate the need for make, cmake, etc.
* Friendly toward package maintainers.
* Eliminate the need for C headers (when using zig internally).
* Ability to declare dependencies as Git URLS with commit locking (can
provide a tag or sha1).
* Tagged union enum type.
* Opinionated when it makes life easier.
- Tab character in source code is a compile error.
- Whitespace at the end of line is a compile error.
* Resilient to parsing errors to make IDE integration work well.
* Source code is UTF-8.
* Shebang line OK so language can be used for "scripting" as well.
* Ability to mark functions as test and automatically run them in test mode.
This mode should automatically provide test coverage.
* Memory zeroed by default, unless you initialize with "uninitialized".
### Building
```
mkdir build
cd build
cmake ..
make
./run_tests
```
## Roadmap
* variable declarations and assignment expressions
* Type checking
* loops
* inline assembly and syscalls
* conditional compilation and ability to check target platform and architecture
* main function with command line arguments
* running code at compile time
* print! macro that takes var args
* panic! macro that prints a stack trace to stderr in debug mode and calls
abort() in release mode
* unreachable codegen to panic("unreachable") in debug mode, and nothing in
release mode
* implement a simple game using SDL2
* How should the Widget use case be solved? In Genesis I'm using C++ and inheritance.
### Primitive Numeric Types:
zig | C equivalent | Description
-------|--------------|-------------------------------
bool | bool | unsigned 1-bit integer
i8 | int8_t | signed 8-bit integer
u8 | uint8_t | unsigned 8-bit integer
i16 | int16_t | signed 16-bit integer
u16 | uint16_t | unsigned 16-bit integer
i32 | int32_t | signed 32-bit integer
u32 | uint32_t | unsigned 32-bit integer
i64 | int64_t | signed 64-bit integer
u64 | uint64_t | unsigned 64-bit integer
f32 | float | 32-bit IEE754 floating point
f64 | double | 64-bit IEE754 floating point
f128 | long double | 128-bit IEE754 floating point
isize | intptr_t | signed pointer sized integer
usize | uintptr_t | unsigned pointer sized integer
### Grammar
```
Root : many(TopLevelDecl) token(EOF)
TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Use
Use : many(Directive) token(Use) token(String) token(Semicolon)
RootExportDecl : many(Directive) token(Export) token(Symbol) token(String) token(Semicolon)
ExternBlock : many(Directive) token(Extern) token(LBrace) many(FnDecl) token(RBrace)
FnProto : many(Directive) option(FnVisibleMod) token(Fn) token(Symbol) ParamDeclList option(token(Arrow) Type)
Directive : token(NumberSign) token(Symbol) token(LParen) token(String) token(RParen)
FnVisibleMod : token(Pub) | token(Export)
FnDecl : FnProto token(Semicolon)
FnDef : FnProto Block
ParamDeclList : token(LParen) list(ParamDecl, token(Comma)) token(RParen)
ParamDecl : token(Symbol) token(Colon) Type
Type : token(Symbol) | PointerType | token(Unreachable)
PointerType : token(Star) token(Const) Type | token(Star) token(Mut) Type
Block : token(LBrace) list(option(Statement), token(Semicolon)) token(RBrace)
Statement : Label | NonBlockExpression token(Semicolon) | BlockExpression
Label: token(Symbol) token(Colon)
Expression : BlockExpression | NonBlockExpression
NonBlockExpression : ReturnExpression | VariableDeclaration | BoolOrExpression
BlockExpression : IfExpression | Block
BoolOrExpression : BoolAndExpression token(BoolOr) BoolAndExpression | BoolAndExpression
ReturnExpression : token(Return) option(Expression)
VariableDeclaration : token(Let) token(Symbole) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
IfExpression : token(If) Expression Block option(Else | ElseIf)
ElseIf : token(Else) IfExpression
Else : token(Else) Block
BoolAndExpression : ComparisonExpression token(BoolAnd) ComparisonExpression | ComparisonExpression
ComparisonExpression : BinaryOrExpression ComparisonOperator BinaryOrExpression | BinaryOrExpression
ComparisonOperator : token(BoolEq) | token(BoolNotEq) | token(BoolLessThan) | token(BoolGreaterThan) | token(BoolLessEqual) | token(BoolGreaterEqual)
BinaryOrExpression : BinaryXorExpression token(BinOr) BinaryXorExpression | BinaryXorExpression
BinaryXorExpression : BinaryAndExpression token(BinXor) BinaryAndExpression | BinaryAndExpression
BinaryAndExpression : BitShiftExpression token(BinAnd) BitShiftExpression | BitShiftExpression
BitShiftExpression : AdditionExpression BitShiftOperator AdditionExpression | AdditionExpression
BitShiftOperator : token(BitShiftLeft | token(BitShiftRight)
AdditionExpression : MultiplyExpression AdditionOperator MultiplyExpression | MultiplyExpression
AdditionOperator : token(Plus) | token(Minus)
MultiplyExpression : CastExpression MultiplyOperator CastExpression | CastExpression
MultiplyOperator : token(Star) | token(Slash) | token(Percent)
CastExpression : PrefixOpExpression token(as) Type | PrefixOpExpression
PrefixOpExpression : PrefixOp FnCallExpression | FnCallExpression
FnCallExpression : PrimaryExpression token(LParen) list(Expression, token(Comma)) token(RParen) | PrimaryExpression
PrefixOp : token(Not) | token(Dash) | token(Tilde)
PrimaryExpression : token(Number) | token(String) | KeywordLiteral | GroupedExpression | token(Symbol) | Goto
Goto: token(Goto) token(Symbol)
GroupedExpression : token(LParen) Expression token(RParen)
KeywordLiteral : token(Unreachable) | token(Void) | token(True) | token(False)
```
### Operator Precedence
```
x()
!x -x ~x
as
* / %
+ -
<< >>
&
^
|
== != < > <= >=
&&
||
=
```