Wind syntax reference
Welcome to the Wind Language Syntax Reference! This page will guide you through the syntax of the Wind programming language, including its keywords, operators, and conventions.
Comments
Comments in Wind are similar to C-style comments and can be single-line or multi-line.
// This is a single-line comment
/* This is a
multi-line comment */
@ Directives
Let's break the ice with the @
directives. These are used to include files, define flags, and more.
include
The include
directive is used to include a file in the current file. The file path is relative to the current file.
@include "path/to/file.w"
Using # as the first character of the file path will include a file from the standard library.
@include "#types.wi"
Multi include is also supported.
@include [
"path/to/file1.w"
"path/to/file2.w"
]
import
Pay attention to the import
directive.
@import "#my_module"
You can use # prefix here as well to include a module from the WIND_PKGS_PATH
.
Import searches for a dir like this:
name/
name.wi
name.w
The name.wi
file is the interface file, and the name.w
file is the implementation file.
The interface file should contain the function prototypes, and the implementation file should contain the function definitions.
Interface file example:
func test_fn(x: int): int;
Implementation file example:
func test_fn(x: int): int {
return x*(x+1);
}
pure
The pure
directive is used to define a function flag.
@pure[stack expr] func foo() {}
stack
- Local variables usage won't be optimized.expr
- Expressions aren't optimized.logue
- No prologue and epilogue will be generated.stchk
- No check for stack overflow and integer overflow will be generated.
extern
The extern
directive is used to define a function as an external function.
@extern func foo();
pub
The pub
directive is used to define a function as public.
While public directive is not required for including functions, it is used to share functions between objects when linking.
@pub func foo() {}
type
The type
directive is used to define a type.
@type my_type = unsigned byte;
linkflag
The linkflag
directive is used to define an ld flag.
@linkflag("-lm);
Keywords
Wind has no concept of reserved-identifiers, so you can use any keyword as an identifier if you wish. However, the following keywords are used in the language and should be avoided as identifiers:
func
var
global
return
branch
else
loop
continue
break
asm
true
false
Null
Data Types
Wind has some primitive data types:
byte = signed 8 bits
short = signed 16 bits
int = signed 32 bits
long = signed 64 bits
unsigned byte = unsigned 8 bits
...
But the "#types.wi" std file provides some more types:
s8 = signed 8 bits
s16 = signed 16 bits
s32 = signed 32 bits
s64 = signed 64 bits
u8 = unsigned 8 bits
s16 = unsigned 16 bits
s32 = unsigned 32 bits
s64 = unsigned 64 bits
bool = 8 bits
char = 8 bits
Arrays are declared using the following syntax:
var arr: [int; 10];
Pointers
Pointers are declared using the following syntax:
var ptr: ptr<int>;
Wind convention is to use heap allocation over stack allocated arrays.
with the guard![]
directive, you can check for null pointers and prevent dereferencing.
var my_ptr: ptr<char> = guard![malloc(32)];
Casting
Casting in Wind is done with the as
operator.
var x: ptr<u64> = malloc(...);
(x as ptr<char>)[0]='x';
Sizeof
The sizeof<>
directive is used to get the (move) size of a type.
var size_int: int = sizeof<int>;
Variables
Variables in Wind are declared using the var
keyword, followed by the variable name and type.
var x: int = 10;
You can declared them in bulk as well.
var [x,y,z]: int = 0;
Global Variables
Global variables are declared using the global
keyword.
global x: int = 10;
Non declarable in bulk.
Functions
Functions in Wind are declared using the func
keyword, followed by the function name, parameters, and return type.
func add(x: int, y: int): int {
return x + y;
}
There's no wrapper for variadic functions, but you can still use ...
for external C functions.
@extern func printf(format: string, ...): int;
Namespaces
Namespaces in Wind are declared using the namespace
keyword.
namespace my_namespace {
func foo() {
puts("Hello, World!");
}
}
Used with the ::
operator.
my_namespace::foo();
Control Flow
Wind has the usual control flow features with unique syntax.
Branch
The branch
keyword is used to define a conditional statement.
branch [
x == 0: puts("x is zero");
else: {
puts("x != 0);
return 1;
}
]
Loop
The loop
keyword is used to define a loop statement.
loop [x < 10] {
puts("x is less than 10");
x++;
}
There's no for
loop in Wind, but you can use the loop
keyword with a counter.
Continue
The continue
keyword is used to skip the current iteration of a loop.
loop [x < 10] {
x++;
continue;
}
Break
The break
keyword is used to exit a loop.
loop [x < 10] {
x++;
break;
}
Try Catch
Wind has a try-catch implementation for error handling.
This is a simple implementation and is not as powerful as other languages.
In fact it's just a wrapper to set the handler code for arithmetic exceptions and other security features like guard![]
.
try {
T += 20_000; // sum overflow
T = guard![Null];
}
[SUM_OF] -> {
printf("Sum overflow handled\n");
}
[GUARD] -> {
printf("Null pointer exception handled\n");
}
finally {
printf("Exceptions handled\n");
}
Exceptions
SUM_OF
- Arithmetic exceptions.SUB_OF
- Arithmetic exceptions.MUL_OF
- Arithmetic exceptions.-
DIV_OF
- Arithmetic exceptions. -
GUARD
- Null pointer exceptions. BOUNDS
- Array out of bounds exceptions.
Inline Assembly
Wind supports inline assembly using the asm
keyword.
asm {
mov eax, 10;
add eax, 20;
}
You can also reference local variables in inline assembly.
asm {
mov eax, ?x;
add eax, 0x10;
}
Happy coding with Wind! 🎉