mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
parent
9ae426a06b
commit
22e6bfca96
@ -5,7 +5,7 @@
|
||||
```
|
||||
Root = many(TopLevelItem) "EOF"
|
||||
|
||||
TopLevelItem = ErrorValueDecl | Block | TopLevelDecl | TestDecl
|
||||
TopLevelItem = ErrorValueDecl | CompTimeExpression | TopLevelDecl | TestDecl
|
||||
|
||||
TestDecl = "test" String Block
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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:
|
||||
{
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user