Syntax in the i language
The i language describes things, and some of those things are programs.
Since it is useful to name things, i allows this, as follows:
~[ zerobyte :: 0x00 ]
This defines something called a zerobyte that is one byte in size and has all it's bits cleared.
In the above example we have a definition with the name on the left side and the thing named on the right side. The right side can contain bit patterns (represented as numbers or strings.) It can also contain references to previously defined things as follows:
~[ i8 :: 0x00 ]
~[ i16 :: [ l8 :: i8 ]
[ h8 :: i8 ] ]
~[ i32 :: [ l16 :: i16 ]
[ h16 :: i16 ] ]
~[ i64 :: [ l32 :: i32 ]
[ h32 :: i32 ] ]
(Note that the above definition is processor-specific. The same definition for a big-endian architecture would be different.)
The above examples contain a tilde (~) in the outermost part of the definitions but not in the interior definitions. That's because the ~ marks the following definition as being a virtual definition--the thing being defined doesn't actually take up space in the enclosing definition.
Now if we want to use the above definitions all we have to do is reference them.
[ foo :: i8 ]
[ bar :: i32 ]
Names may be phrases.
~[ unsigned integer :: i32 ]
~[ signed integer :: i32 ]
~[ point :: [ x :: signed integer ]
[ y :: signed integer ] ]
[ baz :: point ]
All of that is nice for data, but what about code?
~[ nop :: 0x90 ]
~[ hlt :: 0xF4 ]
~[ pusha :: 0x60 ]
~[ popa :: 0x61 ]
~[ ftst :: 0xD9; 0xE4 ]
[ do nothing :: nop; nop; nop ]
Admittedly, that's very primitive but it is code.
Things get more interesting when you want to introduce parameters.
~[ mogrify x' :: do; some; code; x@; more; code ]
mogrify baz;
The tick (') mark identifies a part of the name that may be matched (i.e. it is a variable.)
The at-sign (@) appends the location of the variable to the item being built.