| author | |
| committer | |
| log | 5c18826240fe983a30a9de6e04d3848643db7cf6 |
| tree | d427af30c78ff59d768bf75cd194e008757ab7bf |
| parent | 37aae530098f10565ea3408891c901e086b8d5b8 |
See #2312 files changed, 223 insertions(+), 128 deletions(-)
doc/langref.md+4-4| ... | @@ -7,7 +7,7 @@ Root : many(TopLevelDecl) "EOF" | ... | @@ -7,7 +7,7 @@ Root : many(TopLevelDecl) "EOF" |
| 7 | 7 | ||
| 8 | TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Import | ContainerDecl | VariableDeclaration | ErrorValueDecl | 8 | TopLevelDecl : FnDef | ExternBlock | RootExportDecl | Import | ContainerDecl | VariableDeclaration | ErrorValueDecl |
| 9 | 9 | ||
| 10 | ErrorValueDecl : option(FnVisibleMod) "%." "Symbol" | 10 | ErrorValueDecl : option(FnVisibleMod) "error" "Symbol" |
| 11 | 11 | ||
| 12 | VariableDeclaration : option(FnVisibleMod) ("var" | "const") "Symbol" ("=" Expression | ":" PrefixOpExpression option("=" Expression)) | 12 | VariableDeclaration : option(FnVisibleMod) ("var" | "const") "Symbol" ("=" Expression | ":" PrefixOpExpression option("=" Expression)) |
| 13 | 13 | ||
| ... | @@ -133,9 +133,9 @@ ContainerInitBody : list(StructLiteralField, ",") | list(Expression, ",") | ... | @@ -133,9 +133,9 @@ ContainerInitBody : list(StructLiteralField, ",") | list(Expression, ",") |
| 133 | 133 | ||
| 134 | StructLiteralField : "." "Symbol" "=" Expression | 134 | StructLiteralField : "." "Symbol" "=" Expression |
| 135 | 135 | ||
| 136 | PrefixOp : "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | 136 | PrefixOp : "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%" |
| 137 | 137 | ||
| 138 | PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("%." "Symbol") | 138 | PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("error" "." "Symbol") |
| 139 | 139 | ||
| 140 | ArrayType : "[" option(Expression) "]" option("const") PrefixOpExpression | 140 | ArrayType : "[" option(Expression) "]" option("const") PrefixOpExpression |
| 141 | 141 | ||
| ... | @@ -143,7 +143,7 @@ GotoExpression: "goto" "Symbol" | ... | @@ -143,7 +143,7 @@ GotoExpression: "goto" "Symbol" |
| 143 | 143 | ||
| 144 | GroupedExpression : "(" Expression ")" | 144 | GroupedExpression : "(" Expression ")" |
| 145 | 145 | ||
| 146 | KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | 146 | KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" |
| 147 | ``` | 147 | ``` |
| 148 | 148 | ||
| 149 | ## Operator Precedence | 149 | ## Operator Precedence |
doc/vim/syntax/zig.vim+1-1| ... | @@ -15,7 +15,7 @@ syn keyword zigRepeat while for | ... | @@ -15,7 +15,7 @@ syn keyword zigRepeat while for |
| 15 | 15 | ||
| 16 | syn keyword zigConstant null undefined | 16 | syn keyword zigConstant null undefined |
| 17 | syn keyword zigKeyword fn import | 17 | syn keyword zigKeyword fn import |
| 18 | syn keyword zigType bool i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 f128 void unreachable type | 18 | syn keyword zigType bool i8 u8 i16 u16 i32 u32 i64 u64 isize usize f32 f64 f128 void unreachable type error |
| 19 | 19 | ||
| 20 | syn keyword zigBoolean true false | 20 | syn keyword zigBoolean true false |
| 21 | 21 |
example/cat/main.zig+2-1| ... | @@ -10,6 +10,7 @@ import "std.zig"; | ... | @@ -10,6 +10,7 @@ import "std.zig"; |
| 10 | // * %% binary operator | 10 | // * %% binary operator |
| 11 | // * %% prefix operator | 11 | // * %% prefix operator |
| 12 | // * cast err type to string | 12 | // * cast err type to string |
| 13 | // * string equality | ||
| 13 | 14 | ||
| 14 | pub fn main(args: [][]u8) %void => { | 15 | pub fn main(args: [][]u8) %void => { |
| 15 | const exe = args[0]; | 16 | const exe = args[0]; |
| ... | @@ -39,7 +40,7 @@ pub fn main(args: [][]u8) %void => { | ... | @@ -39,7 +40,7 @@ pub fn main(args: [][]u8) %void => { |
| 39 | 40 | ||
| 40 | fn usage(exe: []u8) %void => { | 41 | fn usage(exe: []u8) %void => { |
| 41 | %%stderr.print("Usage: {} [FILE]...\n", exe); | 42 | %%stderr.print("Usage: {} [FILE]...\n", exe); |
| 42 | return %.Invalid; | 43 | return error.Invalid; |
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | fn cat_stream(is: InputStream) %void => { | 46 | fn cat_stream(is: InputStream) %void => { |
example/guess_number/main.zig+4-4| ... | @@ -3,8 +3,8 @@ export executable "guess_number"; | ... | @@ -3,8 +3,8 @@ export executable "guess_number"; |
| 3 | import "std.zig"; | 3 | import "std.zig"; |
| 4 | import "rand.zig"; | 4 | import "rand.zig"; |
| 5 | 5 | ||
| 6 | %.GetRandomFail; | 6 | error GetRandomFail; |
| 7 | %.ReadInputFail; | 7 | error ReadInputFail; |
| 8 | 8 | ||
| 9 | pub fn main(args: [][]u8) %void => { | 9 | pub fn main(args: [][]u8) %void => { |
| 10 | print_str("Welcome to the Guess Number Game in Zig.\n"); | 10 | print_str("Welcome to the Guess Number Game in Zig.\n"); |
| ... | @@ -15,7 +15,7 @@ pub fn main(args: [][]u8) %void => { | ... | @@ -15,7 +15,7 @@ pub fn main(args: [][]u8) %void => { |
| 15 | if (err != @sizeof(u32)) { | 15 | if (err != @sizeof(u32)) { |
| 16 | // TODO full error message | 16 | // TODO full error message |
| 17 | fprint_str(stderr_fileno, "unable to get random bytes\n"); | 17 | fprint_str(stderr_fileno, "unable to get random bytes\n"); |
| 18 | return %.GetRandomFail; | 18 | return error.GetRandomFail; |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | var rand : Rand; | 21 | var rand : Rand; |
| ... | @@ -31,7 +31,7 @@ pub fn main(args: [][]u8) %void => { | ... | @@ -31,7 +31,7 @@ pub fn main(args: [][]u8) %void => { |
| 31 | if (readline(line_buf, &line_len) || line_len == line_buf.len) { | 31 | if (readline(line_buf, &line_len) || line_len == line_buf.len) { |
| 32 | // TODO full error message | 32 | // TODO full error message |
| 33 | fprint_str(stderr_fileno, "unable to read input\n"); | 33 | fprint_str(stderr_fileno, "unable to read input\n"); |
| 34 | return %.ReadInputFail; | 34 | return error.ReadInputFail; |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | var guess : u64; | 37 | var guess : u64; |
src/all_types.hpp+11-10| ... | @@ -133,7 +133,6 @@ enum NodeType { | ... | @@ -133,7 +133,6 @@ enum NodeType { |
| 133 | NodeTypeNumberLiteral, | 133 | NodeTypeNumberLiteral, |
| 134 | NodeTypeStringLiteral, | 134 | NodeTypeStringLiteral, |
| 135 | NodeTypeCharLiteral, | 135 | NodeTypeCharLiteral, |
| 136 | NodeTypeErrorLiteral, | ||
| 137 | NodeTypeSymbol, | 136 | NodeTypeSymbol, |
| 138 | NodeTypePrefixOpExpr, | 137 | NodeTypePrefixOpExpr, |
| 139 | NodeTypeFnCallExpr, | 138 | NodeTypeFnCallExpr, |
| ... | @@ -161,6 +160,7 @@ enum NodeType { | ... | @@ -161,6 +160,7 @@ enum NodeType { |
| 161 | NodeTypeContainerInitExpr, | 160 | NodeTypeContainerInitExpr, |
| 162 | NodeTypeStructValueField, | 161 | NodeTypeStructValueField, |
| 163 | NodeTypeArrayType, | 162 | NodeTypeArrayType, |
| 163 | NodeTypeErrorType, | ||
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| 166 | struct AstNodeRoot { | 166 | struct AstNodeRoot { |
| ... | @@ -315,6 +315,7 @@ enum CastOp { | ... | @@ -315,6 +315,7 @@ enum CastOp { |
| 315 | CastOpToUnknownSizeArray, | 315 | CastOpToUnknownSizeArray, |
| 316 | CastOpMaybeWrap, | 316 | CastOpMaybeWrap, |
| 317 | CastOpErrorWrap, | 317 | CastOpErrorWrap, |
| 318 | CastOpPureErrorWrap, | ||
| 318 | CastOpPointerReinterpret, | 319 | CastOpPointerReinterpret, |
| 319 | CastOpErrToInt, | 320 | CastOpErrToInt, |
| 320 | }; | 321 | }; |
| ... | @@ -584,13 +585,6 @@ struct AstNodeNumberLiteral { | ... | @@ -584,13 +585,6 @@ struct AstNodeNumberLiteral { |
| 584 | Expr resolved_expr; | 585 | Expr resolved_expr; |
| 585 | }; | 586 | }; |
| 586 | 587 | ||
| 587 | struct AstNodeErrorLiteral { | ||
| 588 | Buf symbol; | ||
| 589 | |||
| 590 | // populated by semantic analyzer | ||
| 591 | Expr resolved_expr; | ||
| 592 | }; | ||
| 593 | |||
| 594 | struct AstNodeStructValueField { | 588 | struct AstNodeStructValueField { |
| 595 | Buf name; | 589 | Buf name; |
| 596 | AstNode *expr; | 590 | AstNode *expr; |
| ... | @@ -663,6 +657,11 @@ struct AstNodeArrayType { | ... | @@ -663,6 +657,11 @@ struct AstNodeArrayType { |
| 663 | Expr resolved_expr; | 657 | Expr resolved_expr; |
| 664 | }; | 658 | }; |
| 665 | 659 | ||
| 660 | struct AstNodeErrorType { | ||
| 661 | // populated by semantic analyzer | ||
| 662 | Expr resolved_expr; | ||
| 663 | }; | ||
| 664 | |||
| 666 | struct AstNode { | 665 | struct AstNode { |
| 667 | enum NodeType type; | 666 | enum NodeType type; |
| 668 | int line; | 667 | int line; |
| ... | @@ -705,7 +704,6 @@ struct AstNode { | ... | @@ -705,7 +704,6 @@ struct AstNode { |
| 705 | AstNodeStringLiteral string_literal; | 704 | AstNodeStringLiteral string_literal; |
| 706 | AstNodeCharLiteral char_literal; | 705 | AstNodeCharLiteral char_literal; |
| 707 | AstNodeNumberLiteral number_literal; | 706 | AstNodeNumberLiteral number_literal; |
| 708 | AstNodeErrorLiteral error_literal; | ||
| 709 | AstNodeContainerInitExpr container_init_expr; | 707 | AstNodeContainerInitExpr container_init_expr; |
| 710 | AstNodeStructValueField struct_val_field; | 708 | AstNodeStructValueField struct_val_field; |
| 711 | AstNodeNullLiteral null_literal; | 709 | AstNodeNullLiteral null_literal; |
| ... | @@ -715,6 +713,7 @@ struct AstNode { | ... | @@ -715,6 +713,7 @@ struct AstNode { |
| 715 | AstNodeBreakExpr break_expr; | 713 | AstNodeBreakExpr break_expr; |
| 716 | AstNodeContinueExpr continue_expr; | 714 | AstNodeContinueExpr continue_expr; |
| 717 | AstNodeArrayType array_type; | 715 | AstNodeArrayType array_type; |
| 716 | AstNodeErrorType error_type; | ||
| 718 | } data; | 717 | } data; |
| 719 | }; | 718 | }; |
| 720 | 719 | ||
| ... | @@ -820,7 +819,8 @@ enum TypeTableEntryId { | ... | @@ -820,7 +819,8 @@ enum TypeTableEntryId { |
| 820 | TypeTableEntryIdNumLitInt, | 819 | TypeTableEntryIdNumLitInt, |
| 821 | TypeTableEntryIdUndefLit, | 820 | TypeTableEntryIdUndefLit, |
| 822 | TypeTableEntryIdMaybe, | 821 | TypeTableEntryIdMaybe, |
| 823 | TypeTableEntryIdError, | 822 | TypeTableEntryIdErrorUnion, |
| 823 | TypeTableEntryIdPureError, | ||
| 824 | TypeTableEntryIdEnum, | 824 | TypeTableEntryIdEnum, |
| 825 | TypeTableEntryIdFn, | 825 | TypeTableEntryIdFn, |
| 826 | }; | 826 | }; |
| ... | @@ -961,6 +961,7 @@ struct CodeGen { | ... | @@ -961,6 +961,7 @@ struct CodeGen { |
| 961 | TypeTableEntry *entry_num_lit_int; | 961 | TypeTableEntry *entry_num_lit_int; |
| 962 | TypeTableEntry *entry_num_lit_float; | 962 | TypeTableEntry *entry_num_lit_float; |
| 963 | TypeTableEntry *entry_undef; | 963 | TypeTableEntry *entry_undef; |
| 964 | TypeTableEntry *entry_pure_error; | ||
| 964 | } builtin_types; | 965 | } builtin_types; |
| 965 | 966 | ||
| 966 | LLVMTargetDataRef target_data_ref; | 967 | LLVMTargetDataRef target_data_ref; |
src/analyze.cpp+111-50| ... | @@ -19,6 +19,8 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE | ... | @@ -19,6 +19,8 @@ static void resolve_struct_type(CodeGen *g, ImportTableEntry *import, TypeTableE |
| 19 | static TypeTableEntry *unwrapped_node_type(AstNode *node); | 19 | static TypeTableEntry *unwrapped_node_type(AstNode *node); |
| 20 | static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 20 | static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 21 | AstNode *node); | 21 | AstNode *node); |
| 22 | static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, | ||
| 23 | BlockContext *context, AstNode *node, Buf *err_name); | ||
| 22 | 24 | ||
| 23 | static AstNode *first_executing_node(AstNode *node) { | 25 | static AstNode *first_executing_node(AstNode *node) { |
| 24 | switch (node->type) { | 26 | switch (node->type) { |
| ... | @@ -47,7 +49,6 @@ static AstNode *first_executing_node(AstNode *node) { | ... | @@ -47,7 +49,6 @@ static AstNode *first_executing_node(AstNode *node) { |
| 47 | case NodeTypeVariableDeclaration: | 49 | case NodeTypeVariableDeclaration: |
| 48 | case NodeTypeErrorValueDecl: | 50 | case NodeTypeErrorValueDecl: |
| 49 | case NodeTypeNumberLiteral: | 51 | case NodeTypeNumberLiteral: |
| 50 | case NodeTypeErrorLiteral: | ||
| 51 | case NodeTypeStringLiteral: | 52 | case NodeTypeStringLiteral: |
| 52 | case NodeTypeCharLiteral: | 53 | case NodeTypeCharLiteral: |
| 53 | case NodeTypeSymbol: | 54 | case NodeTypeSymbol: |
| ... | @@ -71,6 +72,7 @@ static AstNode *first_executing_node(AstNode *node) { | ... | @@ -71,6 +72,7 @@ static AstNode *first_executing_node(AstNode *node) { |
| 71 | case NodeTypeSwitchExpr: | 72 | case NodeTypeSwitchExpr: |
| 72 | case NodeTypeSwitchProng: | 73 | case NodeTypeSwitchProng: |
| 73 | case NodeTypeArrayType: | 74 | case NodeTypeArrayType: |
| 75 | case NodeTypeErrorType: | ||
| 74 | case NodeTypeContainerInitExpr: | 76 | case NodeTypeContainerInitExpr: |
| 75 | return node; | 77 | return node; |
| 76 | } | 78 | } |
| ... | @@ -110,7 +112,8 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) { | ... | @@ -110,7 +112,8 @@ TypeTableEntry *new_type_table_entry(TypeTableEntryId id) { |
| 110 | case TypeTableEntryIdNumLitInt: | 112 | case TypeTableEntryIdNumLitInt: |
| 111 | case TypeTableEntryIdMaybe: | 113 | case TypeTableEntryIdMaybe: |
| 112 | case TypeTableEntryIdFn: | 114 | case TypeTableEntryIdFn: |
| 113 | case TypeTableEntryIdError: | 115 | case TypeTableEntryIdErrorUnion: |
| 116 | case TypeTableEntryIdPureError: | ||
| 114 | case TypeTableEntryIdUndefLit: | 117 | case TypeTableEntryIdUndefLit: |
| 115 | // nothing to init | 118 | // nothing to init |
| 116 | break; | 119 | break; |
| ... | @@ -200,7 +203,7 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { | ... | @@ -200,7 +203,7 @@ static TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) { |
| 200 | "val", di_file, line, child_type->size_in_bits, child_type->align_in_bits, 0, 0, | 203 | "val", di_file, line, child_type->size_in_bits, child_type->align_in_bits, 0, 0, |
| 201 | child_type->di_type), | 204 | child_type->di_type), |
| 202 | LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type), | 205 | LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type), |
| 203 | "maybe", di_file, line, 8, 8, 8, 0, | 206 | "maybe", di_file, line, 8, 8, child_type->size_in_bits, 0, |
| 204 | child_type->di_type), | 207 | child_type->di_type), |
| 205 | }; | 208 | }; |
| 206 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder, | 209 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder, |
| ... | @@ -223,7 +226,7 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { | ... | @@ -223,7 +226,7 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { |
| 223 | if (child_type->error_parent) { | 226 | if (child_type->error_parent) { |
| 224 | return child_type->error_parent; | 227 | return child_type->error_parent; |
| 225 | } else { | 228 | } else { |
| 226 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdError); | 229 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdErrorUnion); |
| 227 | assert(child_type->type_ref); | 230 | assert(child_type->type_ref); |
| 228 | assert(child_type->di_type); | 231 | assert(child_type->di_type); |
| 229 | 232 | ||
| ... | @@ -239,7 +242,38 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { | ... | @@ -239,7 +242,38 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) { |
| 239 | entry->di_type = g->err_tag_type->di_type; | 242 | entry->di_type = g->err_tag_type->di_type; |
| 240 | 243 | ||
| 241 | } else { | 244 | } else { |
| 242 | zig_panic("TODO get_error_type non-void"); | 245 | LLVMTypeRef elem_types[] = { |
| 246 | g->err_tag_type->type_ref, | ||
| 247 | child_type->type_ref, | ||
| 248 | }; | ||
| 249 | entry->type_ref = LLVMStructType(elem_types, 2, false); | ||
| 250 | entry->size_in_bits = g->err_tag_type->size_in_bits + child_type->size_in_bits; | ||
| 251 | entry->align_in_bits = g->err_tag_type->align_in_bits; | ||
| 252 | |||
| 253 | LLVMZigDIScope *compile_unit_scope = LLVMZigCompileUnitToScope(g->compile_unit); | ||
| 254 | LLVMZigDIFile *di_file = nullptr; | ||
| 255 | unsigned line = 0; | ||
| 256 | entry->di_type = LLVMZigCreateReplaceableCompositeType(g->dbuilder, | ||
| 257 | LLVMZigTag_DW_structure_type(), buf_ptr(&entry->name), | ||
| 258 | compile_unit_scope, di_file, line); | ||
| 259 | |||
| 260 | LLVMZigDIType *di_element_types[] = { | ||
| 261 | LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type), | ||
| 262 | "tag", di_file, line, g->err_tag_type->size_in_bits, g->err_tag_type->align_in_bits, | ||
| 263 | 0, 0, child_type->di_type), | ||
| 264 | LLVMZigCreateDebugMemberType(g->dbuilder, LLVMZigTypeToScope(entry->di_type), | ||
| 265 | "value", di_file, line, child_type->size_in_bits, child_type->align_in_bits, | ||
| 266 | g->err_tag_type->size_in_bits, 0, child_type->di_type), | ||
| 267 | }; | ||
| 268 | |||
| 269 | LLVMZigDIType *replacement_di_type = LLVMZigCreateDebugStructType(g->dbuilder, | ||
| 270 | compile_unit_scope, | ||
| 271 | buf_ptr(&entry->name), | ||
| 272 | di_file, line, entry->size_in_bits, entry->align_in_bits, 0, | ||
| 273 | nullptr, di_element_types, 2, 0, nullptr, ""); | ||
| 274 | |||
| 275 | LLVMZigReplaceTemporary(g->dbuilder, entry->di_type, replacement_di_type); | ||
| 276 | entry->di_type = replacement_di_type; | ||
| 243 | } | 277 | } |
| 244 | 278 | ||
| 245 | child_type->error_parent = entry; | 279 | child_type->error_parent = entry; |
| ... | @@ -1012,7 +1046,6 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -1012,7 +1046,6 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 1012 | case NodeTypeArrayAccessExpr: | 1046 | case NodeTypeArrayAccessExpr: |
| 1013 | case NodeTypeSliceExpr: | 1047 | case NodeTypeSliceExpr: |
| 1014 | case NodeTypeNumberLiteral: | 1048 | case NodeTypeNumberLiteral: |
| 1015 | case NodeTypeErrorLiteral: | ||
| 1016 | case NodeTypeStringLiteral: | 1049 | case NodeTypeStringLiteral: |
| 1017 | case NodeTypeCharLiteral: | 1050 | case NodeTypeCharLiteral: |
| 1018 | case NodeTypeBoolLiteral: | 1051 | case NodeTypeBoolLiteral: |
| ... | @@ -1037,6 +1070,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -1037,6 +1070,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 1037 | case NodeTypeStructValueField: | 1070 | case NodeTypeStructValueField: |
| 1038 | case NodeTypeContainerInitExpr: | 1071 | case NodeTypeContainerInitExpr: |
| 1039 | case NodeTypeArrayType: | 1072 | case NodeTypeArrayType: |
| 1073 | case NodeTypeErrorType: | ||
| 1040 | zig_unreachable(); | 1074 | zig_unreachable(); |
| 1041 | } | 1075 | } |
| 1042 | } | 1076 | } |
| ... | @@ -1083,7 +1117,8 @@ static bool type_has_codegen_value(TypeTableEntryId id) { | ... | @@ -1083,7 +1117,8 @@ static bool type_has_codegen_value(TypeTableEntryId id) { |
| 1083 | case TypeTableEntryIdArray: | 1117 | case TypeTableEntryIdArray: |
| 1084 | case TypeTableEntryIdStruct: | 1118 | case TypeTableEntryIdStruct: |
| 1085 | case TypeTableEntryIdMaybe: | 1119 | case TypeTableEntryIdMaybe: |
| 1086 | case TypeTableEntryIdError: | 1120 | case TypeTableEntryIdErrorUnion: |
| 1121 | case TypeTableEntryIdPureError: | ||
| 1087 | case TypeTableEntryIdEnum: | 1122 | case TypeTableEntryIdEnum: |
| 1088 | case TypeTableEntryIdFn: | 1123 | case TypeTableEntryIdFn: |
| 1089 | return true; | 1124 | return true; |
| ... | @@ -1166,8 +1201,8 @@ static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTable | ... | @@ -1166,8 +1201,8 @@ static bool types_match_const_cast_only(TypeTableEntry *expected_type, TypeTable |
| 1166 | } | 1201 | } |
| 1167 | 1202 | ||
| 1168 | // error | 1203 | // error |
| 1169 | if (expected_type->id == TypeTableEntryIdError && | 1204 | if (expected_type->id == TypeTableEntryIdErrorUnion && |
| 1170 | actual_type->id == TypeTableEntryIdError) | 1205 | actual_type->id == TypeTableEntryIdErrorUnion) |
| 1171 | { | 1206 | { |
| 1172 | return types_match_const_cast_only( | 1207 | return types_match_const_cast_only( |
| 1173 | expected_type->data.error.child_type, | 1208 | expected_type->data.error.child_type, |
| ... | @@ -1224,11 +1259,11 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa | ... | @@ -1224,11 +1259,11 @@ static TypeTableEntry *determine_peer_type_compatibility(CodeGen *g, AstNode *pa |
| 1224 | prev_type = cur_type; | 1259 | prev_type = cur_type; |
| 1225 | prev_node = cur_node; | 1260 | prev_node = cur_node; |
| 1226 | } | 1261 | } |
| 1227 | } else if (prev_type->id == TypeTableEntryIdError && | 1262 | } else if (prev_type->id == TypeTableEntryIdErrorUnion && |
| 1228 | types_match_const_cast_only(prev_type->data.error.child_type, cur_type)) | 1263 | types_match_const_cast_only(prev_type->data.error.child_type, cur_type)) |
| 1229 | { | 1264 | { |
| 1230 | continue; | 1265 | continue; |
| 1231 | } else if (cur_type->id == TypeTableEntryIdError && | 1266 | } else if (cur_type->id == TypeTableEntryIdErrorUnion && |
| 1232 | types_match_const_cast_only(cur_type->data.error.child_type, prev_type)) | 1267 | types_match_const_cast_only(cur_type->data.error.child_type, prev_type)) |
| 1233 | { | 1268 | { |
| 1234 | prev_type = cur_type; | 1269 | prev_type = cur_type; |
| ... | @@ -1287,13 +1322,20 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_ | ... | @@ -1287,13 +1322,20 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_ |
| 1287 | } | 1322 | } |
| 1288 | 1323 | ||
| 1289 | // implicit conversion from error child type to error type | 1324 | // implicit conversion from error child type to error type |
| 1290 | if (expected_type->id == TypeTableEntryIdError && | 1325 | if (expected_type->id == TypeTableEntryIdErrorUnion && |
| 1291 | types_match_with_implicit_cast(g, expected_type->data.error.child_type, actual_type, | 1326 | types_match_with_implicit_cast(g, expected_type->data.error.child_type, actual_type, |
| 1292 | literal_node, reported_err)) | 1327 | literal_node, reported_err)) |
| 1293 | { | 1328 | { |
| 1294 | return true; | 1329 | return true; |
| 1295 | } | 1330 | } |
| 1296 | 1331 | ||
| 1332 | // implicit conversion from pure error to error union type | ||
| 1333 | if (expected_type->id == TypeTableEntryIdErrorUnion && | ||
| 1334 | actual_type->id == TypeTableEntryIdPureError) | ||
| 1335 | { | ||
| 1336 | return true; | ||
| 1337 | } | ||
| 1338 | |||
| 1297 | // implicit widening conversion | 1339 | // implicit widening conversion |
| 1298 | if (expected_type->id == TypeTableEntryIdInt && | 1340 | if (expected_type->id == TypeTableEntryIdInt && |
| 1299 | actual_type->id == TypeTableEntryIdInt && | 1341 | actual_type->id == TypeTableEntryIdInt && |
| ... | @@ -1695,12 +1737,11 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -1695,12 +1737,11 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 1695 | 1737 | ||
| 1696 | AstNode *struct_expr_node = node->data.field_access_expr.struct_expr; | 1738 | AstNode *struct_expr_node = node->data.field_access_expr.struct_expr; |
| 1697 | TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr, struct_expr_node); | 1739 | TypeTableEntry *struct_type = analyze_expression(g, import, context, nullptr, struct_expr_node); |
| 1740 | Buf *field_name = &node->data.field_access_expr.field_name; | ||
| 1698 | 1741 | ||
| 1699 | if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer && | 1742 | if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer && |
| 1700 | struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct)) | 1743 | struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct)) |
| 1701 | { | 1744 | { |
| 1702 | Buf *field_name = &node->data.field_access_expr.field_name; | ||
| 1703 | |||
| 1704 | TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ? | 1745 | TypeTableEntry *bare_struct_type = (struct_type->id == TypeTableEntryIdStruct) ? |
| 1705 | struct_type : struct_type->data.pointer.child_type; | 1746 | struct_type : struct_type->data.pointer.child_type; |
| 1706 | 1747 | ||
| ... | @@ -1713,15 +1754,14 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -1713,15 +1754,14 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 1713 | return g->builtin_types.entry_invalid; | 1754 | return g->builtin_types.entry_invalid; |
| 1714 | } | 1755 | } |
| 1715 | } else if (struct_type->id == TypeTableEntryIdArray) { | 1756 | } else if (struct_type->id == TypeTableEntryIdArray) { |
| 1716 | Buf *name = &node->data.field_access_expr.field_name; | 1757 | if (buf_eql_str(field_name, "len")) { |
| 1717 | if (buf_eql_str(name, "len")) { | ||
| 1718 | return g->builtin_types.entry_isize; | 1758 | return g->builtin_types.entry_isize; |
| 1719 | } else if (buf_eql_str(name, "ptr")) { | 1759 | } else if (buf_eql_str(field_name, "ptr")) { |
| 1720 | // TODO determine whether the pointer should be const | 1760 | // TODO determine whether the pointer should be const |
| 1721 | return get_pointer_to_type(g, struct_type->data.array.child_type, false); | 1761 | return get_pointer_to_type(g, struct_type->data.array.child_type, false); |
| 1722 | } else { | 1762 | } else { |
| 1723 | add_node_error(g, node, | 1763 | add_node_error(g, node, |
| 1724 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(name), | 1764 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), |
| 1725 | buf_ptr(&struct_type->name))); | 1765 | buf_ptr(&struct_type->name))); |
| 1726 | return g->builtin_types.entry_invalid; | 1766 | return g->builtin_types.entry_invalid; |
| 1727 | } | 1767 | } |
| ... | @@ -1731,8 +1771,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -1731,8 +1771,9 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i |
| 1731 | if (enum_type->id == TypeTableEntryIdInvalid) { | 1771 | if (enum_type->id == TypeTableEntryIdInvalid) { |
| 1732 | return g->builtin_types.entry_invalid; | 1772 | return g->builtin_types.entry_invalid; |
| 1733 | } else if (enum_type->id == TypeTableEntryIdEnum) { | 1773 | } else if (enum_type->id == TypeTableEntryIdEnum) { |
| 1734 | Buf *field_name = &node->data.field_access_expr.field_name; | ||
| 1735 | return analyze_enum_value_expr(g, import, context, node, nullptr, enum_type, field_name); | 1774 | return analyze_enum_value_expr(g, import, context, node, nullptr, enum_type, field_name); |
| 1775 | } else if (enum_type->id == TypeTableEntryIdPureError) { | ||
| 1776 | return analyze_error_literal_expr(g, import, context, node, field_name); | ||
| 1736 | } else { | 1777 | } else { |
| 1737 | add_node_error(g, node, | 1778 | add_node_error(g, node, |
| 1738 | buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name))); | 1779 | buf_sprintf("type '%s' does not support field access", buf_ptr(&struct_type->name))); |
| ... | @@ -1846,7 +1887,7 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node, | ... | @@ -1846,7 +1887,7 @@ static TypeTableEntry *resolve_expr_const_val_as_err(CodeGen *g, AstNode *node, |
| 1846 | Expr *expr = get_resolved_expr(node); | 1887 | Expr *expr = get_resolved_expr(node); |
| 1847 | expr->const_val.ok = true; | 1888 | expr->const_val.ok = true; |
| 1848 | expr->const_val.data.x_err.err = err; | 1889 | expr->const_val.data.x_err.err = err; |
| 1849 | return get_error_type(g, g->builtin_types.entry_void); | 1890 | return g->builtin_types.entry_pure_error; |
| 1850 | } | 1891 | } |
| 1851 | 1892 | ||
| 1852 | static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value) { | 1893 | static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node, bool value) { |
| ... | @@ -1959,6 +2000,21 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode * | ... | @@ -1959,6 +2000,21 @@ static TypeTableEntry *resolve_expr_const_val_as_bignum_op(CodeGen *g, AstNode * |
| 1959 | return resolved_type; | 2000 | return resolved_type; |
| 1960 | } | 2001 | } |
| 1961 | 2002 | ||
| 2003 | static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, | ||
| 2004 | BlockContext *context, AstNode *node, Buf *err_name) | ||
| 2005 | { | ||
| 2006 | auto err_table_entry = import->block_context->error_table.maybe_get(err_name); | ||
| 2007 | |||
| 2008 | if (err_table_entry) { | ||
| 2009 | return resolve_expr_const_val_as_err(g, node, err_table_entry->value); | ||
| 2010 | } | ||
| 2011 | |||
| 2012 | add_node_error(g, node, | ||
| 2013 | buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name))); | ||
| 2014 | |||
| 2015 | return get_error_type(g, g->builtin_types.entry_void); | ||
| 2016 | } | ||
| 2017 | |||
| 1962 | 2018 | ||
| 1963 | static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 2019 | static TypeTableEntry *analyze_symbol_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 1964 | TypeTableEntry *expected_type, AstNode *node) | 2020 | TypeTableEntry *expected_type, AstNode *node) |
| ... | @@ -2564,23 +2620,6 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry | ... | @@ -2564,23 +2620,6 @@ static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry |
| 2564 | } | 2620 | } |
| 2565 | } | 2621 | } |
| 2566 | 2622 | ||
| 2567 | static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import, | ||
| 2568 | BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node) | ||
| 2569 | { | ||
| 2570 | Buf *err_name = &node->data.error_literal.symbol; | ||
| 2571 | |||
| 2572 | auto err_table_entry = import->block_context->error_table.maybe_get(err_name); | ||
| 2573 | |||
| 2574 | if (err_table_entry) { | ||
| 2575 | return resolve_expr_const_val_as_err(g, node, err_table_entry->value); | ||
| 2576 | } | ||
| 2577 | |||
| 2578 | add_node_error(g, node, | ||
| 2579 | buf_sprintf("use of undeclared error value '%s'", buf_ptr(err_name))); | ||
| 2580 | |||
| 2581 | return get_error_type(g, g->builtin_types.entry_void); | ||
| 2582 | } | ||
| 2583 | |||
| 2584 | static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 2623 | static TypeTableEntry *analyze_array_type(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 2585 | TypeTableEntry *expected_type, AstNode *node) | 2624 | TypeTableEntry *expected_type, AstNode *node) |
| 2586 | { | 2625 | { |
| ... | @@ -2906,6 +2945,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex | ... | @@ -2906,6 +2945,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex |
| 2906 | const_val->data.x_err.payload = other_val; | 2945 | const_val->data.x_err.payload = other_val; |
| 2907 | const_val->ok = true; | 2946 | const_val->ok = true; |
| 2908 | break; | 2947 | break; |
| 2948 | case CastOpPureErrorWrap: | ||
| 2949 | const_val->data.x_err.err = other_val->data.x_err.err; | ||
| 2950 | const_val->ok = true; | ||
| 2951 | break; | ||
| 2909 | case CastOpErrToInt: | 2952 | case CastOpErrToInt: |
| 2910 | { | 2953 | { |
| 2911 | uint64_t value = other_val->data.x_err.err ? other_val->data.x_err.err->value : 0; | 2954 | uint64_t value = other_val->data.x_err.err ? other_val->data.x_err.err->value : 0; |
| ... | @@ -3007,7 +3050,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3007,7 +3050,7 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3007 | } | 3050 | } |
| 3008 | 3051 | ||
| 3009 | // explicit cast from child type of error type to error type | 3052 | // explicit cast from child type of error type to error type |
| 3010 | if (wanted_type->id == TypeTableEntryIdError) { | 3053 | if (wanted_type->id == TypeTableEntryIdErrorUnion) { |
| 3011 | if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) { | 3054 | if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) { |
| 3012 | node->data.fn_call_expr.cast_op = CastOpErrorWrap; | 3055 | node->data.fn_call_expr.cast_op = CastOpErrorWrap; |
| 3013 | eval_const_expr_implicit_cast(g, node, expr_node); | 3056 | eval_const_expr_implicit_cast(g, node, expr_node); |
| ... | @@ -3025,6 +3068,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3025,6 +3068,15 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3025 | } | 3068 | } |
| 3026 | } | 3069 | } |
| 3027 | 3070 | ||
| 3071 | // explicit cast from pure error to error union type | ||
| 3072 | if (wanted_type->id == TypeTableEntryIdErrorUnion && | ||
| 3073 | actual_type->id == TypeTableEntryIdPureError) | ||
| 3074 | { | ||
| 3075 | node->data.fn_call_expr.cast_op = CastOpPureErrorWrap; | ||
| 3076 | eval_const_expr_implicit_cast(g, node, expr_node); | ||
| 3077 | return wanted_type; | ||
| 3078 | } | ||
| 3079 | |||
| 3028 | // explicit cast from number literal to another type | 3080 | // explicit cast from number literal to another type |
| 3029 | if (actual_type->id == TypeTableEntryIdNumLitFloat || | 3081 | if (actual_type->id == TypeTableEntryIdNumLitFloat || |
| 3030 | actual_type->id == TypeTableEntryIdNumLitInt) | 3082 | actual_type->id == TypeTableEntryIdNumLitInt) |
| ... | @@ -3039,8 +3091,10 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B | ... | @@ -3039,8 +3091,10 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 3039 | } | 3091 | } |
| 3040 | 3092 | ||
| 3041 | // explicit cast from %void to integer type which can fit it | 3093 | // explicit cast from %void to integer type which can fit it |
| 3042 | if (actual_type->id == TypeTableEntryIdError && | 3094 | bool actual_type_is_void_err = actual_type->id == TypeTableEntryIdErrorUnion && |
| 3043 | actual_type->data.error.child_type->size_in_bits == 0 && | 3095 | actual_type->data.error.child_type->size_in_bits == 0; |
| 3096 | bool actual_type_is_pure_err = actual_type->id == TypeTableEntryIdPureError; | ||
| 3097 | if ((actual_type_is_void_err || actual_type_is_pure_err) && | ||
| 3044 | wanted_type->id == TypeTableEntryIdInt) | 3098 | wanted_type->id == TypeTableEntryIdInt) |
| 3045 | { | 3099 | { |
| 3046 | BigNum bn; | 3100 | BigNum bn; |
| ... | @@ -3754,9 +3808,6 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -3754,9 +3808,6 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 3754 | case NodeTypeNumberLiteral: | 3808 | case NodeTypeNumberLiteral: |
| 3755 | return_type = analyze_number_literal_expr(g, import, context, expected_type, node); | 3809 | return_type = analyze_number_literal_expr(g, import, context, expected_type, node); |
| 3756 | break; | 3810 | break; |
| 3757 | case NodeTypeErrorLiteral: | ||
| 3758 | return_type = analyze_error_literal_expr(g, import, context, expected_type, node); | ||
| 3759 | break; | ||
| 3760 | case NodeTypeStringLiteral: | 3811 | case NodeTypeStringLiteral: |
| 3761 | return_type = analyze_string_literal_expr(g, import, context, expected_type, node); | 3812 | return_type = analyze_string_literal_expr(g, import, context, expected_type, node); |
| 3762 | break; | 3813 | break; |
| ... | @@ -3794,6 +3845,9 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -3794,6 +3845,9 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 3794 | case NodeTypeArrayType: | 3845 | case NodeTypeArrayType: |
| 3795 | return_type = analyze_array_type(g, import, context, expected_type, node); | 3846 | return_type = analyze_array_type(g, import, context, expected_type, node); |
| 3796 | break; | 3847 | break; |
| 3848 | case NodeTypeErrorType: | ||
| 3849 | return_type = resolve_expr_const_val_as_type(g, node, g->builtin_types.entry_pure_error); | ||
| 3850 | break; | ||
| 3797 | case NodeTypeSwitchExpr: | 3851 | case NodeTypeSwitchExpr: |
| 3798 | return_type = analyze_switch_expr(g, import, context, expected_type, node); | 3852 | return_type = analyze_switch_expr(g, import, context, expected_type, node); |
| 3799 | break; | 3853 | break; |
| ... | @@ -3933,7 +3987,6 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -3933,7 +3987,6 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 3933 | case NodeTypeArrayAccessExpr: | 3987 | case NodeTypeArrayAccessExpr: |
| 3934 | case NodeTypeSliceExpr: | 3988 | case NodeTypeSliceExpr: |
| 3935 | case NodeTypeNumberLiteral: | 3989 | case NodeTypeNumberLiteral: |
| 3936 | case NodeTypeErrorLiteral: | ||
| 3937 | case NodeTypeStringLiteral: | 3990 | case NodeTypeStringLiteral: |
| 3938 | case NodeTypeCharLiteral: | 3991 | case NodeTypeCharLiteral: |
| 3939 | case NodeTypeBoolLiteral: | 3992 | case NodeTypeBoolLiteral: |
| ... | @@ -3958,6 +4011,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -3958,6 +4011,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 3958 | case NodeTypeStructValueField: | 4011 | case NodeTypeStructValueField: |
| 3959 | case NodeTypeContainerInitExpr: | 4012 | case NodeTypeContainerInitExpr: |
| 3960 | case NodeTypeArrayType: | 4013 | case NodeTypeArrayType: |
| 4014 | case NodeTypeErrorType: | ||
| 3961 | zig_unreachable(); | 4015 | zig_unreachable(); |
| 3962 | } | 4016 | } |
| 3963 | } | 4017 | } |
| ... | @@ -3967,7 +4021,6 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -3967,7 +4021,6 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode |
| 3967 | { | 4021 | { |
| 3968 | switch (node->type) { | 4022 | switch (node->type) { |
| 3969 | case NodeTypeNumberLiteral: | 4023 | case NodeTypeNumberLiteral: |
| 3970 | case NodeTypeErrorLiteral: | ||
| 3971 | case NodeTypeStringLiteral: | 4024 | case NodeTypeStringLiteral: |
| 3972 | case NodeTypeCharLiteral: | 4025 | case NodeTypeCharLiteral: |
| 3973 | case NodeTypeBoolLiteral: | 4026 | case NodeTypeBoolLiteral: |
| ... | @@ -3977,6 +4030,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -3977,6 +4030,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode |
| 3977 | case NodeTypeBreak: | 4030 | case NodeTypeBreak: |
| 3978 | case NodeTypeContinue: | 4031 | case NodeTypeContinue: |
| 3979 | case NodeTypeErrorValueDecl: | 4032 | case NodeTypeErrorValueDecl: |
| 4033 | case NodeTypeErrorType: | ||
| 3980 | // no dependencies on other top level declarations | 4034 | // no dependencies on other top level declarations |
| 3981 | break; | 4035 | break; |
| 3982 | case NodeTypeSymbol: | 4036 | case NodeTypeSymbol: |
| ... | @@ -4286,7 +4340,6 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast | ... | @@ -4286,7 +4340,6 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast |
| 4286 | case NodeTypeArrayAccessExpr: | 4340 | case NodeTypeArrayAccessExpr: |
| 4287 | case NodeTypeSliceExpr: | 4341 | case NodeTypeSliceExpr: |
| 4288 | case NodeTypeNumberLiteral: | 4342 | case NodeTypeNumberLiteral: |
| 4289 | case NodeTypeErrorLiteral: | ||
| 4290 | case NodeTypeStringLiteral: | 4343 | case NodeTypeStringLiteral: |
| 4291 | case NodeTypeCharLiteral: | 4344 | case NodeTypeCharLiteral: |
| 4292 | case NodeTypeBoolLiteral: | 4345 | case NodeTypeBoolLiteral: |
| ... | @@ -4311,6 +4364,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast | ... | @@ -4311,6 +4364,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast |
| 4311 | case NodeTypeContainerInitExpr: | 4364 | case NodeTypeContainerInitExpr: |
| 4312 | case NodeTypeStructValueField: | 4365 | case NodeTypeStructValueField: |
| 4313 | case NodeTypeArrayType: | 4366 | case NodeTypeArrayType: |
| 4367 | case NodeTypeErrorType: | ||
| 4314 | zig_unreachable(); | 4368 | zig_unreachable(); |
| 4315 | } | 4369 | } |
| 4316 | } | 4370 | } |
| ... | @@ -4419,7 +4473,14 @@ void semantic_analyze(CodeGen *g) { | ... | @@ -4419,7 +4473,14 @@ void semantic_analyze(CodeGen *g) { |
| 4419 | } | 4473 | } |
| 4420 | } | 4474 | } |
| 4421 | 4475 | ||
| 4422 | g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count); | 4476 | { |
| 4477 | g->err_tag_type = get_smallest_unsigned_int_type(g, g->error_value_count); | ||
| 4478 | |||
| 4479 | g->builtin_types.entry_pure_error->type_ref = g->err_tag_type->type_ref; | ||
| 4480 | g->builtin_types.entry_pure_error->size_in_bits = g->err_tag_type->size_in_bits; | ||
| 4481 | g->builtin_types.entry_pure_error->align_in_bits = g->err_tag_type->align_in_bits; | ||
| 4482 | g->builtin_types.entry_pure_error->di_type = g->err_tag_type->di_type; | ||
| 4483 | } | ||
| 4423 | 4484 | ||
| 4424 | { | 4485 | { |
| 4425 | auto it = g->import_table.entry_iterator(); | 4486 | auto it = g->import_table.entry_iterator(); |
| ... | @@ -4493,8 +4554,6 @@ Expr *get_resolved_expr(AstNode *node) { | ... | @@ -4493,8 +4554,6 @@ Expr *get_resolved_expr(AstNode *node) { |
| 4493 | return &node->data.container_init_expr.resolved_expr; | 4554 | return &node->data.container_init_expr.resolved_expr; |
| 4494 | case NodeTypeNumberLiteral: | 4555 | case NodeTypeNumberLiteral: |
| 4495 | return &node->data.number_literal.resolved_expr; | 4556 | return &node->data.number_literal.resolved_expr; |
| 4496 | case NodeTypeErrorLiteral: | ||
| 4497 | return &node->data.error_literal.resolved_expr; | ||
| 4498 | case NodeTypeStringLiteral: | 4557 | case NodeTypeStringLiteral: |
| 4499 | return &node->data.string_literal.resolved_expr; | 4558 | return &node->data.string_literal.resolved_expr; |
| 4500 | case NodeTypeBlock: | 4559 | case NodeTypeBlock: |
| ... | @@ -4521,6 +4580,8 @@ Expr *get_resolved_expr(AstNode *node) { | ... | @@ -4521,6 +4580,8 @@ Expr *get_resolved_expr(AstNode *node) { |
| 4521 | return &node->data.label.resolved_expr; | 4580 | return &node->data.label.resolved_expr; |
| 4522 | case NodeTypeArrayType: | 4581 | case NodeTypeArrayType: |
| 4523 | return &node->data.array_type.resolved_expr; | 4582 | return &node->data.array_type.resolved_expr; |
| 4583 | case NodeTypeErrorType: | ||
| 4584 | return &node->data.error_type.resolved_expr; | ||
| 4524 | case NodeTypeSwitchExpr: | 4585 | case NodeTypeSwitchExpr: |
| 4525 | return &node->data.switch_expr.resolved_expr; | 4586 | return &node->data.switch_expr.resolved_expr; |
| 4526 | case NodeTypeSwitchProng: | 4587 | case NodeTypeSwitchProng: |
| ... | @@ -4554,7 +4615,6 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) { | ... | @@ -4554,7 +4615,6 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) { |
| 4554 | case NodeTypeErrorValueDecl: | 4615 | case NodeTypeErrorValueDecl: |
| 4555 | return &node->data.error_value_decl.top_level_decl; | 4616 | return &node->data.error_value_decl.top_level_decl; |
| 4556 | case NodeTypeNumberLiteral: | 4617 | case NodeTypeNumberLiteral: |
| 4557 | case NodeTypeErrorLiteral: | ||
| 4558 | case NodeTypeReturnExpr: | 4618 | case NodeTypeReturnExpr: |
| 4559 | case NodeTypeBinOpExpr: | 4619 | case NodeTypeBinOpExpr: |
| 4560 | case NodeTypePrefixOpExpr: | 4620 | case NodeTypePrefixOpExpr: |
| ... | @@ -4593,6 +4653,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) { | ... | @@ -4593,6 +4653,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) { |
| 4593 | case NodeTypeStructField: | 4653 | case NodeTypeStructField: |
| 4594 | case NodeTypeStructValueField: | 4654 | case NodeTypeStructValueField: |
| 4595 | case NodeTypeArrayType: | 4655 | case NodeTypeArrayType: |
| 4656 | case NodeTypeErrorType: | ||
| 4596 | zig_unreachable(); | 4657 | zig_unreachable(); |
| 4597 | } | 4658 | } |
| 4598 | zig_unreachable(); | 4659 | zig_unreachable(); |
src/codegen.cpp+39-7| ... | @@ -306,7 +306,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { | ... | @@ -306,7 +306,7 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { |
| 306 | case CastOpNoop: | 306 | case CastOpNoop: |
| 307 | return expr_val; | 307 | return expr_val; |
| 308 | case CastOpErrToInt: | 308 | case CastOpErrToInt: |
| 309 | assert(actual_type->id == TypeTableEntryIdError); | 309 | assert(actual_type->id == TypeTableEntryIdErrorUnion); |
| 310 | if (actual_type->data.error.child_type->size_in_bits == 0) { | 310 | if (actual_type->data.error.child_type->size_in_bits == 0) { |
| 311 | return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val); | 311 | return gen_widen_or_shorten(g, node, g->err_tag_type, wanted_type, expr_val); |
| 312 | } else { | 312 | } else { |
| ... | @@ -330,12 +330,19 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { | ... | @@ -330,12 +330,19 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) { |
| 330 | return cast_expr->tmp_ptr; | 330 | return cast_expr->tmp_ptr; |
| 331 | } | 331 | } |
| 332 | case CastOpErrorWrap: | 332 | case CastOpErrorWrap: |
| 333 | assert(wanted_type->id == TypeTableEntryIdError); | 333 | assert(wanted_type->id == TypeTableEntryIdErrorUnion); |
| 334 | if (wanted_type->data.error.child_type->size_in_bits == 0) { | 334 | if (wanted_type->data.error.child_type->size_in_bits == 0) { |
| 335 | return LLVMConstNull(g->err_tag_type->type_ref); | 335 | return LLVMConstNull(g->err_tag_type->type_ref); |
| 336 | } else { | 336 | } else { |
| 337 | zig_panic("TODO"); | 337 | zig_panic("TODO"); |
| 338 | } | 338 | } |
| 339 | case CastOpPureErrorWrap: | ||
| 340 | assert(wanted_type->id == TypeTableEntryIdErrorUnion); | ||
| 341 | if (wanted_type->data.error.child_type->size_in_bits == 0) { | ||
| 342 | return expr_val; | ||
| 343 | } else { | ||
| 344 | zig_panic("TODO"); | ||
| 345 | } | ||
| 339 | case CastOpPtrToInt: | 346 | case CastOpPtrToInt: |
| 340 | add_debug_source_node(g, node); | 347 | add_debug_source_node(g, node); |
| 341 | return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); | 348 | return LLVMBuildPtrToInt(g->builder, expr_val, wanted_type->type_ref, ""); |
| ... | @@ -1292,7 +1299,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV | ... | @@ -1292,7 +1299,7 @@ static LLVMValueRef gen_if_bool_expr_raw(CodeGen *g, AstNode *source_node, LLVMV |
| 1292 | return nullptr; | 1299 | return nullptr; |
| 1293 | } | 1300 | } |
| 1294 | 1301 | ||
| 1295 | assert(!use_expr_value || then_type->id == TypeTableEntryIdError); | 1302 | assert(!use_expr_value || then_type->id == TypeTableEntryIdErrorUnion); |
| 1296 | 1303 | ||
| 1297 | LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then"); | 1304 | LLVMBasicBlockRef then_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "Then"); |
| 1298 | LLVMBasicBlockRef endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf"); | 1305 | LLVMBasicBlockRef endif_block = LLVMAppendBasicBlock(g->cur_fn->fn_value, "EndIf"); |
| ... | @@ -2011,7 +2018,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { | ... | @@ -2011,7 +2018,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |
| 2011 | return gen_container_init_expr(g, node); | 2018 | return gen_container_init_expr(g, node); |
| 2012 | case NodeTypeSwitchExpr: | 2019 | case NodeTypeSwitchExpr: |
| 2013 | return gen_switch_expr(g, node); | 2020 | return gen_switch_expr(g, node); |
| 2014 | case NodeTypeErrorLiteral: | ||
| 2015 | case NodeTypeNumberLiteral: | 2021 | case NodeTypeNumberLiteral: |
| 2016 | case NodeTypeBoolLiteral: | 2022 | case NodeTypeBoolLiteral: |
| 2017 | case NodeTypeStringLiteral: | 2023 | case NodeTypeStringLiteral: |
| ... | @@ -2033,6 +2039,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { | ... | @@ -2033,6 +2039,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |
| 2033 | case NodeTypeStructField: | 2039 | case NodeTypeStructField: |
| 2034 | case NodeTypeStructValueField: | 2040 | case NodeTypeStructValueField: |
| 2035 | case NodeTypeArrayType: | 2041 | case NodeTypeArrayType: |
| 2042 | case NodeTypeErrorType: | ||
| 2036 | case NodeTypeSwitchProng: | 2043 | case NodeTypeSwitchProng: |
| 2037 | case NodeTypeSwitchRange: | 2044 | case NodeTypeSwitchRange: |
| 2038 | case NodeTypeErrorValueDecl: | 2045 | case NodeTypeErrorValueDecl: |
| ... | @@ -2063,6 +2070,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE | ... | @@ -2063,6 +2070,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE |
| 2063 | 2070 | ||
| 2064 | if (type_entry->id == TypeTableEntryIdInt) { | 2071 | if (type_entry->id == TypeTableEntryIdInt) { |
| 2065 | return LLVMConstInt(type_entry->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false); | 2072 | return LLVMConstInt(type_entry->type_ref, bignum_to_twos_complement(&const_val->data.x_bignum), false); |
| 2073 | } else if (type_entry->id == TypeTableEntryIdPureError) { | ||
| 2074 | assert(const_val->data.x_err.err); | ||
| 2075 | return LLVMConstInt(g->builtin_types.entry_pure_error->type_ref, const_val->data.x_err.err->value, false); | ||
| 2066 | } else if (type_entry->id == TypeTableEntryIdFloat) { | 2076 | } else if (type_entry->id == TypeTableEntryIdFloat) { |
| 2067 | if (const_val->data.x_bignum.kind == BigNumKindFloat) { | 2077 | if (const_val->data.x_bignum.kind == BigNumKindFloat) { |
| 2068 | return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float); | 2078 | return LLVMConstReal(type_entry->type_ref, const_val->data.x_bignum.data.x_float); |
| ... | @@ -2148,12 +2158,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE | ... | @@ -2148,12 +2158,26 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE |
| 2148 | } else { | 2158 | } else { |
| 2149 | return global_value; | 2159 | return global_value; |
| 2150 | } | 2160 | } |
| 2151 | } else if (type_entry->id == TypeTableEntryIdError) { | 2161 | } else if (type_entry->id == TypeTableEntryIdErrorUnion) { |
| 2152 | if (type_entry->data.error.child_type->size_in_bits == 0) { | 2162 | TypeTableEntry *child_type = type_entry->data.error.child_type; |
| 2163 | if (child_type->size_in_bits == 0) { | ||
| 2153 | uint64_t value = const_val->data.x_err.err ? const_val->data.x_err.err->value : 0; | 2164 | uint64_t value = const_val->data.x_err.err ? const_val->data.x_err.err->value : 0; |
| 2154 | return LLVMConstInt(g->err_tag_type->type_ref, value, false); | 2165 | return LLVMConstInt(g->err_tag_type->type_ref, value, false); |
| 2155 | } else { | 2166 | } else { |
| 2156 | zig_panic("TODO"); | 2167 | LLVMValueRef err_tag_value; |
| 2168 | LLVMValueRef err_payload_value; | ||
| 2169 | if (const_val->data.x_err.err) { | ||
| 2170 | err_tag_value = LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err.err->value, false); | ||
| 2171 | err_payload_value = LLVMConstNull(child_type->type_ref); | ||
| 2172 | } else { | ||
| 2173 | err_tag_value = LLVMConstNull(g->err_tag_type->type_ref); | ||
| 2174 | err_payload_value = gen_const_val(g, child_type, const_val->data.x_err.payload); | ||
| 2175 | } | ||
| 2176 | LLVMValueRef fields[] = { | ||
| 2177 | err_tag_value, | ||
| 2178 | err_payload_value, | ||
| 2179 | }; | ||
| 2180 | return LLVMConstStruct(fields, 2, false); | ||
| 2157 | } | 2181 | } |
| 2158 | } else { | 2182 | } else { |
| 2159 | zig_unreachable(); | 2183 | zig_unreachable(); |
| ... | @@ -2557,6 +2581,14 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -2557,6 +2581,14 @@ static void define_builtin_types(CodeGen *g) { |
| 2557 | g->builtin_types.entry_type = entry; | 2581 | g->builtin_types.entry_type = entry; |
| 2558 | g->primitive_type_table.put(&entry->name, entry); | 2582 | g->primitive_type_table.put(&entry->name, entry); |
| 2559 | } | 2583 | } |
| 2584 | { | ||
| 2585 | // partially complete the error type. we complete it later after we know | ||
| 2586 | // error_value_count. | ||
| 2587 | TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdPureError); | ||
| 2588 | buf_init_from_str(&entry->name, "error"); | ||
| 2589 | g->builtin_types.entry_pure_error = entry; | ||
| 2590 | g->primitive_type_table.put(&entry->name, entry); | ||
| 2591 | } | ||
| 2560 | 2592 | ||
| 2561 | g->builtin_types.entry_u8 = get_int_type(g, false, 8); | 2593 | g->builtin_types.entry_u8 = get_int_type(g, false, 8); |
| 2562 | g->builtin_types.entry_u16 = get_int_type(g, false, 16); | 2594 | g->builtin_types.entry_u16 = get_int_type(g, false, 16); |
src/parser.cpp+18-22| ... | @@ -113,8 +113,6 @@ const char *node_type_str(NodeType node_type) { | ... | @@ -113,8 +113,6 @@ const char *node_type_str(NodeType node_type) { |
| 113 | return "ErrorValueDecl"; | 113 | return "ErrorValueDecl"; |
| 114 | case NodeTypeNumberLiteral: | 114 | case NodeTypeNumberLiteral: |
| 115 | return "NumberLiteral"; | 115 | return "NumberLiteral"; |
| 116 | case NodeTypeErrorLiteral: | ||
| 117 | return "ErrorLiteral"; | ||
| 118 | case NodeTypeStringLiteral: | 116 | case NodeTypeStringLiteral: |
| 119 | return "StringLiteral"; | 117 | return "StringLiteral"; |
| 120 | case NodeTypeCharLiteral: | 118 | case NodeTypeCharLiteral: |
| ... | @@ -167,6 +165,8 @@ const char *node_type_str(NodeType node_type) { | ... | @@ -167,6 +165,8 @@ const char *node_type_str(NodeType node_type) { |
| 167 | return "ContainerInitExpr"; | 165 | return "ContainerInitExpr"; |
| 168 | case NodeTypeArrayType: | 166 | case NodeTypeArrayType: |
| 169 | return "ArrayType"; | 167 | return "ArrayType"; |
| 168 | case NodeTypeErrorType: | ||
| 169 | return "ErrorType"; | ||
| 170 | } | 170 | } |
| 171 | zig_unreachable(); | 171 | zig_unreachable(); |
| 172 | } | 172 | } |
| ... | @@ -313,11 +313,6 @@ void ast_print(AstNode *node, int indent) { | ... | @@ -313,11 +313,6 @@ void ast_print(AstNode *node, int indent) { |
| 313 | } | 313 | } |
| 314 | break; | 314 | break; |
| 315 | } | 315 | } |
| 316 | case NodeTypeErrorLiteral: | ||
| 317 | { | ||
| 318 | fprintf(stderr, "%s '%s'", node_type_str(node->type), buf_ptr(&node->data.error_literal.symbol)); | ||
| 319 | break; | ||
| 320 | } | ||
| 321 | case NodeTypeStringLiteral: | 316 | case NodeTypeStringLiteral: |
| 322 | { | 317 | { |
| 323 | const char *c = node->data.string_literal.c ? "c" : ""; | 318 | const char *c = node->data.string_literal.c ? "c" : ""; |
| ... | @@ -465,6 +460,9 @@ void ast_print(AstNode *node, int indent) { | ... | @@ -465,6 +460,9 @@ void ast_print(AstNode *node, int indent) { |
| 465 | ast_print(node->data.array_type.child_type, indent + 2); | 460 | ast_print(node->data.array_type.child_type, indent + 2); |
| 466 | break; | 461 | break; |
| 467 | } | 462 | } |
| 463 | case NodeTypeErrorType: | ||
| 464 | fprintf(stderr, "%s\n", node_type_str(node->type)); | ||
| 465 | break; | ||
| 468 | } | 466 | } |
| 469 | } | 467 | } |
| 470 | 468 | ||
| ... | @@ -1372,8 +1370,8 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand | ... | @@ -1372,8 +1370,8 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand |
| 1372 | } | 1370 | } |
| 1373 | 1371 | ||
| 1374 | /* | 1372 | /* |
| 1375 | PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("%." "Symbol") | 1373 | PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("error" "." "Symbol") |
| 1376 | KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | 1374 | KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" |
| 1377 | */ | 1375 | */ |
| 1378 | static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) { | 1376 | static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 1379 | Token *token = &pc->tokens->at(*token_index); | 1377 | Token *token = &pc->tokens->at(*token_index); |
| ... | @@ -1419,6 +1417,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool | ... | @@ -1419,6 +1417,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool |
| 1419 | AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token); | 1417 | AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token); |
| 1420 | *token_index += 1; | 1418 | *token_index += 1; |
| 1421 | return node; | 1419 | return node; |
| 1420 | } else if (token->id == TokenIdKeywordError) { | ||
| 1421 | AstNode *node = ast_create_node(pc, NodeTypeErrorType, token); | ||
| 1422 | *token_index += 1; | ||
| 1423 | return node; | ||
| 1422 | } else if (token->id == TokenIdAtSign) { | 1424 | } else if (token->id == TokenIdAtSign) { |
| 1423 | *token_index += 1; | 1425 | *token_index += 1; |
| 1424 | Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); | 1426 | Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); |
| ... | @@ -1448,12 +1450,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool | ... | @@ -1448,12 +1450,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool |
| 1448 | 1450 | ||
| 1449 | ast_buf_from_token(pc, dest_symbol, &node->data.goto_expr.name); | 1451 | ast_buf_from_token(pc, dest_symbol, &node->data.goto_expr.name); |
| 1450 | return node; | 1452 | return node; |
| 1451 | } else if (token->id == TokenIdPercentDot) { | ||
| 1452 | *token_index += 1; | ||
| 1453 | Token *symbol_tok = ast_eat_token(pc, token_index, TokenIdSymbol); | ||
| 1454 | AstNode *node = ast_create_node(pc, NodeTypeErrorLiteral, token); | ||
| 1455 | ast_buf_from_token(pc, symbol_tok, &node->data.error_literal.symbol); | ||
| 1456 | return node; | ||
| 1457 | } | 1453 | } |
| 1458 | 1454 | ||
| 1459 | AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false); | 1455 | AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false); |
| ... | @@ -2969,7 +2965,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { | ... | @@ -2969,7 +2965,7 @@ static AstNode *ast_parse_struct_decl(ParseContext *pc, int *token_index) { |
| 2969 | } | 2965 | } |
| 2970 | 2966 | ||
| 2971 | /* | 2967 | /* |
| 2972 | ErrorValueDecl : option(FnVisibleMod) "%." "Symbol" | 2968 | ErrorValueDecl : option(FnVisibleMod) "error" "Symbol" |
| 2973 | */ | 2969 | */ |
| 2974 | static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, bool mandatory) { | 2970 | static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, bool mandatory) { |
| 2975 | Token *first_token = &pc->tokens->at(*token_index); | 2971 | Token *first_token = &pc->tokens->at(*token_index); |
| ... | @@ -2978,7 +2974,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b | ... | @@ -2978,7 +2974,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b |
| 2978 | 2974 | ||
| 2979 | if (first_token->id == TokenIdKeywordPub) { | 2975 | if (first_token->id == TokenIdKeywordPub) { |
| 2980 | Token *next_token = &pc->tokens->at(*token_index + 1); | 2976 | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2981 | if (next_token->id == TokenIdPercentDot) { | 2977 | if (next_token->id == TokenIdKeywordError) { |
| 2982 | visib_mod = VisibModPub; | 2978 | visib_mod = VisibModPub; |
| 2983 | *token_index += 2; | 2979 | *token_index += 2; |
| 2984 | } else if (mandatory) { | 2980 | } else if (mandatory) { |
| ... | @@ -2988,7 +2984,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b | ... | @@ -2988,7 +2984,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b |
| 2988 | } | 2984 | } |
| 2989 | } else if (first_token->id == TokenIdKeywordExport) { | 2985 | } else if (first_token->id == TokenIdKeywordExport) { |
| 2990 | Token *next_token = &pc->tokens->at(*token_index + 1); | 2986 | Token *next_token = &pc->tokens->at(*token_index + 1); |
| 2991 | if (next_token->id == TokenIdPercentDot) { | 2987 | if (next_token->id == TokenIdKeywordError) { |
| 2992 | visib_mod = VisibModExport; | 2988 | visib_mod = VisibModExport; |
| 2993 | *token_index += 2; | 2989 | *token_index += 2; |
| 2994 | } else if (mandatory) { | 2990 | } else if (mandatory) { |
| ... | @@ -2996,7 +2992,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b | ... | @@ -2996,7 +2992,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, int *token_index, b |
| 2996 | } else { | 2992 | } else { |
| 2997 | return nullptr; | 2993 | return nullptr; |
| 2998 | } | 2994 | } |
| 2999 | } else if (first_token->id == TokenIdPercentDot) { | 2995 | } else if (first_token->id == TokenIdKeywordError) { |
| 3000 | visib_mod = VisibModPrivate; | 2996 | visib_mod = VisibModPrivate; |
| 3001 | *token_index += 1; | 2997 | *token_index += 1; |
| 3002 | } else if (mandatory) { | 2998 | } else if (mandatory) { |
| ... | @@ -3177,9 +3173,6 @@ void normalize_parent_ptrs(AstNode *node) { | ... | @@ -3177,9 +3173,6 @@ void normalize_parent_ptrs(AstNode *node) { |
| 3177 | case NodeTypeCharLiteral: | 3173 | case NodeTypeCharLiteral: |
| 3178 | // none | 3174 | // none |
| 3179 | break; | 3175 | break; |
| 3180 | case NodeTypeErrorLiteral: | ||
| 3181 | // none | ||
| 3182 | break; | ||
| 3183 | case NodeTypeSymbol: | 3176 | case NodeTypeSymbol: |
| 3184 | // none | 3177 | // none |
| 3185 | break; | 3178 | break; |
| ... | @@ -3290,5 +3283,8 @@ void normalize_parent_ptrs(AstNode *node) { | ... | @@ -3290,5 +3283,8 @@ void normalize_parent_ptrs(AstNode *node) { |
| 3290 | set_field(&node->data.array_type.size); | 3283 | set_field(&node->data.array_type.size); |
| 3291 | set_field(&node->data.array_type.child_type); | 3284 | set_field(&node->data.array_type.child_type); |
| 3292 | break; | 3285 | break; |
| 3286 | case NodeTypeErrorType: | ||
| 3287 | // none | ||
| 3288 | break; | ||
| 3293 | } | 3289 | } |
| 3294 | } | 3290 | } |
src/tokenizer.cpp+3| ... | @@ -247,6 +247,8 @@ static void end_token(Tokenize *t) { | ... | @@ -247,6 +247,8 @@ static void end_token(Tokenize *t) { |
| 247 | t->cur_tok->id = TokenIdKeywordSwitch; | 247 | t->cur_tok->id = TokenIdKeywordSwitch; |
| 248 | } else if (mem_eql_str(token_mem, token_len, "undefined")) { | 248 | } else if (mem_eql_str(token_mem, token_len, "undefined")) { |
| 249 | t->cur_tok->id = TokenIdKeywordUndefined; | 249 | t->cur_tok->id = TokenIdKeywordUndefined; |
| 250 | } else if (mem_eql_str(token_mem, token_len, "error")) { | ||
| 251 | t->cur_tok->id = TokenIdKeywordError; | ||
| 250 | } | 252 | } |
| 251 | 253 | ||
| 252 | t->cur_tok = nullptr; | 254 | t->cur_tok = nullptr; |
| ... | @@ -1046,6 +1048,7 @@ const char * token_name(TokenId id) { | ... | @@ -1046,6 +1048,7 @@ const char * token_name(TokenId id) { |
| 1046 | case TokenIdKeywordNoAlias: return "noalias"; | 1048 | case TokenIdKeywordNoAlias: return "noalias"; |
| 1047 | case TokenIdKeywordSwitch: return "switch"; | 1049 | case TokenIdKeywordSwitch: return "switch"; |
| 1048 | case TokenIdKeywordUndefined: return "undefined"; | 1050 | case TokenIdKeywordUndefined: return "undefined"; |
| 1051 | case TokenIdKeywordError: return "error"; | ||
| 1049 | case TokenIdLParen: return "("; | 1052 | case TokenIdLParen: return "("; |
| 1050 | case TokenIdRParen: return ")"; | 1053 | case TokenIdRParen: return ")"; |
| 1051 | case TokenIdComma: return ","; | 1054 | case TokenIdComma: return ","; |
src/tokenizer.hpp+1| ... | @@ -38,6 +38,7 @@ enum TokenId { | ... | @@ -38,6 +38,7 @@ enum TokenId { |
| 38 | TokenIdKeywordNoAlias, | 38 | TokenIdKeywordNoAlias, |
| 39 | TokenIdKeywordSwitch, | 39 | TokenIdKeywordSwitch, |
| 40 | TokenIdKeywordUndefined, | 40 | TokenIdKeywordUndefined, |
| 41 | TokenIdKeywordError, | ||
| 41 | TokenIdLParen, | 42 | TokenIdLParen, |
| 42 | TokenIdRParen, | 43 | TokenIdRParen, |
| 43 | TokenIdComma, | 44 | TokenIdComma, |
std/std.zig+23-23| ... | @@ -25,15 +25,15 @@ pub var stderr = OutStream { | ... | @@ -25,15 +25,15 @@ pub var stderr = OutStream { |
| 25 | }; | 25 | }; |
| 26 | */ | 26 | */ |
| 27 | 27 | ||
| 28 | pub %.Unexpected; | 28 | pub error Unexpected; |
| 29 | pub %.DiskQuota; | 29 | pub error DiskQuota; |
| 30 | pub %.FileTooBig; | 30 | pub error FileTooBig; |
| 31 | pub %.SigInterrupt; | 31 | pub error SigInterrupt; |
| 32 | pub %.Io; | 32 | pub error Io; |
| 33 | pub %.NoSpaceLeft; | 33 | pub error NoSpaceLeft; |
| 34 | pub %.BadPerm; | 34 | pub error BadPerm; |
| 35 | pub %.PipeFail; | 35 | pub error PipeFail; |
| 36 | pub %.Invalid; | 36 | pub error Invalid; |
| 37 | 37 | ||
| 38 | const buffer_size = 4 * 1024; | 38 | const buffer_size = 4 * 1024; |
| 39 | const max_u64_base10_digits = 20; | 39 | const max_u64_base10_digits = 20; |
| ... | @@ -100,14 +100,14 @@ pub struct OutStream { | ... | @@ -100,14 +100,14 @@ pub struct OutStream { |
| 100 | os.index = 0; | 100 | os.index = 0; |
| 101 | switch (write(os.fd, os.buffer.ptr, amt_to_write)) { | 101 | switch (write(os.fd, os.buffer.ptr, amt_to_write)) { |
| 102 | EINVAL => unreachable{}, | 102 | EINVAL => unreachable{}, |
| 103 | EDQUOT => %.DiskQuota, | 103 | EDQUOT => error.DiskQuota, |
| 104 | EFBIG => %.FileTooBig, | 104 | EFBIG => error.FileTooBig, |
| 105 | EINTR => %.SigInterrupt, | 105 | EINTR => error.SigInterrupt, |
| 106 | EIO => %.Io, | 106 | EIO => error.Io, |
| 107 | ENOSPC => %.NoSpaceLeft, | 107 | ENOSPC => error.NoSpaceLeft, |
| 108 | EPERM => %.BadPerm, | 108 | EPERM => error.BadPerm, |
| 109 | EPIPE => %.PipeFail, | 109 | EPIPE => error.PipeFail, |
| 110 | else => %.Unexpected, | 110 | else => error.Unexpected, |
| 111 | } | 111 | } |
| 112 | } | 112 | } |
| 113 | } | 113 | } |
| ... | @@ -121,10 +121,10 @@ pub struct InStream { | ... | @@ -121,10 +121,10 @@ pub struct InStream { |
| 121 | switch (-amt_read) { | 121 | switch (-amt_read) { |
| 122 | EINVAL => unreachable{}, | 122 | EINVAL => unreachable{}, |
| 123 | EFAULT => unreachable{}, | 123 | EFAULT => unreachable{}, |
| 124 | EBADF => %.BadFd, | 124 | EBADF => error.BadFd, |
| 125 | EINTR => %.SigInterrupt, | 125 | EINTR => error.SigInterrupt, |
| 126 | EIO => %.Io, | 126 | EIO => error.Io, |
| 127 | else => %.Unexpected, | 127 | else => error.Unexpected, |
| 128 | } | 128 | } |
| 129 | } | 129 | } |
| 130 | return amt_read; | 130 | return amt_read; |
| ... | @@ -136,8 +136,8 @@ pub fn os_get_random_bytes(buf: []u8) %void => { | ... | @@ -136,8 +136,8 @@ pub fn os_get_random_bytes(buf: []u8) %void => { |
| 136 | switch (getrandom(buf.ptr, buf.len, 0)) { | 136 | switch (getrandom(buf.ptr, buf.len, 0)) { |
| 137 | EINVAL => unreachable{}, | 137 | EINVAL => unreachable{}, |
| 138 | EFAULT => unreachable{}, | 138 | EFAULT => unreachable{}, |
| 139 | EINTR => %.SigInterrupt, | 139 | EINTR => error.SigInterrupt, |
| 140 | else => %.Unexpected, | 140 | else => error.Unexpected, |
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | */ | 143 | */ |
test/run_tests.cpp+6-6| ... | @@ -1213,11 +1213,11 @@ pub fn main(args: [][]u8) %void => { | ... | @@ -1213,11 +1213,11 @@ pub fn main(args: [][]u8) %void => { |
| 1213 | 1213 | ||
| 1214 | add_simple_case("error values", R"SOURCE( | 1214 | add_simple_case("error values", R"SOURCE( |
| 1215 | import "std.zig"; | 1215 | import "std.zig"; |
| 1216 | %.err1; | 1216 | error err1; |
| 1217 | %.err2; | 1217 | error err2; |
| 1218 | pub fn main(args: [][]u8) %void => { | 1218 | pub fn main(args: [][]u8) %void => { |
| 1219 | const a = i32(%.err1); | 1219 | const a = i32(error.err1); |
| 1220 | const b = i32(%.err2); | 1220 | const b = i32(error.err2); |
| 1221 | if (a == b) { | 1221 | if (a == b) { |
| 1222 | print_str("BAD\n"); | 1222 | print_str("BAD\n"); |
| 1223 | } | 1223 | } |
| ... | @@ -1467,8 +1467,8 @@ enum A {} | ... | @@ -1467,8 +1467,8 @@ enum A {} |
| 1467 | )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'"); | 1467 | )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'A'"); |
| 1468 | 1468 | ||
| 1469 | add_compile_fail_case("redefinition of error values", R"SOURCE( | 1469 | add_compile_fail_case("redefinition of error values", R"SOURCE( |
| 1470 | %.A; | 1470 | error A; |
| 1471 | %.A; | 1471 | error A; |
| 1472 | )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of error 'A'"); | 1472 | )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of error 'A'"); |
| 1473 | 1473 | ||
| 1474 | add_compile_fail_case("redefinition of global variables", R"SOURCE( | 1474 | add_compile_fail_case("redefinition of global variables", R"SOURCE( |