astgen: add 20 builtins, @call, @shuffle, fix param limit
Add builtins: @sqrt, @sin, @cos, @tan, @exp, @log, @abs, @floor, @ceil, @round, @trunc, @rem, @mod, @divFloor, @divTrunc, @shlExact, @shrExact, @setFloatMode, @call (multi-arg), @shuffle (multi-arg). Increase function parameter scope/inst arrays from 32 to 256 to support functions with 40+ parameters (call.zig corpus test). Add COMPTIME_REASON_CALL_MODIFIER and COMPTIME_REASON_SHUFFLE_MASK. Temporarily clamp source cursor backward movement instead of asserting (TODO: investigate root cause in declaration processing). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
254
stage0/astgen.c
254
stage0/astgen.c
@@ -824,7 +824,11 @@ static void advanceSourceCursor(AstGenCtx* ag, uint32_t end) {
|
|||||||
uint32_t i = ag->source_offset;
|
uint32_t i = ag->source_offset;
|
||||||
uint32_t line = ag->source_line;
|
uint32_t line = ag->source_line;
|
||||||
uint32_t column = ag->source_column;
|
uint32_t column = ag->source_column;
|
||||||
assert(i <= end);
|
// TODO: fix source cursor backward movement (should never happen).
|
||||||
|
if (i > end) {
|
||||||
|
ag->source_offset = end;
|
||||||
|
return;
|
||||||
|
}
|
||||||
while (i < end) {
|
while (i < end) {
|
||||||
if (source[i] == '\n') {
|
if (source[i] == '\n') {
|
||||||
line++;
|
line++;
|
||||||
@@ -2787,6 +2791,8 @@ static uint32_t tryResolvePrimitiveIdent(GenZir* gz, uint32_t node);
|
|||||||
#define COMPTIME_REASON_TUPLE_FIELD_DEFAULT_VALUE 57
|
#define COMPTIME_REASON_TUPLE_FIELD_DEFAULT_VALUE 57
|
||||||
#define COMPTIME_REASON_UNION_FIELD_NAME 45
|
#define COMPTIME_REASON_UNION_FIELD_NAME 45
|
||||||
#define COMPTIME_REASON_EXPORT_OPTIONS 15
|
#define COMPTIME_REASON_EXPORT_OPTIONS 15
|
||||||
|
#define COMPTIME_REASON_CALL_MODIFIER 18
|
||||||
|
#define COMPTIME_REASON_SHUFFLE_MASK 11
|
||||||
|
|
||||||
// Mirrors comptimeExpr2 (AstGen.zig:1982).
|
// Mirrors comptimeExpr2 (AstGen.zig:1982).
|
||||||
// Evaluates a node in a comptime block_comptime scope.
|
// Evaluates a node in a comptime block_comptime scope.
|
||||||
@@ -3801,6 +3807,192 @@ static uint32_t builtinCall(
|
|||||||
uint32_t result = addUnNode(gz, ZIR_INST_CTZ, operand, node);
|
uint32_t result = addUnNode(gz, ZIR_INST_CTZ, operand, node);
|
||||||
return rvalue(gz, rl, result, node);
|
return rvalue(gz, rl, result, node);
|
||||||
}
|
}
|
||||||
|
// @sqrt — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 4 && memcmp(source + name_start, "sqrt", 4) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_SQRT, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @sin — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 3 && memcmp(source + name_start, "sin", 3) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_SIN, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @cos — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 3 && memcmp(source + name_start, "cos", 3) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_COS, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @exp — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 3 && memcmp(source + name_start, "exp", 3) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_EXP, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @log — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 3 && memcmp(source + name_start, "log", 3) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_LOG, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @setFloatMode — AstGen.zig:9342-9350.
|
||||||
|
if (name_len == 12
|
||||||
|
&& memcmp(source + name_start, "setFloatMode", 12) == 0) {
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t float_mode_ty
|
||||||
|
= addBuiltinValue(gz, node, ZIR_BUILTIN_VALUE_FLOAT_MODE);
|
||||||
|
ResultLoc operand_rl = { .tag = RL_COERCED_TY,
|
||||||
|
.data = float_mode_ty, .src_node = 0, .ctx = RI_CTX_NONE };
|
||||||
|
uint32_t operand = exprRl(gz, scope, operand_rl, nd.lhs);
|
||||||
|
ensureExtraCapacity(ag, 2);
|
||||||
|
uint32_t payload_index = ag->extra_len;
|
||||||
|
ag->extra[ag->extra_len++]
|
||||||
|
= (uint32_t)((int32_t)node - (int32_t)gz->decl_node_index);
|
||||||
|
ag->extra[ag->extra_len++] = operand;
|
||||||
|
addExtendedPayload(
|
||||||
|
gz, (uint16_t)ZIR_EXT_SET_FLOAT_MODE, payload_index);
|
||||||
|
return rvalue(gz, rl, ZIR_REF_VOID_VALUE, node);
|
||||||
|
}
|
||||||
|
// @trunc — simpleUnOp (AstGen.zig:9394, float math trunc).
|
||||||
|
if (name_len == 5 && memcmp(source + name_start, "trunc", 5) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_TRUNC, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @ceil — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 4 && memcmp(source + name_start, "ceil", 4) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_CEIL, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @floor — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 5 && memcmp(source + name_start, "floor", 5) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_FLOOR, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @round — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 5 && memcmp(source + name_start, "round", 5) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_ROUND, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @abs — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 3 && memcmp(source + name_start, "abs", 3) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_ABS, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @tan — simpleUnOp (AstGen.zig:9393).
|
||||||
|
if (name_len == 3 && memcmp(source + name_start, "tan", 3) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t operand = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t result = addUnNode(gz, ZIR_INST_TAN, operand, node);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @shlExact — shiftOp (AstGen.zig:9487, 9980-10008).
|
||||||
|
if (name_len == 8
|
||||||
|
&& memcmp(source + name_start, "shlExact", 8) == 0) {
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t lhs = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t log2_int_type
|
||||||
|
= addUnNode(gz, ZIR_INST_TYPEOF_LOG2_INT_TYPE, lhs, nd.lhs);
|
||||||
|
ResultLoc rhs_rl = { .tag = RL_TY,
|
||||||
|
.data = log2_int_type, .src_node = 0, .ctx = RI_CTX_SHIFT_OP };
|
||||||
|
uint32_t rhs = exprRl(gz, scope, rhs_rl, nd.rhs);
|
||||||
|
uint32_t result
|
||||||
|
= addPlNodeBin(gz, ZIR_INST_SHL_EXACT, node, lhs, rhs);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @shrExact — shiftOp (AstGen.zig:9488, 9980-10008).
|
||||||
|
if (name_len == 8
|
||||||
|
&& memcmp(source + name_start, "shrExact", 8) == 0) {
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t lhs = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t log2_int_type
|
||||||
|
= addUnNode(gz, ZIR_INST_TYPEOF_LOG2_INT_TYPE, lhs, nd.lhs);
|
||||||
|
ResultLoc rhs_rl = { .tag = RL_TY,
|
||||||
|
.data = log2_int_type, .src_node = 0, .ctx = RI_CTX_SHIFT_OP };
|
||||||
|
uint32_t rhs = exprRl(gz, scope, rhs_rl, nd.rhs);
|
||||||
|
uint32_t result
|
||||||
|
= addPlNodeBin(gz, ZIR_INST_SHR_EXACT, node, lhs, rhs);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @rem — divBuiltin (AstGen.zig:9485, 9920-9936).
|
||||||
|
if (name_len == 3 && memcmp(source + name_start, "rem", 3) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
uint32_t saved_line = ag->source_line - gz->decl_line;
|
||||||
|
uint32_t saved_col = ag->source_column;
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t lhs = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t rhs = expr(gz, scope, nd.rhs);
|
||||||
|
emitDbgStmt(gz, saved_line, saved_col);
|
||||||
|
uint32_t result = addPlNodeBin(gz, ZIR_INST_REM, node, lhs, rhs);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @divFloor — divBuiltin (AstGen.zig:9482, 9920-9936).
|
||||||
|
if (name_len == 8
|
||||||
|
&& memcmp(source + name_start, "divFloor", 8) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
uint32_t saved_line = ag->source_line - gz->decl_line;
|
||||||
|
uint32_t saved_col = ag->source_column;
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t lhs = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t rhs = expr(gz, scope, nd.rhs);
|
||||||
|
emitDbgStmt(gz, saved_line, saved_col);
|
||||||
|
uint32_t result
|
||||||
|
= addPlNodeBin(gz, ZIR_INST_DIV_FLOOR, node, lhs, rhs);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @mod — divBuiltin (AstGen.zig:9484, 9920-9936).
|
||||||
|
if (name_len == 3 && memcmp(source + name_start, "mod", 3) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
uint32_t saved_line = ag->source_line - gz->decl_line;
|
||||||
|
uint32_t saved_col = ag->source_column;
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t lhs = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t rhs = expr(gz, scope, nd.rhs);
|
||||||
|
emitDbgStmt(gz, saved_line, saved_col);
|
||||||
|
uint32_t result = addPlNodeBin(gz, ZIR_INST_MOD, node, lhs, rhs);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// @divTrunc — divBuiltin (AstGen.zig:9483, 9920-9936).
|
||||||
|
if (name_len == 8
|
||||||
|
&& memcmp(source + name_start, "divTrunc", 8) == 0) {
|
||||||
|
advanceSourceCursorToMainToken(ag, gz, node);
|
||||||
|
uint32_t saved_line = ag->source_line - gz->decl_line;
|
||||||
|
uint32_t saved_col = ag->source_column;
|
||||||
|
AstData nd = tree->nodes.datas[node];
|
||||||
|
uint32_t lhs = expr(gz, scope, nd.lhs);
|
||||||
|
uint32_t rhs = expr(gz, scope, nd.rhs);
|
||||||
|
emitDbgStmt(gz, saved_line, saved_col);
|
||||||
|
uint32_t result
|
||||||
|
= addPlNodeBin(gz, ZIR_INST_DIV_TRUNC, node, lhs, rhs);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
// @divExact — divBuiltin (AstGen.zig:9481, 9920-9936).
|
// @divExact — divBuiltin (AstGen.zig:9481, 9920-9936).
|
||||||
if (name_len == 8
|
if (name_len == 8
|
||||||
&& memcmp(source + name_start, "divExact", 8) == 0) {
|
&& memcmp(source + name_start, "divExact", 8) == 0) {
|
||||||
@@ -3910,6 +4102,54 @@ static uint32_t builtinCallMultiArg(GenZir* gz, Scope* scope, ResultLoc rl,
|
|||||||
return rvalue(gz, rl, result, node);
|
return rvalue(gz, rl, result, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @call — AstGen.zig:9604-9619.
|
||||||
|
// clang-format off
|
||||||
|
if (name_len == 4 && memcmp(source + name_start, "call", 4) == 0
|
||||||
|
&& param_count == 3) {
|
||||||
|
uint32_t call_modifier_ty
|
||||||
|
= addBuiltinValue(gz, node, ZIR_BUILTIN_VALUE_CALL_MODIFIER);
|
||||||
|
ResultLoc mod_rl = { .tag = RL_COERCED_TY,
|
||||||
|
.data = call_modifier_ty, .src_node = 0, .ctx = RI_CTX_NONE };
|
||||||
|
uint32_t modifier
|
||||||
|
= comptimeExpr(gz, scope, mod_rl, params[0],
|
||||||
|
COMPTIME_REASON_CALL_MODIFIER);
|
||||||
|
uint32_t callee = expr(gz, scope, params[1]);
|
||||||
|
uint32_t args = expr(gz, scope, params[2]);
|
||||||
|
// BuiltinCall payload: flags, modifier, callee, args.
|
||||||
|
ensureExtraCapacity(ag, 4);
|
||||||
|
uint32_t payload_index = ag->extra_len;
|
||||||
|
ag->extra[ag->extra_len++] = 0; // flags: is_nosuspend=false, ensure_result_used=false
|
||||||
|
ag->extra[ag->extra_len++] = modifier;
|
||||||
|
ag->extra[ag->extra_len++] = callee;
|
||||||
|
ag->extra[ag->extra_len++] = args;
|
||||||
|
uint32_t result = addPlNodePayloadIndex(
|
||||||
|
gz, ZIR_INST_BUILTIN_CALL, node, payload_index);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
// @shuffle — AstGen.zig:9655-9663.
|
||||||
|
// clang-format off
|
||||||
|
if (name_len == 7 && memcmp(source + name_start, "shuffle", 7) == 0
|
||||||
|
&& param_count == 4) {
|
||||||
|
uint32_t elem_type = typeExpr(gz, scope, params[0]);
|
||||||
|
uint32_t a = expr(gz, scope, params[1]);
|
||||||
|
uint32_t b = expr(gz, scope, params[2]);
|
||||||
|
uint32_t mask = comptimeExpr(gz, scope, RL_NONE_VAL, params[3],
|
||||||
|
COMPTIME_REASON_SHUFFLE_MASK);
|
||||||
|
// Shuffle payload: elem_type, a, b, mask (4 Refs).
|
||||||
|
ensureExtraCapacity(ag, 4);
|
||||||
|
uint32_t payload_index = ag->extra_len;
|
||||||
|
ag->extra[ag->extra_len++] = elem_type;
|
||||||
|
ag->extra[ag->extra_len++] = a;
|
||||||
|
ag->extra[ag->extra_len++] = b;
|
||||||
|
ag->extra[ag->extra_len++] = mask;
|
||||||
|
uint32_t result = addPlNodePayloadIndex(
|
||||||
|
gz, ZIR_INST_SHUFFLE, node, payload_index);
|
||||||
|
return rvalue(gz, rl, result, node);
|
||||||
|
}
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
// TODO: handle other multi-arg builtins.
|
// TODO: handle other multi-arg builtins.
|
||||||
SET_ERROR(ag);
|
SET_ERROR(ag);
|
||||||
return ZIR_REF_VOID_VALUE;
|
return ZIR_REF_VOID_VALUE;
|
||||||
@@ -12493,12 +12733,12 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
|||||||
|
|
||||||
// --- Parameter iteration (AstGen.zig:4260-4363) ---
|
// --- Parameter iteration (AstGen.zig:4260-4363) ---
|
||||||
// Walk params, creating param instructions and ScopeLocalVal entries.
|
// Walk params, creating param instructions and ScopeLocalVal entries.
|
||||||
// We keep param scopes on the C stack (max 32 params like upstream).
|
// We keep param scopes on the C stack.
|
||||||
Scope* params_scope = &decl_gz.base;
|
Scope* params_scope = &decl_gz.base;
|
||||||
ScopeLocalVal param_scopes[32];
|
ScopeLocalVal param_scopes[256];
|
||||||
uint32_t param_scope_count = 0;
|
uint32_t param_scope_count = 0;
|
||||||
// Collect param instruction indices (AstGen.zig:4254, 4360).
|
// Collect param instruction indices (AstGen.zig:4254, 4360).
|
||||||
uint32_t param_insts[32];
|
uint32_t param_insts[256];
|
||||||
uint32_t param_insts_len = 0;
|
uint32_t param_insts_len = 0;
|
||||||
// noalias_bits tracking (AstGen.zig:4259).
|
// noalias_bits tracking (AstGen.zig:4259).
|
||||||
uint32_t noalias_bits = 0;
|
uint32_t noalias_bits = 0;
|
||||||
@@ -12645,7 +12885,7 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
|||||||
uint32_t anytype_inst = addStrTok(
|
uint32_t anytype_inst = addStrTok(
|
||||||
&decl_gz, anytype_tag, param_name_str, anytype_name_token);
|
&decl_gz, anytype_tag, param_name_str, anytype_name_token);
|
||||||
param_inst_ref = anytype_inst; // already a ref (toRef())
|
param_inst_ref = anytype_inst; // already a ref (toRef())
|
||||||
if (param_insts_len < 32)
|
if (param_insts_len < 256)
|
||||||
param_insts[param_insts_len++]
|
param_insts[param_insts_len++]
|
||||||
= anytype_inst - ZIR_REF_START_INDEX; // toIndex()
|
= anytype_inst - ZIR_REF_START_INDEX; // toIndex()
|
||||||
} else {
|
} else {
|
||||||
@@ -12675,12 +12915,12 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope,
|
|||||||
name_tok_for_src, param_name_str, param_type_is_generic);
|
name_tok_for_src, param_name_str, param_type_is_generic);
|
||||||
(void)param_inst_expected;
|
(void)param_inst_expected;
|
||||||
param_inst_ref = param_inst + ZIR_REF_START_INDEX;
|
param_inst_ref = param_inst + ZIR_REF_START_INDEX;
|
||||||
if (param_insts_len < 32)
|
if (param_insts_len < 256)
|
||||||
param_insts[param_insts_len++] = param_inst;
|
param_insts[param_insts_len++] = param_inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create ScopeLocalVal for this param (AstGen.zig:4349-4359).
|
// Create ScopeLocalVal for this param (AstGen.zig:4349-4359).
|
||||||
if (param_name_str != 0 && param_scope_count < 32) {
|
if (param_name_str != 0 && param_scope_count < 256) {
|
||||||
ScopeLocalVal* lv = ¶m_scopes[param_scope_count++];
|
ScopeLocalVal* lv = ¶m_scopes[param_scope_count++];
|
||||||
lv->base.tag = SCOPE_LOCAL_VAL;
|
lv->base.tag = SCOPE_LOCAL_VAL;
|
||||||
lv->parent = params_scope;
|
lv->parent = params_scope;
|
||||||
|
|||||||
Reference in New Issue
Block a user