mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
parent
8b727557d3
commit
3049410260
9 changed files with 85 additions and 95 deletions
|
|
@ -70,7 +70,7 @@ Statement : Label | VariableDeclaration token(Semicolon) | NonBlockExpression to
|
|||
|
||||
Label: token(Symbol) token(Colon)
|
||||
|
||||
VariableDeclaration : token(Let) option(token(Mut)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
|
||||
VariableDeclaration : (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
|
||||
|
||||
Expression : BlockExpression | NonBlockExpression
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ export executable "arrays";
|
|||
use "std.zig";
|
||||
|
||||
export fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
|
||||
let mut array : [i32; 5];
|
||||
var array : [i32; 5];
|
||||
|
||||
let mut i : i32 = 0;
|
||||
var i : i32 = 0;
|
||||
loop_start:
|
||||
if i == 5 {
|
||||
goto loop_end;
|
||||
|
|
@ -17,7 +17,7 @@ loop_start:
|
|||
loop_end:
|
||||
|
||||
i = 0;
|
||||
let mut accumulator : i32 = 0;
|
||||
var accumulator : i32 = 0;
|
||||
loop_2_start:
|
||||
if i == 5 {
|
||||
goto loop_2_end;
|
||||
|
|
|
|||
|
|
@ -13,17 +13,17 @@ fn other_exit() -> unreachable {
|
|||
}
|
||||
|
||||
export fn _start() -> unreachable {
|
||||
let a : i32 = 1;
|
||||
let b = 2 as i32;
|
||||
// let c : i32; // not yet support for const variables
|
||||
// let d; // parse error
|
||||
const a : i32 = 1;
|
||||
const b = 2 as i32;
|
||||
// const c : i32; // not yet support for const variables
|
||||
// const d; // parse error
|
||||
if (a + b == 3) {
|
||||
let no_conflict : i32 = 5;
|
||||
const no_conflict : i32 = 5;
|
||||
if (no_conflict == 5) { puts(c"OK 1"); }
|
||||
}
|
||||
|
||||
let c = {
|
||||
let no_conflict : i32 = 10;
|
||||
const c = {
|
||||
const no_conflict : i32 = 10;
|
||||
no_conflict
|
||||
};
|
||||
if (c == 10) { puts(c"OK 2"); }
|
||||
|
|
@ -36,15 +36,15 @@ export fn _start() -> unreachable {
|
|||
}
|
||||
|
||||
fn void_fun(a : i32, b : void, c : i32) -> void {
|
||||
let x = a + 1; // i32
|
||||
let y = c + 1; // i32
|
||||
let z = b; // void
|
||||
let w : void = z; // void
|
||||
const x = a + 1; // i32
|
||||
const y = c + 1; // i32
|
||||
const z = b; // void
|
||||
const w : void = z; // void
|
||||
if (x + y == 4) { return w; }
|
||||
}
|
||||
|
||||
fn test_mutable_vars() {
|
||||
let mut i : i32 = 0;
|
||||
var i : i32 = 0;
|
||||
loop_start:
|
||||
if i == 3 {
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ export executable "structs";
|
|||
use "std.zig";
|
||||
|
||||
export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
|
||||
let mut foo : Foo;
|
||||
var foo : Foo;
|
||||
|
||||
foo.a = foo.a + 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -1561,29 +1561,28 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m
|
|||
}
|
||||
|
||||
/*
|
||||
VariableDeclaration : token(Let) option(token(Mut)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
|
||||
VariableDeclaration : (token(Var) | token(Const)) token(Symbol) (token(Eq) Expression | token(Colon) Type option(token(Eq) Expression))
|
||||
*/
|
||||
static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token_index, bool mandatory) {
|
||||
Token *let_tok = &pc->tokens->at(*token_index);
|
||||
if (let_tok->id == TokenIdKeywordLet) {
|
||||
*token_index += 1;
|
||||
AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, let_tok);
|
||||
Token *var_or_const_tok = &pc->tokens->at(*token_index);
|
||||
|
||||
Token *name_token;
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
if (token->id == TokenIdKeywordMut) {
|
||||
node->data.variable_declaration.is_const = false;
|
||||
*token_index += 1;
|
||||
name_token = &pc->tokens->at(*token_index);
|
||||
ast_expect_token(pc, name_token, TokenIdSymbol);
|
||||
} else if (token->id == TokenIdSymbol) {
|
||||
node->data.variable_declaration.is_const = true;
|
||||
name_token = token;
|
||||
bool is_const;
|
||||
if (var_or_const_tok->id == TokenIdKeywordVar) {
|
||||
is_const = false;
|
||||
} else if (var_or_const_tok->id == TokenIdKeywordConst) {
|
||||
is_const = true;
|
||||
} else if (mandatory) {
|
||||
ast_invalid_token_error(pc, var_or_const_tok);
|
||||
} else {
|
||||
ast_invalid_token_error(pc, token);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
*token_index += 1;
|
||||
AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, var_or_const_tok);
|
||||
|
||||
node->data.variable_declaration.is_const = is_const;
|
||||
|
||||
Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
|
||||
ast_buf_from_token(pc, name_token, &node->data.variable_declaration.symbol);
|
||||
|
||||
Token *eq_or_colon = &pc->tokens->at(*token_index);
|
||||
|
|
@ -1604,11 +1603,6 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, int *token
|
|||
} else {
|
||||
ast_invalid_token_error(pc, eq_or_colon);
|
||||
}
|
||||
} else if (mandatory) {
|
||||
ast_invalid_token_error(pc, let_tok);
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -179,10 +179,8 @@ static void end_token(Tokenize *t) {
|
|||
t->cur_tok->id = TokenIdKeywordFn;
|
||||
} else if (mem_eql_str(token_mem, token_len, "return")) {
|
||||
t->cur_tok->id = TokenIdKeywordReturn;
|
||||
} else if (mem_eql_str(token_mem, token_len, "let")) {
|
||||
t->cur_tok->id = TokenIdKeywordLet;
|
||||
} else if (mem_eql_str(token_mem, token_len, "mut")) {
|
||||
t->cur_tok->id = TokenIdKeywordMut;
|
||||
} else if (mem_eql_str(token_mem, token_len, "var")) {
|
||||
t->cur_tok->id = TokenIdKeywordVar;
|
||||
} else if (mem_eql_str(token_mem, token_len, "const")) {
|
||||
t->cur_tok->id = TokenIdKeywordConst;
|
||||
} else if (mem_eql_str(token_mem, token_len, "extern")) {
|
||||
|
|
@ -797,9 +795,8 @@ static const char * token_name(Token *token) {
|
|||
case TokenIdSymbol: return "Symbol";
|
||||
case TokenIdKeywordFn: return "Fn";
|
||||
case TokenIdKeywordConst: return "Const";
|
||||
case TokenIdKeywordMut: return "Mut";
|
||||
case TokenIdKeywordVar: return "Var";
|
||||
case TokenIdKeywordReturn: return "Return";
|
||||
case TokenIdKeywordLet: return "Let";
|
||||
case TokenIdKeywordExtern: return "Extern";
|
||||
case TokenIdKeywordUnreachable: return "Unreachable";
|
||||
case TokenIdKeywordPub: return "Pub";
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ enum TokenId {
|
|||
TokenIdSymbol,
|
||||
TokenIdKeywordFn,
|
||||
TokenIdKeywordReturn,
|
||||
TokenIdKeywordLet,
|
||||
TokenIdKeywordMut,
|
||||
TokenIdKeywordVar,
|
||||
TokenIdKeywordConst,
|
||||
TokenIdKeywordExtern,
|
||||
TokenIdKeywordUnreachable,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
|
||||
let mut result : isize;
|
||||
var result : isize;
|
||||
asm volatile ("
|
||||
mov %[number], %%rax
|
||||
mov %[arg1], %%rdi
|
||||
|
|
@ -15,13 +15,13 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize {
|
|||
|
||||
// TODO constants for SYS_write and stdout_fileno
|
||||
pub fn write(fd: isize, buf: &const u8, count: usize) -> isize {
|
||||
let SYS_write : isize = 1;
|
||||
const SYS_write : isize = 1;
|
||||
return syscall3(SYS_write, fd, buf as isize, count as isize);
|
||||
}
|
||||
|
||||
// TODO error handling
|
||||
// TODO handle buffering and flushing
|
||||
pub fn print_str(str : string) -> isize {
|
||||
let stdout_fileno : isize = 1;
|
||||
const stdout_fileno : isize = 1;
|
||||
return write(stdout_fileno, str.ptr, str.len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -265,8 +265,8 @@ extern {
|
|||
}
|
||||
|
||||
export fn _start() -> unreachable {
|
||||
let a : i32 = 1;
|
||||
let b = 2 as i32;
|
||||
const a : i32 = 1;
|
||||
const b = 2 as i32;
|
||||
if (a + b == 3) {
|
||||
puts(c"OK");
|
||||
}
|
||||
|
|
@ -299,12 +299,12 @@ extern {
|
|||
|
||||
export fn _start() -> unreachable {
|
||||
if (true) {
|
||||
let no_conflict : i32 = 5;
|
||||
const no_conflict : i32 = 5;
|
||||
if (no_conflict == 5) { puts(c"OK 1"); }
|
||||
}
|
||||
|
||||
let c = {
|
||||
let no_conflict = 10 as i32;
|
||||
const c = {
|
||||
const no_conflict = 10 as i32;
|
||||
no_conflict
|
||||
};
|
||||
if (c == 10) { puts(c"OK 2"); }
|
||||
|
|
@ -325,8 +325,8 @@ export fn _start() -> unreachable {
|
|||
}
|
||||
|
||||
fn void_fun(a : i32, b : void, c : i32) {
|
||||
let v = b;
|
||||
let vv : void = if (a == 1) {v} else {};
|
||||
const v = b;
|
||||
const vv : void = if (a == 1) {v} else {};
|
||||
if (a + c == 3) { puts(c"OK"); }
|
||||
return vv;
|
||||
}
|
||||
|
|
@ -340,10 +340,10 @@ extern {
|
|||
}
|
||||
|
||||
export fn _start() -> unreachable {
|
||||
let mut zero : i32;
|
||||
var zero : i32;
|
||||
if (zero == 0) { puts(c"zero"); }
|
||||
|
||||
let mut i = 0 as i32;
|
||||
var i = 0 as i32;
|
||||
loop_start:
|
||||
if i == 3 {
|
||||
goto done;
|
||||
|
|
@ -364,9 +364,9 @@ extern {
|
|||
}
|
||||
|
||||
export fn _start() -> unreachable {
|
||||
let mut array : [i32; 5];
|
||||
var array : [i32; 5];
|
||||
|
||||
let mut i : i32 = 0;
|
||||
var i : i32 = 0;
|
||||
loop_start:
|
||||
if i == 5 {
|
||||
goto loop_end;
|
||||
|
|
@ -378,7 +378,7 @@ loop_start:
|
|||
loop_end:
|
||||
|
||||
i = 0;
|
||||
let mut accumulator = 0 as i32;
|
||||
var accumulator = 0 as i32;
|
||||
loop_2_start:
|
||||
if i == 5 {
|
||||
goto loop_2_end;
|
||||
|
|
@ -458,7 +458,7 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
|
|||
use "std.zig";
|
||||
|
||||
export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
|
||||
let mut i : i32 = 0;
|
||||
var i : i32 = 0;
|
||||
i += 5; if i != 5 { print_str("BAD +=\n" as string); }
|
||||
i -= 2; if i != 3 { print_str("BAD -=\n" as string); }
|
||||
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 {
|
|||
use "std.zig";
|
||||
|
||||
export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
|
||||
let mut foo : Foo;
|
||||
var foo : Foo;
|
||||
foo.a = foo.a + 1;
|
||||
foo.b = foo.a == 1;
|
||||
test_foo(foo);
|
||||
|
|
@ -589,20 +589,20 @@ fn f(a : i32, a : i32) {
|
|||
|
||||
add_compile_fail_case("local variable redeclaration", R"SOURCE(
|
||||
fn f() {
|
||||
let a : i32 = 0;
|
||||
let a = 0;
|
||||
const a : i32 = 0;
|
||||
const a = 0;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:4:5: error: redeclaration of variable 'a'");
|
||||
|
||||
add_compile_fail_case("local variable redeclares parameter", R"SOURCE(
|
||||
fn f(a : i32) {
|
||||
let a = 0;
|
||||
const a = 0;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
|
||||
|
||||
add_compile_fail_case("variable has wrong type", R"SOURCE(
|
||||
fn f() -> i32 {
|
||||
let a = c"a";
|
||||
const a = c"a";
|
||||
a
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:2:15: error: expected type 'i32', got '&const u8'");
|
||||
|
|
@ -615,15 +615,15 @@ fn f() {
|
|||
|
||||
add_compile_fail_case("assign unreachable", R"SOURCE(
|
||||
fn f() {
|
||||
let a = return;
|
||||
const a = return;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: variable initialization is unreachable");
|
||||
|
||||
add_compile_fail_case("unreachable variable", R"SOURCE(
|
||||
fn f() {
|
||||
let a : unreachable = return;
|
||||
const a : unreachable = return;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:13: error: variable of type 'unreachable' not allowed");
|
||||
)SOURCE", 1, ".tmp_source.zig:3:15: error: variable of type 'unreachable' not allowed");
|
||||
|
||||
add_compile_fail_case("unreachable parameter", R"SOURCE(
|
||||
fn f(a : unreachable) {}
|
||||
|
|
@ -647,7 +647,7 @@ fn f() {
|
|||
|
||||
add_compile_fail_case("assign to constant variable", R"SOURCE(
|
||||
fn f() {
|
||||
let a = 3;
|
||||
const a = 3;
|
||||
a = 4;
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:4:5: error: cannot assign to constant variable");
|
||||
|
|
@ -658,15 +658,15 @@ fn f() {
|
|||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'");
|
||||
|
||||
add_compile_fail_case("let is a statement, not an expression", R"SOURCE(
|
||||
add_compile_fail_case("const is a statement, not an expression", R"SOURCE(
|
||||
fn f() {
|
||||
(let a = 0);
|
||||
(const a = 0);
|
||||
}
|
||||
)SOURCE", 1, ".tmp_source.zig:3:6: error: invalid token: 'let'");
|
||||
)SOURCE", 1, ".tmp_source.zig:3:6: error: invalid token: 'const'");
|
||||
|
||||
add_compile_fail_case("array access errors", R"SOURCE(
|
||||
fn f() {
|
||||
let mut bad : bool;
|
||||
var bad : bool;
|
||||
i[i] = i[i];
|
||||
bad[bad] = bad[bad];
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue