Skip to content

Commit 0861515

Browse files
gh-72: Correct argument parsing.
1 parent 4019273 commit 0861515

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

src/interpreter.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,21 @@ Value eval_expr(Interpreter* interp, Expr* expr, Env* env) {
790790
}
791791

792792
case EXPR_LAMBDA: {
793+
// Validate lambda parameter ordering just like named functions:
794+
for (size_t _pi = 0; _pi < expr->as.lambda.params.count; _pi++) {
795+
Param* _p = &expr->as.lambda.params.items[_pi];
796+
if (!_p) continue;
797+
if (_p->default_value) continue;
798+
for (size_t _pj = 0; _pj < _pi; _pj++) {
799+
if (expr->as.lambda.params.items[_pj].default_value) {
800+
interp->error = strdup("Parameters with defaults must follow positional parameters");
801+
interp->error_line = expr->line;
802+
interp->error_col = expr->column;
803+
return value_null();
804+
}
805+
}
806+
}
807+
793808
Func* f = create_runtime_function(NULL,
794809
expr->as.lambda.return_type,
795810
&expr->as.lambda.params,
@@ -2249,6 +2264,32 @@ static ExecResult exec_stmt(Interpreter* interp, Stmt* stmt, Env* env, LabelMap*
22492264
}
22502265

22512266
case STMT_FUNC: {
2267+
// Validate parameter ordering: per specification positional
2268+
// parameters MUST appear before any parameters with defaults.
2269+
// Reject function definitions which violate this rule early so
2270+
// callers get a clear error at definition time instead of
2271+
// experiencing confusing call-time failures.
2272+
for (size_t _pi = 0; _pi < stmt->as.func_stmt.params.count; _pi++) {
2273+
Param* _p = &stmt->as.func_stmt.params.items[_pi];
2274+
if (!_p) continue;
2275+
// Once we observe a parameter with a default, all subsequent
2276+
// parameters must also have defaults.
2277+
if (_p->default_value) {
2278+
// mark and continue scanning remaining params to ensure
2279+
// any subsequent non-defaults are detected below
2280+
continue;
2281+
}
2282+
// If any earlier parameter had a default, but this one does
2283+
// not, that's a violation. To detect that we scan backwards
2284+
// from here to see if any prior param had a default.
2285+
for (size_t _pj = 0; _pj < _pi; _pj++) {
2286+
if (stmt->as.func_stmt.params.items[_pj].default_value) {
2287+
return make_error("Parameters with defaults must follow positional parameters",
2288+
stmt->line, stmt->column);
2289+
}
2290+
}
2291+
}
2292+
22522293
// Register user-defined function in the interpreter
22532294
Func* f = create_runtime_function(stmt->as.func_stmt.name,
22542295
stmt->as.func_stmt.return_type,

0 commit comments

Comments
 (0)