authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-26 23:47:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-26 23:47:30-04:00
log183976b242dac0731caa7d925e88ad151a4dc8ee
tree426fe019d53dd2c27695518fc64f5fddd449fef0
parentf4d7c91363c2525741522a7ad942a419653ae47b

add this keyword refers to thing in immediate scope

See #169

16 files changed, 167 insertions(+), 16 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" | "zeroes" | "error" | "type"154KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
155```155```
156156
157## Operator Precedence157## Operator Precedence
doc/vim/syntax/zig.vim+1-1
...@@ -14,7 +14,7 @@ syn keyword zigStatement goto break return continue asm defer...@@ -14,7 +14,7 @@ syn keyword zigStatement goto break return continue asm defer
14syn keyword zigConditional if else switch14syn keyword zigConditional if else switch
15syn keyword zigRepeat while for15syn keyword zigRepeat while for
1616
17syn keyword zigConstant null undefined zeroes17syn keyword zigConstant null undefined zeroes this
18syn keyword zigKeyword fn use18syn keyword zigKeyword fn use
19syn keyword zigType bool f32 f64 void unreachable type error19syn keyword zigType bool f32 f64 void unreachable type error
20syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize20syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize
src/all_types.hpp+10-2
...@@ -85,6 +85,7 @@ struct ConstExprValue {...@@ -85,6 +85,7 @@ struct ConstExprValue {
85 ConstArrayValue x_array;85 ConstArrayValue x_array;
86 ConstPtrValue x_ptr;86 ConstPtrValue x_ptr;
87 ImportTableEntry *x_import;87 ImportTableEntry *x_import;
88 BlockContext *x_block;
88 } data;89 } data;
89};90};
9091
...@@ -174,6 +175,7 @@ enum NodeType {...@@ -174,6 +175,7 @@ enum NodeType {
174 NodeTypeNullLiteral,175 NodeTypeNullLiteral,
175 NodeTypeUndefinedLiteral,176 NodeTypeUndefinedLiteral,
176 NodeTypeZeroesLiteral,177 NodeTypeZeroesLiteral,
178 NodeTypeThisLiteral,
177 NodeTypeIfBoolExpr,179 NodeTypeIfBoolExpr,
178 NodeTypeIfVarExpr,180 NodeTypeIfVarExpr,
179 NodeTypeWhileExpr,181 NodeTypeWhileExpr,
...@@ -719,6 +721,11 @@ struct AstNodeZeroesLiteral {...@@ -719,6 +721,11 @@ struct AstNodeZeroesLiteral {
719 Expr resolved_expr;721 Expr resolved_expr;
720};722};
721723
724struct AstNodeThisLiteral {
725 // populated by semantic analyzer
726 Expr resolved_expr;
727};
728
722struct AstNodeSymbolExpr {729struct AstNodeSymbolExpr {
723 Buf *symbol;730 Buf *symbol;
724731
...@@ -822,6 +829,7 @@ struct AstNode {...@@ -822,6 +829,7 @@ struct AstNode {
822 AstNodeNullLiteral null_literal;829 AstNodeNullLiteral null_literal;
823 AstNodeUndefinedLiteral undefined_literal;830 AstNodeUndefinedLiteral undefined_literal;
824 AstNodeZeroesLiteral zeroes_literal;831 AstNodeZeroesLiteral zeroes_literal;
832 AstNodeThisLiteral this_literal;
825 AstNodeSymbolExpr symbol_expr;833 AstNodeSymbolExpr symbol_expr;
826 AstNodeBoolLiteral bool_literal;834 AstNodeBoolLiteral bool_literal;
827 AstNodeBreakExpr break_expr;835 AstNodeBreakExpr break_expr;
...@@ -1005,6 +1013,7 @@ enum TypeTableEntryId {...@@ -1005,6 +1013,7 @@ enum TypeTableEntryId {
1005 TypeTableEntryIdFn,1013 TypeTableEntryIdFn,
1006 TypeTableEntryIdTypeDecl,1014 TypeTableEntryIdTypeDecl,
1007 TypeTableEntryIdNamespace,1015 TypeTableEntryIdNamespace,
1016 TypeTableEntryIdBlock,
1008 TypeTableEntryIdGenericFn,1017 TypeTableEntryIdGenericFn,
1009};1018};
10101019
...@@ -1102,7 +1111,6 @@ struct FnTableEntry {...@@ -1102,7 +1111,6 @@ struct FnTableEntry {
1102 AstNode *want_pure_return_type;1111 AstNode *want_pure_return_type;
1103 bool safety_off;1112 bool safety_off;
1104 FnInline fn_inline;1113 FnInline fn_inline;
1105 BlockContext *parent_block_context;
1106 FnAnalState anal_state;1114 FnAnalState anal_state;
11071115
1108 ZigList<AstNode *> cast_alloca_list;1116 ZigList<AstNode *> cast_alloca_list;
...@@ -1209,6 +1217,7 @@ struct CodeGen {...@@ -1209,6 +1217,7 @@ struct CodeGen {
1209 TypeTableEntry *entry_type;1217 TypeTableEntry *entry_type;
1210 TypeTableEntry *entry_invalid;1218 TypeTableEntry *entry_invalid;
1211 TypeTableEntry *entry_namespace;1219 TypeTableEntry *entry_namespace;
1220 TypeTableEntry *entry_block;
1212 TypeTableEntry *entry_num_lit_int;1221 TypeTableEntry *entry_num_lit_int;
1213 TypeTableEntry *entry_num_lit_float;1222 TypeTableEntry *entry_num_lit_float;
1214 TypeTableEntry *entry_undef;1223 TypeTableEntry *entry_undef;
...@@ -1340,7 +1349,6 @@ struct LabelTableEntry {...@@ -1340,7 +1349,6 @@ struct LabelTableEntry {
1340};1349};
13411350
1342struct BlockContext {1351struct BlockContext {
1343 // One of: NodeTypeFnDef, NodeTypeBlock, NodeTypeRoot, NodeTypeDefer, NodeTypeVariableDeclaration
1344 AstNode *node;1352 AstNode *node;
13451353
1346 // any variables that are introduced by this scope1354 // any variables that are introduced by this scope
src/analyze.cpp+58-8
...@@ -91,6 +91,7 @@ static AstNode *first_executing_node(AstNode *node) {...@@ -91,6 +91,7 @@ static AstNode *first_executing_node(AstNode *node) {
91 case NodeTypeNullLiteral:91 case NodeTypeNullLiteral:
92 case NodeTypeUndefinedLiteral:92 case NodeTypeUndefinedLiteral:
93 case NodeTypeZeroesLiteral:93 case NodeTypeZeroesLiteral:
94 case NodeTypeThisLiteral:
94 case NodeTypeIfBoolExpr:95 case NodeTypeIfBoolExpr:
95 case NodeTypeIfVarExpr:96 case NodeTypeIfVarExpr:
96 case NodeTypeLabel:97 case NodeTypeLabel:
...@@ -246,6 +247,7 @@ static bool type_is_complete(TypeTableEntry *type_entry) {...@@ -246,6 +247,7 @@ static bool type_is_complete(TypeTableEntry *type_entry) {
246 case TypeTableEntryIdFn:247 case TypeTableEntryIdFn:
247 case TypeTableEntryIdTypeDecl:248 case TypeTableEntryIdTypeDecl:
248 case TypeTableEntryIdNamespace:249 case TypeTableEntryIdNamespace:
250 case TypeTableEntryIdBlock:
249 case TypeTableEntryIdGenericFn:251 case TypeTableEntryIdGenericFn:
250 return true;252 return true;
251 }253 }
...@@ -962,6 +964,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -962,6 +964,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
962 case TypeTableEntryIdNullLit:964 case TypeTableEntryIdNullLit:
963 case TypeTableEntryIdUnreachable:965 case TypeTableEntryIdUnreachable:
964 case TypeTableEntryIdNamespace:966 case TypeTableEntryIdNamespace:
967 case TypeTableEntryIdBlock:
965 case TypeTableEntryIdGenericFn:968 case TypeTableEntryIdGenericFn:
966 fn_proto->skip = true;969 fn_proto->skip = true;
967 add_node_error(g, child->data.param_decl.type,970 add_node_error(g, child->data.param_decl.type,
...@@ -1012,6 +1015,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -1012,6 +1015,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
1012 case TypeTableEntryIdUndefLit:1015 case TypeTableEntryIdUndefLit:
1013 case TypeTableEntryIdNullLit:1016 case TypeTableEntryIdNullLit:
1014 case TypeTableEntryIdNamespace:1017 case TypeTableEntryIdNamespace:
1018 case TypeTableEntryIdBlock:
1015 case TypeTableEntryIdGenericFn:1019 case TypeTableEntryIdGenericFn:
1016 case TypeTableEntryIdVar:1020 case TypeTableEntryIdVar:
1017 fn_proto->skip = true;1021 fn_proto->skip = true;
...@@ -1896,6 +1900,7 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)...@@ -1896,6 +1900,7 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)
1896 case NodeTypeNullLiteral:1900 case NodeTypeNullLiteral:
1897 case NodeTypeUndefinedLiteral:1901 case NodeTypeUndefinedLiteral:
1898 case NodeTypeZeroesLiteral:1902 case NodeTypeZeroesLiteral:
1903 case NodeTypeThisLiteral:
1899 case NodeTypeSymbol:1904 case NodeTypeSymbol:
1900 case NodeTypePrefixOpExpr:1905 case NodeTypePrefixOpExpr:
1901 case NodeTypeIfBoolExpr:1906 case NodeTypeIfBoolExpr:
...@@ -1960,6 +1965,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {...@@ -1960,6 +1965,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
1960 case TypeTableEntryIdUndefLit:1965 case TypeTableEntryIdUndefLit:
1961 case TypeTableEntryIdNullLit:1966 case TypeTableEntryIdNullLit:
1962 case TypeTableEntryIdNamespace:1967 case TypeTableEntryIdNamespace:
1968 case TypeTableEntryIdBlock:
1963 case TypeTableEntryIdGenericFn:1969 case TypeTableEntryIdGenericFn:
1964 return false;1970 return false;
19651971
...@@ -2745,6 +2751,7 @@ static bool is_container(TypeTableEntry *type_entry) {...@@ -2745,6 +2751,7 @@ static bool is_container(TypeTableEntry *type_entry) {
2745 case TypeTableEntryIdFn:2751 case TypeTableEntryIdFn:
2746 case TypeTableEntryIdTypeDecl:2752 case TypeTableEntryIdTypeDecl:
2747 case TypeTableEntryIdNamespace:2753 case TypeTableEntryIdNamespace:
2754 case TypeTableEntryIdBlock:
2748 case TypeTableEntryIdGenericFn:2755 case TypeTableEntryIdGenericFn:
2749 return false;2756 return false;
2750 }2757 }
...@@ -2791,6 +2798,7 @@ static void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {...@@ -2791,6 +2798,7 @@ static void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
2791 case TypeTableEntryIdFn:2798 case TypeTableEntryIdFn:
2792 case TypeTableEntryIdTypeDecl:2799 case TypeTableEntryIdTypeDecl:
2793 case TypeTableEntryIdNamespace:2800 case TypeTableEntryIdNamespace:
2801 case TypeTableEntryIdBlock:
2794 case TypeTableEntryIdGenericFn:2802 case TypeTableEntryIdGenericFn:
2795 case TypeTableEntryIdInvalid:2803 case TypeTableEntryIdInvalid:
2796 case TypeTableEntryIdVar:2804 case TypeTableEntryIdVar:
...@@ -2965,7 +2973,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -2965,7 +2973,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
2965 }2973 }
2966 if (decl_node) {2974 if (decl_node) {
2967 TopLevelDecl *tld = get_as_top_level_decl(decl_node);2975 TopLevelDecl *tld = get_as_top_level_decl(decl_node);
2968 if (tld->visib_mod == VisibModPrivate) {2976 if (tld->visib_mod == VisibModPrivate && decl_node->owner != import) {
2969 ErrorMsg *msg = add_node_error(g, node,2977 ErrorMsg *msg = add_node_error(g, node,
2970 buf_sprintf("'%s' is private", buf_ptr(field_name)));2978 buf_sprintf("'%s' is private", buf_ptr(field_name)));
2971 add_error_note(g, msg, decl_node, buf_sprintf("declared here"));2979 add_error_note(g, msg, decl_node, buf_sprintf("declared here"));
...@@ -3093,6 +3101,16 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node,...@@ -3093,6 +3101,16 @@ static TypeTableEntry *resolve_expr_const_val_as_type(CodeGen *g, AstNode *node,
3093 return g->builtin_types.entry_type;3101 return g->builtin_types.entry_type;
3094}3102}
30953103
3104static TypeTableEntry *resolve_expr_const_val_as_block(CodeGen *g, AstNode *node, BlockContext *block_context,
3105 bool depends_on_compile_var)
3106{
3107 Expr *expr = get_resolved_expr(node);
3108 expr->const_val.ok = true;
3109 expr->const_val.data.x_block = block_context;
3110 expr->const_val.depends_on_compile_var = depends_on_compile_var;
3111 return g->builtin_types.entry_block;
3112}
3113
3096static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other,3114static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other,
3097 bool depends_on_compile_var)3115 bool depends_on_compile_var)
3098{3116{
...@@ -3221,6 +3239,13 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As...@@ -3221,6 +3239,13 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As
3221 return g->builtin_types.entry_num_lit_int;3239 return g->builtin_types.entry_num_lit_int;
3222}3240}
32233241
3242static TypeTableEntry *resolve_expr_const_val_as_import(CodeGen *g, AstNode *node, ImportTableEntry *import) {
3243 Expr *expr = get_resolved_expr(node);
3244 expr->const_val.ok = true;
3245 expr->const_val.data.x_import = import;
3246 return g->builtin_types.entry_namespace;
3247}
3248
3224static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,3249static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
3225 BlockContext *context, AstNode *node, Buf *err_name)3250 BlockContext *context, AstNode *node, Buf *err_name)
3226{3251{
...@@ -3497,6 +3522,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im...@@ -3497,6 +3522,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
3497 case TypeTableEntryIdFn:3522 case TypeTableEntryIdFn:
3498 case TypeTableEntryIdTypeDecl:3523 case TypeTableEntryIdTypeDecl:
3499 case TypeTableEntryIdNamespace:3524 case TypeTableEntryIdNamespace:
3525 case TypeTableEntryIdBlock:
3500 case TypeTableEntryIdGenericFn:3526 case TypeTableEntryIdGenericFn:
3501 if (!is_equality_cmp) {3527 if (!is_equality_cmp) {
3502 add_node_error(g, node,3528 add_node_error(g, node,
...@@ -4120,6 +4146,25 @@ static TypeTableEntry *analyze_zeroes_literal_expr(CodeGen *g, ImportTableEntry...@@ -4120,6 +4146,25 @@ static TypeTableEntry *analyze_zeroes_literal_expr(CodeGen *g, ImportTableEntry
4120 return expected_type ? expected_type : g->builtin_types.entry_undef;4146 return expected_type ? expected_type : g->builtin_types.entry_undef;
4121}4147}
41224148
4149static TypeTableEntry *analyze_this_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
4150 TypeTableEntry *expected_type, AstNode *node)
4151{
4152 if (!context->parent) {
4153 return resolve_expr_const_val_as_import(g, node, import);
4154 }
4155 if (context->fn_entry && (!context->parent->fn_entry ||
4156 (context->parent->parent && !context->parent->parent->fn_entry)))
4157 {
4158 return resolve_expr_const_val_as_fn(g, node, context->fn_entry, false);
4159 }
4160 if (context->node->type == NodeTypeContainerDecl) {
4161 return resolve_expr_const_val_as_type(g, node, context->node->data.struct_decl.type_entry, false);
4162 }
4163 if (context->node->type == NodeTypeBlock) {
4164 return resolve_expr_const_val_as_block(g, node, context, false);
4165 }
4166 zig_unreachable();
4167}
41234168
4124static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import,4169static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import,
4125 BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)4170 BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
...@@ -4793,13 +4838,6 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -4793,13 +4838,6 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
4793 return g->builtin_types.entry_invalid;4838 return g->builtin_types.entry_invalid;
4794}4839}
47954840
4796static TypeTableEntry *resolve_expr_const_val_as_import(CodeGen *g, AstNode *node, ImportTableEntry *import) {
4797 Expr *expr = get_resolved_expr(node);
4798 expr->const_val.ok = true;
4799 expr->const_val.data.x_import = import;
4800 return g->builtin_types.entry_namespace;
4801}
4802
4803static TypeTableEntry *analyze_import(CodeGen *g, ImportTableEntry *import, BlockContext *context,4841static TypeTableEntry *analyze_import(CodeGen *g, ImportTableEntry *import, BlockContext *context,
4804 AstNode *node)4842 AstNode *node)
4805{4843{
...@@ -5394,6 +5432,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -5394,6 +5432,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
5394 case TypeTableEntryIdUndefLit:5432 case TypeTableEntryIdUndefLit:
5395 case TypeTableEntryIdNullLit:5433 case TypeTableEntryIdNullLit:
5396 case TypeTableEntryIdNamespace:5434 case TypeTableEntryIdNamespace:
5435 case TypeTableEntryIdBlock:
5397 case TypeTableEntryIdGenericFn:5436 case TypeTableEntryIdGenericFn:
5398 case TypeTableEntryIdVar:5437 case TypeTableEntryIdVar:
5399 add_node_error(g, expr_node,5438 add_node_error(g, expr_node,
...@@ -6796,6 +6835,9 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn...@@ -6796,6 +6835,9 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn
6796 case NodeTypeZeroesLiteral:6835 case NodeTypeZeroesLiteral:
6797 return_type = analyze_zeroes_literal_expr(g, import, context, expected_type, node);6836 return_type = analyze_zeroes_literal_expr(g, import, context, expected_type, node);
6798 break;6837 break;
6838 case NodeTypeThisLiteral:
6839 return_type = analyze_this_literal_expr(g, import, context, expected_type, node);
6840 break;
6799 case NodeTypeSymbol:6841 case NodeTypeSymbol:
6800 return_type = analyze_symbol_expr(g, import, context, expected_type, node, pointer_only);6842 return_type = analyze_symbol_expr(g, import, context, expected_type, node, pointer_only);
6801 break;6843 break;
...@@ -7085,6 +7127,7 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte...@@ -7085,6 +7127,7 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte
7085 case NodeTypeNullLiteral:7127 case NodeTypeNullLiteral:
7086 case NodeTypeUndefinedLiteral:7128 case NodeTypeUndefinedLiteral:
7087 case NodeTypeZeroesLiteral:7129 case NodeTypeZeroesLiteral:
7130 case NodeTypeThisLiteral:
7088 case NodeTypeSymbol:7131 case NodeTypeSymbol:
7089 case NodeTypePrefixOpExpr:7132 case NodeTypePrefixOpExpr:
7090 case NodeTypeIfBoolExpr:7133 case NodeTypeIfBoolExpr:
...@@ -7347,6 +7390,8 @@ Expr *get_resolved_expr(AstNode *node) {...@@ -7347,6 +7390,8 @@ Expr *get_resolved_expr(AstNode *node) {
7347 return &node->data.undefined_literal.resolved_expr;7390 return &node->data.undefined_literal.resolved_expr;
7348 case NodeTypeZeroesLiteral:7391 case NodeTypeZeroesLiteral:
7349 return &node->data.zeroes_literal.resolved_expr;7392 return &node->data.zeroes_literal.resolved_expr;
7393 case NodeTypeThisLiteral:
7394 return &node->data.this_literal.resolved_expr;
7350 case NodeTypeGoto:7395 case NodeTypeGoto:
7351 return &node->data.goto_expr.resolved_expr;7396 return &node->data.goto_expr.resolved_expr;
7352 case NodeTypeBreak:7397 case NodeTypeBreak:
...@@ -7432,6 +7477,7 @@ static TopLevelDecl *get_as_top_level_decl(AstNode *node) {...@@ -7432,6 +7477,7 @@ static TopLevelDecl *get_as_top_level_decl(AstNode *node) {
7432 case NodeTypeNullLiteral:7477 case NodeTypeNullLiteral:
7433 case NodeTypeUndefinedLiteral:7478 case NodeTypeUndefinedLiteral:
7434 case NodeTypeZeroesLiteral:7479 case NodeTypeZeroesLiteral:
7480 case NodeTypeThisLiteral:
7435 case NodeTypeLabel:7481 case NodeTypeLabel:
7436 case NodeTypeGoto:7482 case NodeTypeGoto:
7437 case NodeTypeBreak:7483 case NodeTypeBreak:
...@@ -7499,6 +7545,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -7499,6 +7545,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
7499 case TypeTableEntryIdUndefLit:7545 case TypeTableEntryIdUndefLit:
7500 case TypeTableEntryIdNullLit:7546 case TypeTableEntryIdNullLit:
7501 case TypeTableEntryIdNamespace:7547 case TypeTableEntryIdNamespace:
7548 case TypeTableEntryIdBlock:
7502 case TypeTableEntryIdGenericFn:7549 case TypeTableEntryIdGenericFn:
7503 case TypeTableEntryIdVar:7550 case TypeTableEntryIdVar:
7504 zig_unreachable();7551 zig_unreachable();
...@@ -7640,6 +7687,8 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)...@@ -7640,6 +7687,8 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
7640 return hash_ptr(const_val->data.x_type);7687 return hash_ptr(const_val->data.x_type);
7641 case TypeTableEntryIdNamespace:7688 case TypeTableEntryIdNamespace:
7642 return hash_ptr(const_val->data.x_import);7689 return hash_ptr(const_val->data.x_import);
7690 case TypeTableEntryIdBlock:
7691 return hash_ptr(const_val->data.x_block);
7643 case TypeTableEntryIdGenericFn:7692 case TypeTableEntryIdGenericFn:
7644 case TypeTableEntryIdInvalid:7693 case TypeTableEntryIdInvalid:
7645 case TypeTableEntryIdUnreachable:7694 case TypeTableEntryIdUnreachable:
...@@ -7715,6 +7764,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)...@@ -7715,6 +7764,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
7715 case TypeTableEntryIdMetaType:7764 case TypeTableEntryIdMetaType:
7716 case TypeTableEntryIdVoid:7765 case TypeTableEntryIdVoid:
7717 case TypeTableEntryIdNamespace:7766 case TypeTableEntryIdNamespace:
7767 case TypeTableEntryIdBlock:
7718 case TypeTableEntryIdGenericFn:7768 case TypeTableEntryIdGenericFn:
7719 case TypeTableEntryIdVar:7769 case TypeTableEntryIdVar:
7720 zig_unreachable();7770 zig_unreachable();
src/ast_render.cpp+4
...@@ -173,6 +173,8 @@ static const char *node_type_str(NodeType node_type) {...@@ -173,6 +173,8 @@ static const char *node_type_str(NodeType node_type) {
173 return "UndefinedLiteral";173 return "UndefinedLiteral";
174 case NodeTypeZeroesLiteral:174 case NodeTypeZeroesLiteral:
175 return "ZeroesLiteral";175 return "ZeroesLiteral";
176 case NodeTypeThisLiteral:
177 return "ThisLiteral";
176 case NodeTypeIfBoolExpr:178 case NodeTypeIfBoolExpr:
177 return "IfBoolExpr";179 return "IfBoolExpr";
178 case NodeTypeIfVarExpr:180 case NodeTypeIfVarExpr:
...@@ -597,6 +599,8 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -597,6 +599,8 @@ static void render_node(AstRender *ar, AstNode *node) {
597 zig_panic("TODO");599 zig_panic("TODO");
598 case NodeTypeZeroesLiteral:600 case NodeTypeZeroesLiteral:
599 zig_panic("TODO");601 zig_panic("TODO");
602 case NodeTypeThisLiteral:
603 zig_panic("TODO");
600 case NodeTypeIfBoolExpr:604 case NodeTypeIfBoolExpr:
601 zig_panic("TODO");605 zig_panic("TODO");
602 case NodeTypeIfVarExpr:606 case NodeTypeIfVarExpr:
src/codegen.cpp+10
...@@ -3605,6 +3605,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {...@@ -3605,6 +3605,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
3605 case NodeTypeNullLiteral:3605 case NodeTypeNullLiteral:
3606 case NodeTypeUndefinedLiteral:3606 case NodeTypeUndefinedLiteral:
3607 case NodeTypeZeroesLiteral:3607 case NodeTypeZeroesLiteral:
3608 case NodeTypeThisLiteral:
3608 case NodeTypeErrorType:3609 case NodeTypeErrorType:
3609 case NodeTypeTypeLiteral:3610 case NodeTypeTypeLiteral:
3610 case NodeTypeArrayType:3611 case NodeTypeArrayType:
...@@ -3826,6 +3827,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -3826,6 +3827,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
3826 case TypeTableEntryIdNullLit:3827 case TypeTableEntryIdNullLit:
3827 case TypeTableEntryIdVoid:3828 case TypeTableEntryIdVoid:
3828 case TypeTableEntryIdNamespace:3829 case TypeTableEntryIdNamespace:
3830 case TypeTableEntryIdBlock:
3829 case TypeTableEntryIdGenericFn:3831 case TypeTableEntryIdGenericFn:
3830 case TypeTableEntryIdVar:3832 case TypeTableEntryIdVar:
3831 zig_unreachable();3833 zig_unreachable();
...@@ -4349,6 +4351,13 @@ static void define_builtin_types(CodeGen *g) {...@@ -4349,6 +4351,13 @@ static void define_builtin_types(CodeGen *g) {
4349 entry->deep_const = true;4351 entry->deep_const = true;
4350 g->builtin_types.entry_namespace = entry;4352 g->builtin_types.entry_namespace = entry;
4351 }4353 }
4354 {
4355 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBlock);
4356 buf_init_from_str(&entry->name, "(block)");
4357 entry->zero_bits = true;
4358 entry->deep_const = true;
4359 g->builtin_types.entry_block = entry;
4360 }
4352 {4361 {
4353 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);4362 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
4354 buf_init_from_str(&entry->name, "(float literal)");4363 buf_init_from_str(&entry->name, "(float literal)");
...@@ -5145,6 +5154,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {...@@ -5145,6 +5154,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
5145 case TypeTableEntryIdMetaType:5154 case TypeTableEntryIdMetaType:
5146 case TypeTableEntryIdGenericFn:5155 case TypeTableEntryIdGenericFn:
5147 case TypeTableEntryIdNamespace:5156 case TypeTableEntryIdNamespace:
5157 case TypeTableEntryIdBlock:
5148 case TypeTableEntryIdNumLitFloat:5158 case TypeTableEntryIdNumLitFloat:
5149 case TypeTableEntryIdNumLitInt:5159 case TypeTableEntryIdNumLitInt:
5150 case TypeTableEntryIdUndefLit:5160 case TypeTableEntryIdUndefLit:
src/eval.cpp+2
...@@ -83,6 +83,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty...@@ -83,6 +83,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
83 zig_panic("TODO");83 zig_panic("TODO");
84 case TypeTableEntryIdNamespace:84 case TypeTableEntryIdNamespace:
85 zig_panic("TODO");85 zig_panic("TODO");
86 case TypeTableEntryIdBlock:
86 zig_panic("TODO");87 zig_panic("TODO");
87 case TypeTableEntryIdGenericFn:88 case TypeTableEntryIdGenericFn:
88 case TypeTableEntryIdInvalid:89 case TypeTableEntryIdInvalid:
...@@ -1373,6 +1374,7 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {...@@ -1373,6 +1374,7 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
1373 case NodeTypeNullLiteral:1374 case NodeTypeNullLiteral:
1374 case NodeTypeUndefinedLiteral:1375 case NodeTypeUndefinedLiteral:
1375 case NodeTypeZeroesLiteral:1376 case NodeTypeZeroesLiteral:
1377 case NodeTypeThisLiteral:
1376 case NodeTypeIfVarExpr:1378 case NodeTypeIfVarExpr:
1377 case NodeTypeSwitchExpr:1379 case NodeTypeSwitchExpr:
1378 case NodeTypeSwitchProng:1380 case NodeTypeSwitchProng:
src/parser.cpp+11-1
...@@ -620,7 +620,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m...@@ -620,7 +620,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m
620620
621/*621/*
622PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")622PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")
623KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type"623KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
624*/624*/
625static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {625static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
626 Token *token = &pc->tokens->at(*token_index);626 Token *token = &pc->tokens->at(*token_index);
...@@ -672,6 +672,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo...@@ -672,6 +672,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
672 AstNode *node = ast_create_node(pc, NodeTypeZeroesLiteral, token);672 AstNode *node = ast_create_node(pc, NodeTypeZeroesLiteral, token);
673 *token_index += 1;673 *token_index += 1;
674 return node;674 return node;
675 } else if (token->id == TokenIdKeywordThis) {
676 AstNode *node = ast_create_node(pc, NodeTypeThisLiteral, token);
677 *token_index += 1;
678 return node;
675 } else if (token->id == TokenIdKeywordType) {679 } else if (token->id == TokenIdKeywordType) {
676 AstNode *node = ast_create_node(pc, NodeTypeTypeLiteral, token);680 AstNode *node = ast_create_node(pc, NodeTypeTypeLiteral, token);
677 *token_index += 1;681 *token_index += 1;
...@@ -2560,6 +2564,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont...@@ -2560,6 +2564,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
2560 case NodeTypeZeroesLiteral:2564 case NodeTypeZeroesLiteral:
2561 // none2565 // none
2562 break;2566 break;
2567 case NodeTypeThisLiteral:
2568 // none
2569 break;
2563 case NodeTypeIfBoolExpr:2570 case NodeTypeIfBoolExpr:
2564 visit_field(&node->data.if_bool_expr.condition, visit, context);2571 visit_field(&node->data.if_bool_expr.condition, visit, context);
2565 visit_field(&node->data.if_bool_expr.then_block, visit, context);2572 visit_field(&node->data.if_bool_expr.then_block, visit, context);
...@@ -2840,6 +2847,9 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,...@@ -2840,6 +2847,9 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,
2840 case NodeTypeZeroesLiteral:2847 case NodeTypeZeroesLiteral:
2841 // none2848 // none
2842 break;2849 break;
2850 case NodeTypeThisLiteral:
2851 // none
2852 break;
2843 case NodeTypeIfBoolExpr:2853 case NodeTypeIfBoolExpr:
2844 clone_subtree_field(&new_node->data.if_bool_expr.condition, old_node->data.if_bool_expr.condition, next_node_index);2854 clone_subtree_field(&new_node->data.if_bool_expr.condition, old_node->data.if_bool_expr.condition, next_node_index);
2845 clone_subtree_field(&new_node->data.if_bool_expr.then_block, old_node->data.if_bool_expr.then_block, next_node_index);2855 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
...@@ -129,6 +129,7 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -129,6 +129,7 @@ static const struct ZigKeyword zig_keywords[] = {
129 {"return", TokenIdKeywordReturn},129 {"return", TokenIdKeywordReturn},
130 {"struct", TokenIdKeywordStruct},130 {"struct", TokenIdKeywordStruct},
131 {"switch", TokenIdKeywordSwitch},131 {"switch", TokenIdKeywordSwitch},
132 {"this", TokenIdKeywordThis},
132 {"true", TokenIdKeywordTrue},133 {"true", TokenIdKeywordTrue},
133 {"type", TokenIdKeywordType},134 {"type", TokenIdKeywordType},
134 {"undefined", TokenIdKeywordUndefined},135 {"undefined", TokenIdKeywordUndefined},
...@@ -1470,6 +1471,7 @@ const char * token_name(TokenId id) {...@@ -1470,6 +1471,7 @@ const char * token_name(TokenId id) {
1470 case TokenIdKeywordSwitch: return "switch";1471 case TokenIdKeywordSwitch: return "switch";
1471 case TokenIdKeywordUndefined: return "undefined";1472 case TokenIdKeywordUndefined: return "undefined";
1472 case TokenIdKeywordZeroes: return "zeroes";1473 case TokenIdKeywordZeroes: return "zeroes";
1474 case TokenIdKeywordThis: return "this";
1473 case TokenIdKeywordError: return "error";1475 case TokenIdKeywordError: return "error";
1474 case TokenIdKeywordType: return "type";1476 case TokenIdKeywordType: return "type";
1475 case TokenIdKeywordInline: return "inline";1477 case TokenIdKeywordInline: return "inline";
src/tokenizer.hpp+1
...@@ -45,6 +45,7 @@ enum TokenId {...@@ -45,6 +45,7 @@ enum TokenId {
45 TokenIdKeywordType,45 TokenIdKeywordType,
46 TokenIdKeywordInline,46 TokenIdKeywordInline,
47 TokenIdKeywordDefer,47 TokenIdKeywordDefer,
48 TokenIdKeywordThis,
48 TokenIdLParen,49 TokenIdLParen,
49 TokenIdRParen,50 TokenIdRParen,
50 TokenIdComma,51 TokenIdComma,
std/hash_map.zig+1-1
...@@ -24,7 +24,7 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b...@@ -24,7 +24,7 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
24 // this is used to detect bugs where a hashtable is edited while an iterator is running.24 // this is used to detect bugs where a hashtable is edited while an iterator is running.
25 modification_count: debug_u32,25 modification_count: debug_u32,
2626
27 const Self = SmallHashMap(K, V, hash, eql, static_size);27 const Self = this;
2828
29 pub struct Entry {29 pub struct Entry {
30 used: bool,30 used: bool,
std/list.zig+1-1
...@@ -4,7 +4,7 @@ const mem = @import("mem.zig");...@@ -4,7 +4,7 @@ const mem = @import("mem.zig");
4const Allocator = mem.Allocator;4const Allocator = mem.Allocator;
55
6pub struct List(T: type) {6pub struct List(T: type) {
7 const Self = List(T);7 const Self = this;
88
9 items: []T,9 items: []T,
10 len: usize,10 len: usize,
std/rand.zig+1-1
...@@ -101,7 +101,7 @@ struct MersenneTwister(...@@ -101,7 +101,7 @@ struct MersenneTwister(
101 t: int, c: int,101 t: int, c: int,
102 l: int, f: int)102 l: int, f: int)
103{103{
104 const Self = MersenneTwister(int, n, m, r, a, u, d, s, b, t, c, l, f);104 const Self = this;
105105
106 array: [n]int,106 array: [n]int,
107 index: usize,107 index: usize,
test/cases/this.zig created+47
...@@ -0,0 +1,47 @@
1const assert = @import("std").debug.assert;
2const module = this;
3
4struct Point(inline T: type) {
5 const Self = this;
6 x: T,
7 y: T,
8
9 fn addOne(self: &Self) {
10 self.x += 1;
11 self.y += 1;
12 }
13}
14
15fn add(x: i32, y: i32) -> i32 {
16 x + y
17}
18
19fn factorial(x: i32) -> i32 {
20 const selfFn = this;
21 if (x == 0) {
22 1
23 } else {
24 x * selfFn(x - 1)
25 }
26}
27
28#attribute("test")
29fn thisReferToModuleCallPrivateFn() {
30 assert(module.add(1, 2) == 3);
31}
32
33#attribute("test")
34fn thisReferToContainer() {
35 var pt = Point(i32) {
36 .x = 12,
37 .y = 34,
38 };
39 pt.addOne();
40 assert(pt.x == 13);
41 assert(pt.y == 35);
42}
43
44#attribute("test")
45fn thisReferToFn() {
46 assert(factorial(5) == 120);
47}
test/run_tests.cpp+16
...@@ -1597,6 +1597,22 @@ const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;...@@ -1597,6 +1597,22 @@ const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
1597var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);1597var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
1598 )SOURCE", 1, ".tmp_source.zig:4:60: error: unable to perform binary not operation on type '(integer literal)'");1598 )SOURCE", 1, ".tmp_source.zig:4:60: error: unable to perform binary not operation on type '(integer literal)'");
15991599
1600 {
1601 TestCase *tc = add_compile_fail_case("multiple files with private function error", R"SOURCE(
1602const foo = @import("foo.zig");
1603
1604fn callPrivFunction() {
1605 foo.privateFunction();
1606}
1607 )SOURCE", 2,
1608 ".tmp_source.zig:5:8: error: 'privateFunction' is private",
1609 "foo.zig:2:1: note: declared here");
1610
1611 add_source_file(tc, "foo.zig", R"SOURCE(
1612fn privateFunction() { }
1613 )SOURCE");
1614 }
1615
1600}1616}
16011617
1602//////////////////////////////////////////////////////////////////////////////1618//////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig+1
...@@ -15,6 +15,7 @@ const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cas...@@ -15,6 +15,7 @@ const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cas
15const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");15const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");
16const test_enum_with_members = @import("cases/enum_with_members.zig");16const test_enum_with_members = @import("cases/enum_with_members.zig");
17const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig");17const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig");
18const test_this = @import("cases/this.zig");
1819
19// normal comment20// normal comment
20/// this is a documentation comment21/// this is a documentation comment