~james/remy

feat(frontend): accept digits after identifier prefixes

commit
76eb8c0c102b513568343ee91839bb0ab21e49d4 browse tree
parent
21d77cf288325dcfb456295637061e22fb3d28e9
author
james <j@cpl0.zip>
signature
Verified ~james signed with a key registered by ~james
date
2026-09-21 11:00 UTC

4 files changed, +16 −2

src/Examples.thy modified

@@ -77,6 +77,13 @@ lemma lexical_shadow:
7777 "reference ''(let x 7 (let x (+ x 2) (* x x)))'' ''1'' ''2'' ''3'' = (True,''81'' @ newline)"
7878 by eval
7979
80+lemma numeric_identifier:
81+ "reference ''(let x1 7 (let x1 (+ x1 2) (* x1 x1)))'' ''0'' ''0'' ''0'' = (True,''81'' @ newline)"
82+ by eval
83+
84+lemma numeric_prefix_rejected: "prepare ''(let 1x 3 1x)'' = None"
85+ by eval
86+
8087 lemma nested_temporaries:
8188 "reference ''(+ 10 (let a 3 (+ a (let b 4 (* a b)))))'' ''0'' ''0'' ''0'' = (True,''25'' @ newline)"
8289 by eval

src/Frontend.thy modified

@@ -33,8 +33,10 @@ theorem number_bound: "number s = Some n \<Longrightarrow> n < 2 ^ 64"
3333 by (auto simp: number_def parse_digits_def Let_def split: list.splits if_splits)
3434
3535 definition valid_name :: "string \<Rightarrow> bool" where
36- "valid_name s = (s \<noteq> [] \<and> list_all (\<lambda>c. (97 \<le> nat_of_char c \<and> nat_of_char c \<le> 122)) s
37- \<and> s \<noteq> ''let'' \<and> s \<noteq> ''if'')"
36+ "valid_name s = (case s of [] \<Rightarrow> False | c # cs \<Rightarrow>
37+ 97 \<le> nat_of_char c \<and> nat_of_char c \<le> 122 \<and>
38+ list_all (\<lambda>d. (97 \<le> nat_of_char d \<and> nat_of_char d \<le> 122) \<or>
39+ (48 \<le> nat_of_char d \<and> nat_of_char d < 58)) cs \<and> s \<noteq> ''let'' \<and> s \<noteq> ''if'')"
3840
3941 fun lookup :: "string \<Rightarrow> string list \<Rightarrow> nat option" where
4042 "lookup name [] = None"

tests/cli.py modified

@@ -22,6 +22,10 @@ def main():
2222 assert int(invoke('eval',source,'0','0','0')) == expected, text
2323 source.write_text('(+ x y)')
2424 assert int(invoke('eval',source,'0xFF','0x1','0x0')) == 256
25+ source.write_text('(let x1 7 (let x1 (+ x1 2) (* x1 x1)))')
26+ assert int(invoke('eval',source,'0','0','0')) == 81
27+ source.write_text('(let 1x 3 1x)')
28+ invoke(source,binary,ok=False)
2529 for text in ['0x','0x10000000000000000','0xfg','0xffextra','-0x1']:
2630 source.write_text(text)
2731 binary.write_bytes(b'preserve')

tests/native.py modified

@@ -69,6 +69,7 @@ def main():
6969 cases += [("*", "x", 1), ("*", 1, "x"), ("and", "x", MASK)]
7070 cases += [("*", "x", 0), ("and", "x", 0), ("shl", 0, "y"), ("shr", 0, "y"), ("or", "x", MASK)]
7171 cases += [("if", "x", ("+", "y", "t"), ("+", "y", "t"))]
72+ cases += [("let", "x1", ("+", "x", 1), ("*", "x1", "x1"))]
7273 cases += [("let", "a", ("+", "x", 3), ("+", "y", ("let", "b", "t", ("*", "a", "b")))),
7374 ("let", "x", "y", ("if", "t", ("+", "x", 1), ("-", "x", 1)))]
7475 cases += [generate(rng, 5, ["x", "y", "t"]) for _ in range(117)]