3387 Commits

Author SHA1 Message Date
Isaac Freund
515d4920e7 zig fmt: fix 0 element struct and array init 2021-02-10 11:53:53 -08:00
Isaac Freund
5df7fc36c6 zig fmt: implement Tree.lastToken() for struct init 2021-02-10 11:53:53 -08:00
Isaac Freund
928f6f48a6 zig fmt: implement Tree.lastToken() for array init 2021-02-10 11:53:53 -08:00
Isaac Freund
3110a73486 zig fmt: implement Tree.lastToken() for array types 2021-02-10 11:53:53 -08:00
Isaac Freund
8c4f3e5a31 zig fmt: fix render of pointers with ** tokens 2021-02-10 11:53:53 -08:00
Isaac Freund
a524e57090 zig fmt: support bodyless function decls
extern function declarations do not have a body, so allow setting
the rhs for FnDecl to 0 to indicate this is the case.
2021-02-10 11:53:53 -08:00
Isaac Freund
80b719d967 zig fmt: fix typo in firstToken() for pointer types 2021-02-10 11:53:53 -08:00
Andrew Kelley
58db3d2775 zig fmt: re-enable now-passing test cases 2021-02-09 23:07:29 -07:00
Andrew Kelley
fa5fcdd734 zig fmt: fix regression with many container members 2021-02-09 22:42:00 -07:00
Andrew Kelley
9d87e6aeb8 zig fmt: remove dead code
likely these will be resurrected to make array literal cases pass.
2021-02-09 22:29:01 -07:00
Andrew Kelley
36eee7bc6c zig fmt: anytype, fn calls with one param, trailing commas
and extra newlines between top level declarations
2021-02-09 22:26:21 -07:00
Andrew Kelley
25bcf4eb99 zig fmt: grouped expressions 2021-02-09 21:17:43 -07:00
Andrew Kelley
7295d4b807 zig fmt: suspend blocks 2021-02-09 20:35:43 -07:00
Andrew Kelley
ebf04c56e1 zig fmt: usingnamespace 2021-02-09 20:17:47 -07:00
Andrew Kelley
39acc4c020 zig fmt: for loops 2021-02-09 20:08:40 -07:00
Andrew Kelley
1c79eea125 zig fmt: while loops 2021-02-09 17:23:57 -07:00
Andrew Kelley
bcafc51e58 zig fmt: fn protos and anytype 2021-02-09 14:41:50 -07:00
Andrew Kelley
b1d8a0a5a6 zig fmt: asm expressions 2021-02-08 22:03:23 -07:00
Isaac Freund
d869133a9f zig fmt: implement switches 2021-02-08 15:41:31 -08:00
Isaac Freund
837cd748a8 zig fmt: fix block lbrace indent 2021-02-08 15:41:31 -08:00
Isaac Freund
aaf13a2bb3 zig fmt: implement break 2021-02-08 15:41:31 -08:00
Isaac Freund
57cec38e61 std/zig/ast: fix Tree.lastToken() for blocks
The fact that blocks may end in a semicolon but this semicolon is not
counted by recursive lastToken() evaluation on the sub expression causes
off-by-one errors for lastToken() on blocks currently.

To fix this, introduce BlockSemicolon and BlockTwoSemicolon following
the pattern used for trailing commas in e.g. builtin function arguments.
2021-02-07 14:51:37 -08:00
Isaac Freund
0e38362d24 zig fmt: split Slice and SliceSentinel
This saves 4 whole bytes in the common case where there is no sentinel.
2021-02-07 14:51:37 -08:00
Isaac Freund
1d71b19c0d zig fmt: implement error set decls 2021-02-07 14:51:37 -08:00
Isaac Freund
bb7b5ee2ac zig fmt: implement catch and return 2021-02-07 12:04:32 -08:00
Isaac Freund
0929fcbc34 zig fmt: implement slices 2021-02-07 12:04:32 -08:00
Isaac Freund
33915cb1ed zig fmt: implement pointer types
rename PtrType => PtrTypeBitRange, SliceType => PtrType

This rename was done as the current SliceType is used for non-bitrange
pointers as well as slices and because PtrTypeSentinel/PtrTypeAligned
are also used for slices. Therefore using the same Ptr prefix for all
these pointer/slice nodes is an improvement.
2021-02-06 21:29:45 -08:00
Andrew Kelley
d898945786 zig fmt: builtin call with trailing comma 2021-02-05 20:38:30 -07:00
Andrew Kelley
409ca88829 zig fmt: trailing comma in fn parameter list 2021-02-05 17:46:15 -07:00
Andrew Kelley
16a2562c3f zig fmt: implement container decls 2021-02-05 15:47:18 -07:00
Andrew Kelley
cf42ae178d std.MultiArrayList: use @memset builtin for undefined
See comment for more details
2021-02-05 15:45:33 -07:00
Isaac Freund
0f3fa4d654 zig fmt: array types 2021-02-05 11:36:19 -08:00
Isaac Freund
6f3b93e2e8 zig fmt: struct and anon array initialization 2021-02-05 10:51:45 -08:00
Isaac Freund
3e960cfffe zig fmt: float literal with exponent 2021-02-05 10:51:45 -08:00
Isaac Freund
0b4bb9b84f std.MultiArrayList: implement review comments 2021-02-05 10:51:45 -08:00
Andrew Kelley
7069459a76 zig fmt: implement struct init 2021-02-04 19:59:06 -07:00
Andrew Kelley
8e46d06650 zig fmt: implement fn protos and defers 2021-02-04 16:38:29 -07:00
Asherah Connor
4428acf0f7 zig fmt: deref, unwrap optional 2021-02-04 10:49:45 -08:00
Andrew Kelley
725adf8332 zig fmt: builtin calls and array access 2021-02-03 22:12:11 -07:00
Andrew Kelley
f5279cbada zig fmt: implement top-level fields 2021-02-03 17:02:12 -07:00
Andrew Kelley
1a83b29bea zig fmt: implement if, call, field access, assignment 2021-02-02 21:05:53 -07:00
Andrew Kelley
0c6b98b825 zig fmt: implement simple test with doc comments 2021-02-01 21:31:41 -07:00
Andrew Kelley
272a0ab359 zig fmt: implement "line comment followed by top-level comptime" 2021-02-01 20:11:55 -07:00
Andrew Kelley
20554d32c0 zig fmt: start reworking with new memory layout
* start implementation of ast.Tree.firstToken and lastToken
 * clarify some ast.Node doc comments
 * reimplement renderToken
2021-02-01 17:23:49 -07:00
Andrew Kelley
bf8fafc37d stage2: tokenizer does not emit line comments anymore
only std.zig.render cares about these, and it can find them in the
original source easily enough.
2021-01-31 21:57:48 -07:00
Andrew Kelley
4dca99d3f6 stage2: rework AST memory layout
This is a proof-of-concept of switching to a new memory layout for
tokens and AST nodes. The goal is threefold:

 * smaller memory footprint
 * faster performance for tokenization and parsing
 * most importantly, a proof-of-concept that can be also applied to ZIR
   and TZIR to improve the entire compiler pipeline in this way.

I had a few key insights here:

 * Underlying premise: using less memory will make things faster, because
   of fewer allocations and better cache utilization. Also using less
   memory is valuable in and of itself.
 * Using a Struct-Of-Arrays for tokens and AST nodes, saves the bytes of
   padding between the enum tag (which kind of token is it; which kind
   of AST node is it) and the next fields in the struct. It also improves
   cache coherence, since one can peek ahead in the tokens array without
   having to load the source locations of tokens.
 * Token memory can be conserved by only having the tag (1 byte) and byte
   offset (4 bytes) for a total of 5 bytes per token. It is not necessary
   to store the token ending byte offset because one can always re-tokenize
   later, but also most tokens the length can be trivially determined from
   the tag alone, and for ones where it doesn't, string literals for
   example, one must parse the string literal again later anyway in
   astgen, making it free to re-tokenize.
 * AST nodes do not actually need to store more than 1 token index because
   one can poke left and right in the tokens array very cheaply.

So far we are left with one big problem though: how can we put AST nodes
into an array, since different AST nodes are different sizes?

This is where my key observation comes in: one can have a hash table for
the extra data for the less common AST nodes! But it gets even better than
that:

I defined this data that is always present for every AST Node:

 * tag (1 byte)
   - which AST node is it
 * main_token (4 bytes, index into tokens array)
   - the tag determines which token this points to
 * struct{lhs: u32, rhs: u32}
   - enough to store 2 indexes to other AST nodes, the tag determines
     how to interpret this data

You can see how a binary operation, such as `a * b` would fit into this
structure perfectly. A unary operation, such as `*a` would also fit,
and leave `rhs` unused. So this is a total of 13 bytes per AST node.
And again, we don't have to pay for the padding to round up to 16 because
we store in struct-of-arrays format.

I made a further observation: the only kind of data AST nodes need to
store other than the main_token is indexes to sub-expressions. That's it.
The only purpose of an AST is to bring a tree structure to a list of tokens.
This observation means all the data that nodes store are only sets of u32
indexes to other nodes. The other tokens can be found later by the compiler,
by poking around in the tokens array, which again is super fast because it
is struct-of-arrays, so you often only need to look at the token tags array,
which is an array of bytes, very cache friendly.

So for nearly every kind of AST node, you can store it in 13 bytes. For the
rarer AST nodes that have 3 or more indexes to other nodes to store, either
the lhs or the rhs will be repurposed to be an index into an extra_data array
which contains the extra AST node indexes. In other words, no hash table needed,
it's just 1 big ArrayList with the extra data for AST Nodes.

Final observation, no need to have a canonical tag for a given AST. For example:
The expression `foo(bar)` is a function call. Function calls can have any
number of parameters. However in this example, we can encode the function
call into the AST with a tag called `FunctionCallOnlyOneParam`, and use lhs
for the function expr and rhs for the only parameter expr. Meanwhile if the
code was `foo(bar, baz)` then the AST node would have to be `FunctionCall`
with lhs still being the function expr, but rhs being the index into
`extra_data`. Then because the tag is `FunctionCall` it means
`extra_data[rhs]` is the "start" and `extra_data[rhs+1]` is the "end".
Now the range `extra_data[start..end]` describes the list of parameters
to the function.

Point being, you only have to pay for the extra bytes if the AST actually
requires it. There's no limit to the number of different AST tag encodings.

Preliminary results:

 * 15% improvement on cache-misses
 * 28% improvement on total instructions executed
 * 26% improvement on total CPU cycles
 * 22% improvement on wall clock time

This is 1/4 items on the checklist before this can actually be merged:

 * [x] parser
 * [ ] render (zig fmt)
 * [ ] astgen
 * [ ] translate-c
2021-01-30 20:16:59 -07:00
Andrew Kelley
766b315b38 std.GeneralPurposeAllocator: logging improvements
It now uses the log scope "gpa" instead of "std".

Additionally, there is a new config option `verbose_log` which enables
info log messages for every allocation. Can be useful when debugging.
This option is off by default.
2021-01-30 20:15:26 -07:00
Andrew Kelley
0808d98e10 add std.MultiArrayList
Also known as "Struct-Of-Arrays" or "SOA". The purpose of this data
structure is to provide a similar API to ArrayList but instead of
the element type being a struct, the fields of the struct are in N
different arrays, all with the same length and capacity.

Having this abstraction means we can put them in the same allocation,
avoiding overhead with the allocator. It also saves a tiny bit of
overhead from the redundant capacity and length fields, since each
struct element shares the same value.

This is an alternate implementation to #7854.
2021-01-30 20:12:13 -07:00
Joran Dirk Greef
881ecdc72f Add MAX_RW_COUNT limit to std.os.pread()
Fixes: https://github.com/ziglang/zig/issues/7805
2021-01-25 10:41:38 -08:00
Timon Kruiper
e23bc1f76a render: fix bug when rendering struct initializer with length 1
This crashed the compiler when running translate-c. See the added test.
2021-01-25 10:40:00 -08:00