* Remove parser error on double ampersand
* Add failing test for double ampersand case
* Add error when encountering double ampersand in AstGen
"Bit and" operator should not make sense when one of its operands
is an address.
* Check that 2 ampersands are adjacent to each other in source string
* Remove cases of unused variables in tests
Instead of having one function per precedence level, mirroring the BNF grammar,
this uses the "precedence climbing" algorithm with a table of operator
precedences (and a few special cases that don't fit into the table as it is).
This is a first pass -- it's probably possible to put more of the parser
into this form, e.g. to support prefix/suffix operators with precedence, if
necessary, or just to simplify the code more.
It may also be possible to speed this up by putting more useful information
into the tokens during tokenization, to avoid the extra branch on the token in
operInfo.
Introduce "inline" variants of ZIR tags:
* block => block_inline
* repeat => repeat_inline
* break => break_inline
* condbr => condbr_inline
The inline variants perform control flow at compile-time, and they
utilize the return value of `Sema.analyzeBody`.
`analyzeBody` now returns an Index, not a Ref, which is the ZIR index of
a break instruction. This effectively communicates both the intended
break target block as well as the operand, allowing parent blocks to
find out whether they, in turn, should return the break instruction up the
call stack, or accept the operand as the block's result and continue
analyzing instructions in the block.
Additionally:
* removed the deprecated ZIR tag `block_comptime`.
* removed `break_void_node` so that all break instructions use the same Data.
* zir.Code: remove the `root_start` and `root_len` fields. There is now
implied to be a block at index 0 for the root body. This is so that
`break_inline` has something to point at and we no longer need the
special instruction `break_flat`.
* implement source location byteOffset() for .node_offset_if_cond
.node_offset_for_cond is probably redundant and can be deleted.
We don't have `comptime var` supported yet, so this commit adds a test
that at least makes sure the condition is required to be comptime known
for `inline while`.
We are now passing this test:
```zig
export fn _start() noreturn {}
```
```
test.zig:1:30: error: expected noreturn, found void
```
I ran into an issue where we get an integer overflow trying to compute
node index offsets from the containing Decl. The problem is that the
parser adds the Decl node after adding the child nodes. For some things,
it is easy to reserve the node index and then set it later, however, for
this case, it is not a trivial code change, because depending on tokens
after parsing the decl determines whether we want to add a new node or
not.
Possible strategies here:
1. Rework the parser code to make sure that Decl nodes are before
children nodes in the AST node array.
2. Use signed integers for Decl node offsets.
3. Just flip the order of subtraction and addition. Expect Decl Node
index to be greater than children Node indexes.
I opted for (3) because it seems like the simplest thing to do. We'll
want to unify the logic for computing the offsets though because if the
logic gets repeated, it will probably get repeated wrong.
The modification to the grammar in the comment is in line with the
grammar in the zig-spec repo.
Note: checking if the previous token is a colon is insufficent to tell
if a block has a label, the identifier must be checked for as well. This
can be seen in sentinel terminated slicing: `foo[0..1:{}]`
After #35 is implemented,
we should be able to recover from this *at any indentation level*,
reporting a parse error and yet also parsing all the decls even
inside structs. Until then, I don't want to add any hacks to make
this work.
Allowing same line doc comments causes some ambiguity as to how
generated docs should represent the case in which both same line
and preceding line doc comments are present:
/// preceding line
const foobar = 42; /// same line
Furthermore disallowing these makes things simpler as there is now only
one way to add a doc comment to a decl or struct field.
break, continue, blocks, bit_not, negation, identifiers, string
literals, integer literals, inline assembly
also gave multiline string literals a different node tag from regular
string literals, for code clarity and to avoid an unnecessary load from
token_tags array.