mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
parent
e14db23661
commit
76ab1d2b6c
@ -5958,10 +5958,12 @@ MultiplyOperator = "||" | "*" | "/" | "%" | "**" | "*%"
|
||||
|
||||
PrefixOpExpression = PrefixOp TypeExpr | SuffixOpExpression
|
||||
|
||||
SuffixOpExpression = ("async" option("<" SuffixOpExpression ">") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
|
||||
SuffixOpExpression = ("async" option("<" SuffixOpExpression ">") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression | PtrDerefExpression)
|
||||
|
||||
FieldAccessExpression = "." Symbol
|
||||
|
||||
PtrDerefExpression = ".*"
|
||||
|
||||
FnCallExpression = "(" list(Expression, ",") ")"
|
||||
|
||||
ArrayAccessExpression = "[" Expression "]"
|
||||
@ -5974,7 +5976,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")
|
||||
|
||||
StructLiteralField = "." Symbol "=" Expression
|
||||
|
||||
PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"
|
||||
PrefixOp = "!" | "-" | "~" | ("*" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "??" | "-%" | "try" | "await"
|
||||
|
||||
PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ContainerDecl | ("continue" option(":" Symbol)) | ErrorSetDecl | PromiseType
|
||||
|
||||
|
||||
@ -379,6 +379,7 @@ enum NodeType {
|
||||
NodeTypeArrayAccessExpr,
|
||||
NodeTypeSliceExpr,
|
||||
NodeTypeFieldAccessExpr,
|
||||
NodeTypePtrDeref,
|
||||
NodeTypeUse,
|
||||
NodeTypeBoolLiteral,
|
||||
NodeTypeNullLiteral,
|
||||
@ -603,6 +604,10 @@ struct AstNodeFieldAccessExpr {
|
||||
Buf *field_name;
|
||||
};
|
||||
|
||||
struct AstNodePtrDerefExpr {
|
||||
AstNode *target;
|
||||
};
|
||||
|
||||
enum PrefixOp {
|
||||
PrefixOpInvalid,
|
||||
PrefixOpBoolNot,
|
||||
@ -911,6 +916,7 @@ struct AstNode {
|
||||
AstNodeCompTime comptime_expr;
|
||||
AstNodeAsmExpr asm_expr;
|
||||
AstNodeFieldAccessExpr field_access_expr;
|
||||
AstNodePtrDerefExpr ptr_deref_expr;
|
||||
AstNodeContainerDecl container_decl;
|
||||
AstNodeStructField struct_field;
|
||||
AstNodeStringLiteral string_literal;
|
||||
|
||||
@ -3275,6 +3275,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
|
||||
case NodeTypeUnreachable:
|
||||
case NodeTypeAsmExpr:
|
||||
case NodeTypeFieldAccessExpr:
|
||||
case NodeTypePtrDeref:
|
||||
case NodeTypeStructField:
|
||||
case NodeTypeContainerInitExpr:
|
||||
case NodeTypeStructValueField:
|
||||
|
||||
@ -222,6 +222,8 @@ static const char *node_type_str(NodeType node_type) {
|
||||
return "AsmExpr";
|
||||
case NodeTypeFieldAccessExpr:
|
||||
return "FieldAccessExpr";
|
||||
case NodeTypePtrDeref:
|
||||
return "PtrDerefExpr";
|
||||
case NodeTypeContainerDecl:
|
||||
return "ContainerDecl";
|
||||
case NodeTypeStructField:
|
||||
@ -696,6 +698,13 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
|
||||
print_symbol(ar, rhs);
|
||||
break;
|
||||
}
|
||||
case NodeTypePtrDeref:
|
||||
{
|
||||
AstNode *lhs = node->data.ptr_deref_expr.target;
|
||||
render_node_ungrouped(ar, lhs);
|
||||
fprintf(ar->f, ".*");
|
||||
break;
|
||||
}
|
||||
case NodeTypeUndefinedLiteral:
|
||||
fprintf(ar->f, "undefined");
|
||||
break;
|
||||
|
||||
12
src/ir.cpp
12
src/ir.cpp
@ -4548,8 +4548,14 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
|
||||
}
|
||||
|
||||
static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {
|
||||
assert(node->type == NodeTypePrefixOpExpr);
|
||||
AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
|
||||
AstNode *expr_node;
|
||||
if (node->type == NodeTypePrefixOpExpr) {
|
||||
expr_node = node->data.prefix_op_expr.primary_expr;
|
||||
} else if (node->type == NodeTypePtrDeref) {
|
||||
expr_node = node->data.ptr_deref_expr.target;
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval);
|
||||
if (value == irb->codegen->invalid_instruction)
|
||||
@ -6527,6 +6533,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
|
||||
|
||||
return ir_build_load_ptr(irb, scope, node, ptr_instruction);
|
||||
}
|
||||
case NodeTypePtrDeref:
|
||||
return ir_gen_prefix_op_id_lval(irb, scope, node, IrUnOpDereference, lval);
|
||||
case NodeTypeThisLiteral:
|
||||
return ir_lval_wrap(irb, scope, ir_gen_this_literal(irb, scope, node), lval);
|
||||
case NodeTypeBoolLiteral:
|
||||
|
||||
@ -1046,11 +1046,12 @@ static AstNode *ast_parse_fn_proto_partial(ParseContext *pc, size_t *token_index
|
||||
}
|
||||
|
||||
/*
|
||||
SuffixOpExpression = ("async" option("<" SuffixOpExpression ">") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression)
|
||||
SuffixOpExpression = ("async" option("<" SuffixOpExpression ">") SuffixOpExpression FnCallExpression) | PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | PtrDerefExpression | SliceExpression)
|
||||
FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen)
|
||||
ArrayAccessExpression : token(LBracket) Expression token(RBracket)
|
||||
SliceExpression = "[" Expression ".." option(Expression) "]"
|
||||
FieldAccessExpression : token(Dot) token(Symbol)
|
||||
PtrDerefExpression = ".*"
|
||||
StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression
|
||||
*/
|
||||
static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
|
||||
@ -1131,13 +1132,27 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index,
|
||||
} else if (first_token->id == TokenIdDot) {
|
||||
*token_index += 1;
|
||||
|
||||
Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
|
||||
AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token);
|
||||
node->data.field_access_expr.struct_expr = primary_expr;
|
||||
node->data.field_access_expr.field_name = token_buf(name_token);
|
||||
if (token->id == TokenIdSymbol) {
|
||||
*token_index += 1;
|
||||
|
||||
AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token);
|
||||
node->data.field_access_expr.struct_expr = primary_expr;
|
||||
node->data.field_access_expr.field_name = token_buf(token);
|
||||
|
||||
primary_expr = node;
|
||||
} else if (token->id == TokenIdStar) {
|
||||
*token_index += 1;
|
||||
|
||||
AstNode *node = ast_create_node(pc, NodeTypePtrDeref, first_token);
|
||||
node->data.ptr_deref_expr.target = primary_expr;
|
||||
|
||||
primary_expr = node;
|
||||
} else {
|
||||
ast_invalid_token_error(pc, token);
|
||||
}
|
||||
|
||||
primary_expr = node;
|
||||
} else {
|
||||
return primary_expr;
|
||||
}
|
||||
@ -3012,6 +3027,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
|
||||
case NodeTypeFieldAccessExpr:
|
||||
visit_field(&node->data.field_access_expr.struct_expr, visit, context);
|
||||
break;
|
||||
case NodeTypePtrDeref:
|
||||
visit_field(&node->data.ptr_deref_expr.target, visit, context);
|
||||
break;
|
||||
case NodeTypeUse:
|
||||
visit_field(&node->data.use.expr, visit, context);
|
||||
break;
|
||||
|
||||
@ -33,6 +33,7 @@ comptime {
|
||||
_ = @import("cases/misc.zig");
|
||||
_ = @import("cases/namespace_depends_on_compile_var/index.zig");
|
||||
_ = @import("cases/null.zig");
|
||||
_ = @import("cases/pointers.zig");
|
||||
_ = @import("cases/pub_enum/index.zig");
|
||||
_ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");
|
||||
_ = @import("cases/reflection.zig");
|
||||
|
||||
14
test/cases/pointers.zig
Normal file
14
test/cases/pointers.zig
Normal file
@ -0,0 +1,14 @@
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "dereference pointer" {
|
||||
comptime testDerefPtr();
|
||||
testDerefPtr();
|
||||
}
|
||||
|
||||
fn testDerefPtr() void {
|
||||
var x: i32 = 1234;
|
||||
var y = &x;
|
||||
y.* += 1;
|
||||
assert(x == 1235);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user