From bdca82ea66259de136ce9374e172f567ee93ef89 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 9 Jan 2016 00:37:48 -0700 Subject: [PATCH] implement pub const --- example/guess_number/main.zig | 4 ---- src/analyze.cpp | 23 +++++++++++++++++++++++ src/parser.cpp | 27 +++++++++++++++++++-------- src/parser.hpp | 1 + std/std.zig | 7 +++---- 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/example/guess_number/main.zig b/example/guess_number/main.zig index 52578d0a00..12b7a53752 100644 --- a/example/guess_number/main.zig +++ b/example/guess_number/main.zig @@ -3,10 +3,6 @@ export executable "guess_number"; use "std.zig"; use "rand.zig"; -// TODO don't duplicate these; implement pub const -const stdout_fileno : isize = 1; -const stderr_fileno : isize = 2; - pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 { print_str("Welcome to the Guess Number Game in Zig.\n"); diff --git a/src/analyze.cpp b/src/analyze.cpp index 141492689a..29729070af 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2635,6 +2635,29 @@ static void analyze_top_level_declaration(CodeGen *g, ImportTableEntry *import, } } } + + // import all the public variables + { + auto it = target_import->block_context->variable_table.entry_iterator(); + for (;;) { + auto *entry = it.next(); + if (!entry) + break; + + VariableTableEntry *var = entry->value; + bool is_pub = (var->decl_node->data.variable_declaration.visib_mod != VisibModPrivate); + if (is_pub) { + auto existing_entry = import->type_table.maybe_get(entry->key); + if (existing_entry) { + add_node_error(g, node, + buf_sprintf("import of variable '%s' overrides existing definition", + buf_ptr(&var->name))); + } else { + import->block_context->variable_table.put(entry->key, entry->value); + } + } + } + } break; } case NodeTypeStructDecl: diff --git a/src/parser.cpp b/src/parser.cpp index 567d5a9c0c..a27f2d66d9 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1965,23 +1965,34 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, int *token_index, bool m VariableDeclaration : option(FnVisibleMod) (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 *var_or_const_tok = &pc->tokens->at(*token_index); + Token *first_token = &pc->tokens->at(*token_index); - bool is_const; - if (var_or_const_tok->id == TokenIdKeywordVar) { - is_const = false; - } else if (var_or_const_tok->id == TokenIdKeywordConst) { - is_const = true; + VisibMod visib_mod; + + if (first_token->id == TokenIdKeywordPub) { + *token_index += 1; + visib_mod = VisibModPub; + } else if (first_token->id == TokenIdKeywordExport) { + *token_index += 1; + visib_mod = VisibModExport; + } else if (first_token->id == TokenIdKeywordVar || + first_token->id == TokenIdKeywordConst) + { + visib_mod = VisibModPrivate; } else if (mandatory) { - ast_invalid_token_error(pc, var_or_const_tok); + ast_invalid_token_error(pc, first_token); } else { return nullptr; } + Token *var_or_const_tok = &pc->tokens->at(*token_index); + bool is_const = (var_or_const_tok->id == TokenIdKeywordConst); *token_index += 1; - AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, var_or_const_tok); + + AstNode *node = ast_create_node(pc, NodeTypeVariableDeclaration, first_token); node->data.variable_declaration.is_const = is_const; + node->data.variable_declaration.visib_mod = visib_mod; Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol); ast_buf_from_token(pc, name_token, &node->data.variable_declaration.symbol); diff --git a/src/parser.hpp b/src/parser.hpp index 46ef69db02..43d8281657 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -126,6 +126,7 @@ struct AstNodeReturnExpr { struct AstNodeVariableDeclaration { Buf symbol; bool is_const; + VisibMod visib_mod; // one or both of type and expr will be non null AstNode *type; AstNode *expr; diff --git a/std/std.zig b/std/std.zig index 2ccacc3166..e1d669624f 100644 --- a/std/std.zig +++ b/std/std.zig @@ -1,8 +1,8 @@ use "syscall.zig"; -const stdin_fileno : isize = 0; -const stdout_fileno : isize = 1; -const stderr_fileno : isize = 2; +pub const stdin_fileno : isize = 0; +pub const stdout_fileno : isize = 1; +pub const stderr_fileno : isize = 2; // TODO error handling pub fn os_get_random_bytes(buf: &u8, count: usize) -> isize { @@ -41,7 +41,6 @@ pub fn print_i64(x: i64) -> isize { // TODO error handling pub fn readline(buf: []u8, out_len: &usize) -> bool { - // TODO unknown size array indexing operator const amt_read = read(stdin_fileno, buf.ptr, buf.len); if (amt_read < 0) { return true;