authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-08-08 20:43:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-08-08 20:43:38-07:00
log2ed949a6ae053262ee563b198a8758ba82f50e84
tree6bb367b942f9f4b319a9e1b452260e9a7725d6a3
parent0d5ecc4312f45f9288c4a349837f04b733405960

add zeroes value


11 files changed, 99 insertions(+), 14 deletions(-)

doc/langref.md+1-1
...@@ -151,7 +151,7 @@ GotoExpression = "goto" Symbol...@@ -151,7 +151,7 @@ GotoExpression = "goto" Symbol
151151
152GroupedExpression = "(" Expression ")"152GroupedExpression = "(" Expression ")"
153153
154KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type"154KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type"
155```155```
156156
157## Operator Precedence157## Operator Precedence
src/all_types.hpp+17-2
...@@ -62,11 +62,18 @@ struct ConstErrValue {...@@ -62,11 +62,18 @@ struct ConstErrValue {
62 ConstExprValue *payload;62 ConstExprValue *payload;
63};63};
6464
65enum ConstValSpecial {
66 ConstValSpecialOther,
67 ConstValSpecialUndef,
68 ConstValSpecialZeroes,
69};
70
65struct ConstExprValue {71struct ConstExprValue {
66 bool ok; // true if constant expression evalution worked72 bool ok;
67 bool depends_on_compile_var;73 bool depends_on_compile_var;
68 bool undef;74 ConstValSpecial special;
6975
76 // populated if val_type == ConstValTypeOk
70 union {77 union {
71 BigNum x_bignum;78 BigNum x_bignum;
72 bool x_bool;79 bool x_bool;
...@@ -167,6 +174,7 @@ enum NodeType {...@@ -167,6 +174,7 @@ enum NodeType {
167 NodeTypeBoolLiteral,174 NodeTypeBoolLiteral,
168 NodeTypeNullLiteral,175 NodeTypeNullLiteral,
169 NodeTypeUndefinedLiteral,176 NodeTypeUndefinedLiteral,
177 NodeTypeZeroesLiteral,
170 NodeTypeIfBoolExpr,178 NodeTypeIfBoolExpr,
171 NodeTypeIfVarExpr,179 NodeTypeIfVarExpr,
172 NodeTypeWhileExpr,180 NodeTypeWhileExpr,
...@@ -694,6 +702,12 @@ struct AstNodeUndefinedLiteral {...@@ -694,6 +702,12 @@ struct AstNodeUndefinedLiteral {
694 Expr resolved_expr;702 Expr resolved_expr;
695};703};
696704
705struct AstNodeZeroesLiteral {
706 // populated by semantic analyzer
707 StructValExprCodeGen resolved_struct_val_expr;
708 Expr resolved_expr;
709};
710
697struct AstNodeSymbolExpr {711struct AstNodeSymbolExpr {
698 Buf *symbol;712 Buf *symbol;
699713
...@@ -791,6 +805,7 @@ struct AstNode {...@@ -791,6 +805,7 @@ struct AstNode {
791 AstNodeStructValueField struct_val_field;805 AstNodeStructValueField struct_val_field;
792 AstNodeNullLiteral null_literal;806 AstNodeNullLiteral null_literal;
793 AstNodeUndefinedLiteral undefined_literal;807 AstNodeUndefinedLiteral undefined_literal;
808 AstNodeZeroesLiteral zeroes_literal;
794 AstNodeSymbolExpr symbol_expr;809 AstNodeSymbolExpr symbol_expr;
795 AstNodeBoolLiteral bool_literal;810 AstNodeBoolLiteral bool_literal;
796 AstNodeBreakExpr break_expr;811 AstNodeBreakExpr break_expr;
src/analyze.cpp+23-2
...@@ -90,6 +90,7 @@ static AstNode *first_executing_node(AstNode *node) {...@@ -90,6 +90,7 @@ static AstNode *first_executing_node(AstNode *node) {
90 case NodeTypeBoolLiteral:90 case NodeTypeBoolLiteral:
91 case NodeTypeNullLiteral:91 case NodeTypeNullLiteral:
92 case NodeTypeUndefinedLiteral:92 case NodeTypeUndefinedLiteral:
93 case NodeTypeZeroesLiteral:
93 case NodeTypeIfBoolExpr:94 case NodeTypeIfBoolExpr:
94 case NodeTypeIfVarExpr:95 case NodeTypeIfVarExpr:
95 case NodeTypeLabel:96 case NodeTypeLabel:
...@@ -1849,6 +1850,7 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)...@@ -1849,6 +1850,7 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)
1849 case NodeTypeBoolLiteral:1850 case NodeTypeBoolLiteral:
1850 case NodeTypeNullLiteral:1851 case NodeTypeNullLiteral:
1851 case NodeTypeUndefinedLiteral:1852 case NodeTypeUndefinedLiteral:
1853 case NodeTypeZeroesLiteral:
1852 case NodeTypeSymbol:1854 case NodeTypeSymbol:
1853 case NodeTypePrefixOpExpr:1855 case NodeTypePrefixOpExpr:
1854 case NodeTypeIfBoolExpr:1856 case NodeTypeIfBoolExpr:
...@@ -3937,7 +3939,19 @@ static TypeTableEntry *analyze_undefined_literal_expr(CodeGen *g, ImportTableEnt...@@ -3937,7 +3939,19 @@ static TypeTableEntry *analyze_undefined_literal_expr(CodeGen *g, ImportTableEnt
3937 ConstExprValue *const_val = &expr->const_val;3939 ConstExprValue *const_val = &expr->const_val;
39383940
3939 const_val->ok = true;3941 const_val->ok = true;
3940 const_val->undef = true;3942 const_val->special = ConstValSpecialUndef;
3943
3944 return expected_type ? expected_type : g->builtin_types.entry_undef;
3945}
3946
3947static TypeTableEntry *analyze_zeroes_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
3948 TypeTableEntry *expected_type, AstNode *node)
3949{
3950 Expr *expr = get_resolved_expr(node);
3951 ConstExprValue *const_val = &expr->const_val;
3952
3953 const_val->ok = true;
3954 const_val->special = ConstValSpecialZeroes;
39413955
3942 return expected_type ? expected_type : g->builtin_types.entry_undef;3956 return expected_type ? expected_type : g->builtin_types.entry_undef;
3943}3957}
...@@ -4252,7 +4266,7 @@ static TypeTableEntry *analyze_if_bool_expr(CodeGen *g, ImportTableEntry *import...@@ -4252,7 +4266,7 @@ static TypeTableEntry *analyze_if_bool_expr(CodeGen *g, ImportTableEntry *import
4252 }4266 }
42534267
4254 ConstExprValue *cond_val = &get_resolved_expr(*cond)->const_val;4268 ConstExprValue *cond_val = &get_resolved_expr(*cond)->const_val;
4255 if (cond_val->undef) {4269 if (cond_val->special == ConstValSpecialUndef) {
4256 add_node_error(g, first_executing_node(*cond), buf_sprintf("branch on undefined value"));4270 add_node_error(g, first_executing_node(*cond), buf_sprintf("branch on undefined value"));
4257 return cond_type;4271 return cond_type;
4258 }4272 }
...@@ -6504,6 +6518,9 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn...@@ -6504,6 +6518,9 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn
6504 case NodeTypeUndefinedLiteral:6518 case NodeTypeUndefinedLiteral:
6505 return_type = analyze_undefined_literal_expr(g, import, context, expected_type, node);6519 return_type = analyze_undefined_literal_expr(g, import, context, expected_type, node);
6506 break;6520 break;
6521 case NodeTypeZeroesLiteral:
6522 return_type = analyze_zeroes_literal_expr(g, import, context, expected_type, node);
6523 break;
6507 case NodeTypeSymbol:6524 case NodeTypeSymbol:
6508 return_type = analyze_symbol_expr(g, import, context, expected_type, node, pointer_only);6525 return_type = analyze_symbol_expr(g, import, context, expected_type, node, pointer_only);
6509 break;6526 break;
...@@ -6771,6 +6788,7 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte...@@ -6771,6 +6788,7 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte
6771 case NodeTypeBoolLiteral:6788 case NodeTypeBoolLiteral:
6772 case NodeTypeNullLiteral:6789 case NodeTypeNullLiteral:
6773 case NodeTypeUndefinedLiteral:6790 case NodeTypeUndefinedLiteral:
6791 case NodeTypeZeroesLiteral:
6774 case NodeTypeSymbol:6792 case NodeTypeSymbol:
6775 case NodeTypePrefixOpExpr:6793 case NodeTypePrefixOpExpr:
6776 case NodeTypeIfBoolExpr:6794 case NodeTypeIfBoolExpr:
...@@ -7029,6 +7047,8 @@ Expr *get_resolved_expr(AstNode *node) {...@@ -7029,6 +7047,8 @@ Expr *get_resolved_expr(AstNode *node) {
7029 return &node->data.null_literal.resolved_expr;7047 return &node->data.null_literal.resolved_expr;
7030 case NodeTypeUndefinedLiteral:7048 case NodeTypeUndefinedLiteral:
7031 return &node->data.undefined_literal.resolved_expr;7049 return &node->data.undefined_literal.resolved_expr;
7050 case NodeTypeZeroesLiteral:
7051 return &node->data.zeroes_literal.resolved_expr;
7032 case NodeTypeGoto:7052 case NodeTypeGoto:
7033 return &node->data.goto_expr.resolved_expr;7053 return &node->data.goto_expr.resolved_expr;
7034 case NodeTypeBreak:7054 case NodeTypeBreak:
...@@ -7111,6 +7131,7 @@ static TopLevelDecl *get_as_top_level_decl(AstNode *node) {...@@ -7111,6 +7131,7 @@ static TopLevelDecl *get_as_top_level_decl(AstNode *node) {
7111 case NodeTypeBoolLiteral:7131 case NodeTypeBoolLiteral:
7112 case NodeTypeNullLiteral:7132 case NodeTypeNullLiteral:
7113 case NodeTypeUndefinedLiteral:7133 case NodeTypeUndefinedLiteral:
7134 case NodeTypeZeroesLiteral:
7114 case NodeTypeLabel:7135 case NodeTypeLabel:
7115 case NodeTypeGoto:7136 case NodeTypeGoto:
7116 case NodeTypeBreak:7137 case NodeTypeBreak:
src/ast_render.cpp+4
...@@ -171,6 +171,8 @@ static const char *node_type_str(NodeType node_type) {...@@ -171,6 +171,8 @@ static const char *node_type_str(NodeType node_type) {
171 return "NullLiteral";171 return "NullLiteral";
172 case NodeTypeUndefinedLiteral:172 case NodeTypeUndefinedLiteral:
173 return "UndefinedLiteral";173 return "UndefinedLiteral";
174 case NodeTypeZeroesLiteral:
175 return "ZeroesLiteral";
174 case NodeTypeIfBoolExpr:176 case NodeTypeIfBoolExpr:
175 return "IfBoolExpr";177 return "IfBoolExpr";
176 case NodeTypeIfVarExpr:178 case NodeTypeIfVarExpr:
...@@ -591,6 +593,8 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -591,6 +593,8 @@ static void render_node(AstRender *ar, AstNode *node) {
591 zig_panic("TODO");593 zig_panic("TODO");
592 case NodeTypeUndefinedLiteral:594 case NodeTypeUndefinedLiteral:
593 zig_panic("TODO");595 zig_panic("TODO");
596 case NodeTypeZeroesLiteral:
597 zig_panic("TODO");
594 case NodeTypeIfBoolExpr:598 case NodeTypeIfBoolExpr:
595 zig_panic("TODO");599 zig_panic("TODO");
596 case NodeTypeIfVarExpr:600 case NodeTypeIfVarExpr:
src/codegen.cpp+17-5
...@@ -3141,11 +3141,15 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa...@@ -3141,11 +3141,15 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
3141 }3141 }
31423142
3143 bool have_init_expr = false;3143 bool have_init_expr = false;
3144 bool want_zeroes = false;
3144 if (var_decl->expr) {3145 if (var_decl->expr) {
3145 ConstExprValue *const_val = &get_resolved_expr(var_decl->expr)->const_val;3146 ConstExprValue *const_val = &get_resolved_expr(var_decl->expr)->const_val;
3146 if (!const_val->ok || !const_val->undef) {3147 if (!const_val->ok || const_val->special == ConstValSpecialOther) {
3147 have_init_expr = true;3148 have_init_expr = true;
3148 }3149 }
3150 if (const_val->ok && const_val->special == ConstValSpecialZeroes) {
3151 want_zeroes = true;
3152 }
3149 }3153 }
3150 if (have_init_expr) {3154 if (have_init_expr) {
3151 TypeTableEntry *expr_type = get_expr_type(var_decl->expr);3155 TypeTableEntry *expr_type = get_expr_type(var_decl->expr);
...@@ -3204,7 +3208,8 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa...@@ -3204,7 +3208,8 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
3204 }3208 }
3205 }3209 }
3206 }3210 }
3207 if (!ignore_uninit && want_debug_safety(g, source_node)) {3211 bool want_safe = want_debug_safety(g, source_node);
3212 if (!ignore_uninit && (want_safe || want_zeroes)) {
3208 TypeTableEntry *usize = g->builtin_types.entry_usize;3213 TypeTableEntry *usize = g->builtin_types.entry_usize;
3209 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, variable->type->type_ref);3214 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, variable->type->type_ref);
3210 uint64_t align_bytes = get_memcpy_align(g, variable->type);3215 uint64_t align_bytes = get_memcpy_align(g, variable->type);
...@@ -3212,7 +3217,7 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa...@@ -3212,7 +3217,7 @@ static LLVMValueRef gen_var_decl_raw(CodeGen *g, AstNode *source_node, AstNodeVa
3212 // memset uninitialized memory to 0xa3217 // memset uninitialized memory to 0xa
3213 set_debug_source_node(g, source_node);3218 set_debug_source_node(g, source_node);
3214 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);3219 LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0);
3215 LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), 0xaa, false);3220 LLVMValueRef fill_char = LLVMConstInt(LLVMInt8Type(), want_zeroes ? 0x00 : 0xaa, false);
3216 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, variable->value_ref, ptr_u8, "");3221 LLVMValueRef dest_ptr = LLVMBuildBitCast(g->builder, variable->value_ref, ptr_u8, "");
3217 LLVMValueRef byte_count = LLVMConstInt(usize->type_ref, size_bytes, false);3222 LLVMValueRef byte_count = LLVMConstInt(usize->type_ref, size_bytes, false);
3218 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(), align_bytes, false);3223 LLVMValueRef align_in_bytes = LLVMConstInt(LLVMInt32Type(), align_bytes, false);
...@@ -3535,6 +3540,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -3535,6 +3540,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
3535 case NodeTypeCharLiteral:3540 case NodeTypeCharLiteral:
3536 case NodeTypeNullLiteral:3541 case NodeTypeNullLiteral:
3537 case NodeTypeUndefinedLiteral:3542 case NodeTypeUndefinedLiteral:
3543 case NodeTypeZeroesLiteral:
3538 case NodeTypeErrorType:3544 case NodeTypeErrorType:
3539 case NodeTypeTypeLiteral:3545 case NodeTypeTypeLiteral:
3540 case NodeTypeArrayType:3546 case NodeTypeArrayType:
...@@ -3562,8 +3568,14 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -3562,8 +3568,14 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
3562static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val) {3568static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *const_val) {
3563 assert(const_val->ok);3569 assert(const_val->ok);
35643570
3565 if (const_val->undef) {3571 switch (const_val->special) {
3566 return LLVMGetUndef(type_entry->type_ref);3572 case ConstValSpecialUndef:
3573 return LLVMGetUndef(type_entry->type_ref);
3574 case ConstValSpecialZeroes:
3575 return LLVMConstNull(type_entry->type_ref);
3576 case ConstValSpecialOther:
3577 break;
3578
3567 }3579 }
35683580
3569 switch (type_entry->id) {3581 switch (type_entry->id) {
src/eval.cpp+4-3
...@@ -545,7 +545,7 @@ void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -545,7 +545,7 @@ void eval_const_expr_implicit_cast(CastOp cast_op,
545 ConstExprValue *const_val, TypeTableEntry *new_type)545 ConstExprValue *const_val, TypeTableEntry *new_type)
546{546{
547 const_val->depends_on_compile_var = other_val->depends_on_compile_var;547 const_val->depends_on_compile_var = other_val->depends_on_compile_var;
548 const_val->undef = other_val->undef;548 const_val->special = other_val->special;
549549
550 assert(other_val != const_val);550 assert(other_val != const_val);
551 switch (cast_op) {551 switch (cast_op) {
...@@ -572,7 +572,7 @@ void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -572,7 +572,7 @@ void eval_const_expr_implicit_cast(CastOp cast_op,
572 const_val->data.x_ptr.ptr = ptr_val;572 const_val->data.x_ptr.ptr = ptr_val;
573 const_val->data.x_ptr.len = 1;573 const_val->data.x_ptr.len = 1;
574 const_val->ok = true;574 const_val->ok = true;
575 const_val->undef = other_val->undef;575 const_val->special = other_val->special;
576 const_val->depends_on_compile_var = other_val->depends_on_compile_var;576 const_val->depends_on_compile_var = other_val->depends_on_compile_var;
577 } else {577 } else {
578 zig_panic("TODO");578 zig_panic("TODO");
...@@ -608,7 +608,7 @@ void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -608,7 +608,7 @@ void eval_const_expr_implicit_cast(CastOp cast_op,
608608
609 const_val->data.x_maybe = ptr_parent;609 const_val->data.x_maybe = ptr_parent;
610 const_val->ok = true;610 const_val->ok = true;
611 const_val->undef = other_val->undef;611 const_val->special = other_val->special;
612 const_val->depends_on_compile_var = other_val->depends_on_compile_var;612 const_val->depends_on_compile_var = other_val->depends_on_compile_var;
613 } else {613 } else {
614 zig_panic("TODO");614 zig_panic("TODO");
...@@ -1277,6 +1277,7 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {...@@ -1277,6 +1277,7 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
1277 case NodeTypeSliceExpr:1277 case NodeTypeSliceExpr:
1278 case NodeTypeNullLiteral:1278 case NodeTypeNullLiteral:
1279 case NodeTypeUndefinedLiteral:1279 case NodeTypeUndefinedLiteral:
1280 case NodeTypeZeroesLiteral:
1280 case NodeTypeIfVarExpr:1281 case NodeTypeIfVarExpr:
1281 case NodeTypeSwitchExpr:1282 case NodeTypeSwitchExpr:
1282 case NodeTypeSwitchProng:1283 case NodeTypeSwitchProng:
src/parser.cpp+11-1
...@@ -606,7 +606,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand...@@ -606,7 +606,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand
606606
607/*607/*
608PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")608PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")
609KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type"609KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type"
610*/610*/
611static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {611static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) {
612 Token *token = &pc->tokens->at(*token_index);612 Token *token = &pc->tokens->at(*token_index);
...@@ -654,6 +654,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool...@@ -654,6 +654,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool
654 AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token);654 AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token);
655 *token_index += 1;655 *token_index += 1;
656 return node;656 return node;
657 } else if (token->id == TokenIdKeywordZeroes) {
658 AstNode *node = ast_create_node(pc, NodeTypeZeroesLiteral, token);
659 *token_index += 1;
660 return node;
657 } else if (token->id == TokenIdKeywordType) {661 } else if (token->id == TokenIdKeywordType) {
658 AstNode *node = ast_create_node(pc, NodeTypeTypeLiteral, token);662 AstNode *node = ast_create_node(pc, NodeTypeTypeLiteral, token);
659 *token_index += 1;663 *token_index += 1;
...@@ -2539,6 +2543,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2539,6 +2543,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2539 case NodeTypeUndefinedLiteral:2543 case NodeTypeUndefinedLiteral:
2540 // none2544 // none
2541 break;2545 break;
2546 case NodeTypeZeroesLiteral:
2547 // none
2548 break;
2542 case NodeTypeIfBoolExpr:2549 case NodeTypeIfBoolExpr:
2543 visit_field(&node->data.if_bool_expr.condition, visit, context);2550 visit_field(&node->data.if_bool_expr.condition, visit, context);
2544 visit_field(&node->data.if_bool_expr.then_block, visit, context);2551 visit_field(&node->data.if_bool_expr.then_block, visit, context);
...@@ -2813,6 +2820,9 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,...@@ -2813,6 +2820,9 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,
2813 case NodeTypeUndefinedLiteral:2820 case NodeTypeUndefinedLiteral:
2814 // none2821 // none
2815 break;2822 break;
2823 case NodeTypeZeroesLiteral:
2824 // none
2825 break;
2816 case NodeTypeIfBoolExpr:2826 case NodeTypeIfBoolExpr:
2817 clone_subtree_field(&new_node->data.if_bool_expr.condition, old_node->data.if_bool_expr.condition, next_node_index);2827 clone_subtree_field(&new_node->data.if_bool_expr.condition, old_node->data.if_bool_expr.condition, next_node_index);
2818 clone_subtree_field(&new_node->data.if_bool_expr.then_block, old_node->data.if_bool_expr.then_block, next_node_index);2828 clone_subtree_field(&new_node->data.if_bool_expr.then_block, old_node->data.if_bool_expr.then_block, next_node_index);
src/tokenizer.cpp+2
...@@ -137,6 +137,7 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -137,6 +137,7 @@ static const struct ZigKeyword zig_keywords[] = {
137 {"var", TokenIdKeywordVar},137 {"var", TokenIdKeywordVar},
138 {"volatile", TokenIdKeywordVolatile},138 {"volatile", TokenIdKeywordVolatile},
139 {"while", TokenIdKeywordWhile},139 {"while", TokenIdKeywordWhile},
140 {"zeroes", TokenIdKeywordZeroes},
140};141};
141142
142bool is_zig_keyword(Buf *buf) {143bool is_zig_keyword(Buf *buf) {
...@@ -1467,6 +1468,7 @@ const char * token_name(TokenId id) {...@@ -1467,6 +1468,7 @@ const char * token_name(TokenId id) {
1467 case TokenIdKeywordNoAlias: return "noalias";1468 case TokenIdKeywordNoAlias: return "noalias";
1468 case TokenIdKeywordSwitch: return "switch";1469 case TokenIdKeywordSwitch: return "switch";
1469 case TokenIdKeywordUndefined: return "undefined";1470 case TokenIdKeywordUndefined: return "undefined";
1471 case TokenIdKeywordZeroes: return "zeroes";
1470 case TokenIdKeywordError: return "error";1472 case TokenIdKeywordError: return "error";
1471 case TokenIdKeywordType: return "type";1473 case TokenIdKeywordType: return "type";
1472 case TokenIdKeywordInline: return "inline";1474 case TokenIdKeywordInline: return "inline";
src/tokenizer.hpp+1
...@@ -40,6 +40,7 @@ enum TokenId {...@@ -40,6 +40,7 @@ enum TokenId {
40 TokenIdKeywordNoAlias,40 TokenIdKeywordNoAlias,
41 TokenIdKeywordSwitch,41 TokenIdKeywordSwitch,
42 TokenIdKeywordUndefined,42 TokenIdKeywordUndefined,
43 TokenIdKeywordZeroes,
43 TokenIdKeywordError,44 TokenIdKeywordError,
44 TokenIdKeywordType,45 TokenIdKeywordType,
45 TokenIdKeywordInline,46 TokenIdKeywordInline,
test/cases/zeroes.zig created+18
...@@ -0,0 +1,18 @@
1const assert = @import("std").debug.assert;
2
3struct Foo {
4 a: f32,
5 b: i32,
6 c: bool,
7 d: ?i32,
8}
9
10#attribute("test")
11fn initializing_a_struct_with_zeroes() {
12 const foo: Foo = zeroes;
13 assert(foo.a == 0.0);
14 assert(foo.b == 0);
15 assert(foo.c == false);
16 assert(if (const x ?= foo.d) false else true);
17}
18
test/self_hosted.zig+1
...@@ -4,6 +4,7 @@ const str = std.str;...@@ -4,6 +4,7 @@ const str = std.str;
4const cstr = std.cstr;4const cstr = std.cstr;
5const other = @import("other.zig");5const other = @import("other.zig");
6const cases_return_type_type = @import("cases/return_type_type.zig");6const cases_return_type_type = @import("cases/return_type_type.zig");
7const test_zeroes = @import("cases/zeroes.zig");
78
8// normal comment9// normal comment
9/// this is a documentation comment10/// this is a documentation comment