aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-14 15:53:37 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-14 15:53:37 +0330
commit5a4f3885edafe289dce17ec8b53a8fc188b9e146 (patch)
tree1a44421ad2b988b5ed95c08a000062eae4244243
parentmerge spec conformance suite (diff)
capture_scan: restore panic after the dry scan, so a bad literal in a function's first statement is reported
-rw-r--r--src/compiler/expr.zc4
-rw-r--r--tests/conformance/known.txt8
-rw-r--r--tests/langerrors/bad_char_first_statement.zc3
-rw-r--r--tests/langerrors/bad_float_first_statement.zc3
4 files changed, 8 insertions, 10 deletions
diff --git a/src/compiler/expr.zc b/src/compiler/expr.zc
index 40de6ef..bcb92da 100644
--- a/src/compiler/expr.zc
+++ b/src/compiler/expr.zc
@@ -538,7 +538,7 @@ int enhcall(int s) {
// scan with the compiler lexer, restoring its source and lookahead. only functions containing a closure
// need cells; their scalars get cells from declaration time, so loop back edges and earlier references agree.
int capture_scan() {
- word old, f; int depth = 1, found = 0, docs = docs_on, record = grec;
+ word old, f; int depth = 1, found = 0, docs = docs_on, record = grec, sp = panic;
if (isp < 0 || R_SRC[isp * 32] == 0 || !is_op(s_lb)) return 0;
old = R_SRC + isp * 32;
src_push(1, capture_dummy, 0, 0); old = R_SRC + (isp - 1) * 32; f = R_SRC + isp * 32;
@@ -550,7 +550,7 @@ int capture_scan() {
else if (is_op(s_rb)) depth--;
else if (is_id(s_fn)) { peek(); if (pk_tk == T_OP && (pk_tv == s_lp || pk_tv == s_colon)) found = 1; }
}
- dry--; src_pop(); docs_on = docs; grec = record; return found;
+ dry--; src_pop(); docs_on = docs; grec = record; panic = sp; return found; // a lexer error in the dry scan must not leave panic set for the real parse
}
int capture_cell(int i, int copy) {
if (!capture_enabled || o3on || (ltag[i] & 16) || larr[i] || local_cell[i]) return 0;
diff --git a/tests/conformance/known.txt b/tests/conformance/known.txt
index c26b50e..2412378 100644
--- a/tests/conformance/known.txt
+++ b/tests/conformance/known.txt
@@ -2,14 +2,6 @@
# class a: self-hosted compiler bug; b: zc0 deviation (appendix a/b); c: spec issue to settle
1-source/ident_tags_as_variables_glued_star.zc zy a u*d with visible variables u and d is taken as a recast, not a multiplication (spec 1.6.3)
1-source/lit_bstr_cast_to_int_pointer.zc zy a the bstr flag leaks into an int* local, so p[0] reads a byte
-1-source/lit_char_non_ascii.zc zy a bad character literal in the first statement of a body is swallowed by lookahead
-1-source/lit_char_two_bytes.zc zy a bad character literal in the first statement of a body is swallowed by lookahead
-1-source/lit_char_two_bytes_local_init.zc zy a bad character literal in the first statement of a body is swallowed by lookahead
-1-source/lit_float_bad_exponent.zc zy a bad float literal in the first statement of a body is swallowed by lookahead
-1-source/lit_float_bad_exponent_first_stmt_local.zc zy a bad float literal in the first statement of a body is swallowed by lookahead
-1-source/lit_float_bad_exponent_first_stmt_paren.zc zy a bad float literal in the first statement of a body is swallowed by lookahead
-1-source/lit_float_bad_exponent_in_helper.zc zy a bad float literal in the first statement of a body is swallowed by lookahead
-1-source/lit_float_bad_exponent_sign.zc zy a bad float literal in the first statement of a body is swallowed by lookahead
2-types/typecheck_off_void_return_value_ok.zc zy a void f() { return 3; } yields 3, not 0 (spec 4.8.3)
3-expressions/call_24_parameters.zc zy a the parameter limit is 23, not 24 (decl.zc; closures 19)
3-expressions/call_24_parameters_prototype.zc zy a the parameter limit is 23, not 24 (decl.zc; closures 19)
diff --git a/tests/langerrors/bad_char_first_statement.zc b/tests/langerrors/bad_char_first_statement.zc
new file mode 100644
index 0000000..ca2ccfa
--- /dev/null
+++ b/tests/langerrors/bad_char_first_statement.zc
@@ -0,0 +1,3 @@
+// expect: bad character literal
+include rt;
+fn main() { int a = 'ab'; rt.put_n(a); return 0; }
diff --git a/tests/langerrors/bad_float_first_statement.zc b/tests/langerrors/bad_float_first_statement.zc
new file mode 100644
index 0000000..2dcca38
--- /dev/null
+++ b/tests/langerrors/bad_float_first_statement.zc
@@ -0,0 +1,3 @@
+// expect: bad float
+include rt;
+fn main() { rt.put_n(1e); return 0; }