Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pointer Reform - change prefix deref syntax to postfix deref syntax #1019

Merged
merged 11 commits into from
May 18, 2018
59 changes: 34 additions & 25 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub fn build(b: &Builder) !void {
var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");

const rel_zig_exe = try os.path.relative(b.allocator, b.build_root, b.zig_exe);
var docgen_cmd = b.addCommand(null, b.env_map, [][]const u8 {
var docgen_cmd = b.addCommand(null, b.env_map, [][]const u8{
docgen_exe.getOutputPath(),
rel_zig_exe,
"doc/langref.html.in",
Expand All @@ -30,7 +30,10 @@ pub fn build(b: &Builder) !void {
const test_step = b.step("test", "Run all the tests");

// find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library
const build_info = try b.exec([][]const u8{b.zig_exe, "BUILD_INFO"});
const build_info = try b.exec([][]const u8{
b.zig_exe,
"BUILD_INFO",
});
var index: usize = 0;
const cmake_binary_dir = nextValue(&index, build_info);
const cxx_compiler = nextValue(&index, build_info);
Expand Down Expand Up @@ -67,7 +70,10 @@ pub fn build(b: &Builder) !void {
dependOnLib(exe, llvm);

if (exe.target.getOs() == builtin.Os.linux) {
const libstdcxx_path_padded = try b.exec([][]const u8{cxx_compiler, "-print-file-name=libstdc++.a"});
const libstdcxx_path_padded = try b.exec([][]const u8{
cxx_compiler,
"-print-file-name=libstdc++.a",
});
const libstdcxx_path = ??mem.split(libstdcxx_path_padded, "\r\n").next();
if (mem.eql(u8, libstdcxx_path, "libstdc++.a")) {
warn(
Expand Down Expand Up @@ -111,17 +117,11 @@ pub fn build(b: &Builder) !void {

test_step.dependOn(docs_step);

test_step.dependOn(tests.addPkgTests(b, test_filter,
"test/behavior.zig", "behavior", "Run the behavior tests",
with_lldb));
test_step.dependOn(tests.addPkgTests(b, test_filter, "test/behavior.zig", "behavior", "Run the behavior tests", with_lldb));

test_step.dependOn(tests.addPkgTests(b, test_filter,
"std/index.zig", "std", "Run the standard library tests",
with_lldb));
test_step.dependOn(tests.addPkgTests(b, test_filter, "std/index.zig", "std", "Run the standard library tests", with_lldb));

test_step.dependOn(tests.addPkgTests(b, test_filter,
"std/special/compiler_rt/index.zig", "compiler-rt", "Run the compiler_rt tests",
with_lldb));
test_step.dependOn(tests.addPkgTests(b, test_filter, "std/special/compiler_rt/index.zig", "compiler-rt", "Run the compiler_rt tests", with_lldb));

test_step.dependOn(tests.addCompareOutputTests(b, test_filter));
test_step.dependOn(tests.addBuildExampleTests(b, test_filter));
Expand Down Expand Up @@ -149,8 +149,7 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) vo

fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) void {
const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";
lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp",
b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp", b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
}

const LibraryDep = struct {
Expand All @@ -161,11 +160,21 @@ const LibraryDep = struct {
};

fn findLLVM(b: &Builder, llvm_config_exe: []const u8) !LibraryDep {
const libs_output = try b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"});
const includes_output = try b.exec([][]const u8{llvm_config_exe, "--includedir"});
const libdir_output = try b.exec([][]const u8{llvm_config_exe, "--libdir"});
const libs_output = try b.exec([][]const u8{
llvm_config_exe,
"--libs",
"--system-libs",
});
const includes_output = try b.exec([][]const u8{
llvm_config_exe,
"--includedir",
});
const libdir_output = try b.exec([][]const u8{
llvm_config_exe,
"--libdir",
});

var result = LibraryDep {
var result = LibraryDep{
.libs = ArrayList([]const u8).init(b.allocator),
.system_libs = ArrayList([]const u8).init(b.allocator),
.includes = ArrayList([]const u8).init(b.allocator),
Expand Down Expand Up @@ -227,17 +236,17 @@ pub fn installCHeaders(b: &Builder, c_header_files: []const u8) void {
}

fn nextValue(index: &usize, build_info: []const u8) []const u8 {
const start = *index;
while (true) : (*index += 1) {
switch (build_info[*index]) {
const start = index.*;
while (true) : (index.* += 1) {
switch (build_info[index.*]) {
'\n' => {
const result = build_info[start..*index];
*index += 1;
const result = build_info[start..index.*];
index.* += 1;
return result;
},
'\r' => {
const result = build_info[start..*index];
*index += 2;
const result = build_info[start..index.*];
index.* += 2;
return result;
},
else => continue,
Expand Down
66 changes: 34 additions & 32 deletions doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>
</td>
</tr>
<tr>
<td><pre><code class="zig">*a<code></pre></td>
<td><pre><code class="zig">a.*<code></pre></td>
<td>
<ul>
<li>{#link|Pointers#}</li>
Expand All @@ -1244,7 +1244,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>
<td>
<pre><code class="zig">const x: u32 = 1234;
const ptr = &amp;x;
*x == 1234</code></pre>
x.* == 1234</code></pre>
</td>
</tr>
<tr>
Expand All @@ -1258,7 +1258,7 @@ const ptr = &amp;x;
<td>
<pre><code class="zig">const x: u32 = 1234;
const ptr = &amp;x;
*x == 1234</code></pre>
x.* == 1234</code></pre>
</td>
</tr>
</table>
Expand All @@ -1267,8 +1267,8 @@ const ptr = &amp;x;
{#header_open|Precedence#}
<pre><code>x() x[] x.y
a!b
!x -x -%x ~x *x &amp;x ?x ??x
x{}
!x -x -%x ~x &amp;x ?x ??x
x{} x.*
! * / % ** *%
+ - ++ +% -%
&lt;&lt; &gt;&gt;
Expand Down Expand Up @@ -1316,7 +1316,7 @@ var some_integers: [100]i32 = undefined;

test "modify an array" {
for (some_integers) |*item, i| {
*item = i32(i);
item.* = i32(i);
}
assert(some_integers[10] == 10);
assert(some_integers[99] == 99);
Expand Down Expand Up @@ -1357,7 +1357,7 @@ comptime {
var fancy_array = init: {
var initial_value: [10]Point = undefined;
for (initial_value) |*pt, i| {
*pt = Point {
pt.* = Point {
.x = i32(i),
.y = i32(i) * 2,
};
Expand Down Expand Up @@ -1400,7 +1400,7 @@ test "address of syntax" {
const x_ptr = &x;

// Deference a pointer:
assert(*x_ptr == 1234);
assert(x_ptr.* == 1234);

// When you get the address of a const variable, you get a const pointer.
assert(@typeOf(x_ptr) == &const i32);
Expand All @@ -1409,8 +1409,8 @@ test "address of syntax" {
var y: i32 = 5678;
const y_ptr = &y;
assert(@typeOf(y_ptr) == &i32);
*y_ptr += 1;
assert(*y_ptr == 5679);
y_ptr.* += 1;
assert(y_ptr.* == 5679);
}

test "pointer array access" {
Expand Down Expand Up @@ -1448,9 +1448,9 @@ comptime {
// @ptrCast.
var x: i32 = 1;
const ptr = &x;
*ptr += 1;
ptr.* += 1;
x += 1;
assert(*ptr == 3);
assert(ptr.* == 3);
}

test "@ptrToInt and @intToPtr" {
Expand Down Expand Up @@ -1492,7 +1492,7 @@ test "nullable pointers" {
var x: i32 = 1;
ptr = &x;

assert(*??ptr == 1);
assert((??ptr).* == 1);

// Nullable pointers are the same size as normal pointers, because pointer
// value 0 is used as the null value.
Expand All @@ -1505,7 +1505,7 @@ test "pointer casting" {
// conversions are not possible.
const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12};
const u32_ptr = @ptrCast(&const u32, &bytes[0]);
assert(*u32_ptr == 0x12121212);
assert(u32_ptr.* == 0x12121212);

// Even this example is contrived - there are better ways to do the above than
// pointer casting. For example, using a slice narrowing cast:
Expand Down Expand Up @@ -1610,7 +1610,7 @@ fn foo(bytes: []u8) u32 {
<code>u8</code> can alias any memory.
</p>
<p>As an example, this code produces undefined behavior:</p>
<pre><code class="zig">*@ptrCast(&amp;u32, f32(12.34))</code></pre>
<pre><code class="zig">@ptrCast(&amp;u32, f32(12.34)).*</code></pre>
<p>Instead, use {#link|@bitCast#}:
<pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>
<p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p>
Expand Down Expand Up @@ -2040,7 +2040,7 @@ const Variant = union(enum) {
Bool: bool,

fn truthy(self: &const Variant) bool {
return switch (*self) {
return switch (self.*) {
Variant.Int => |x_int| x_int != 0,
Variant.Bool => |x_bool| x_bool,
};
Expand Down Expand Up @@ -2151,7 +2151,7 @@ test "switch enum" {

// A reference to the matched value can be obtained using `*` syntax.
Item.C => |*item| blk: {
(*item).x += 1;
item.*.x += 1;
break :blk 6;
},

Expand Down Expand Up @@ -2374,7 +2374,7 @@ test "for reference" {
// Iterate over the slice by reference by
// specifying that the capture value is a pointer.
for (items) |*value| {
*value += 1;
value.* += 1;
}

assert(items[0] == 4);
Expand Down Expand Up @@ -2483,7 +2483,7 @@ test "if nullable" {
// Access the value by reference using a pointer capture.
var c: ?u32 = 3;
if (c) |*value| {
*value = 2;
value.* = 2;
}

if (c) |value| {
Expand Down Expand Up @@ -2524,7 +2524,7 @@ test "if error union" {
// Access the value by reference using a pointer capture.
var c: error!u32 = 3;
if (c) |*value| {
*value = 9;
value.* = 9;
} else |err| {
unreachable;
}
Expand Down Expand Up @@ -3872,7 +3872,7 @@ pub fn main() void {
{#header_open|@addWithOverflow#}
<pre><code class="zig">@addWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
<p>
Performs <code>*result = a + b</code>. If overflow or underflow occurs,
Performs <code>result.* = a + b</code>. If overflow or underflow occurs,
stores the overflowed bits in <code>result</code> and returns <code>true</code>.
If no overflow or underflow occurs, returns <code>false</code>.
</p>
Expand Down Expand Up @@ -4073,9 +4073,9 @@ comptime {
</p>
{#code_begin|syntax#}
fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T {
const old_value = *ptr;
const old_value = ptr.*;
if (old_value == expected_value) {
*ptr = new_value;
ptr.* = new_value;
return null;
} else {
return old_value;
Expand All @@ -4100,9 +4100,9 @@ fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_v
</p>
{#code_begin|syntax#}
fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: &T, expected_value: T, new_value: T) ?T {
const old_value = *ptr;
const old_value = ptr.*;
if (old_value == expected_value and usuallyTrueButSometimesFalse()) {
*ptr = new_value;
ptr.* = new_value;
return null;
} else {
return old_value;
Expand Down Expand Up @@ -4447,7 +4447,7 @@ mem.copy(u8, dest[0...byte_count], source[0...byte_count]);</code></pre>
This function is a low level intrinsic with no safety mechanisms. Most
code should not use this function, instead using something like this:
</p>
<pre><code class="zig">for (dest[0...byte_count]) |*b| *b = c;</code></pre>
<pre><code class="zig">for (dest[0...byte_count]) |*b| b.* = c;</code></pre>
<p>
The optimizer is intelligent enough to turn the above snippet into a memset.
</p>
Expand Down Expand Up @@ -4480,7 +4480,7 @@ mem.set(u8, dest, c);</code></pre>
{#header_open|@mulWithOverflow#}
<pre><code class="zig">@mulWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
<p>
Performs <code>*result = a * b</code>. If overflow or underflow occurs,
Performs <code>result.* = a * b</code>. If overflow or underflow occurs,
stores the overflowed bits in <code>result</code> and returns <code>true</code>.
If no overflow or underflow occurs, returns <code>false</code>.
</p>
Expand Down Expand Up @@ -4514,7 +4514,7 @@ fn targetFunction(x: i32) usize {

var local_variable: i32 = 42;
const ptr = &local_variable;
*ptr += 1;
ptr.* += 1;

assert(local_variable == 43);
return @ptrToInt(ptr);
Expand Down Expand Up @@ -4746,7 +4746,7 @@ pub const FloatMode = enum {
{#header_open|@shlWithOverflow#}
<pre><code class="zig">@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: &T) -&gt; bool</code></pre>
<p>
Performs <code>*result = a &lt;&lt; b</code>. If overflow or underflow occurs,
Performs <code>result.* = a &lt;&lt; b</code>. If overflow or underflow occurs,
stores the overflowed bits in <code>result</code> and returns <code>true</code>.
If no overflow or underflow occurs, returns <code>false</code>.
</p>
Expand Down Expand Up @@ -4790,7 +4790,7 @@ pub const FloatMode = enum {
{#header_open|@subWithOverflow#}
<pre><code class="zig">@subWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
<p>
Performs <code>*result = a - b</code>. If overflow or underflow occurs,
Performs <code>result.* = a - b</code>. If overflow or underflow occurs,
stores the overflowed bits in <code>result</code> and returns <code>true</code>.
If no overflow or underflow occurs, returns <code>false</code>.
</p>
Expand Down Expand Up @@ -6382,10 +6382,12 @@ MultiplyOperator = "||" | "*" | "/" | "%" | "**" | "*%"

PrefixOpExpression = PrefixOp TypeExpr | SuffixOpExpression

SuffixOpExpression = ("async" option("&lt;" SuffixOpExpression "&gt;") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
SuffixOpExpression = ("async" option("&lt;" SuffixOpExpression "&gt;") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression | PtrDerefExpression)

FieldAccessExpression = "." Symbol

PtrDerefExpression = ".*"

FnCallExpression = "(" list(Expression, ",") ")"

ArrayAccessExpression = "[" Expression "]"
Expand All @@ -6398,7 +6400,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")

StructLiteralField = "." Symbol "=" Expression

PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"
PrefixOp = "!" | "-" | "~" | ("*" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"

PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl | PromiseType

Expand Down
Loading