aboutsummaryrefslogtreecommitdiff
path: root/tests/drivers/parser_growth_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/drivers/parser_growth_test.py')
-rw-r--r--tests/drivers/parser_growth_test.py48
1 files changed, 48 insertions, 0 deletions
diff --git a/tests/drivers/parser_growth_test.py b/tests/drivers/parser_growth_test.py
new file mode 100644
index 0000000..4cbfbb2
--- /dev/null
+++ b/tests/drivers/parser_growth_test.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+# parser storage grows across enum members, tagged enums, methods, and generated text.
+import subprocess
+import sys
+
+command = sys.argv[1:]
+
+
+def run(source, expected):
+ result = subprocess.run(command, input=source, text=True, capture_output=True, timeout=30)
+ assert result.returncode == 0, (result.stdout, result.stderr)
+ assert result.stdout == expected, result.stdout[:1000]
+
+
+source = 'enum values { ' + ', '.join(f'member_{i}' for i in range(300)) + ' };\n'
+source += 'fn main() { gc(); put_n(member_299); put_c(10); return 0; }\n'
+run(source, '299\n')
+source = ''.join(f'enum tagged_{i} {{ item_{i} {{ int value; }}, empty_{i} }};\n' for i in range(25))
+source += 'fn main() { tagged_24*.m item = tagged_24.item_24(7); gc(); put_n(item.item_24_value); put_c(10); return 0; }\n'
+run(source, '7\n')
+source = 'struct methods { int value;\n'
+source += ''.join(f'int get_{i}() {{ return this.value + {i}; }}\n' for i in range(100))
+source += '}\nfn main() { methods item; item.value = 7; gc(); put_n(item.get_99()); put_c(10); return 0; }\n'
+run(source, '106\n')
+source = 'enum expanded {\n'
+source += ',\n'.join(f'member_with_long_generated_name_{i} {{ ' + ''.join(f'int field_with_long_generated_name_{j}; ' for j in range(8)) + '}' for i in range(40))
+source += '\n};\nfn main() { gc(); put_n(ebcap > 8192); put_c(10); return 0; }\n'
+run(source, '1\n')
+source = 'fn main() { int result = 0; switch (127) {\n'
+source += ''.join(f'case {i}: result = {i};\n' for i in range(128))
+source += '} gc(); put_n(result); put_c(32); put_n(jpscap > 64); put_c(10); return 0; }\n'
+run(source, '127 1\n')
+source = 'fn main() { int result = 0;\n'
+source += ''.join('o3 { result += 1; }\n' for _ in range(40))
+source += 'gc(); put_n(result); put_c(32); put_n(o3pendcap > 10); put_c(10); return 0; }\n'
+run(source, '40 1\n')
+source = 'fn main() { int i = 0; while (i < 120) { putfact(i, i, 1); i++; } gc(); put_n(factcap > 32); put_c(32); put_n(getlo(119)); put_c(10); return 0; }\n'
+run(source, '1 119\n')
+long_type = 'structure_' + 't' * 180
+long_method = 'method_' + 'm' * 180
+source = f'struct {long_type} {{ int {long_method}() {{ return 7; }} }};\n'
+source += f'fn main() {{ {long_type} value; put_n(value.{long_method}()); put_c(10); return 0; }}\n'
+run(source, '7\n')
+name = 'generic_' + 'g' * 180
+source = f'int {name}_one<T>() {{ return sizeof(T); }}\nint {name}_two<T>() {{ return sizeof(T) + 1; }}\n'
+source += f'fn main() {{ put_n({name}_one<int>() + {name}_two<int>()); put_c(10); return 0; }}\n'
+run(source, '3\n')
+print('ok parser tables, analyzer paths, queued regions, and generated names grow')