mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
parent
a25307c0a1
commit
6acc354957
@ -81,7 +81,7 @@ SwitchItem = Expression | (Expression "..." Expression)
|
||||
|
||||
WhileExpression = "while" "(" Expression option(";" Expression) ")" Expression
|
||||
|
||||
ForExpression = "for" "(" Expression ")" option("|" "Symbol" option("," "Symbol") "|") Expression
|
||||
ForExpression = "for" "(" Expression ")" option("|" option("*") "Symbol" option("," "Symbol") "|") Expression
|
||||
|
||||
BoolOrExpression = BoolAndExpression "||" BoolOrExpression | BoolAndExpression
|
||||
|
||||
|
||||
@ -508,6 +508,7 @@ struct AstNodeForExpr {
|
||||
Expr resolved_expr;
|
||||
VariableTableEntry *elem_var;
|
||||
VariableTableEntry *index_var;
|
||||
bool elem_is_ptr;
|
||||
};
|
||||
|
||||
struct AstNodeSwitchExpr {
|
||||
|
||||
@ -3567,6 +3567,13 @@ static TypeTableEntry *analyze_for_expr(CodeGen *g, ImportTableEntry *import, Bl
|
||||
child_type = g->builtin_types.entry_invalid;
|
||||
}
|
||||
|
||||
TypeTableEntry *var_type;
|
||||
if (node->data.for_expr.elem_is_ptr) {
|
||||
var_type = get_pointer_to_type(g, child_type, false);
|
||||
} else {
|
||||
var_type = child_type;
|
||||
}
|
||||
|
||||
BlockContext *child_context = new_block_context(node, context);
|
||||
child_context->parent_loop_node = node;
|
||||
|
||||
@ -3574,7 +3581,7 @@ static TypeTableEntry *analyze_for_expr(CodeGen *g, ImportTableEntry *import, Bl
|
||||
elem_var_node->block_context = child_context;
|
||||
Buf *elem_var_name = &elem_var_node->data.symbol_expr.symbol;
|
||||
node->data.for_expr.elem_var = add_local_var(g, elem_var_node, import, child_context, elem_var_name,
|
||||
child_type, true, nullptr);
|
||||
var_type, true, nullptr);
|
||||
|
||||
AstNode *index_var_node = node->data.for_expr.index_node;
|
||||
if (index_var_node) {
|
||||
|
||||
@ -2427,9 +2427,14 @@ static LLVMValueRef gen_for_expr(CodeGen *g, AstNode *node) {
|
||||
|
||||
LLVMPositionBuilderAtEnd(g->builder, body_block);
|
||||
LLVMValueRef elem_ptr = gen_array_elem_ptr(g, node, array_val, array_type, index_val);
|
||||
LLVMValueRef elem_val = handle_is_ptr(child_type) ? elem_ptr : LLVMBuildLoad(g->builder, elem_ptr, "");
|
||||
gen_assign_raw(g, node, BinOpTypeAssign, elem_var->value_ref, elem_val,
|
||||
elem_var->type, child_type);
|
||||
|
||||
LLVMValueRef elem_val;
|
||||
if (node->data.for_expr.elem_is_ptr) {
|
||||
elem_val = elem_ptr;
|
||||
} else {
|
||||
elem_val = handle_is_ptr(child_type) ? elem_ptr : LLVMBuildLoad(g->builder, elem_ptr, "");
|
||||
}
|
||||
gen_assign_raw(g, node, BinOpTypeAssign, elem_var->value_ref, elem_val, elem_var->type, child_type);
|
||||
gen_var_debug_decl(g, elem_var);
|
||||
g->break_block_stack.append(end_block);
|
||||
g->continue_block_stack.append(continue_block);
|
||||
|
||||
@ -812,6 +812,10 @@ static bool eval_for_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) {
|
||||
assert(elem_node->type == NodeTypeSymbol);
|
||||
Buf *elem_var_name = &elem_node->data.symbol_expr.symbol;
|
||||
|
||||
if (node->data.for_expr.elem_is_ptr) {
|
||||
zig_panic("TODO");
|
||||
}
|
||||
|
||||
Buf *index_var_name = nullptr;
|
||||
if (index_node) {
|
||||
assert(index_node->type == NodeTypeSymbol);
|
||||
|
||||
@ -1932,7 +1932,7 @@ static AstNode *ast_parse_symbol(ParseContext *pc, int *token_index) {
|
||||
}
|
||||
|
||||
/*
|
||||
ForExpression = "for" "(" Expression ")" option("|" "Symbol" option("," "Symbol") "|") Expression
|
||||
ForExpression = "for" "(" Expression ")" option("|" option("*") "Symbol" option("," "Symbol") "|") Expression
|
||||
*/
|
||||
static AstNode *ast_parse_for_expr(ParseContext *pc, int *token_index, bool mandatory) {
|
||||
Token *token = &pc->tokens->at(*token_index);
|
||||
@ -1955,6 +1955,13 @@ static AstNode *ast_parse_for_expr(ParseContext *pc, int *token_index, bool mand
|
||||
Token *maybe_bar = &pc->tokens->at(*token_index);
|
||||
if (maybe_bar->id == TokenIdBinOr) {
|
||||
*token_index += 1;
|
||||
|
||||
Token *maybe_star = &pc->tokens->at(*token_index);
|
||||
if (maybe_star->id == TokenIdStar) {
|
||||
*token_index += 1;
|
||||
node->data.for_expr.elem_is_ptr = true;
|
||||
}
|
||||
|
||||
node->data.for_expr.elem_node = ast_parse_symbol(pc, token_index);
|
||||
|
||||
Token *maybe_comma = &pc->tokens->at(*token_index);
|
||||
|
||||
@ -1269,3 +1269,19 @@ fn while_with_continue_expr() {
|
||||
}}
|
||||
assert(sum == 40);
|
||||
}
|
||||
|
||||
|
||||
#attribute("test")
|
||||
fn for_loop_with_pointer_elem_var() {
|
||||
const source = "abcdefg";
|
||||
var target: [source.len]u8 = undefined;
|
||||
@memcpy(&target[0], &source[0], source.len);
|
||||
mangle_string(target);
|
||||
assert(str.eql(target, "bcdefgh"));
|
||||
}
|
||||
#static_eval_enable(false)
|
||||
fn mangle_string(s: []u8) {
|
||||
for (s) |*c| {
|
||||
*c += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user