2015-12-09 14:20:31 -08:00
|
|
|
# Language Reference
|
|
|
|
|
|
|
|
## Grammar
|
|
|
|
|
|
|
|
```
|
2016-09-27 23:33:32 -07:00
|
|
|
Root = many(TopLevelItem) "EOF"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-09-27 23:33:32 -07:00
|
|
|
TopLevelItem = ErrorValueDecl | Block | TopLevelDecl
|
|
|
|
|
2016-12-18 13:56:50 -08:00
|
|
|
TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl)
|
2016-01-20 17:18:50 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
TypeDecl = "type" Symbol "=" TypeExpr ";"
|
2016-01-31 00:20:47 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
ErrorValueDecl = "error" Symbol ";"
|
2015-12-11 23:10:37 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
GlobalVarDecl = VariableDeclaration ";"
|
2016-01-04 15:57:22 -08:00
|
|
|
|
2016-11-03 11:13:57 -07:00
|
|
|
VariableDeclaration = option("inline") ("var" | "const") Symbol option(":" TypeExpr) "=" Expression
|
2016-01-26 12:08:21 -08:00
|
|
|
|
2016-12-18 13:56:50 -08:00
|
|
|
StructMember = (StructField | FnDef | GlobalVarDecl)
|
2015-12-11 23:10:37 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
StructField = Symbol option(":" Expression) ",")
|
2016-01-10 10:48:54 -08:00
|
|
|
|
2016-02-27 21:06:46 -08:00
|
|
|
UseDecl = "use" Expression ";"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-29 15:06:17 -08:00
|
|
|
ExternDecl = "extern" (FnProto | VariableDeclaration) ";"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-09-27 23:33:32 -07:00
|
|
|
FnProto = option("coldcc" | "nakedcc") "fn" option(Symbol) ParamDeclList option("->" TypeExpr)
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
VisibleMod = "pub" | "export"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-04-28 16:04:44 -07:00
|
|
|
FnDef = option("inline" | "extern") FnProto Block
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
ParamDeclList = "(" list(ParamDecl, ",") ")"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
ParamDecl = option("noalias" | "inline") option(Symbol ":") TypeExpr | "..."
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
Block = "{" list(option(Statement), ";") "}"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-02-05 23:56:01 -08:00
|
|
|
Statement = Label | VariableDeclaration ";" | Defer ";" | NonBlockExpression ";" | BlockExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
Label = Symbol ":"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
Expression = BlockExpression | NonBlockExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-09-07 21:24:48 -07:00
|
|
|
TypeExpr = PrefixOpExpression | "var"
|
2016-01-31 00:20:47 -08:00
|
|
|
|
2016-02-05 23:56:01 -08:00
|
|
|
NonBlockExpression = ReturnExpression | AssignmentExpression
|
2015-12-10 14:34:38 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
AsmExpression = "asm" option("volatile") "(" String option(AsmOutput) ")"
|
2015-12-10 14:34:38 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
AsmOutput = ":" list(AsmOutputItem, ",") option(AsmInput)
|
2015-12-10 14:34:38 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
AsmInput = ":" list(AsmInputItem, ",") option(AsmClobbers)
|
2015-12-10 14:34:38 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
AsmOutputItem = "[" Symbol "]" String "(" (Symbol | "->" TypeExpr) ")"
|
2015-12-11 02:55:26 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
AsmInputItem = "[" Symbol "]" String "(" Expression ")"
|
2015-12-11 02:55:26 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
AsmClobbers= ":" list(String, ",")
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
UnwrapExpression = BoolOrExpression (UnwrapMaybe | UnwrapError) | BoolOrExpression
|
2016-01-07 02:23:38 -08:00
|
|
|
|
2016-02-06 18:28:11 -08:00
|
|
|
UnwrapMaybe = "??" Expression
|
2016-01-25 12:53:40 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
UnwrapError = "%%" option("|" Symbol "|") Expression
|
2016-01-25 12:53:40 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | UnwrapExpression
|
2015-12-12 17:17:27 -08:00
|
|
|
|
2016-07-27 23:04:24 -07:00
|
|
|
AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" | "&&=" | "||=" | "*%=" | "+%=" | "-%=" | "<<%="
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
BlockExpression = IfExpression | Block | WhileExpression | ForExpression | SwitchExpression
|
2015-12-24 13:37:43 -08:00
|
|
|
|
2016-11-26 12:38:07 -08:00
|
|
|
SwitchExpression = option("inline") "switch" "(" Expression ")" "{" many(SwitchProng) "}"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-11-23 23:44:03 -08:00
|
|
|
SwitchProng = (list(SwitchItem, ",") | "else") "=>" option("|" option("*") Symbol "|") Expression ","
|
2016-01-18 06:00:45 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
SwitchItem = Expression | (Expression "..." Expression)
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-11-03 11:13:57 -07:00
|
|
|
WhileExpression = option("inline") "while" "(" Expression option(";" Expression) ")" Expression
|
2016-01-19 18:15:36 -08:00
|
|
|
|
2016-11-03 11:13:57 -07:00
|
|
|
ForExpression = option("inline") "for" "(" Expression ")" option("|" option("*") Symbol option("," Symbol) "|") Expression
|
2016-01-19 18:15:36 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
BoolOrExpression = BoolAndExpression "||" BoolOrExpression | BoolAndExpression
|
2016-01-19 18:15:36 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
ReturnExpression = option("%" | "?") "return" option(Expression)
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-12-06 18:26:17 -08:00
|
|
|
Defer = option("%" | "?") "defer" Expression
|
2016-02-05 22:20:34 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
IfExpression = IfVarExpression | IfBoolExpression
|
2015-12-26 14:05:27 -08:00
|
|
|
|
2016-12-06 21:22:14 -08:00
|
|
|
IfBoolExpression = option("inline") "if" "(" Expression ")" Expression option(Else)
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-12-06 21:22:14 -08:00
|
|
|
IfVarExpression = option("inline") "if" "(" ("const" | "var") option("*") Symbol option(":" TypeExpr) "?=" Expression ")" Expression Option(Else)
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
Else = "else" Expression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
BoolAndExpression = ComparisonExpression "&&" BoolAndExpression | ComparisonExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
ComparisonExpression = BinaryOrExpression ComparisonOperator BinaryOrExpression | BinaryOrExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
ComparisonOperator = "==" | "!=" | "<" | ">" | "<=" | ">="
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
BinaryOrExpression = BinaryXorExpression "|" BinaryOrExpression | BinaryXorExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
BinaryXorExpression = BinaryAndExpression "^" BinaryXorExpression | BinaryAndExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
BinaryAndExpression = BitShiftExpression "&" BinaryAndExpression | BitShiftExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
BitShiftExpression = AdditionExpression BitShiftOperator BitShiftExpression | AdditionExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-07-27 23:04:24 -07:00
|
|
|
BitShiftOperator = "<<" | ">>" | "<<%"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
AdditionExpression = MultiplyExpression AdditionOperator AdditionExpression | MultiplyExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-07-27 23:04:24 -07:00
|
|
|
AdditionOperator = "+" | "-" | "++" | "+%" | "-%"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
MultiplyExpression = CurlySuffixExpression MultiplyOperator MultiplyExpression | CurlySuffixExpression
|
2016-01-15 16:40:12 -08:00
|
|
|
|
2016-01-31 00:20:47 -08:00
|
|
|
CurlySuffixExpression = TypeExpr option(ContainerInitExpression)
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-07-27 23:04:24 -07:00
|
|
|
MultiplyOperator = "*" | "/" | "%" | "**" | "*%"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-12-31 14:10:29 -08:00
|
|
|
SuffixOpExpression = option("inline") PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
|
2015-12-11 23:10:37 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
FieldAccessExpression = "." Symbol
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
FnCallExpression = "(" list(Expression, ",") ")"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
ArrayAccessExpression = "[" Expression "]"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
SliceExpression = "[" Expression "..." option(Expression) "]" option("const")
|
2016-01-07 04:29:11 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
ContainerInitExpression = "{" ContainerInitBody "}"
|
2016-01-13 17:15:51 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")
|
2016-01-13 17:15:51 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
StructLiteralField = "." Symbol "=" Expression
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-07-27 23:04:24 -07:00
|
|
|
PrefixOp = "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%" | "%%" | "??" | "-%"
|
2015-12-23 23:00:23 -08:00
|
|
|
|
2016-12-18 13:56:50 -08:00
|
|
|
PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
|
2015-12-23 23:00:23 -08:00
|
|
|
|
2016-01-31 00:20:47 -08:00
|
|
|
ArrayType = "[" option(Expression) "]" option("const") TypeExpr
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-11-26 20:33:07 -08:00
|
|
|
GotoExpression = option("inline") "goto" Symbol
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-28 17:58:28 -08:00
|
|
|
GroupedExpression = "(" Expression ")"
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-09-26 20:47:30 -07:00
|
|
|
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
|
2016-12-18 13:56:50 -08:00
|
|
|
|
2016-12-18 14:24:52 -08:00
|
|
|
ContainerDecl = option("extern") ("struct" | "enum" | "union") "{" many(StructMember) "}"
|
2016-12-18 13:56:50 -08:00
|
|
|
|
2015-12-09 14:20:31 -08:00
|
|
|
```
|
|
|
|
|
|
|
|
## Operator Precedence
|
|
|
|
|
|
|
|
```
|
2016-01-15 16:40:12 -08:00
|
|
|
x() x[] x.y
|
2016-01-25 14:45:05 -08:00
|
|
|
!x -x ~x *x &x ?x %x %%x
|
2016-01-15 16:40:12 -08:00
|
|
|
x{}
|
2015-12-09 14:20:31 -08:00
|
|
|
* / %
|
2016-01-25 20:56:29 -08:00
|
|
|
+ - ++
|
2015-12-09 14:20:31 -08:00
|
|
|
<< >>
|
|
|
|
&
|
|
|
|
^
|
|
|
|
|
|
|
|
|
== != < > <= >=
|
|
|
|
&&
|
|
|
|
||
|
2016-01-25 12:53:40 -08:00
|
|
|
?? %%
|
2015-12-12 17:17:27 -08:00
|
|
|
= *= /= %= += -= <<= >>= &= ^= |= &&= ||=
|
2015-12-09 14:20:31 -08:00
|
|
|
```
|
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
## Types
|
|
|
|
|
|
|
|
### Numeric Types
|
|
|
|
|
|
|
|
```
|
|
|
|
Type name C equivalent Description
|
|
|
|
|
|
|
|
i8 int8_t signed 8-bit integer
|
2016-07-27 23:04:24 -07:00
|
|
|
u8 uint8_t unsigned 8-bit integer
|
2016-01-20 00:27:53 -08:00
|
|
|
i16 int16_t signed 16-bit integer
|
2016-07-27 23:04:24 -07:00
|
|
|
u16 uint16_t unsigned 16-bit integer
|
2016-01-20 00:27:53 -08:00
|
|
|
i32 int32_t signed 32-bit integer
|
2016-07-27 23:04:24 -07:00
|
|
|
u32 uint32_t unsigned 32-bit integer
|
2016-01-20 00:27:53 -08:00
|
|
|
i64 int64_t signed 64-bit integer
|
2016-07-27 23:04:24 -07:00
|
|
|
u64 uint64_t unsigned 64-bit integer
|
2016-01-20 00:27:53 -08:00
|
|
|
isize intptr_t signed pointer sized integer
|
2016-07-27 23:04:24 -07:00
|
|
|
usize uintptr_t unsigned pointer sized integer
|
2016-01-20 00:27:53 -08:00
|
|
|
|
|
|
|
c_short short for ABI compatibility with C
|
|
|
|
c_ushort unsigned short for ABI compatibility with C
|
|
|
|
c_int int for ABI compatibility with C
|
|
|
|
c_uint unsigned int for ABI compatibility with C
|
|
|
|
c_long long for ABI compatibility with C
|
|
|
|
c_ulong unsigned long for ABI compatibility with C
|
|
|
|
c_longlong long long for ABI compatibility with C
|
|
|
|
c_ulonglong unsigned long long for ABI compatibility with C
|
2016-01-31 14:44:02 -08:00
|
|
|
c_long_double long double for ABI compatibility with C
|
2016-03-01 14:26:41 -08:00
|
|
|
c_void void for ABI compatibility with C
|
2016-05-05 17:19:01 -07:00
|
|
|
|
2016-07-27 23:04:24 -07:00
|
|
|
f32 float 32-bit floating point
|
|
|
|
f64 double 64-bit floating point
|
2016-01-20 00:27:53 -08:00
|
|
|
```
|
|
|
|
|
|
|
|
### Boolean Type
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
The boolean type has the name `bool` and represents either true or false.
|
|
|
|
|
2016-01-20 17:18:50 -08:00
|
|
|
### Function Type
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
TODO
|
|
|
|
|
2016-01-20 17:18:50 -08:00
|
|
|
### Fixed-Size Array Type
|
|
|
|
|
|
|
|
Example: The string `"aoeu"` has type `[4]u8`.
|
|
|
|
|
|
|
|
The size is known at compile time and is part of the type.
|
|
|
|
|
|
|
|
### Slice Type
|
|
|
|
|
|
|
|
A slice can be obtained with the slicing syntax: `array[start...end]`
|
|
|
|
|
|
|
|
Example: `"aoeu"[0...2]` has type `[]u8`.
|
2016-01-20 00:27:53 -08:00
|
|
|
|
2016-01-22 15:05:29 -08:00
|
|
|
### Struct Type
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
TODO
|
|
|
|
|
2016-01-22 15:05:29 -08:00
|
|
|
### Enum Type
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
### Maybe Type
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
2016-02-10 15:35:07 -08:00
|
|
|
### Pure Error Type
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
### Error Union Type
|
2016-01-22 15:05:29 -08:00
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
### Pointer Type
|
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
TODO
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
### Unreachable Type
|
2016-01-20 17:18:50 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
The unreachable type has the name `unreachable`. TODO explanation
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
### Void Type
|
2016-01-20 17:18:50 -08:00
|
|
|
|
|
|
|
The void type has the name `void`. void types are zero bits and are omitted
|
|
|
|
from codegen.
|
2015-12-09 14:20:31 -08:00
|
|
|
|
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
## Expressions
|
|
|
|
|
|
|
|
### Literals
|
|
|
|
|
|
|
|
#### Character and String Literals
|
2016-08-01 23:11:31 -07:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
```
|
2016-04-03 18:44:17 -07:00
|
|
|
Literal Example Characters Escapes Null Term Type
|
2016-01-20 00:27:53 -08:00
|
|
|
|
2016-04-03 18:44:17 -07:00
|
|
|
Byte 'H' All ASCII Byte No u8
|
|
|
|
UTF-8 Bytes "hello" All Unicode Byte & Unicode No [5]u8
|
|
|
|
UTF-8 C string c"hello" All Unicode Byte & Unicode Yes &const u8
|
2016-01-20 00:27:53 -08:00
|
|
|
```
|
|
|
|
|
2016-05-01 14:53:48 -07:00
|
|
|
### Escapes
|
|
|
|
|
|
|
|
Escape | Name
|
|
|
|
----------|-------------------------------------------------------------------
|
|
|
|
\n | Newline
|
|
|
|
\r | Carriage Return
|
|
|
|
\t | Tab
|
|
|
|
\\ | Backslash
|
|
|
|
\' | Single Quote
|
|
|
|
\" | Double Quote
|
|
|
|
\xNN | hexadecimal 8-bit character code (2 digits)
|
|
|
|
\uNNNN | hexadecimal 16-bit Unicode character code UTF-8 encoded (4 digits)
|
|
|
|
\UNNNNNN | hexadecimal 24-bit Unicode character code UTF-8 encoded (6 digits)
|
|
|
|
|
|
|
|
Note that the maximum valid Unicode point is 0x10ffff.
|
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
##### Multiline String Literals
|
2016-04-03 18:44:17 -07:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
Multiline string literals have no escapes and can span across multiple lines.
|
|
|
|
To start a multiline string literal, use the `\\` token. Just like a comment,
|
|
|
|
the string literal goes until the end of the line. The end of the line is not
|
|
|
|
included in the string literal.
|
2016-04-03 18:44:17 -07:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
However, if the next line begins with `\\` then a newline is appended and
|
|
|
|
the string literal continues.
|
2016-04-03 18:44:17 -07:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
Example:
|
2016-01-20 00:27:53 -08:00
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
```zig
|
|
|
|
const hello_world_in_c =
|
|
|
|
\\#include <stdio.h>
|
|
|
|
\\
|
|
|
|
\\int main(int argc, char **argv) {
|
|
|
|
\\ printf("hello world\n");
|
|
|
|
\\ return 0;
|
|
|
|
\\}
|
|
|
|
;
|
2016-01-20 00:27:53 -08:00
|
|
|
```
|
2016-08-01 23:11:31 -07:00
|
|
|
|
|
|
|
For a multiline C string literal, prepend `c` to each `\\`. Example:
|
|
|
|
|
|
|
|
```zig
|
|
|
|
const c_string_literal =
|
|
|
|
c\\#include <stdio.h>
|
|
|
|
c\\
|
|
|
|
c\\int main(int argc, char **argv) {
|
|
|
|
c\\ printf("hello world\n");
|
|
|
|
c\\ return 0;
|
|
|
|
c\\}
|
|
|
|
;
|
2016-01-20 00:27:53 -08:00
|
|
|
```
|
|
|
|
|
2016-08-01 23:11:31 -07:00
|
|
|
In this example the variable `c_string_literal` has type `&const char` and
|
|
|
|
has a terminating null byte.
|
|
|
|
|
|
|
|
#### Number Literals
|
|
|
|
|
|
|
|
Number literals | Example | Exponentiation
|
|
|
|
--------------------|-------------|--------------
|
|
|
|
Decimal integer | 98222 | N/A
|
|
|
|
Hex integer | 0xff | N/A
|
|
|
|
Octal integer | 0o77 | N/A
|
|
|
|
Binary integer | 0b11110000 | N/A
|
|
|
|
Floating point | 123.0E+77 | Optional
|
|
|
|
Hex floating point | 0x103.70p-5 | Optional
|
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
### Identifiers
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
TODO
|
|
|
|
|
|
|
|
### Declarations
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
Declarations have type `void`.
|
|
|
|
|
|
|
|
#### Function Declarations
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
TODO
|
|
|
|
|
|
|
|
#### Variable Declarations
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
TODO
|
|
|
|
|
|
|
|
#### Struct Declarations
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
TODO
|
|
|
|
|
|
|
|
#### Enum Declarations
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-01-20 00:27:53 -08:00
|
|
|
TODO
|
|
|
|
|
|
|
|
|
|
|
|
## Built-in Functions
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
Built-in functions are prefixed with `@`. Remember that the `inline` keyword on
|
|
|
|
a parameter means that the parameter must be known at compile time.
|
2016-01-20 00:27:53 -08:00
|
|
|
|
2016-12-11 16:43:06 -08:00
|
|
|
### @alloca(inline T: type, count: usize) -> []T
|
|
|
|
|
|
|
|
Allocates memory in the stack frame of the caller. This temporary space is
|
|
|
|
automatically freed when the function that called alloca returns to its caller,
|
|
|
|
just like other stack variables.
|
|
|
|
|
|
|
|
When using this function to allocate memory, you should know the upper bound
|
|
|
|
of `count`. Consider putting a constant array on the stack with the upper bound
|
|
|
|
instead of using alloca. If you do use alloca it is to save a few bytes off
|
|
|
|
the memory size given that you didn't actually hit your upper bound.
|
|
|
|
|
|
|
|
The allocated memory contents are undefined.
|
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
### @typeof(expression) -> type
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
This function returns a compile-time constant, which is the type of the
|
|
|
|
expression passed as an argument. The expression is *not evaluated*.
|
2016-01-20 00:27:53 -08:00
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
### @sizeof(inline T: type) -> (number literal)
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
This function returns the number of bytes it takes to store T in memory.
|
|
|
|
|
|
|
|
The result is a target-specific compile time constant.
|
|
|
|
|
|
|
|
### @alignof(inline T: type) -> (number literal)
|
|
|
|
|
|
|
|
This function returns the number of bytes that this type should be aligned to
|
|
|
|
for the current target.
|
|
|
|
|
|
|
|
The result is a target-specific compile time constant.
|
2016-01-20 00:27:53 -08:00
|
|
|
|
|
|
|
### Overflow Arithmetic
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
These functions take an integer type, two variables of the specified type,
|
|
|
|
and a pointer to memory of the specified type where the result is stored.
|
2016-01-20 00:27:53 -08:00
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
The functions return a boolean value: true if overflow or underflow occurred,
|
|
|
|
false otherwise.
|
2016-01-20 00:27:53 -08:00
|
|
|
|
|
|
|
```
|
2016-05-18 16:59:55 -07:00
|
|
|
Function Operation
|
2016-09-09 09:10:27 -07:00
|
|
|
@addWithOverflow(inline T: type, a: T, b: T, result: &T) -> bool *x = a + b
|
|
|
|
@subWithOverflow(inline T: type, a: T, b: T, result: &T) -> bool *x = a - b
|
|
|
|
@mulWithOverflow(inline T: type, a: T, b: T, result: &T) -> bool *x = a * b
|
|
|
|
@shlWithOverflow(inline T: type, a: T, b: T, result: &T) -> bool *x = a << b
|
2016-05-18 16:59:55 -07:00
|
|
|
```
|
|
|
|
|
2016-12-11 21:31:35 -08:00
|
|
|
### @memset(dest: &u8, c: u8, byte_count: usize)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function sets a region of memory to `c`. `dest` is a pointer.
|
|
|
|
|
|
|
|
This function is a low level intrinsic with no safety mechanisms. Most higher
|
|
|
|
level code will not use this function, instead using something like this:
|
|
|
|
|
|
|
|
```zig
|
2016-11-18 19:24:41 -08:00
|
|
|
for (destSlice) |*b| *b = c;
|
2016-05-18 16:59:55 -07:00
|
|
|
```
|
|
|
|
|
2016-12-11 21:31:35 -08:00
|
|
|
The optimizer is intelligent enough to turn the above snippet into a memset.
|
|
|
|
|
|
|
|
### @memcpy(noalias dest: &u8, noalias source: &const u8, byte_count: usize)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function copies bytes from one region of memory to another. `dest` and
|
|
|
|
`source` are both pointers and must not overlap.
|
|
|
|
|
|
|
|
This function is a low level intrinsic with no safety mechanisms. Most higher
|
|
|
|
level code will not use this function, instead using something like this:
|
|
|
|
|
|
|
|
```zig
|
|
|
|
const mem = @import("std").mem;
|
2016-11-18 19:24:41 -08:00
|
|
|
mem.copy(destSlice, sourceSlice);
|
2016-05-18 16:59:55 -07:00
|
|
|
```
|
|
|
|
|
2016-12-11 21:31:35 -08:00
|
|
|
The optimizer is intelligent enough to turn the above snippet into a memcpy.
|
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
### @breakpoint()
|
|
|
|
|
|
|
|
This function inserts a platform-specific debug trap instruction which causes
|
|
|
|
debuggers to break there.
|
|
|
|
|
|
|
|
This function is only valid within function scope.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @returnAddress()
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function returns a pointer to the return address of the current stack
|
|
|
|
frame.
|
|
|
|
|
|
|
|
The implications of this are target specific and not consistent across
|
|
|
|
all platforms.
|
|
|
|
|
|
|
|
This function is only valid within function scope.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @frameAddress()
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function returns the base pointer of the current stack frame.
|
|
|
|
|
|
|
|
The implications of this are target specific and not consistent across all
|
|
|
|
platforms. The frame address may not be available in release mode due to
|
|
|
|
aggressive optimizations.
|
|
|
|
|
|
|
|
This function is only valid within function scope.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @maxValue(inline T: type) -> (number literal)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function returns the maximum integer value of the integer type T.
|
|
|
|
|
|
|
|
The result is a compile time constant. For some types such as `c_long`, the
|
|
|
|
result is marked as depending on a compile variable.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @minValue(inline T: type) -> (number literal)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function returns the minimum integer value of the integer type T.
|
|
|
|
|
|
|
|
The result is a compile time constant. For some types such as `c_long`, the
|
|
|
|
result is marked as depending on a compile variable.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @memberCount(inline T: type) -> (number literal)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function returns the number of enum values in an enum type.
|
|
|
|
|
|
|
|
The result is a compile time constant.
|
|
|
|
|
|
|
|
### @import(inline path: []u8) -> (namespace)
|
|
|
|
|
|
|
|
This function finds a zig file corresponding to `path` and imports all the
|
|
|
|
public top level declarations into the resulting namespace.
|
|
|
|
|
|
|
|
`path` can be a relative or absolute path, or it can be the name of a package,
|
|
|
|
such as "std".
|
|
|
|
|
|
|
|
This function is only valid at top level scope.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @cImport(expression) -> (namespace)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function parses C code and imports the functions, types, variables, and
|
|
|
|
compatible macro definitions into the result namespace.
|
|
|
|
|
|
|
|
`expression` is interpreted at compile time. The builtin functions
|
|
|
|
`@c_include`, `@c_define`, and `@c_undef` work within this expression,
|
|
|
|
appending to a temporary buffer which is then parsed as C code.
|
|
|
|
|
|
|
|
This function is only valid at top level scope.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @cInclude(inline path: []u8)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function can only occur inside `@c_import`.
|
|
|
|
|
|
|
|
This appends `#include <$path>\n` to the `c_import` temporary buffer.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @cDefine(inline name: []u8, value)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function can only occur inside `@c_import`.
|
|
|
|
|
|
|
|
This appends `#define $name $value` to the `c_import` temporary buffer.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @cUndef(inline name: []u8)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function can only occur inside `@c_import`.
|
|
|
|
|
|
|
|
This appends `#undef $name` to the `c_import` temporary buffer.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @compileVar(inline name: []u8) -> (varying type)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function returns a compile-time variable. There are built in compile
|
|
|
|
variables:
|
|
|
|
|
|
|
|
* "is_big_endian" `bool` - either `true` for big endian or `false` for little endian.
|
|
|
|
* "is_release" `bool`- either `true` for release mode builds or `false` for debug mode builds.
|
|
|
|
* "is_test" `bool`- either `true` for test builds or `false` otherwise.
|
|
|
|
* "os" `@OS` - use `zig targets` to see what enum values are possible here.
|
|
|
|
* "arch" `@Arch` - use `zig targets` to see what enum values are possible here.
|
|
|
|
* "environ" `@Environ` - use `zig targets` to see what enum values are possible here.
|
|
|
|
|
|
|
|
Build scripts can set additional compile variables of any name and type.
|
|
|
|
|
|
|
|
The result of this function is a compile time constant that is marked as
|
|
|
|
depending on a compile variable.
|
|
|
|
|
2016-11-26 01:37:34 -08:00
|
|
|
### @staticEval(expression) -> @typeOf(expression)
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function wraps an expression and generates a compile error if the
|
|
|
|
expression is not known at compile time.
|
|
|
|
|
|
|
|
The result of the function is the result of the expression.
|
|
|
|
|
2016-11-21 10:27:44 -08:00
|
|
|
### @ctz(x: T) -> T
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function counts the number of trailing zeroes in x which is an integer
|
|
|
|
type T.
|
|
|
|
|
2016-11-21 10:27:44 -08:00
|
|
|
### @clz(x: T) -> T
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function counts the number of leading zeroes in x which is an integer
|
|
|
|
type T.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @errorName(err: error) -> []u8
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function returns the string representation of an error. If an error
|
|
|
|
declaration is:
|
|
|
|
|
|
|
|
```zig
|
|
|
|
error OutOfMem;
|
2016-01-20 00:27:53 -08:00
|
|
|
```
|
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
Then the string representation is "OutOfMem".
|
|
|
|
|
|
|
|
If there are no calls to `@err_name` in an entire application, then no error
|
|
|
|
name table will be generated.
|
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @embedFile(inline path: []u8) -> [X]u8
|
2016-05-18 16:59:55 -07:00
|
|
|
|
|
|
|
This function returns a compile time constant fixed-size array with length
|
|
|
|
equal to the byte count of the file given by `path`. The contents of the array
|
|
|
|
are the contents of the file.
|
|
|
|
|
|
|
|
### @cmpxchg(ptr: &T, cmp: T, new: T, success_order: MemoryOrder, fail_order: MemoryOrder) -> bool
|
|
|
|
|
|
|
|
This function performs an atomic compare exchange operation.
|
|
|
|
|
|
|
|
### @fence(order: MemoryOrder)
|
|
|
|
|
|
|
|
The `fence` function is used to introduce happens-before edges between operations.
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @divExact(a: T, b: T) -> T
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
This function performs integer division `a / b` and returns the result.
|
|
|
|
|
|
|
|
The caller guarantees that this operation will have no remainder.
|
|
|
|
|
|
|
|
In debug mode, a remainder causes a panic. In release mode, a remainder is
|
|
|
|
undefined behavior.
|
|
|
|
|
|
|
|
### @truncate(inline T: type, integer) -> T
|
|
|
|
|
|
|
|
This function truncates bits from an integer type, resulting in a smaller
|
|
|
|
integer type.
|
|
|
|
|
|
|
|
The following produces a crash in debug mode and undefined behavior in
|
|
|
|
release mode:
|
|
|
|
|
|
|
|
```zig
|
|
|
|
const a: u16 = 0xabcd;
|
|
|
|
const b: u8 = u8(a);
|
|
|
|
```
|
|
|
|
|
|
|
|
However this is well defined and working code:
|
|
|
|
|
|
|
|
```zig
|
|
|
|
const a: u16 = 0xabcd;
|
|
|
|
const b: u8 = @truncate(u8, a);
|
|
|
|
// b is now 0xcd
|
|
|
|
```
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @compileError(inline msg: []u8)
|
2016-02-10 15:35:07 -08:00
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
This function, when semantically analyzed, causes a compile error with the message `msg`.
|
2016-02-10 15:35:07 -08:00
|
|
|
|
2016-05-18 16:59:55 -07:00
|
|
|
There are several ways that code avoids being semantically checked, such as using `if`
|
2016-07-27 23:04:24 -07:00
|
|
|
or `switch` with compile time constants, and inline functions.
|
2015-12-09 14:20:31 -08:00
|
|
|
|
2016-09-09 09:10:27 -07:00
|
|
|
### @intType(inline is_signed: bool, inline bit_count: u8) -> type
|
2016-01-28 17:58:28 -08:00
|
|
|
|
2016-07-27 23:04:24 -07:00
|
|
|
This function returns an integer type with the given signness and bit count.
|
2016-12-05 18:39:15 -08:00
|
|
|
|
|
|
|
### @setFnTest(func)
|
|
|
|
|
|
|
|
Makes the target function a test function.
|