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 @@
55```
66Root = many(TopLevelItem) "EOF"
77
8TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl
8TopLevelItem = ErrorValueDecl | CompTimeExpression | TopLevelDecl | TestDecl
99
1010TestDecl = "test" String Block
1111
src/all_types.hpp+5-4
......@@ -242,6 +242,7 @@ enum TldId {
242242 TldIdFn,
243243 TldIdContainer,
244244 TldIdTypeDef,
245 TldIdCompTime,
245246};
246247
247248enum TldResolution {
......@@ -293,6 +294,10 @@ struct TldTypeDef {
293294 TypeTableEntry *type_entry;
294295};
295296
297struct TldCompTime {
298 Tld base;
299};
300
296301struct TypeEnumField {
297302 Buf *name;
298303 TypeTableEntry *type_entry;
......@@ -430,16 +435,12 @@ struct AstNodeTypeDecl {
430435};
431436
432437struct AstNodeErrorValueDecl {
433 // always invalid if it's not VisibModPrivate but can be parsed that way
434 VisibMod visib_mod;
435438 Buf *name;
436439
437440 ErrorTableEntry *err;
438441};
439442
440443struct AstNodeTestDecl {
441 // always invalid if it's not VisibModPrivate but can be parsed that way
442 VisibMod visib_mod;
443444 Buf *name;
444445
445446 AstNode *body;
src/analyze.cpp+24-9
......@@ -1924,6 +1924,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
19241924 }
19251925}
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
19271933static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
19281934 if (tld->visib_mod == VisibModExport ||
19291935 (buf_eql_str(tld->name, "panic") &&
......@@ -1955,10 +1961,6 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
19551961static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
19561962 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
19621964 if (!g->is_test_build)
19631965 return;
19641966
......@@ -1976,10 +1978,6 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope
19761978static void preview_error_value_decl(CodeGen *g, AstNode *node) {
19771979 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
19831981 ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
19841982
19851983 err->decl_node = node;
......@@ -2000,6 +1998,15 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
20001998 node->data.error_value_decl.err = err;
20011999}
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
20032010void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,
20042011 Scope *parent_scope)
20052012{
......@@ -2069,6 +2076,9 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
20692076 case NodeTypeTestDecl:
20702077 preview_test_decl(g, node, decls_scope);
20712078 break;
2079 case NodeTypeCompTime:
2080 preview_comptime_decl(g, node, decls_scope);
2081 break;
20722082 case NodeTypeContainerDecl:
20732083 case NodeTypeParamDecl:
20742084 case NodeTypeFnDecl:
......@@ -2098,7 +2108,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
20982108 case NodeTypeSwitchRange:
20992109 case NodeTypeLabel:
21002110 case NodeTypeGoto:
2101 case NodeTypeCompTime:
21022111 case NodeTypeBreak:
21032112 case NodeTypeContinue:
21042113 case NodeTypeAsmExpr:
......@@ -2357,6 +2366,12 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) {
23572366 resolve_decl_typedef(g, tld_typedef);
23582367 break;
23592368 }
2369 case TldIdCompTime:
2370 {
2371 TldCompTime *tld_comptime = (TldCompTime *)tld;
2372 resolve_decl_comptime(g, tld_comptime);
2373 break;
2374 }
23602375 }
23612376
23622377 tld->resolution = TldResolutionOk;
src/ast_render.cpp+4-1
......@@ -1055,7 +1055,7 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {
10551055
10561056 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)) {
10591059 fprintf(ar.f, "pub const ");
10601060 print_symbol(&ar, entry->key);
10611061 fprintf(ar.f, " = %s;\n", buf_ptr(tld->name));
......@@ -1075,6 +1075,9 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {
10751075 case TldIdTypeDef:
10761076 ast_render_tld_typedef(&ar, entry->key, (TldTypeDef *)tld);
10771077 break;
1078 case TldIdCompTime:
1079 fprintf(stdout, "comptime\n");
1080 break;
10781081 }
10791082 }
10801083}
src/ir.cpp+2
......@@ -9114,6 +9114,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
91149114
91159115 switch (tld->id) {
91169116 case TldIdContainer:
9117 case TldIdCompTime:
91179118 zig_unreachable();
91189119 case TldIdVar:
91199120 {
......@@ -12122,6 +12123,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
1212212123
1212312124 switch (tld->id) {
1212412125 case TldIdContainer:
12126 case TldIdCompTime:
1212512127 zig_unreachable();
1212612128 case TldIdVar:
1212712129 {
src/parser.cpp+21-17
......@@ -2399,7 +2399,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
23992399/*
24002400ErrorValueDecl : "error" "Symbol" ";"
24012401*/
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) {
24032403 Token *first_token = &pc->tokens->at(*token_index);
24042404
24052405 if (first_token->id != TokenIdKeywordError) {
......@@ -2411,7 +2411,6 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
24112411 ast_eat_token(pc, token_index, TokenIdSemicolon);
24122412
24132413 AstNode *node = ast_create_node(pc, NodeTypeErrorValueDecl, first_token);
2414 node->data.error_value_decl.visib_mod = visib_mod;
24152414 node->data.error_value_decl.name = token_buf(name_tok);
24162415
24172416 return node;
......@@ -2420,7 +2419,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
24202419/*
24212420TestDecl = "test" String Block
24222421*/
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) {
24242423 Token *first_token = &pc->tokens->at(*token_index);
24252424
24262425 if (first_token->id != TokenIdKeywordTest) {
......@@ -2431,7 +2430,6 @@ static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index,
24312430 Token *name_tok = ast_eat_token(pc, token_index, TokenIdStringLiteral);
24322431
24332432 AstNode *node = ast_create_node(pc, NodeTypeTestDecl, first_token);
2434 node->data.test_decl.visib_mod = visib_mod;
24352433 node->data.test_decl.name = token_buf(name_tok);
24362434 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
24642462}
24652463
24662464/*
2467TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl
2465TopLevelItem = ErrorValueDecl | CompTimeExpression | TopLevelDecl | TestDecl
24682466TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl)
24692467*/
24702468static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) {
24712469 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
24722488 Token *visib_tok = &pc->tokens->at(*token_index);
24732489 VisibMod visib_mod;
24742490 if (visib_tok->id == TokenIdKeywordPub) {
......@@ -2506,18 +2522,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
25062522 continue;
25072523 }
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
25212525 AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, visib_mod);
25222526 if (type_decl_node) {
25232527 top_level_decls->append(type_decl_node);
test/self_hosted.zig+38-37
......@@ -1,37 +1,38 @@
1// TODO '_' identifier for unused variable bindings
2const test_array = @import("cases/array.zig");
3const test_atomics = @import("cases/atomics.zig");
4const test_bool = @import("cases/bool.zig");
5const test_cast = @import("cases/cast.zig");
6const test_const_slice_child = @import("cases/const_slice_child.zig");
7const test_defer = @import("cases/defer.zig");
8const test_enum = @import("cases/enum.zig");
9const test_enum_with_members = @import("cases/enum_with_members.zig");
10const test_error = @import("cases/error.zig");
11const test_eval = @import("cases/eval.zig");
12const test_fn = @import("cases/fn.zig");
13const test_for = @import("cases/for.zig");
14const test_generics = @import("cases/generics.zig");
15const test_goto = @import("cases/goto.zig");
16const test_if = @import("cases/if.zig");
17const test_import = @import("cases/import.zig");
18const test_incomplete_struct_param_tld = @import("cases/incomplete_struct_param_tld.zig");
19const test_ir_block_deps = @import("cases/ir_block_deps.zig");
20const test_math = @import("cases/math.zig");
21const test_misc = @import("cases/misc.zig");
22const test_namespace_depends_on_compile_var = @import("cases/namespace_depends_on_compile_var/index.zig");
23const test_null = @import("cases/null.zig");
24const test_pub_enum = @import("cases/pub_enum/index.zig");
25const test_sizeof_and_typeof = @import("cases/sizeof_and_typeof.zig");
26const test_struct = @import("cases/struct.zig");
27const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig");
28const test_switch = @import("cases/switch.zig");
29const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");
30const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig");
31const test_this = @import("cases/this.zig");
32const test_try = @import("cases/try.zig");
33const test_typedef = @import("cases/typedef.zig");
34const test_undefined = @import("cases/undefined.zig");
35const test_var_args = @import("cases/var_args.zig");
36const test_void = @import("cases/void.zig");
37const test_while = @import("cases/while.zig");
1comptime {
2 _ = @import("cases/array.zig");
3 _ = @import("cases/atomics.zig");
4 _ = @import("cases/bool.zig");
5 _ = @import("cases/cast.zig");
6 _ = @import("cases/const_slice_child.zig");
7 _ = @import("cases/defer.zig");
8 _ = @import("cases/enum.zig");
9 _ = @import("cases/enum_with_members.zig");
10 _ = @import("cases/error.zig");
11 _ = @import("cases/eval.zig");
12 _ = @import("cases/fn.zig");
13 _ = @import("cases/for.zig");
14 _ = @import("cases/generics.zig");
15 _ = @import("cases/goto.zig");
16 _ = @import("cases/if.zig");
17 _ = @import("cases/import.zig");
18 _ = @import("cases/incomplete_struct_param_tld.zig");
19 _ = @import("cases/ir_block_deps.zig");
20 _ = @import("cases/math.zig");
21 _ = @import("cases/misc.zig");
22 _ = @import("cases/namespace_depends_on_compile_var/index.zig");
23 _ = @import("cases/null.zig");
24 _ = @import("cases/pub_enum/index.zig");
25 _ = @import("cases/sizeof_and_typeof.zig");
26 _ = @import("cases/struct.zig");
27 _ = @import("cases/struct_contains_slice_of_itself.zig");
28 _ = @import("cases/switch.zig");
29 _ = @import("cases/switch_prong_err_enum.zig");
30 _ = @import("cases/switch_prong_implicit_cast.zig");
31 _ = @import("cases/this.zig");
32 _ = @import("cases/try.zig");
33 _ = @import("cases/typedef.zig");
34 _ = @import("cases/undefined.zig");
35 _ = @import("cases/var_args.zig");
36 _ = @import("cases/void.zig");
37 _ = @import("cases/while.zig");
38}