| author | |
| committer | |
| log | 0e51c16ef57b3b8239c512d78f0dcafb202be21c |
| tree | 17589df96ea0df0ffc5c66eae1d9404fb0a14151 |
| parent | 523e3b86af44b97bcf68e3eb0956ef297421ee10 |
4 files changed, 54 insertions(+), 21 deletions(-)
src/all_types.hpp+8| ... | @@ -135,6 +135,7 @@ enum NodeType { | ... | @@ -135,6 +135,7 @@ enum NodeType { |
| 135 | NodeTypeUse, | 135 | NodeTypeUse, |
| 136 | NodeTypeBoolLiteral, | 136 | NodeTypeBoolLiteral, |
| 137 | NodeTypeNullLiteral, | 137 | NodeTypeNullLiteral, |
| 138 | NodeTypeUndefinedLiteral, | ||
| 138 | NodeTypeIfBoolExpr, | 139 | NodeTypeIfBoolExpr, |
| 139 | NodeTypeIfVarExpr, | 140 | NodeTypeIfVarExpr, |
| 140 | NodeTypeWhileExpr, | 141 | NodeTypeWhileExpr, |
| ... | @@ -609,6 +610,12 @@ struct AstNodeNullLiteral { | ... | @@ -609,6 +610,12 @@ struct AstNodeNullLiteral { |
| 609 | Expr resolved_expr; | 610 | Expr resolved_expr; |
| 610 | }; | 611 | }; |
| 611 | 612 | ||
| 613 | struct AstNodeUndefinedLiteral { | ||
| 614 | // populated by semantic analyzer | ||
| 615 | StructValExprCodeGen resolved_struct_val_expr; | ||
| 616 | Expr resolved_expr; | ||
| 617 | }; | ||
| 618 | |||
| 612 | struct AstNodeSymbolExpr { | 619 | struct AstNodeSymbolExpr { |
| 613 | Buf symbol; | 620 | Buf symbol; |
| 614 | 621 | ||
| ... | @@ -692,6 +699,7 @@ struct AstNode { | ... | @@ -692,6 +699,7 @@ struct AstNode { |
| 692 | AstNodeContainerInitExpr container_init_expr; | 699 | AstNodeContainerInitExpr container_init_expr; |
| 693 | AstNodeStructValueField struct_val_field; | 700 | AstNodeStructValueField struct_val_field; |
| 694 | AstNodeNullLiteral null_literal; | 701 | AstNodeNullLiteral null_literal; |
| 702 | AstNodeUndefinedLiteral undefined_literal; | ||
| 695 | AstNodeSymbolExpr symbol_expr; | 703 | AstNodeSymbolExpr symbol_expr; |
| 696 | AstNodeBoolLiteral bool_literal; | 704 | AstNodeBoolLiteral bool_literal; |
| 697 | AstNodeBreakExpr break_expr; | 705 | AstNodeBreakExpr break_expr; |
src/analyze.cpp+28-3| ... | @@ -55,6 +55,7 @@ static AstNode *first_executing_node(AstNode *node) { | ... | @@ -55,6 +55,7 @@ static AstNode *first_executing_node(AstNode *node) { |
| 55 | case NodeTypeUse: | 55 | case NodeTypeUse: |
| 56 | case NodeTypeBoolLiteral: | 56 | case NodeTypeBoolLiteral: |
| 57 | case NodeTypeNullLiteral: | 57 | case NodeTypeNullLiteral: |
| 58 | case NodeTypeUndefinedLiteral: | ||
| 58 | case NodeTypeIfBoolExpr: | 59 | case NodeTypeIfBoolExpr: |
| 59 | case NodeTypeIfVarExpr: | 60 | case NodeTypeIfVarExpr: |
| 60 | case NodeTypeLabel: | 61 | case NodeTypeLabel: |
| ... | @@ -1006,6 +1007,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -1006,6 +1007,7 @@ static void resolve_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 1006 | case NodeTypeCharLiteral: | 1007 | case NodeTypeCharLiteral: |
| 1007 | case NodeTypeBoolLiteral: | 1008 | case NodeTypeBoolLiteral: |
| 1008 | case NodeTypeNullLiteral: | 1009 | case NodeTypeNullLiteral: |
| 1010 | case NodeTypeUndefinedLiteral: | ||
| 1009 | case NodeTypeSymbol: | 1011 | case NodeTypeSymbol: |
| 1010 | case NodeTypePrefixOpExpr: | 1012 | case NodeTypePrefixOpExpr: |
| 1011 | case NodeTypeIfBoolExpr: | 1013 | case NodeTypeIfBoolExpr: |
| ... | @@ -1079,7 +1081,9 @@ static bool type_has_codegen_value(TypeTableEntryId id) { | ... | @@ -1079,7 +1081,9 @@ static bool type_has_codegen_value(TypeTableEntryId id) { |
| 1079 | } | 1081 | } |
| 1080 | 1082 | ||
| 1081 | static void add_global_const_expr(CodeGen *g, Expr *expr) { | 1083 | static void add_global_const_expr(CodeGen *g, Expr *expr) { |
| 1082 | if (expr->const_val.ok && type_has_codegen_value(expr->type_entry->id) && !expr->has_global_const) { | 1084 | if (expr->const_val.ok && |
| 1085 | type_has_codegen_value(expr->type_entry->id) && !expr->has_global_const) | ||
| 1086 | { | ||
| 1083 | g->global_const_list.append(expr); | 1087 | g->global_const_list.append(expr); |
| 1084 | expr->has_global_const = true; | 1088 | expr->has_global_const = true; |
| 1085 | } | 1089 | } |
| ... | @@ -2470,6 +2474,20 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i | ... | @@ -2470,6 +2474,20 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i |
| 2470 | return resolve_expr_const_val_as_null(g, node, expected_type); | 2474 | return resolve_expr_const_val_as_null(g, node, expected_type); |
| 2471 | } | 2475 | } |
| 2472 | 2476 | ||
| 2477 | static TypeTableEntry *analyze_undefined_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | ||
| 2478 | TypeTableEntry *expected_type, AstNode *node) | ||
| 2479 | { | ||
| 2480 | Expr *expr = get_resolved_expr(node); | ||
| 2481 | ConstExprValue *const_val = &expr->const_val; | ||
| 2482 | |||
| 2483 | const_val->ok = true; | ||
| 2484 | |||
| 2485 | zig_panic("TODO"); | ||
| 2486 | |||
| 2487 | return expected_type; | ||
| 2488 | } | ||
| 2489 | |||
| 2490 | |||
| 2473 | static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import, | 2491 | static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import, |
| 2474 | BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node) | 2492 | BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node) |
| 2475 | { | 2493 | { |
| ... | @@ -3634,11 +3652,12 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, | ... | @@ -3634,11 +3652,12 @@ static TypeTableEntry *analyze_expression(CodeGen *g, ImportTableEntry *import, |
| 3634 | case NodeTypeBoolLiteral: | 3652 | case NodeTypeBoolLiteral: |
| 3635 | return_type = resolve_expr_const_val_as_bool(g, node, node->data.bool_literal.value); | 3653 | return_type = resolve_expr_const_val_as_bool(g, node, node->data.bool_literal.value); |
| 3636 | break; | 3654 | break; |
| 3637 | |||
| 3638 | case NodeTypeNullLiteral: | 3655 | case NodeTypeNullLiteral: |
| 3639 | return_type = analyze_null_literal_expr(g, import, context, expected_type, node); | 3656 | return_type = analyze_null_literal_expr(g, import, context, expected_type, node); |
| 3640 | break; | 3657 | break; |
| 3641 | 3658 | case NodeTypeUndefinedLiteral: | |
| 3659 | return_type = analyze_undefined_literal_expr(g, import, context, expected_type, node); | ||
| 3660 | break; | ||
| 3642 | case NodeTypeSymbol: | 3661 | case NodeTypeSymbol: |
| 3643 | return_type = analyze_symbol_expr(g, import, context, expected_type, node); | 3662 | return_type = analyze_symbol_expr(g, import, context, expected_type, node); |
| 3644 | break; | 3663 | break; |
| ... | @@ -3804,6 +3823,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -3804,6 +3823,7 @@ static void analyze_top_level_decl(CodeGen *g, ImportTableEntry *import, AstNode |
| 3804 | case NodeTypeCharLiteral: | 3823 | case NodeTypeCharLiteral: |
| 3805 | case NodeTypeBoolLiteral: | 3824 | case NodeTypeBoolLiteral: |
| 3806 | case NodeTypeNullLiteral: | 3825 | case NodeTypeNullLiteral: |
| 3826 | case NodeTypeUndefinedLiteral: | ||
| 3807 | case NodeTypeSymbol: | 3827 | case NodeTypeSymbol: |
| 3808 | case NodeTypePrefixOpExpr: | 3828 | case NodeTypePrefixOpExpr: |
| 3809 | case NodeTypeIfBoolExpr: | 3829 | case NodeTypeIfBoolExpr: |
| ... | @@ -3837,6 +3857,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode | ... | @@ -3837,6 +3857,7 @@ static void collect_expr_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode |
| 3837 | case NodeTypeCharLiteral: | 3857 | case NodeTypeCharLiteral: |
| 3838 | case NodeTypeBoolLiteral: | 3858 | case NodeTypeBoolLiteral: |
| 3839 | case NodeTypeNullLiteral: | 3859 | case NodeTypeNullLiteral: |
| 3860 | case NodeTypeUndefinedLiteral: | ||
| 3840 | case NodeTypeGoto: | 3861 | case NodeTypeGoto: |
| 3841 | case NodeTypeBreak: | 3862 | case NodeTypeBreak: |
| 3842 | case NodeTypeContinue: | 3863 | case NodeTypeContinue: |
| ... | @@ -4155,6 +4176,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast | ... | @@ -4155,6 +4176,7 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast |
| 4155 | case NodeTypeCharLiteral: | 4176 | case NodeTypeCharLiteral: |
| 4156 | case NodeTypeBoolLiteral: | 4177 | case NodeTypeBoolLiteral: |
| 4157 | case NodeTypeNullLiteral: | 4178 | case NodeTypeNullLiteral: |
| 4179 | case NodeTypeUndefinedLiteral: | ||
| 4158 | case NodeTypeSymbol: | 4180 | case NodeTypeSymbol: |
| 4159 | case NodeTypePrefixOpExpr: | 4181 | case NodeTypePrefixOpExpr: |
| 4160 | case NodeTypeIfBoolExpr: | 4182 | case NodeTypeIfBoolExpr: |
| ... | @@ -4364,6 +4386,8 @@ Expr *get_resolved_expr(AstNode *node) { | ... | @@ -4364,6 +4386,8 @@ Expr *get_resolved_expr(AstNode *node) { |
| 4364 | return &node->data.bool_literal.resolved_expr; | 4386 | return &node->data.bool_literal.resolved_expr; |
| 4365 | case NodeTypeNullLiteral: | 4387 | case NodeTypeNullLiteral: |
| 4366 | return &node->data.null_literal.resolved_expr; | 4388 | return &node->data.null_literal.resolved_expr; |
| 4389 | case NodeTypeUndefinedLiteral: | ||
| 4390 | return &node->data.undefined_literal.resolved_expr; | ||
| 4367 | case NodeTypeGoto: | 4391 | case NodeTypeGoto: |
| 4368 | return &node->data.goto_expr.resolved_expr; | 4392 | return &node->data.goto_expr.resolved_expr; |
| 4369 | case NodeTypeBreak: | 4393 | case NodeTypeBreak: |
| ... | @@ -4438,6 +4462,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) { | ... | @@ -4438,6 +4462,7 @@ TopLevelDecl *get_resolved_top_level_decl(AstNode *node) { |
| 4438 | case NodeTypeUse: | 4462 | case NodeTypeUse: |
| 4439 | case NodeTypeBoolLiteral: | 4463 | case NodeTypeBoolLiteral: |
| 4440 | case NodeTypeNullLiteral: | 4464 | case NodeTypeNullLiteral: |
| 4465 | case NodeTypeUndefinedLiteral: | ||
| 4441 | case NodeTypeLabel: | 4466 | case NodeTypeLabel: |
| 4442 | case NodeTypeGoto: | 4467 | case NodeTypeGoto: |
| 4443 | case NodeTypeBreak: | 4468 | case NodeTypeBreak: |
src/codegen.cpp+5-17| ... | @@ -1486,22 +1486,6 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) { | ... | @@ -1486,22 +1486,6 @@ static LLVMValueRef gen_asm_expr(CodeGen *g, AstNode *node) { |
| 1486 | return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, ""); | 1486 | return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, ""); |
| 1487 | } | 1487 | } |
| 1488 | 1488 | ||
| 1489 | static LLVMValueRef gen_null_literal(CodeGen *g, AstNode *node) { | ||
| 1490 | assert(node->type == NodeTypeNullLiteral); | ||
| 1491 | |||
| 1492 | TypeTableEntry *type_entry = get_expr_type(node); | ||
| 1493 | assert(type_entry->id == TypeTableEntryIdMaybe); | ||
| 1494 | |||
| 1495 | LLVMValueRef tmp_struct_ptr = node->data.null_literal.resolved_struct_val_expr.ptr; | ||
| 1496 | |||
| 1497 | add_debug_source_node(g, node); | ||
| 1498 | LLVMValueRef field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, 1, ""); | ||
| 1499 | LLVMValueRef null_value = LLVMConstNull(LLVMInt1Type()); | ||
| 1500 | LLVMBuildStore(g->builder, null_value, field_ptr); | ||
| 1501 | |||
| 1502 | return tmp_struct_ptr; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { | 1489 | static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) { |
| 1506 | assert(node->type == NodeTypeContainerInitExpr); | 1490 | assert(node->type == NodeTypeContainerInitExpr); |
| 1507 | 1491 | ||
| ... | @@ -1963,7 +1947,11 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { | ... | @@ -1963,7 +1947,11 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { |
| 1963 | case NodeTypeFieldAccessExpr: | 1947 | case NodeTypeFieldAccessExpr: |
| 1964 | return gen_field_access_expr(g, node, false); | 1948 | return gen_field_access_expr(g, node, false); |
| 1965 | case NodeTypeNullLiteral: | 1949 | case NodeTypeNullLiteral: |
| 1966 | return gen_null_literal(g, node); | 1950 | // caught by constant expression eval codegen |
| 1951 | zig_unreachable(); | ||
| 1952 | case NodeTypeUndefinedLiteral: | ||
| 1953 | // caught by constant expression eval codegen | ||
| 1954 | zig_unreachable(); | ||
| 1967 | case NodeTypeIfBoolExpr: | 1955 | case NodeTypeIfBoolExpr: |
| 1968 | return gen_if_bool_expr(g, node); | 1956 | return gen_if_bool_expr(g, node); |
| 1969 | case NodeTypeIfVarExpr: | 1957 | case NodeTypeIfVarExpr: |
src/parser.cpp+13-1| ... | @@ -129,6 +129,8 @@ const char *node_type_str(NodeType node_type) { | ... | @@ -129,6 +129,8 @@ const char *node_type_str(NodeType node_type) { |
| 129 | return "BoolLiteral"; | 129 | return "BoolLiteral"; |
| 130 | case NodeTypeNullLiteral: | 130 | case NodeTypeNullLiteral: |
| 131 | return "NullLiteral"; | 131 | return "NullLiteral"; |
| 132 | case NodeTypeUndefinedLiteral: | ||
| 133 | return "UndefinedLiteral"; | ||
| 132 | case NodeTypeIfBoolExpr: | 134 | case NodeTypeIfBoolExpr: |
| 133 | return "IfBoolExpr"; | 135 | return "IfBoolExpr"; |
| 134 | case NodeTypeIfVarExpr: | 136 | case NodeTypeIfVarExpr: |
| ... | @@ -412,6 +414,9 @@ void ast_print(AstNode *node, int indent) { | ... | @@ -412,6 +414,9 @@ void ast_print(AstNode *node, int indent) { |
| 412 | case NodeTypeContinue: | 414 | case NodeTypeContinue: |
| 413 | fprintf(stderr, "%s\n", node_type_str(node->type)); | 415 | fprintf(stderr, "%s\n", node_type_str(node->type)); |
| 414 | break; | 416 | break; |
| 417 | case NodeTypeUndefinedLiteral: | ||
| 418 | fprintf(stderr, "%s\n", node_type_str(node->type)); | ||
| 419 | break; | ||
| 415 | case NodeTypeAsmExpr: | 420 | case NodeTypeAsmExpr: |
| 416 | fprintf(stderr, "%s\n", node_type_str(node->type)); | 421 | fprintf(stderr, "%s\n", node_type_str(node->type)); |
| 417 | break; | 422 | break; |
| ... | @@ -1368,7 +1373,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand | ... | @@ -1368,7 +1373,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, int *token_index, bool mand |
| 1368 | 1373 | ||
| 1369 | /* | 1374 | /* |
| 1370 | PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("%." "Symbol") | 1375 | PrimaryExpression : "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | AsmExpression | ("%." "Symbol") |
| 1371 | KeywordLiteral : token(True) | token(False) | token(Null) | token(Break) | token(Continue) | 1376 | KeywordLiteral : "true" | "false" | "null" | "break" | "continue" | "undefined" |
| 1372 | */ | 1377 | */ |
| 1373 | static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) { | 1378 | static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool mandatory) { |
| 1374 | Token *token = &pc->tokens->at(*token_index); | 1379 | Token *token = &pc->tokens->at(*token_index); |
| ... | @@ -1410,6 +1415,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool | ... | @@ -1410,6 +1415,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, int *token_index, bool |
| 1410 | AstNode *node = ast_create_node(pc, NodeTypeContinue, token); | 1415 | AstNode *node = ast_create_node(pc, NodeTypeContinue, token); |
| 1411 | *token_index += 1; | 1416 | *token_index += 1; |
| 1412 | return node; | 1417 | return node; |
| 1418 | } else if (token->id == TokenIdKeywordUndefined) { | ||
| 1419 | AstNode *node = ast_create_node(pc, NodeTypeUndefinedLiteral, token); | ||
| 1420 | *token_index += 1; | ||
| 1421 | return node; | ||
| 1413 | } else if (token->id == TokenIdAtSign) { | 1422 | } else if (token->id == TokenIdAtSign) { |
| 1414 | *token_index += 1; | 1423 | *token_index += 1; |
| 1415 | Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); | 1424 | Token *name_tok = ast_eat_token(pc, token_index, TokenIdSymbol); |
| ... | @@ -3202,6 +3211,9 @@ void normalize_parent_ptrs(AstNode *node) { | ... | @@ -3202,6 +3211,9 @@ void normalize_parent_ptrs(AstNode *node) { |
| 3202 | case NodeTypeNullLiteral: | 3211 | case NodeTypeNullLiteral: |
| 3203 | // none | 3212 | // none |
| 3204 | break; | 3213 | break; |
| 3214 | case NodeTypeUndefinedLiteral: | ||
| 3215 | // none | ||
| 3216 | break; | ||
| 3205 | case NodeTypeIfBoolExpr: | 3217 | case NodeTypeIfBoolExpr: |
| 3206 | set_field(&node->data.if_bool_expr.condition); | 3218 | set_field(&node->data.if_bool_expr.condition); |
| 3207 | set_field(&node->data.if_bool_expr.then_block); | 3219 | set_field(&node->data.if_bool_expr.then_block); |