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...@@ -70,7 +70,7 @@ Statement : Label | VariableDeclaration token(Semicolon) | NonBlockExpression to
7070
71Label: token(Symbol) token(Colon)71Label: 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
75Expression : BlockExpression | NonBlockExpression75Expression : BlockExpression | NonBlockExpression
7676
example/arrays/arrays.zig+3-3
...@@ -3,9 +3,9 @@ export executable "arrays";...@@ -3,9 +3,9 @@ export executable "arrays";
3use "std.zig";3use "std.zig";
44
5export fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {5export 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;
9loop_start:9loop_start:
10 if i == 5 {10 if i == 5 {
11 goto loop_end;11 goto loop_end;
...@@ -17,7 +17,7 @@ loop_start:...@@ -17,7 +17,7 @@ loop_start:
17loop_end:17loop_end:
1818
19 i = 0;19 i = 0;
20 let mut accumulator : i32 = 0;20 var accumulator : i32 = 0;
21loop_2_start:21loop_2_start:
22 if i == 5 {22 if i == 5 {
23 goto loop_2_end;23 goto loop_2_end;
example/expressions/expressions.zig+12-12
...@@ -13,17 +13,17 @@ fn other_exit() -> unreachable {...@@ -13,17 +13,17 @@ fn other_exit() -> unreachable {
13}13}
1414
15export fn _start() -> unreachable {15export fn _start() -> unreachable {
16 let a : i32 = 1;16 const a : i32 = 1;
17 let b = 2 as i32;17 const b = 2 as i32;
18 // let c : i32; // not yet support for const variables18 // const c : i32; // not yet support for const variables
19 // let d; // parse error19 // const d; // parse error
20 if (a + b == 3) {20 if (a + b == 3) {
21 let no_conflict : i32 = 5;21 const no_conflict : i32 = 5;
22 if (no_conflict == 5) { puts(c"OK 1"); }22 if (no_conflict == 5) { puts(c"OK 1"); }
23 }23 }
2424
25 let c = {25 const c = {
26 let no_conflict : i32 = 10;26 const no_conflict : i32 = 10;
27 no_conflict27 no_conflict
28 };28 };
29 if (c == 10) { puts(c"OK 2"); }29 if (c == 10) { puts(c"OK 2"); }
...@@ -36,15 +36,15 @@ export fn _start() -> unreachable {...@@ -36,15 +36,15 @@ export fn _start() -> unreachable {
36}36}
3737
38fn void_fun(a : i32, b : void, c : i32) -> void {38fn void_fun(a : i32, b : void, c : i32) -> void {
39 let x = a + 1; // i3239 const x = a + 1; // i32
40 let y = c + 1; // i3240 const y = c + 1; // i32
41 let z = b; // void41 const z = b; // void
42 let w : void = z; // void42 const w : void = z; // void
43 if (x + y == 4) { return w; }43 if (x + y == 4) { return w; }
44}44}
4545
46fn test_mutable_vars() {46fn test_mutable_vars() {
47 let mut i : i32 = 0;47 var i : i32 = 0;
48loop_start:48loop_start:
49 if i == 3 {49 if i == 3 {
50 goto done;50 goto done;
example/structs/structs.zig+1-1
...@@ -3,7 +3,7 @@ export executable "structs";...@@ -3,7 +3,7 @@ export executable "structs";
3use "std.zig";3use "std.zig";
44
5export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {5export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
6 let mut foo : Foo;6 var foo : Foo;
77
8 foo.a = foo.a + 1;8 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...@@ -1561,53 +1561,47 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m
1561}1561}
15621562
1563/*1563/*
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))
1565*/1565*/
1566static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token_index, bool mandatory) {1566static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token_index, bool mandatory) {
1567 Token *let_tok = &pc->tokens->at(*token_index);1567 Token *var_or_const_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);
15711568
1572 Token *name_token;1569 bool is_const;
1573 Token *token = &pc->tokens->at(*token_index);1570 if (var_or_const_tok->id == TokenIdKeywordVar) {
1574 if (token->id == TokenIdKeywordMut) {1571 is_const = false;
1575 node->data.variable_declaration.is_const = false;1572 } else if (var_or_const_tok->id == TokenIdKeywordConst) {
1576 *token_index += 1;1573 is_const = true;
1577 name_token = &pc->tokens->at(*token_index);1574 } else if (mandatory) {
1578 ast_expect_token(pc, name_token, TokenIdSymbol);1575 ast_invalid_token_error(pc, var_or_const_tok);
1579 } else if (token->id == TokenIdSymbol) {1576 } else {
1580 node->data.variable_declaration.is_const = true;1577 return nullptr;
1581 name_token = token;1578 }
1582 } else {
1583 ast_invalid_token_error(pc, token);
1584 }
15851579
1586 *token_index += 1;1580 *token_index += 1;
1587 ast_buf_from_token(pc, name_token, &node->data.variable_declaration.symbol);1581 AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, var_or_const_tok);
15881582
1589 Token *eq_or_colon = &pc->tokens->at(*token_index);1583 node->data.variable_declaration.is_const = is_const;
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);
15961584
1597 Token *eq_token = &pc->tokens->at(*token_index);1585 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
1598 if (eq_token->id == TokenIdEq) {1586 ast_buf_from_token(pc, name_token, &node->data.variable_declaration.symbol);
1599 *token_index += 1;
16001587
1601 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);1588 Token *eq_or_colon = &pc->tokens->at(*token_index);
1602 }1589 *token_index += 1;
1603 return node;1590 if (eq_or_colon->id == TokenIdEq) {
1604 } else {1591 node->data.variable_declaration.expr = ast_parse_expression(pc, token_index, true);
1605 ast_invalid_token_error(pc, eq_or_colon);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);
1606 }1601 }
1607 } else if (mandatory) {1602 return node;
1608 ast_invalid_token_error(pc, let_tok);
1609 } else {1603 } else {
1610 return nullptr;1604 ast_invalid_token_error(pc, eq_or_colon);
1611 }1605 }
1612}1606}
16131607
src/tokenizer.cpp+3-6
...@@ -179,10 +179,8 @@ static void end_token(Tokenize *t) {...@@ -179,10 +179,8 @@ static void end_token(Tokenize *t) {
179 t->cur_tok->id = TokenIdKeywordFn;179 t->cur_tok->id = TokenIdKeywordFn;
180 } else if (mem_eql_str(token_mem, token_len, "return")) {180 } else if (mem_eql_str(token_mem, token_len, "return")) {
181 t->cur_tok->id = TokenIdKeywordReturn;181 t->cur_tok->id = TokenIdKeywordReturn;
182 } else if (mem_eql_str(token_mem, token_len, "let")) {182 } else if (mem_eql_str(token_mem, token_len, "var")) {
183 t->cur_tok->id = TokenIdKeywordLet;183 t->cur_tok->id = TokenIdKeywordVar;
184 } else if (mem_eql_str(token_mem, token_len, "mut")) {
185 t->cur_tok->id = TokenIdKeywordMut;
186 } else if (mem_eql_str(token_mem, token_len, "const")) {184 } else if (mem_eql_str(token_mem, token_len, "const")) {
187 t->cur_tok->id = TokenIdKeywordConst;185 t->cur_tok->id = TokenIdKeywordConst;
188 } else if (mem_eql_str(token_mem, token_len, "extern")) {186 } else if (mem_eql_str(token_mem, token_len, "extern")) {
...@@ -797,9 +795,8 @@ static const char * token_name(Token *token) {...@@ -797,9 +795,8 @@ static const char * token_name(Token *token) {
797 case TokenIdSymbol: return "Symbol";795 case TokenIdSymbol: return "Symbol";
798 case TokenIdKeywordFn: return "Fn";796 case TokenIdKeywordFn: return "Fn";
799 case TokenIdKeywordConst: return "Const";797 case TokenIdKeywordConst: return "Const";
800 case TokenIdKeywordMut: return "Mut";798 case TokenIdKeywordVar: return "Var";
801 case TokenIdKeywordReturn: return "Return";799 case TokenIdKeywordReturn: return "Return";
802 case TokenIdKeywordLet: return "Let";
803 case TokenIdKeywordExtern: return "Extern";800 case TokenIdKeywordExtern: return "Extern";
804 case TokenIdKeywordUnreachable: return "Unreachable";801 case TokenIdKeywordUnreachable: return "Unreachable";
805 case TokenIdKeywordPub: return "Pub";802 case TokenIdKeywordPub: return "Pub";
src/tokenizer.hpp+1-2
...@@ -15,8 +15,7 @@ enum TokenId {...@@ -15,8 +15,7 @@ enum TokenId {
15 TokenIdSymbol,15 TokenIdSymbol,
16 TokenIdKeywordFn,16 TokenIdKeywordFn,
17 TokenIdKeywordReturn,17 TokenIdKeywordReturn,
18 TokenIdKeywordLet,18 TokenIdKeywordVar,
19 TokenIdKeywordMut,
20 TokenIdKeywordConst,19 TokenIdKeywordConst,
21 TokenIdKeywordExtern,20 TokenIdKeywordExtern,
22 TokenIdKeywordUnreachable,21 TokenIdKeywordUnreachable,
std/std.zig+3-3
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {1fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
2 let mut result : isize;2 var result : isize;
3 asm volatile ("3 asm volatile ("
4 mov %[number], %%rax4 mov %[number], %%rax
5 mov %[arg1], %%rdi5 mov %[arg1], %%rdi
...@@ -15,13 +15,13 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {...@@ -15,13 +15,13 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
1515
16// TODO constants for SYS_write and stdout_fileno16// TODO constants for SYS_write and stdout_fileno
17pub fn write(fd: isize, buf: &const u8, count: usize) -> isize {17pub fn write(fd: isize, buf: &const u8, count: usize) -> isize {
18 let SYS_write : isize = 1;18 const SYS_write : isize = 1;
19 return syscall3(SYS_write, fd, buf as isize, count as isize);19 return syscall3(SYS_write, fd, buf as isize, count as isize);
20}20}
2121
22// TODO error handling22// TODO error handling
23// TODO handle buffering and flushing23// TODO handle buffering and flushing
24pub fn print_str(str : string) -> isize {24pub fn print_str(str : string) -> isize {
25 let stdout_fileno : isize = 1;25 const stdout_fileno : isize = 1;
26 return write(stdout_fileno, str.ptr, str.len);26 return write(stdout_fileno, str.ptr, str.len);
27}27}
test/run_tests.cpp+26-26
...@@ -265,8 +265,8 @@ extern {...@@ -265,8 +265,8 @@ extern {
265}265}
266266
267export fn _start() -> unreachable {267export fn _start() -> unreachable {
268 let a : i32 = 1;268 const a : i32 = 1;
269 let b = 2 as i32;269 const b = 2 as i32;
270 if (a + b == 3) {270 if (a + b == 3) {
271 puts(c"OK");271 puts(c"OK");
272 }272 }
...@@ -299,12 +299,12 @@ extern {...@@ -299,12 +299,12 @@ extern {
299299
300export fn _start() -> unreachable {300export fn _start() -> unreachable {
301 if (true) {301 if (true) {
302 let no_conflict : i32 = 5;302 const no_conflict : i32 = 5;
303 if (no_conflict == 5) { puts(c"OK 1"); }303 if (no_conflict == 5) { puts(c"OK 1"); }
304 }304 }
305305
306 let c = {306 const c = {
307 let no_conflict = 10 as i32;307 const no_conflict = 10 as i32;
308 no_conflict308 no_conflict
309 };309 };
310 if (c == 10) { puts(c"OK 2"); }310 if (c == 10) { puts(c"OK 2"); }
...@@ -325,8 +325,8 @@ export fn _start() -> unreachable {...@@ -325,8 +325,8 @@ export fn _start() -> unreachable {
325}325}
326326
327fn void_fun(a : i32, b : void, c : i32) {327fn void_fun(a : i32, b : void, c : i32) {
328 let v = b;328 const v = b;
329 let vv : void = if (a == 1) {v} else {};329 const vv : void = if (a == 1) {v} else {};
330 if (a + c == 3) { puts(c"OK"); }330 if (a + c == 3) { puts(c"OK"); }
331 return vv;331 return vv;
332}332}
...@@ -340,10 +340,10 @@ extern {...@@ -340,10 +340,10 @@ extern {
340}340}
341341
342export fn _start() -> unreachable {342export fn _start() -> unreachable {
343 let mut zero : i32;343 var zero : i32;
344 if (zero == 0) { puts(c"zero"); }344 if (zero == 0) { puts(c"zero"); }
345345
346 let mut i = 0 as i32;346 var i = 0 as i32;
347loop_start:347loop_start:
348 if i == 3 {348 if i == 3 {
349 goto done;349 goto done;
...@@ -364,9 +364,9 @@ extern {...@@ -364,9 +364,9 @@ extern {
364}364}
365365
366export fn _start() -> unreachable {366export 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;
370loop_start:370loop_start:
371 if i == 5 {371 if i == 5 {
372 goto loop_end;372 goto loop_end;
...@@ -378,7 +378,7 @@ loop_start:...@@ -378,7 +378,7 @@ loop_start:
378loop_end:378loop_end:
379379
380 i = 0;380 i = 0;
381 let mut accumulator = 0 as i32;381 var accumulator = 0 as i32;
382loop_2_start:382loop_2_start:
383 if i == 5 {383 if i == 5 {
384 goto loop_2_end;384 goto loop_2_end;
...@@ -458,7 +458,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {...@@ -458,7 +458,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
458use "std.zig";458use "std.zig";
459459
460export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {460export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
461 let mut i : i32 = 0;461 var i : i32 = 0;
462 i += 5; if i != 5 { print_str("BAD +=\n" as string); }462 i += 5; if i != 5 { print_str("BAD +=\n" as string); }
463 i -= 2; if i != 3 { print_str("BAD -=\n" as string); }463 i -= 2; if i != 3 { print_str("BAD -=\n" as string); }
464 i *= 20; if i != 60 { print_str("BAD *=\n" as string); }464 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 {...@@ -481,7 +481,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
481use "std.zig";481use "std.zig";
482482
483export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {483export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
484 let mut foo : Foo;484 var foo : Foo;
485 foo.a = foo.a + 1;485 foo.a = foo.a + 1;
486 foo.b = foo.a == 1;486 foo.b = foo.a == 1;
487 test_foo(foo);487 test_foo(foo);
...@@ -589,20 +589,20 @@ fn f(a : i32, a : i32) {...@@ -589,20 +589,20 @@ fn f(a : i32, a : i32) {
589589
590 add_compile_fail_case("local variable redeclaration", R"SOURCE(590 add_compile_fail_case("local variable redeclaration", R"SOURCE(
591fn f() {591fn f() {
592 let a : i32 = 0;592 const a : i32 = 0;
593 let a = 0;593 const a = 0;
594}594}
595 )SOURCE", 1, ".tmp_source.zig:4:5: error: redeclaration of variable 'a'");595 )SOURCE", 1, ".tmp_source.zig:4:5: error: redeclaration of variable 'a'");
596596
597 add_compile_fail_case("local variable redeclares parameter", R"SOURCE(597 add_compile_fail_case("local variable redeclares parameter", R"SOURCE(
598fn f(a : i32) {598fn f(a : i32) {
599 let a = 0;599 const a = 0;
600}600}
601 )SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");601 )SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
602602
603 add_compile_fail_case("variable has wrong type", R"SOURCE(603 add_compile_fail_case("variable has wrong type", R"SOURCE(
604fn f() -> i32 {604fn f() -> i32 {
605 let a = c"a";605 const a = c"a";
606 a606 a
607}607}
608 )SOURCE", 1, ".tmp_source.zig:2:15: error: expected type 'i32', got '&const u8'");608 )SOURCE", 1, ".tmp_source.zig:2:15: error: expected type 'i32', got '&const u8'");
...@@ -615,15 +615,15 @@ fn f() {...@@ -615,15 +615,15 @@ fn f() {
615615
616 add_compile_fail_case("assign unreachable", R"SOURCE(616 add_compile_fail_case("assign unreachable", R"SOURCE(
617fn f() {617fn f() {
618 let a = return;618 const a = return;
619}619}
620 )SOURCE", 1, ".tmp_source.zig:3:5: error: variable initialization is unreachable");620 )SOURCE", 1, ".tmp_source.zig:3:5: error: variable initialization is unreachable");
621621
622 add_compile_fail_case("unreachable variable", R"SOURCE(622 add_compile_fail_case("unreachable variable", R"SOURCE(
623fn f() {623fn f() {
624 let a : unreachable = return;624 const a : unreachable = return;
625}625}
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
628 add_compile_fail_case("unreachable parameter", R"SOURCE(628 add_compile_fail_case("unreachable parameter", R"SOURCE(
629fn f(a : unreachable) {}629fn f(a : unreachable) {}
...@@ -647,7 +647,7 @@ fn f() {...@@ -647,7 +647,7 @@ fn f() {
647647
648 add_compile_fail_case("assign to constant variable", R"SOURCE(648 add_compile_fail_case("assign to constant variable", R"SOURCE(
649fn f() {649fn f() {
650 let a = 3;650 const a = 3;
651 a = 4;651 a = 4;
652}652}
653 )SOURCE", 1, ".tmp_source.zig:4:5: error: cannot assign to constant variable");653 )SOURCE", 1, ".tmp_source.zig:4:5: error: cannot assign to constant variable");
...@@ -658,15 +658,15 @@ fn f() {...@@ -658,15 +658,15 @@ fn f() {
658}658}
659 )SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'");659 )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(
662fn f() {662fn f() {
663 (let a = 0);663 (const a = 0);
664}664}
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
667 add_compile_fail_case("array access errors", R"SOURCE(667 add_compile_fail_case("array access errors", R"SOURCE(
668fn f() {668fn f() {
669 let mut bad : bool;669 var bad : bool;
670 i[i] = i[i];670 i[i] = i[i];
671 bad[bad] = bad[bad];671 bad[bad] = bad[bad];
672}672}