Commit 22e6bfca96
Changed files (7)
doc/langref.md
@@ -5,7 +5,7 @@
```
Root = many(TopLevelItem) "EOF"
-TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl
+TopLevelItem = ErrorValueDecl | CompTimeExpression | TopLevelDecl | TestDecl
TestDecl = "test" String Block
src/all_types.hpp
@@ -242,6 +242,7 @@ enum TldId {
TldIdFn,
TldIdContainer,
TldIdTypeDef,
+ TldIdCompTime,
};
enum TldResolution {
@@ -293,6 +294,10 @@ struct TldTypeDef {
TypeTableEntry *type_entry;
};
+struct TldCompTime {
+ Tld base;
+};
+
struct TypeEnumField {
Buf *name;
TypeTableEntry *type_entry;
@@ -430,16 +435,12 @@ struct AstNodeTypeDecl {
};
struct AstNodeErrorValueDecl {
- // always invalid if it's not VisibModPrivate but can be parsed that way
- VisibMod visib_mod;
Buf *name;
ErrorTableEntry *err;
};
struct AstNodeTestDecl {
- // always invalid if it's not VisibModPrivate but can be parsed that way
- VisibMod visib_mod;
Buf *name;
AstNode *body;
src/analyze.cpp
@@ -1924,6 +1924,12 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
}
}
+static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {
+ assert(tld_comptime->base.source_node->type == NodeTypeCompTime);
+ AstNode *expr_node = tld_comptime->base.source_node->data.comptime_expr.expr;
+ analyze_const_value(g, tld_comptime->base.parent_scope, expr_node, g->builtin_types.entry_void, nullptr);
+}
+
static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
if (tld->visib_mod == VisibModExport ||
(buf_eql_str(tld->name, "panic") &&
@@ -1955,10 +1961,6 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
assert(node->type == NodeTypeTestDecl);
- if (node->data.test_decl.visib_mod != VisibModPrivate) {
- add_node_error(g, node, buf_sprintf("tests require no visibility modifier"));
- }
-
if (!g->is_test_build)
return;
@@ -1976,10 +1978,6 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope
static void preview_error_value_decl(CodeGen *g, AstNode *node) {
assert(node->type == NodeTypeErrorValueDecl);
- if (node->data.error_value_decl.visib_mod != VisibModPrivate) {
- add_node_error(g, node, buf_sprintf("error values require no visibility modifier"));
- }
-
ErrorTableEntry *err = allocate<ErrorTableEntry>(1);
err->decl_node = node;
@@ -2000,6 +1998,15 @@ static void preview_error_value_decl(CodeGen *g, AstNode *node) {
node->data.error_value_decl.err = err;
}
+static void preview_comptime_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope) {
+ assert(node->type == NodeTypeCompTime);
+
+ TldCompTime *tld_comptime = allocate<TldCompTime>(1);
+ init_tld(&tld_comptime->base, TldIdCompTime, nullptr, VisibModPrivate, node, &decls_scope->base);
+ g->resolve_queue.append(&tld_comptime->base);
+}
+
+
void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node,
Scope *parent_scope)
{
@@ -2069,6 +2076,9 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
case NodeTypeTestDecl:
preview_test_decl(g, node, decls_scope);
break;
+ case NodeTypeCompTime:
+ preview_comptime_decl(g, node, decls_scope);
+ break;
case NodeTypeContainerDecl:
case NodeTypeParamDecl:
case NodeTypeFnDecl:
@@ -2098,7 +2108,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
case NodeTypeSwitchRange:
case NodeTypeLabel:
case NodeTypeGoto:
- case NodeTypeCompTime:
case NodeTypeBreak:
case NodeTypeContinue:
case NodeTypeAsmExpr:
@@ -2357,6 +2366,12 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only) {
resolve_decl_typedef(g, tld_typedef);
break;
}
+ case TldIdCompTime:
+ {
+ TldCompTime *tld_comptime = (TldCompTime *)tld;
+ resolve_decl_comptime(g, tld_comptime);
+ break;
+ }
}
tld->resolution = TldResolutionOk;
src/ast_render.cpp
@@ -1055,7 +1055,7 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {
Tld *tld = entry->value;
- if (!buf_eql_buf(entry->key, tld->name)) {
+ if (tld->name != nullptr && !buf_eql_buf(entry->key, tld->name)) {
fprintf(ar.f, "pub const ");
print_symbol(&ar, entry->key);
fprintf(ar.f, " = %s;\n", buf_ptr(tld->name));
@@ -1075,6 +1075,9 @@ void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {
case TldIdTypeDef:
ast_render_tld_typedef(&ar, entry->key, (TldTypeDef *)tld);
break;
+ case TldIdCompTime:
+ fprintf(stdout, "comptime\n");
+ break;
}
}
}
src/ir.cpp
@@ -9114,6 +9114,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
switch (tld->id) {
case TldIdContainer:
+ case TldIdCompTime:
zig_unreachable();
case TldIdVar:
{
@@ -12122,6 +12123,7 @@ static TypeTableEntry *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
switch (tld->id) {
case TldIdContainer:
+ case TldIdCompTime:
zig_unreachable();
case TldIdVar:
{
src/parser.cpp
@@ -2399,7 +2399,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
/*
ErrorValueDecl : "error" "Symbol" ";"
*/
-static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {
+static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index) {
Token *first_token = &pc->tokens->at(*token_index);
if (first_token->id != TokenIdKeywordError) {
@@ -2411,7 +2411,6 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
ast_eat_token(pc, token_index, TokenIdSemicolon);
AstNode *node = ast_create_node(pc, NodeTypeErrorValueDecl, first_token);
- node->data.error_value_decl.visib_mod = visib_mod;
node->data.error_value_decl.name = token_buf(name_tok);
return node;
@@ -2420,7 +2419,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
/*
TestDecl = "test" String Block
*/
-static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {
+static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index) {
Token *first_token = &pc->tokens->at(*token_index);
if (first_token->id != TokenIdKeywordTest) {
@@ -2431,7 +2430,6 @@ static AstNode *ast_parse_test_decl_node(ParseContext *pc, size_t *token_index,
Token *name_tok = ast_eat_token(pc, token_index, TokenIdStringLiteral);
AstNode *node = ast_create_node(pc, NodeTypeTestDecl, first_token);
- node->data.test_decl.visib_mod = visib_mod;
node->data.test_decl.name = token_buf(name_tok);
node->data.test_decl.body = ast_parse_block(pc, token_index, true);
@@ -2464,11 +2462,29 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, Visib
}
/*
-TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl
+TopLevelItem = ErrorValueDecl | CompTimeExpression | TopLevelDecl | TestDecl
TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | GlobalVarDecl | TypeDecl | UseDecl)
*/
static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) {
for (;;) {
+ AstNode *comptime_expr_node = ast_parse_comptime_expr(pc, token_index, false);
+ if (comptime_expr_node) {
+ top_level_decls->append(comptime_expr_node);
+ continue;
+ }
+
+ AstNode *error_value_node = ast_parse_error_value_decl(pc, token_index);
+ if (error_value_node) {
+ top_level_decls->append(error_value_node);
+ continue;
+ }
+
+ AstNode *test_decl_node = ast_parse_test_decl_node(pc, token_index);
+ if (test_decl_node) {
+ top_level_decls->append(test_decl_node);
+ continue;
+ }
+
Token *visib_tok = &pc->tokens->at(*token_index);
VisibMod visib_mod;
if (visib_tok->id == TokenIdKeywordPub) {
@@ -2506,18 +2522,6 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
continue;
}
- AstNode *error_value_node = ast_parse_error_value_decl(pc, token_index, visib_mod);
- if (error_value_node) {
- top_level_decls->append(error_value_node);
- continue;
- }
-
- AstNode *test_decl_node = ast_parse_test_decl_node(pc, token_index, visib_mod);
- if (test_decl_node) {
- top_level_decls->append(test_decl_node);
- continue;
- }
-
AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, visib_mod);
if (type_decl_node) {
top_level_decls->append(type_decl_node);
test/self_hosted.zig
@@ -1,37 +1,38 @@
-// TODO '_' identifier for unused variable bindings
-const test_array = @import("cases/array.zig");
-const test_atomics = @import("cases/atomics.zig");
-const test_bool = @import("cases/bool.zig");
-const test_cast = @import("cases/cast.zig");
-const test_const_slice_child = @import("cases/const_slice_child.zig");
-const test_defer = @import("cases/defer.zig");
-const test_enum = @import("cases/enum.zig");
-const test_enum_with_members = @import("cases/enum_with_members.zig");
-const test_error = @import("cases/error.zig");
-const test_eval = @import("cases/eval.zig");
-const test_fn = @import("cases/fn.zig");
-const test_for = @import("cases/for.zig");
-const test_generics = @import("cases/generics.zig");
-const test_goto = @import("cases/goto.zig");
-const test_if = @import("cases/if.zig");
-const test_import = @import("cases/import.zig");
-const test_incomplete_struct_param_tld = @import("cases/incomplete_struct_param_tld.zig");
-const test_ir_block_deps = @import("cases/ir_block_deps.zig");
-const test_math = @import("cases/math.zig");
-const test_misc = @import("cases/misc.zig");
-const test_namespace_depends_on_compile_var = @import("cases/namespace_depends_on_compile_var/index.zig");
-const test_null = @import("cases/null.zig");
-const test_pub_enum = @import("cases/pub_enum/index.zig");
-const test_sizeof_and_typeof = @import("cases/sizeof_and_typeof.zig");
-const test_struct = @import("cases/struct.zig");
-const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig");
-const test_switch = @import("cases/switch.zig");
-const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");
-const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cast.zig");
-const test_this = @import("cases/this.zig");
-const test_try = @import("cases/try.zig");
-const test_typedef = @import("cases/typedef.zig");
-const test_undefined = @import("cases/undefined.zig");
-const test_var_args = @import("cases/var_args.zig");
-const test_void = @import("cases/void.zig");
-const test_while = @import("cases/while.zig");
+comptime {
+ _ = @import("cases/array.zig");
+ _ = @import("cases/atomics.zig");
+ _ = @import("cases/bool.zig");
+ _ = @import("cases/cast.zig");
+ _ = @import("cases/const_slice_child.zig");
+ _ = @import("cases/defer.zig");
+ _ = @import("cases/enum.zig");
+ _ = @import("cases/enum_with_members.zig");
+ _ = @import("cases/error.zig");
+ _ = @import("cases/eval.zig");
+ _ = @import("cases/fn.zig");
+ _ = @import("cases/for.zig");
+ _ = @import("cases/generics.zig");
+ _ = @import("cases/goto.zig");
+ _ = @import("cases/if.zig");
+ _ = @import("cases/import.zig");
+ _ = @import("cases/incomplete_struct_param_tld.zig");
+ _ = @import("cases/ir_block_deps.zig");
+ _ = @import("cases/math.zig");
+ _ = @import("cases/misc.zig");
+ _ = @import("cases/namespace_depends_on_compile_var/index.zig");
+ _ = @import("cases/null.zig");
+ _ = @import("cases/pub_enum/index.zig");
+ _ = @import("cases/sizeof_and_typeof.zig");
+ _ = @import("cases/struct.zig");
+ _ = @import("cases/struct_contains_slice_of_itself.zig");
+ _ = @import("cases/switch.zig");
+ _ = @import("cases/switch_prong_err_enum.zig");
+ _ = @import("cases/switch_prong_implicit_cast.zig");
+ _ = @import("cases/this.zig");
+ _ = @import("cases/try.zig");
+ _ = @import("cases/typedef.zig");
+ _ = @import("cases/undefined.zig");
+ _ = @import("cases/var_args.zig");
+ _ = @import("cases/void.zig");
+ _ = @import("cases/while.zig");
+}