mirror of
https://github.com/ziglang/zig.git
synced 2025-02-04 20:02:47 +00:00
parent
f4d7c91363
commit
183976b242
@ -151,7 +151,7 @@ GotoExpression = "goto" Symbol
|
||||
|
||||
GroupedExpression = "(" Expression ")"
|
||||
|
||||
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type"
|
||||
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
|
||||
```
|
||||
|
||||
## Operator Precedence
|
||||
|
@ -14,7 +14,7 @@ syn keyword zigStatement goto break return continue asm defer
|
||||
syn keyword zigConditional if else switch
|
||||
syn keyword zigRepeat while for
|
||||
|
||||
syn keyword zigConstant null undefined zeroes
|
||||
syn keyword zigConstant null undefined zeroes this
|
||||
syn keyword zigKeyword fn use
|
||||
syn keyword zigType bool f32 f64 void unreachable type error
|
||||
syn keyword zigType i8 u8 i16 u16 i32 u32 i64 u64 isize usize
|
||||
|
@ -85,6 +85,7 @@ struct ConstExprValue {
|
||||
ConstArrayValue x_array;
|
||||
ConstPtrValue x_ptr;
|
||||
ImportTableEntry *x_import;
|
||||
BlockContext *x_block;
|
||||
} data;
|
||||
};
|
||||
|
||||
@ -174,6 +175,7 @@ enum NodeType {
|
||||
NodeTypeNullLiteral,
|
||||
NodeTypeUndefinedLiteral,
|
||||
NodeTypeZeroesLiteral,
|
||||
NodeTypeThisLiteral,
|
||||
NodeTypeIfBoolExpr,
|
||||
NodeTypeIfVarExpr,
|
||||
NodeTypeWhileExpr,
|
||||
@ -719,6 +721,11 @@ struct AstNodeZeroesLiteral {
|
||||
Expr resolved_expr;
|
||||
};
|
||||
|
||||
struct AstNodeThisLiteral {
|
||||
// populated by semantic analyzer
|
||||
Expr resolved_expr;
|
||||
};
|
||||
|
||||
struct AstNodeSymbolExpr {
|
||||
Buf *symbol;
|
||||
|
||||
@ -822,6 +829,7 @@ struct AstNode {
|
||||
AstNodeNullLiteral null_literal;
|
||||
AstNodeUndefinedLiteral undefined_literal;
|
||||
AstNodeZeroesLiteral zeroes_literal;
|
||||
AstNodeThisLiteral this_literal;
|
||||
AstNodeSymbolExpr symbol_expr;
|
||||
AstNodeBoolLiteral bool_literal;
|
||||
AstNodeBreakExpr break_expr;
|
||||
@ -1005,6 +1013,7 @@ enum TypeTableEntryId {
|
||||
TypeTableEntryIdFn,
|
||||
TypeTableEntryIdTypeDecl,
|
||||
TypeTableEntryIdNamespace,
|
||||
TypeTableEntryIdBlock,
|
||||
TypeTableEntryIdGenericFn,
|
||||
};
|
||||
|
||||
@ -1102,7 +1111,6 @@ struct FnTableEntry {
|
||||
AstNode *want_pure_return_type;
|
||||
bool safety_off;
|
||||
FnInline fn_inline;
|
||||
BlockContext *parent_block_context;
|
||||
FnAnalState anal_state;
|
||||
|
||||
ZigList<AstNode *> cast_alloca_list;
|
||||
@ -1209,6 +1217,7 @@ struct CodeGen {
|
||||
TypeTableEntry *entry_type;
|
||||
TypeTableEntry *entry_invalid;
|
||||
TypeTableEntry *entry_namespace;
|
||||
TypeTableEntry *entry_block;
|
||||
TypeTableEntry *entry_num_lit_int;
|
||||
TypeTableEntry *entry_num_lit_float;
|
||||
TypeTableEntry *entry_undef;
|
||||
@ -1340,7 +1349,6 @@ struct LabelTableEntry {
|
||||
};
|
||||
|
||||
struct BlockContext {
|
||||
// One of: NodeTypeFnDef, NodeTypeBlock, NodeTypeRoot, NodeTypeDefer, NodeTypeVariableDeclaration
|
||||
AstNode *node;
|
||||
|
||||
// any variables that are introduced by this scope
|
||||
|
@ -91,6 +91,7 @@ static AstNode *first_executing_node(AstNode *node) {
|
||||
case NodeTypeNullLiteral:
|
||||
case NodeTypeUndefinedLiteral:
|
||||
case NodeTypeZeroesLiteral:
|
||||
case NodeTypeThisLiteral:
|
||||
case NodeTypeIfBoolExpr:
|
||||
case NodeTypeIfVarExpr:
|
||||
case NodeTypeLabel:
|
||||
@ -246,6 +247,7 @@ static bool type_is_complete(TypeTableEntry *type_entry) {
|
||||
case TypeTableEntryIdFn:
|
||||
case TypeTableEntryIdTypeDecl:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
return true;
|
||||
}
|
||||
@ -962,6 +964,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
|
||||
case TypeTableEntryIdNullLit:
|
||||
case TypeTableEntryIdUnreachable:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
fn_proto->skip = true;
|
||||
add_node_error(g, child->data.param_decl.type,
|
||||
@ -1012,6 +1015,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
|
||||
case TypeTableEntryIdUndefLit:
|
||||
case TypeTableEntryIdNullLit:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdVar:
|
||||
fn_proto->skip = true;
|
||||
@ -1896,6 +1900,7 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)
|
||||
case NodeTypeNullLiteral:
|
||||
case NodeTypeUndefinedLiteral:
|
||||
case NodeTypeZeroesLiteral:
|
||||
case NodeTypeThisLiteral:
|
||||
case NodeTypeSymbol:
|
||||
case NodeTypePrefixOpExpr:
|
||||
case NodeTypeIfBoolExpr:
|
||||
@ -1960,6 +1965,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
|
||||
case TypeTableEntryIdUndefLit:
|
||||
case TypeTableEntryIdNullLit:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
return false;
|
||||
|
||||
@ -2745,6 +2751,7 @@ static bool is_container(TypeTableEntry *type_entry) {
|
||||
case TypeTableEntryIdFn:
|
||||
case TypeTableEntryIdTypeDecl:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
return false;
|
||||
}
|
||||
@ -2791,6 +2798,7 @@ static void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
|
||||
case TypeTableEntryIdFn:
|
||||
case TypeTableEntryIdTypeDecl:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdInvalid:
|
||||
case TypeTableEntryIdVar:
|
||||
@ -2965,7 +2973,7 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
|
||||
}
|
||||
if (decl_node) {
|
||||
TopLevelDecl *tld = get_as_top_level_decl(decl_node);
|
||||
if (tld->visib_mod == VisibModPrivate) {
|
||||
if (tld->visib_mod == VisibModPrivate && decl_node->owner != import) {
|
||||
ErrorMsg *msg = add_node_error(g, node,
|
||||
buf_sprintf("'%s' is private", buf_ptr(field_name)));
|
||||
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,
|
||||
return g->builtin_types.entry_type;
|
||||
}
|
||||
|
||||
static TypeTableEntry *resolve_expr_const_val_as_block(CodeGen *g, AstNode *node, BlockContext *block_context,
|
||||
bool depends_on_compile_var)
|
||||
{
|
||||
Expr *expr = get_resolved_expr(node);
|
||||
expr->const_val.ok = true;
|
||||
expr->const_val.data.x_block = block_context;
|
||||
expr->const_val.depends_on_compile_var = depends_on_compile_var;
|
||||
return g->builtin_types.entry_block;
|
||||
}
|
||||
|
||||
static TypeTableEntry *resolve_expr_const_val_as_other_expr(CodeGen *g, AstNode *node, AstNode *other,
|
||||
bool depends_on_compile_var)
|
||||
{
|
||||
@ -3221,6 +3239,13 @@ static TypeTableEntry *resolve_expr_const_val_as_unsigned_num_lit(CodeGen *g, As
|
||||
return g->builtin_types.entry_num_lit_int;
|
||||
}
|
||||
|
||||
static TypeTableEntry *resolve_expr_const_val_as_import(CodeGen *g, AstNode *node, ImportTableEntry *import) {
|
||||
Expr *expr = get_resolved_expr(node);
|
||||
expr->const_val.ok = true;
|
||||
expr->const_val.data.x_import = import;
|
||||
return g->builtin_types.entry_namespace;
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *import,
|
||||
BlockContext *context, AstNode *node, Buf *err_name)
|
||||
{
|
||||
@ -3497,6 +3522,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
|
||||
case TypeTableEntryIdFn:
|
||||
case TypeTableEntryIdTypeDecl:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
if (!is_equality_cmp) {
|
||||
add_node_error(g, node,
|
||||
@ -4120,6 +4146,25 @@ static TypeTableEntry *analyze_zeroes_literal_expr(CodeGen *g, ImportTableEntry
|
||||
return expected_type ? expected_type : g->builtin_types.entry_undef;
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_this_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||
TypeTableEntry *expected_type, AstNode *node)
|
||||
{
|
||||
if (!context->parent) {
|
||||
return resolve_expr_const_val_as_import(g, node, import);
|
||||
}
|
||||
if (context->fn_entry && (!context->parent->fn_entry ||
|
||||
(context->parent->parent && !context->parent->parent->fn_entry)))
|
||||
{
|
||||
return resolve_expr_const_val_as_fn(g, node, context->fn_entry, false);
|
||||
}
|
||||
if (context->node->type == NodeTypeContainerDecl) {
|
||||
return resolve_expr_const_val_as_type(g, node, context->node->data.struct_decl.type_entry, false);
|
||||
}
|
||||
if (context->node->type == NodeTypeBlock) {
|
||||
return resolve_expr_const_val_as_block(g, node, context, false);
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_number_literal_expr(CodeGen *g, ImportTableEntry *import,
|
||||
BlockContext *block_context, TypeTableEntry *expected_type, AstNode *node)
|
||||
@ -4793,13 +4838,6 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
|
||||
return g->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
static TypeTableEntry *resolve_expr_const_val_as_import(CodeGen *g, AstNode *node, ImportTableEntry *import) {
|
||||
Expr *expr = get_resolved_expr(node);
|
||||
expr->const_val.ok = true;
|
||||
expr->const_val.data.x_import = import;
|
||||
return g->builtin_types.entry_namespace;
|
||||
}
|
||||
|
||||
static TypeTableEntry *analyze_import(CodeGen *g, ImportTableEntry *import, BlockContext *context,
|
||||
AstNode *node)
|
||||
{
|
||||
@ -5394,6 +5432,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
|
||||
case TypeTableEntryIdUndefLit:
|
||||
case TypeTableEntryIdNullLit:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdVar:
|
||||
add_node_error(g, expr_node,
|
||||
@ -6796,6 +6835,9 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn
|
||||
case NodeTypeZeroesLiteral:
|
||||
return_type = analyze_zeroes_literal_expr(g, import, context, expected_type, node);
|
||||
break;
|
||||
case NodeTypeThisLiteral:
|
||||
return_type = analyze_this_literal_expr(g, import, context, expected_type, node);
|
||||
break;
|
||||
case NodeTypeSymbol:
|
||||
return_type = analyze_symbol_expr(g, import, context, expected_type, node, pointer_only);
|
||||
break;
|
||||
@ -7085,6 +7127,7 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte
|
||||
case NodeTypeNullLiteral:
|
||||
case NodeTypeUndefinedLiteral:
|
||||
case NodeTypeZeroesLiteral:
|
||||
case NodeTypeThisLiteral:
|
||||
case NodeTypeSymbol:
|
||||
case NodeTypePrefixOpExpr:
|
||||
case NodeTypeIfBoolExpr:
|
||||
@ -7347,6 +7390,8 @@ Expr *get_resolved_expr(AstNode *node) {
|
||||
return &node->data.undefined_literal.resolved_expr;
|
||||
case NodeTypeZeroesLiteral:
|
||||
return &node->data.zeroes_literal.resolved_expr;
|
||||
case NodeTypeThisLiteral:
|
||||
return &node->data.this_literal.resolved_expr;
|
||||
case NodeTypeGoto:
|
||||
return &node->data.goto_expr.resolved_expr;
|
||||
case NodeTypeBreak:
|
||||
@ -7432,6 +7477,7 @@ static TopLevelDecl *get_as_top_level_decl(AstNode *node) {
|
||||
case NodeTypeNullLiteral:
|
||||
case NodeTypeUndefinedLiteral:
|
||||
case NodeTypeZeroesLiteral:
|
||||
case NodeTypeThisLiteral:
|
||||
case NodeTypeLabel:
|
||||
case NodeTypeGoto:
|
||||
case NodeTypeBreak:
|
||||
@ -7499,6 +7545,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
|
||||
case TypeTableEntryIdUndefLit:
|
||||
case TypeTableEntryIdNullLit:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdVar:
|
||||
zig_unreachable();
|
||||
@ -7640,6 +7687,8 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
|
||||
return hash_ptr(const_val->data.x_type);
|
||||
case TypeTableEntryIdNamespace:
|
||||
return hash_ptr(const_val->data.x_import);
|
||||
case TypeTableEntryIdBlock:
|
||||
return hash_ptr(const_val->data.x_block);
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdInvalid:
|
||||
case TypeTableEntryIdUnreachable:
|
||||
@ -7715,6 +7764,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
|
||||
case TypeTableEntryIdMetaType:
|
||||
case TypeTableEntryIdVoid:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdVar:
|
||||
zig_unreachable();
|
||||
|
@ -173,6 +173,8 @@ static const char *node_type_str(NodeType node_type) {
|
||||
return "UndefinedLiteral";
|
||||
case NodeTypeZeroesLiteral:
|
||||
return "ZeroesLiteral";
|
||||
case NodeTypeThisLiteral:
|
||||
return "ThisLiteral";
|
||||
case NodeTypeIfBoolExpr:
|
||||
return "IfBoolExpr";
|
||||
case NodeTypeIfVarExpr:
|
||||
@ -597,6 +599,8 @@ static void render_node(AstRender *ar, AstNode *node) {
|
||||
zig_panic("TODO");
|
||||
case NodeTypeZeroesLiteral:
|
||||
zig_panic("TODO");
|
||||
case NodeTypeThisLiteral:
|
||||
zig_panic("TODO");
|
||||
case NodeTypeIfBoolExpr:
|
||||
zig_panic("TODO");
|
||||
case NodeTypeIfVarExpr:
|
||||
|
@ -3605,6 +3605,7 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
|
||||
case NodeTypeNullLiteral:
|
||||
case NodeTypeUndefinedLiteral:
|
||||
case NodeTypeZeroesLiteral:
|
||||
case NodeTypeThisLiteral:
|
||||
case NodeTypeErrorType:
|
||||
case NodeTypeTypeLiteral:
|
||||
case NodeTypeArrayType:
|
||||
@ -3826,6 +3827,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
|
||||
case TypeTableEntryIdNullLit:
|
||||
case TypeTableEntryIdVoid:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdVar:
|
||||
zig_unreachable();
|
||||
@ -4349,6 +4351,13 @@ static void define_builtin_types(CodeGen *g) {
|
||||
entry->deep_const = true;
|
||||
g->builtin_types.entry_namespace = entry;
|
||||
}
|
||||
{
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdBlock);
|
||||
buf_init_from_str(&entry->name, "(block)");
|
||||
entry->zero_bits = true;
|
||||
entry->deep_const = true;
|
||||
g->builtin_types.entry_block = entry;
|
||||
}
|
||||
{
|
||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);
|
||||
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) {
|
||||
case TypeTableEntryIdMetaType:
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdNamespace:
|
||||
case TypeTableEntryIdBlock:
|
||||
case TypeTableEntryIdNumLitFloat:
|
||||
case TypeTableEntryIdNumLitInt:
|
||||
case TypeTableEntryIdUndefLit:
|
||||
|
@ -83,6 +83,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
|
||||
zig_panic("TODO");
|
||||
case TypeTableEntryIdNamespace:
|
||||
zig_panic("TODO");
|
||||
case TypeTableEntryIdBlock:
|
||||
zig_panic("TODO");
|
||||
case TypeTableEntryIdGenericFn:
|
||||
case TypeTableEntryIdInvalid:
|
||||
@ -1373,6 +1374,7 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
|
||||
case NodeTypeNullLiteral:
|
||||
case NodeTypeUndefinedLiteral:
|
||||
case NodeTypeZeroesLiteral:
|
||||
case NodeTypeThisLiteral:
|
||||
case NodeTypeIfVarExpr:
|
||||
case NodeTypeSwitchExpr:
|
||||
case NodeTypeSwitchProng:
|
||||
|
@ -620,7 +620,7 @@ static AstNode *ast_parse_asm_expr(ParseContext *pc, size_t *token_index, bool m
|
||||
|
||||
/*
|
||||
PrimaryExpression = "Number" | "String" | "CharLiteral" | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | "Symbol" | ("@" "Symbol" FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." "Symbol")
|
||||
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type"
|
||||
KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "zeroes" | "error" | "type" | "this"
|
||||
*/
|
||||
static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
@ -672,6 +672,10 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
|
||||
AstNode *node = ast_create_node(pc, NodeTypeZeroesLiteral, token);
|
||||
*token_index += 1;
|
||||
return node;
|
||||
} else if (token->id == TokenIdKeywordThis) {
|
||||
AstNode *node = ast_create_node(pc, NodeTypeThisLiteral, token);
|
||||
*token_index += 1;
|
||||
return node;
|
||||
} else if (token->id == TokenIdKeywordType) {
|
||||
AstNode *node = ast_create_node(pc, NodeTypeTypeLiteral, token);
|
||||
*token_index += 1;
|
||||
@ -2560,6 +2564,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
|
||||
case NodeTypeZeroesLiteral:
|
||||
// none
|
||||
break;
|
||||
case NodeTypeThisLiteral:
|
||||
// none
|
||||
break;
|
||||
case NodeTypeIfBoolExpr:
|
||||
visit_field(&node->data.if_bool_expr.condition, visit, context);
|
||||
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,
|
||||
case NodeTypeZeroesLiteral:
|
||||
// none
|
||||
break;
|
||||
case NodeTypeThisLiteral:
|
||||
// none
|
||||
break;
|
||||
case NodeTypeIfBoolExpr:
|
||||
clone_subtree_field(&new_node->data.if_bool_expr.condition, old_node->data.if_bool_expr.condition, next_node_index);
|
||||
clone_subtree_field(&new_node->data.if_bool_expr.then_block, old_node->data.if_bool_expr.then_block, next_node_index);
|
||||
|
@ -129,6 +129,7 @@ static const struct ZigKeyword zig_keywords[] = {
|
||||
{"return", TokenIdKeywordReturn},
|
||||
{"struct", TokenIdKeywordStruct},
|
||||
{"switch", TokenIdKeywordSwitch},
|
||||
{"this", TokenIdKeywordThis},
|
||||
{"true", TokenIdKeywordTrue},
|
||||
{"type", TokenIdKeywordType},
|
||||
{"undefined", TokenIdKeywordUndefined},
|
||||
@ -1470,6 +1471,7 @@ const char * token_name(TokenId id) {
|
||||
case TokenIdKeywordSwitch: return "switch";
|
||||
case TokenIdKeywordUndefined: return "undefined";
|
||||
case TokenIdKeywordZeroes: return "zeroes";
|
||||
case TokenIdKeywordThis: return "this";
|
||||
case TokenIdKeywordError: return "error";
|
||||
case TokenIdKeywordType: return "type";
|
||||
case TokenIdKeywordInline: return "inline";
|
||||
|
@ -45,6 +45,7 @@ enum TokenId {
|
||||
TokenIdKeywordType,
|
||||
TokenIdKeywordInline,
|
||||
TokenIdKeywordDefer,
|
||||
TokenIdKeywordThis,
|
||||
TokenIdLParen,
|
||||
TokenIdRParen,
|
||||
TokenIdComma,
|
||||
|
@ -24,7 +24,7 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
|
||||
// this is used to detect bugs where a hashtable is edited while an iterator is running.
|
||||
modification_count: debug_u32,
|
||||
|
||||
const Self = SmallHashMap(K, V, hash, eql, static_size);
|
||||
const Self = this;
|
||||
|
||||
pub struct Entry {
|
||||
used: bool,
|
||||
|
@ -4,7 +4,7 @@ const mem = @import("mem.zig");
|
||||
const Allocator = mem.Allocator;
|
||||
|
||||
pub struct List(T: type) {
|
||||
const Self = List(T);
|
||||
const Self = this;
|
||||
|
||||
items: []T,
|
||||
len: usize,
|
||||
|
@ -101,7 +101,7 @@ struct MersenneTwister(
|
||||
t: int, c: int,
|
||||
l: int, f: int)
|
||||
{
|
||||
const Self = MersenneTwister(int, n, m, r, a, u, d, s, b, t, c, l, f);
|
||||
const Self = this;
|
||||
|
||||
array: [n]int,
|
||||
index: usize,
|
||||
|
47
test/cases/this.zig
Normal file
47
test/cases/this.zig
Normal file
@ -0,0 +1,47 @@
|
||||
const assert = @import("std").debug.assert;
|
||||
const module = this;
|
||||
|
||||
struct Point(inline T: type) {
|
||||
const Self = this;
|
||||
x: T,
|
||||
y: T,
|
||||
|
||||
fn addOne(self: &Self) {
|
||||
self.x += 1;
|
||||
self.y += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn add(x: i32, y: i32) -> i32 {
|
||||
x + y
|
||||
}
|
||||
|
||||
fn factorial(x: i32) -> i32 {
|
||||
const selfFn = this;
|
||||
if (x == 0) {
|
||||
1
|
||||
} else {
|
||||
x * selfFn(x - 1)
|
||||
}
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn thisReferToModuleCallPrivateFn() {
|
||||
assert(module.add(1, 2) == 3);
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn thisReferToContainer() {
|
||||
var pt = Point(i32) {
|
||||
.x = 12,
|
||||
.y = 34,
|
||||
};
|
||||
pt.addOne();
|
||||
assert(pt.x == 13);
|
||||
assert(pt.y == 35);
|
||||
}
|
||||
|
||||
#attribute("test")
|
||||
fn thisReferToFn() {
|
||||
assert(factorial(5) == 120);
|
||||
}
|
@ -1597,6 +1597,22 @@ const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
|
||||
var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
|
||||
)SOURCE", 1, ".tmp_source.zig:4:60: error: unable to perform binary not operation on type '(integer literal)'");
|
||||
|
||||
{
|
||||
TestCase *tc = add_compile_fail_case("multiple files with private function error", R"SOURCE(
|
||||
const foo = @import("foo.zig");
|
||||
|
||||
fn callPrivFunction() {
|
||||
foo.privateFunction();
|
||||
}
|
||||
)SOURCE", 2,
|
||||
".tmp_source.zig:5:8: error: 'privateFunction' is private",
|
||||
"foo.zig:2:1: note: declared here");
|
||||
|
||||
add_source_file(tc, "foo.zig", R"SOURCE(
|
||||
fn privateFunction() { }
|
||||
)SOURCE");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -15,6 +15,7 @@ const test_switch_prong_implicit_cast = @import("cases/switch_prong_implicit_cas
|
||||
const test_switch_prong_err_enum = @import("cases/switch_prong_err_enum.zig");
|
||||
const test_enum_with_members = @import("cases/enum_with_members.zig");
|
||||
const test_struct_contains_slice_of_itself = @import("cases/struct_contains_slice_of_itself.zig");
|
||||
const test_this = @import("cases/this.zig");
|
||||
|
||||
// normal comment
|
||||
/// this is a documentation comment
|
||||
|
Loading…
Reference in New Issue
Block a user