authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-14 18:51:07-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-14 18:51:07-07:00
log304941026013e6310c9362849610c32d98d1332a
treee1c82472dfe7e887020b306dbd37aa89491426a5
parent8b727557d31714e87e489522f452cef9880ba30d

`const` and `var` instead of `let` and `let mut`

closes #34

9 files changed, 82 insertions(+), 92 deletions(-)

doc/langref.md+1-1
......@@ -70,7 +70,7 @@ Statement : Label | VariableDeclaration token(Semicolon) | NonBlockExpression to
7070
7171Label: token(Symbol) token(Colon)
7272
73VariableDeclaration : token(Let) option(token(Mut)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
73VariableDeclaration : (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
7474
7575Expression : BlockExpression | NonBlockExpression
7676
example/arrays/arrays.zig+3-3
......@@ -3,9 +3,9 @@ export executable "arrays";
33use "std.zig";
44
55export fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
6 let mut array : [i32; 5];
6 var array : [i32; 5];
77
8 let mut i : i32 = 0;
8 var i : i32 = 0;
99loop_start:
1010 if i == 5 {
1111 goto loop_end;
......@@ -17,7 +17,7 @@ loop_start:
1717loop_end:
1818
1919 i = 0;
20 let mut accumulator : i32 = 0;
20 var accumulator : i32 = 0;
2121loop_2_start:
2222 if i == 5 {
2323 goto loop_2_end;
example/expressions/expressions.zig+12-12
......@@ -13,17 +13,17 @@ fn other_exit() -> unreachable {
1313}
1414
1515export fn _start() -> unreachable {
16 let a : i32 = 1;
17 let b = 2 as i32;
18 // let c : i32; // not yet support for const variables
19 // let d; // parse error
16 const a : i32 = 1;
17 const b = 2 as i32;
18 // const c : i32; // not yet support for const variables
19 // const d; // parse error
2020 if (a + b == 3) {
21 let no_conflict : i32 = 5;
21 const no_conflict : i32 = 5;
2222 if (no_conflict == 5) { puts(c"OK 1"); }
2323 }
2424
25 let c = {
26 let no_conflict : i32 = 10;
25 const c = {
26 const no_conflict : i32 = 10;
2727 no_conflict
2828 };
2929 if (c == 10) { puts(c"OK 2"); }
......@@ -36,15 +36,15 @@ export fn _start() -> unreachable {
3636}
3737
3838fn void_fun(a : i32, b : void, c : i32) -> void {
39 let x = a + 1; // i32
40 let y = c + 1; // i32
41 let z = b; // void
42 let w : void = z; // void
39 const x = a + 1; // i32
40 const y = c + 1; // i32
41 const z = b; // void
42 const w : void = z; // void
4343 if (x + y == 4) { return w; }
4444}
4545
4646fn test_mutable_vars() {
47 let mut i : i32 = 0;
47 var i : i32 = 0;
4848loop_start:
4949 if i == 3 {
5050 goto done;
example/structs/structs.zig+1-1
......@@ -3,7 +3,7 @@ export executable "structs";
33use "std.zig";
44
55export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
6 let mut foo : Foo;
6 var foo : Foo;
77
88 foo.a = foo.a + 1;
99
src/parser.cpp+32-38
......@@ -1561,53 +1561,47 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m
15611561}
15621562
15631563/*
1564VariableDeclaration : token(Let) option(token(Mut)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
1564VariableDeclaration : (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
15651565*/
15661566static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token_index, bool mandatory) {
1567 Token *let_tok = &pc->tokens->at(*token_index);
1568 if (let_tok->id == TokenIdKeywordLet) {
1569 *token_index += 1;
1570 AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, let_tok);
1567 Token *var_or_const_tok = &pc->tokens->at(*token_index);
15711568
1572 Token *name_token;
1573 Token *token = &pc->tokens->at(*token_index);
1574 if (token->id == TokenIdKeywordMut) {
1575 node->data.variable_declaration.is_const = false;
1576 *token_index += 1;
1577 name_token = &pc->tokens->at(*token_index);
1578 ast_expect_token(pc, name_token, TokenIdSymbol);
1579 } else if (token->id == TokenIdSymbol) {
1580 node->data.variable_declaration.is_const = true;
1581 name_token = token;
1582 } else {
1583 ast_invalid_token_error(pc, token);
1584 }
1569 bool is_const;
1570 if (var_or_const_tok->id == TokenIdKeywordVar) {
1571 is_const = false;
1572 } else if (var_or_const_tok->id == TokenIdKeywordConst) {
1573 is_const = true;
1574 } else if (mandatory) {
1575 ast_invalid_token_error(pc, var_or_const_tok);
1576 } else {
1577 return nullptr;
1578 }
15851579
1586 *token_index += 1;
1587 ast_buf_from_token(pc, name_token, &node->data.variable_declaration.symbol);
1580 *token_index += 1;
1581 AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, var_or_const_tok);
15881582
1589 Token *eq_or_colon = &pc->tokens->at(*token_index);
1590 *token_index += 1;
1591 if (eq_or_colon->id == TokenIdEq) {
1592 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
1593 return node;
1594 } else if (eq_or_colon->id == TokenIdColon) {
1595 node->data.variable_declaration.type = ast_parse_type(pc, token_index);
1583 node->data.variable_declaration.is_const = is_const;
15961584
1597 Token *eq_token = &pc->tokens->at(*token_index);
1598 if (eq_token->id == TokenIdEq) {
1599 *token_index += 1;
1585 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
1586 ast_buf_from_token(pc, name_token, &node->data.variable_declaration.symbol);
16001587
1601 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
1602 }
1603 return node;
1604 } else {
1605 ast_invalid_token_error(pc, eq_or_colon);
1588 Token *eq_or_colon = &pc->tokens->at(*token_index);
1589 *token_index += 1;
1590 if (eq_or_colon->id == TokenIdEq) {
1591 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
1592 return node;
1593 } else if (eq_or_colon->id == TokenIdColon) {
1594 node->data.variable_declaration.type = ast_parse_type(pc, token_index);
1595
1596 Token *eq_token = &pc->tokens->at(*token_index);
1597 if (eq_token->id == TokenIdEq) {
1598 *token_index += 1;
1599
1600 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
16061601 }
1607 } else if (mandatory) {
1608 ast_invalid_token_error(pc, let_tok);
1602 return node;
16091603 } else {
1610 return nullptr;
1604 ast_invalid_token_error(pc, eq_or_colon);
16111605 }
16121606}
16131607
src/tokenizer.cpp+3-6
......@@ -179,10 +179,8 @@ static void end_token(Tokenize *t) {
179179 t->cur_tok->id = TokenIdKeywordFn;
180180 } else if (mem_eql_str(token_mem, token_len, "return")) {
181181 t->cur_tok->id = TokenIdKeywordReturn;
182 } else if (mem_eql_str(token_mem, token_len, "let")) {
183 t->cur_tok->id = TokenIdKeywordLet;
184 } else if (mem_eql_str(token_mem, token_len, "mut")) {
185 t->cur_tok->id = TokenIdKeywordMut;
182 } else if (mem_eql_str(token_mem, token_len, "var")) {
183 t->cur_tok->id = TokenIdKeywordVar;
186184 } else if (mem_eql_str(token_mem, token_len, "const")) {
187185 t->cur_tok->id = TokenIdKeywordConst;
188186 } else if (mem_eql_str(token_mem, token_len, "extern")) {
......@@ -797,9 +795,8 @@ static const char * token_name(Token *token) {
797795 case TokenIdSymbol: return "Symbol";
798796 case TokenIdKeywordFn: return "Fn";
799797 case TokenIdKeywordConst: return "Const";
800 case TokenIdKeywordMut: return "Mut";
798 case TokenIdKeywordVar: return "Var";
801799 case TokenIdKeywordReturn: return "Return";
802 case TokenIdKeywordLet: return "Let";
803800 case TokenIdKeywordExtern: return "Extern";
804801 case TokenIdKeywordUnreachable: return "Unreachable";
805802 case TokenIdKeywordPub: return "Pub";
src/tokenizer.hpp+1-2
......@@ -15,8 +15,7 @@ enum TokenId {
1515 TokenIdSymbol,
1616 TokenIdKeywordFn,
1717 TokenIdKeywordReturn,
18 TokenIdKeywordLet,
19 TokenIdKeywordMut,
18 TokenIdKeywordVar,
2019 TokenIdKeywordConst,
2120 TokenIdKeywordExtern,
2221 TokenIdKeywordUnreachable,
std/std.zig+3-3
......@@ -1,5 +1,5 @@
11fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
2 let mut result : isize;
2 var result : isize;
33 asm volatile ("
44 mov %[number], %%rax
55 mov %[arg1], %%rdi
......@@ -15,13 +15,13 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
1515
1616// TODO constants for SYS_write and stdout_fileno
1717pub fn write(fd: isize, buf: &const u8, count: usize) -> isize {
18 let SYS_write : isize = 1;
18 const SYS_write : isize = 1;
1919 return syscall3(SYS_write, fd, buf as isize, count as isize);
2020}
2121
2222// TODO error handling
2323// TODO handle buffering and flushing
2424pub fn print_str(str : string) -> isize {
25 let stdout_fileno : isize = 1;
25 const stdout_fileno : isize = 1;
2626 return write(stdout_fileno, str.ptr, str.len);
2727}
test/run_tests.cpp+26-26
......@@ -265,8 +265,8 @@ extern {
265265}
266266
267267export fn _start() -> unreachable {
268 let a : i32 = 1;
269 let b = 2 as i32;
268 const a : i32 = 1;
269 const b = 2 as i32;
270270 if (a + b == 3) {
271271 puts(c"OK");
272272 }
......@@ -299,12 +299,12 @@ extern {
299299
300300export fn _start() -> unreachable {
301301 if (true) {
302 let no_conflict : i32 = 5;
302 const no_conflict : i32 = 5;
303303 if (no_conflict == 5) { puts(c"OK 1"); }
304304 }
305305
306 let c = {
307 let no_conflict = 10 as i32;
306 const c = {
307 const no_conflict = 10 as i32;
308308 no_conflict
309309 };
310310 if (c == 10) { puts(c"OK 2"); }
......@@ -325,8 +325,8 @@ export fn _start() -> unreachable {
325325}
326326
327327fn void_fun(a : i32, b : void, c : i32) {
328 let v = b;
329 let vv : void = if (a == 1) {v} else {};
328 const v = b;
329 const vv : void = if (a == 1) {v} else {};
330330 if (a + c == 3) { puts(c"OK"); }
331331 return vv;
332332}
......@@ -340,10 +340,10 @@ extern {
340340}
341341
342342export fn _start() -> unreachable {
343 let mut zero : i32;
343 var zero : i32;
344344 if (zero == 0) { puts(c"zero"); }
345345
346 let mut i = 0 as i32;
346 var i = 0 as i32;
347347loop_start:
348348 if i == 3 {
349349 goto done;
......@@ -364,9 +364,9 @@ extern {
364364}
365365
366366export fn _start() -> unreachable {
367 let mut array : [i32; 5];
367 var array : [i32; 5];
368368
369 let mut i : i32 = 0;
369 var i : i32 = 0;
370370loop_start:
371371 if i == 5 {
372372 goto loop_end;
......@@ -378,7 +378,7 @@ loop_start:
378378loop_end:
379379
380380 i = 0;
381 let mut accumulator = 0 as i32;
381 var accumulator = 0 as i32;
382382loop_2_start:
383383 if i == 5 {
384384 goto loop_2_end;
......@@ -458,7 +458,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
458458use "std.zig";
459459
460460export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
461 let mut i : i32 = 0;
461 var i : i32 = 0;
462462 i += 5; if i != 5 { print_str("BAD +=\n" as string); }
463463 i -= 2; if i != 3 { print_str("BAD -=\n" as string); }
464464 i *= 20; if i != 60 { print_str("BAD *=\n" as string); }
......@@ -481,7 +481,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
481481use "std.zig";
482482
483483export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
484 let mut foo : Foo;
484 var foo : Foo;
485485 foo.a = foo.a + 1;
486486 foo.b = foo.a == 1;
487487 test_foo(foo);
......@@ -589,20 +589,20 @@ fn f(a : i32, a : i32) {
589589
590590 add_compile_fail_case("local variable redeclaration", R"SOURCE(
591591fn f() {
592 let a : i32 = 0;
593 let a = 0;
592 const a : i32 = 0;
593 const a = 0;
594594}
595595 )SOURCE", 1, ".tmp_source.zig:4:5: error: redeclaration of variable 'a'");
596596
597597 add_compile_fail_case("local variable redeclares parameter", R"SOURCE(
598598fn f(a : i32) {
599 let a = 0;
599 const a = 0;
600600}
601601 )SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
602602
603603 add_compile_fail_case("variable has wrong type", R"SOURCE(
604604fn f() -> i32 {
605 let a = c"a";
605 const a = c"a";
606606 a
607607}
608608 )SOURCE", 1, ".tmp_source.zig:2:15: error: expected type 'i32', got '&const u8'");
......@@ -615,15 +615,15 @@ fn f() {
615615
616616 add_compile_fail_case("assign unreachable", R"SOURCE(
617617fn f() {
618 let a = return;
618 const a = return;
619619}
620620 )SOURCE", 1, ".tmp_source.zig:3:5: error: variable initialization is unreachable");
621621
622622 add_compile_fail_case("unreachable variable", R"SOURCE(
623623fn f() {
624 let a : unreachable = return;
624 const a : unreachable = return;
625625}
626 )SOURCE", 1, ".tmp_source.zig:3:13: error: variable of type 'unreachable' not allowed");
626 )SOURCE", 1, ".tmp_source.zig:3:15: error: variable of type 'unreachable' not allowed");
627627
628628 add_compile_fail_case("unreachable parameter", R"SOURCE(
629629fn f(a : unreachable) {}
......@@ -647,7 +647,7 @@ fn f() {
647647
648648 add_compile_fail_case("assign to constant variable", R"SOURCE(
649649fn f() {
650 let a = 3;
650 const a = 3;
651651 a = 4;
652652}
653653 )SOURCE", 1, ".tmp_source.zig:4:5: error: cannot assign to constant variable");
......@@ -658,15 +658,15 @@ fn f() {
658658}
659659 )SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'");
660660
661 add_compile_fail_case("let is a statement, not an expression", R"SOURCE(
661 add_compile_fail_case("const is a statement, not an expression", R"SOURCE(
662662fn f() {
663 (let a = 0);
663 (const a = 0);
664664}
665 )SOURCE", 1, ".tmp_source.zig:3:6: error: invalid token: 'let'");
665 )SOURCE", 1, ".tmp_source.zig:3:6: error: invalid token: 'const'");
666666
667667 add_compile_fail_case("array access errors", R"SOURCE(
668668fn f() {
669 let mut bad : bool;
669 var bad : bool;
670670 i[i] = i[i];
671671 bad[bad] = bad[bad];
672672}