authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-26 04:30:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-03-26 04:32:13-04:00
log22e6bfca9602fdb79f669b494fa7f1c58094706c
tree560c8a37e895e914afaa1386a1b3a48d839d5e95
parent9ae426a06b2e380e688fa0b4d4ad1587bebefa64

add comptime top level declaration

closes #255

7 files changed, 95 insertions(+), 69 deletions(-)

doc/langref.md+1-1
...@@ -5,7 +5,7 @@...@@ -5,7 +5,7 @@
5```5```
6Root = many(TopLevelItem) "EOF"6Root = many(TopLevelItem) "EOF"
77
8TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl8TopLevelItem = ErrorValueDecl | CompTimeExpression | TopLevelDecl | TestDecl
99
10TestDecl = "test" String Block10TestDecl = "test" String Block
1111
src/all_types.hpp+5-4
...@@ -242,6 +242,7 @@ enum TldId {...@@ -242,6 +242,7 @@ enum TldId {
242 TldIdFn,242 TldIdFn,
243 TldIdContainer,243 TldIdContainer,
244 TldIdTypeDef,244 TldIdTypeDef,
245 TldIdCompTime,
245};246};
246247
247enum TldResolution {248enum TldResolution {
...@@ -293,6 +294,10 @@ struct TldTypeDef {...@@ -293,6 +294,10 @@ struct TldTypeDef {
293 TypeTableEntry *type_entry;294 TypeTableEntry *type_entry;
294};295};
295296
297struct TldCompTime {
298 Tld base;
299};
300
296struct TypeEnumField {301struct TypeEnumField {
297 Buf *name;302 Buf *name;
298 TypeTableEntry *type_entry;303 TypeTableEntry *type_entry;
...@@ -430,16 +435,12 @@ struct AstNodeTypeDecl {...@@ -430,16 +435,12 @@ struct AstNodeTypeDecl {
430};435};
431436
432struct AstNodeErrorValueDecl {437struct AstNodeErrorValueDecl {
433 // always invalid if it's not VisibModPrivate but can be parsed that way
434 VisibMod visib_mod;
435 Buf *name;438 Buf *name;
436439
437 ErrorTableEntry *err;440 ErrorTableEntry *err;
438};441};
439442
440struct AstNodeTestDecl {443struct AstNodeTestDecl {
441 // always invalid if it's not VisibModPrivate but can be parsed that way
442 VisibMod visib_mod;
443 Buf *name;444 Buf *name;
444445
445 AstNode *body;446 AstNode *body;
src/analyze.cpp+24-9
...@@ -1924,6 +1924,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -1924,6 +1924,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
1924 }1924 }
1925}1925}
19261926
1927static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {
1928 assert(tld_comptime->base.source_node->type == NodeTypeCompTime);
1929 AstNode *expr_node = tld_comptime->base.source_node->data.comptime_expr.expr;
1930 analyze_const_value(g, tld_comptime->base.parent_scope, expr_node, g->builtin_types.entry_void, nullptr);
1931}
1932
1927static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {1933static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
1928 if (tld->visib_mod == VisibModExport ||1934 if (tld->visib_mod == VisibModExport ||
1929 (buf_eql_str(tld->name, "panic") &&1935 (buf_eql_str(tld->name, "panic") &&
...@@ -1955,10 +1961,6 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {...@@ -1955,10 +1961,6 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
1955static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {1961static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
1956 assert(node->type == NodeTypeTestDecl);1962 assert(node->type == NodeTypeTestDecl);
19571963
1958 if (node->data.test_decl.visib_mod != VisibModPrivate) {
1959 add_node_error(g, node, buf_sprintf("tests require no visibility modifier"));
1960 }
1961
1962 if (!g->is_test_build)1964 if (!g->is_test_build)
1963 return;1965 return;
19641966
...@@ -1976,10 +1978,6 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope...@@ -1976,10 +1978,6 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope
1976static void preview_error_value_decl(CodeGen *g, AstNode *node) {1978static void preview_error_value_decl(CodeGen *g, AstNode *node) {
1977 assert(node->type == NodeTypeErrorValueDecl);1979 assert(node->type == NodeTypeErrorValueDecl);
19781980
1979 if (node->data.error_value_decl.visib_mod != VisibModPrivate) {
1980 add_node_error(g, node, buf_sprintf("error values require no visibility modifier"));
1981 }
1982
1983 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);1981 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
19841982
1985 err->decl_node = node;1983 err->decl_node = node;
...@@ -2000,6 +1998,15 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {...@@ -2000,6 +1998,15 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
2000 node->data.error_value_decl.err = err;1998 node->data.error_value_decl.err = err;
2001}1999}
20022000
2001static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
2002 assert(node->type == NodeTypeCompTime);
2003
2004 TldCompTime *tld_comptime = allocate<TldCompTime>(1);
2005 init_tld(&tld_comptime->base, TldIdCompTime, nullptr, VisibModPrivate, node, &decls_scope->base);
2006 g->resolve_queue.append(&tld_comptime->base);
2007}
2008
2009
2003void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,2010void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,
2004 Scope *parent_scope)2011 Scope *parent_scope)
2005{2012{
...@@ -2069,6 +2076,9 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -2069,6 +2076,9 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
2069 case NodeTypeTestDecl:2076 case NodeTypeTestDecl:
2070 preview_test_decl(g, node, decls_scope);2077 preview_test_decl(g, node, decls_scope);
2071 break;2078 break;
2079 case NodeTypeCompTime:
2080 preview_comptime_decl(g, node, decls_scope);
2081 break;
2072 case NodeTypeContainerDecl:2082 case NodeTypeContainerDecl:
2073 case NodeTypeParamDecl:2083 case NodeTypeParamDecl:
2074 case NodeTypeFnDecl:2084 case NodeTypeFnDecl:
...@@ -2098,7 +2108,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {...@@ -2098,7 +2108,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
2098 case NodeTypeSwitchRange:2108 case NodeTypeSwitchRange:
2099 case NodeTypeLabel:2109 case NodeTypeLabel:
2100 case NodeTypeGoto:2110 case NodeTypeGoto:
2101 case NodeTypeCompTime:
2102 case NodeTypeBreak:2111 case NodeTypeBreak:
2103 case NodeTypeContinue:2112 case NodeTypeContinue:
2104 case NodeTypeAsmExpr:2113 case NodeTypeAsmExpr:
...@@ -2357,6 +2366,12 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) {...@@ -2357,6 +2366,12 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) {
2357 resolve_decl_typedef(g, tld_typedef);2366 resolve_decl_typedef(g, tld_typedef);
2358 break;2367 break;
2359 }2368 }
2369 case TldIdCompTime:
2370 {
2371 TldCompTime *tld_comptime = (TldCompTime *)tld;
2372 resolve_decl_comptime(g, tld_comptime);
2373 break;
2374 }
2360 }2375 }
23612376
2362 tld->resolution = TldResolutionOk;2377 tld->resolution = TldResolutionOk;
src/ast_render.cpp+4-1
...@@ -1055,7 +1055,7 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {...@@ -1055,7 +1055,7 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {
10551055
1056 Tld *tld = entry->value;1056 Tld *tld = entry->value;
10571057
1058 if (!buf_eql_buf(entry->key, tld->name)) {1058 if (tld->name != nullptr && !buf_eql_buf(entry->key, tld->name)) {
1059 fprintf(ar.f, "pub const ");1059 fprintf(ar.f, "pub const ");
1060 print_symbol(&ar, entry->key);1060 print_symbol(&ar, entry->key);
1061 fprintf(ar.f, " = %s;\n", buf_ptr(tld->name));1061 fprintf(ar.f, " = %s;\n", buf_ptr(tld->name));
...@@ -1075,6 +1075,9 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {...@@ -1075,6 +1075,9 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {
1075 case TldIdTypeDef:1075 case TldIdTypeDef:
1076 ast_render_tld_typedef(&ar, entry->key, (TldTypeDef *)tld);1076 ast_render_tld_typedef(&ar, entry->key, (TldTypeDef *)tld);
1077 break;1077 break;
1078 case TldIdCompTime:
1079 fprintf(stdout, "comptime\n");
1080 break;
1078 }1081 }
1079 }1082 }
1080}1083}
src/ir.cpp+2
...@@ -9114,6 +9114,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source...@@ -9114,6 +9114,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
91149114
9115 switch (tld->id) {9115 switch (tld->id) {
9116 case TldIdContainer:9116 case TldIdContainer:
9117 case TldIdCompTime:
9117 zig_unreachable();9118 zig_unreachable();
9118 case TldIdVar:9119 case TldIdVar:
9119 {9120 {
...@@ -12122,6 +12123,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,...@@ -12122,6 +12123,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
1212212123
12123 switch (tld->id) {12124 switch (tld->id) {
12124 case TldIdContainer:12125 case TldIdContainer:
12126 case TldIdCompTime:
12125 zig_unreachable();12127 zig_unreachable();
12126 case TldIdVar:12128 case TldIdVar:
12127 {12129 {
src/parser.cpp+21-17
...@@ -2399,7 +2399,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,...@@ -2399,7 +2399,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
2399/*2399/*
2400ErrorValueDecl : "error" "Symbol" ";"2400ErrorValueDecl : "error" "Symbol" ";"
2401*/2401*/
2402static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {2402static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index) {
2403 Token *first_token = &pc->tokens->at(*token_index);2403 Token *first_token = &pc->tokens->at(*token_index);
24042404
2405 if (first_token->id != TokenIdKeywordError) {2405 if (first_token->id != TokenIdKeywordError) {
...@@ -2411,7 +2411,6 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index...@@ -2411,7 +2411,6 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
2411 ast_eat_token(pc, token_index, TokenIdSemicolon);2411 ast_eat_token(pc, token_index, TokenIdSemicolon);
24122412
2413 AstNode *node = ast_create_node(pc, NodeTypeErrorValueDecl, first_token);2413 AstNode *node = ast_create_node(pc, NodeTypeErrorValueDecl, first_token);
2414 node->data.error_value_decl.visib_mod = visib_mod;
2415 node->data.error_value_decl.name = token_buf(name_tok);2414 node->data.error_value_decl.name = token_buf(name_tok);
24162415
2417 return node;2416 return node;
...@@ -2420,7 +2419,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index...@@ -2420,7 +2419,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
2420/*2419/*
2421TestDecl = "test" String Block2420TestDecl = "test" String Block
2422*/2421*/
2423static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {2422static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index) {
2424 Token *first_token = &pc->tokens->at(*token_index);2423 Token *first_token = &pc->tokens->at(*token_index);
24252424
2426 if (first_token->id != TokenIdKeywordTest) {2425 if (first_token->id != TokenIdKeywordTest) {
...@@ -2431,7 +2430,6 @@ static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index,...@@ -2431,7 +2430,6 @@ static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index,
2431 Token *name_tok = ast_eat_token(pc, token_index, TokenIdStringLiteral);2430 Token *name_tok = ast_eat_token(pc, token_index, TokenIdStringLiteral);
24322431
2433 AstNode *node = ast_create_node(pc, NodeTypeTestDecl, first_token);2432 AstNode *node = ast_create_node(pc, NodeTypeTestDecl, first_token);
2434 node->data.test_decl.visib_mod = visib_mod;
2435 node->data.test_decl.name = token_buf(name_tok);2433 node->data.test_decl.name = token_buf(name_tok);
2436 node->data.test_decl.body = ast_parse_block(pc, token_index, true);2434 node->data.test_decl.body = ast_parse_block(pc, token_index, true);
24372435
...@@ -2464,11 +2462,29 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib...@@ -2464,11 +2462,29 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib
2464}2462}
24652463
2466/*2464/*
2467TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl2465TopLevelItem = ErrorValueDecl | CompTimeExpression | TopLevelDecl | TestDecl
2468TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl)2466TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl)
2469*/2467*/
2470static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) {2468static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) {
2471 for (;;) {2469 for (;;) {
2470 AstNode *comptime_expr_node = ast_parse_comptime_expr(pc, token_index, false);
2471 if (comptime_expr_node) {
2472 top_level_decls->append(comptime_expr_node);
2473 continue;
2474 }
2475
2476 AstNode *error_value_node = ast_parse_error_value_decl(pc, token_index);
2477 if (error_value_node) {
2478 top_level_decls->append(error_value_node);
2479 continue;
2480 }
2481
2482 AstNode *test_decl_node = ast_parse_test_decl_node(pc, token_index);
2483 if (test_decl_node) {
2484 top_level_decls->append(test_decl_node);
2485 continue;
2486 }
2487
2472 Token *visib_tok = &pc->tokens->at(*token_index);2488 Token *visib_tok = &pc->tokens->at(*token_index);
2473 VisibMod visib_mod;2489 VisibMod visib_mod;
2474 if (visib_tok->id == TokenIdKeywordPub) {2490 if (visib_tok->id == TokenIdKeywordPub) {
...@@ -2506,18 +2522,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig...@@ -2506,18 +2522,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
2506 continue;2522 continue;
2507 }2523 }
25082524
2509 AstNode *error_value_node = ast_parse_error_value_decl(pc, token_index, visib_mod);
2510 if (error_value_node) {
2511 top_level_decls->append(error_value_node);
2512 continue;
2513 }
2514
2515 AstNode *test_decl_node = ast_parse_test_decl_node(pc, token_index, visib_mod);
2516 if (test_decl_node) {
2517 top_level_decls->append(test_decl_node);
2518 continue;
2519 }
2520
2521 AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, visib_mod);2525 AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, visib_mod);
2522 if (type_decl_node) {2526 if (type_decl_node) {
2523 top_level_decls->append(type_decl_node);2527 top_level_decls->append(type_decl_node);
test/self_hosted.zig+38-37
...@@ -1,37 +1,38 @@...@@ -1,37 +1,38 @@
1// TODO '_' identifier for unused variable bindings1comptime {
2const test_array = @import("cases/array.zig");2 _ = @import("cases/array.zig");
3const test_atomics = @import("cases/atomics.zig");3 _ = @import("cases/atomics.zig");
4const test_bool = @import("cases/bool.zig");4 _ = @import("cases/bool.zig");
5const test_cast = @import("cases/cast.zig");5 _ = @import("cases/cast.zig");
6const test_const_slice_child = @import("cases/const_slice_child.zig");6 _ = @import("cases/const_slice_child.zig");
7const test_defer = @import("cases/defer.zig");7 _ = @import("cases/defer.zig");
8const test_enum = @import("cases/enum.zig");8 _ = @import("cases/enum.zig");
9const test_enum_with_members = @import("cases/enum_with_members.zig");9 _ = @import("cases/enum_with_members.zig");
10const test_error = @import("cases/error.zig");10 _ = @import("cases/error.zig");
11const test_eval = @import("cases/eval.zig");11 _ = @import("cases/eval.zig");
12const test_fn = @import("cases/fn.zig");12 _ = @import("cases/fn.zig");
13const test_for = @import("cases/for.zig");13 _ = @import("cases/for.zig");
14const test_generics = @import("cases/generics.zig");14 _ = @import("cases/generics.zig");
15const test_goto = @import("cases/goto.zig");15 _ = @import("cases/goto.zig");
16const test_if = @import("cases/if.zig");16 _ = @import("cases/if.zig");
17const test_import = @import("cases/import.zig");17 _ = @import("cases/import.zig");
18const test_incomplete_struct_param_tld = @import("cases/incomplete_struct_param_tld.zig");18 _ = @import("cases/incomplete_struct_param_tld.zig");
19const test_ir_block_deps = @import("cases/ir_block_deps.zig");19 _ = @import("cases/ir_block_deps.zig");
20const test_math = @import("cases/math.zig");20 _ = @import("cases/math.zig");
21const test_misc = @import("cases/misc.zig");21 _ = @import("cases/misc.zig");
22const test_namespace_depends_on_compile_var = @import("cases/namespace_depends_on_compile_var/index.zig");22 _ = @import("cases/namespace_depends_on_compile_var/index.zig");
23const test_null = @import("cases/null.zig");23 _ = @import("cases/null.zig");
24const test_pub_enum = @import("cases/pub_enum/index.zig");24 _ = @import("cases/pub_enum/index.zig");
25const test_sizeof_and_typeof = @import("cases/sizeof_and_typeof.zig");25 _ = @import("cases/sizeof_and_typeof.zig");
26const test_struct = @import("cases/struct.zig");26 _ = @import("cases/struct.zig");
27const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig");27 _ = @import("cases/struct_contains_slice_of_itself.zig");
28const test_switch = @import("cases/switch.zig");28 _ = @import("cases/switch.zig");
29const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");29 _ = @import("cases/switch_prong_err_enum.zig");
30const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig");30 _ = @import("cases/switch_prong_implicit_cast.zig");
31const test_this = @import("cases/this.zig");31 _ = @import("cases/this.zig");
32const test_try = @import("cases/try.zig");32 _ = @import("cases/try.zig");
33const test_typedef = @import("cases/typedef.zig");33 _ = @import("cases/typedef.zig");
34const test_undefined = @import("cases/undefined.zig");34 _ = @import("cases/undefined.zig");
35const test_var_args = @import("cases/var_args.zig");35 _ = @import("cases/var_args.zig");
36const test_void = @import("cases/void.zig");36 _ = @import("cases/void.zig");
37const test_while = @import("cases/while.zig");37 _ = @import("cases/while.zig");
38}