lang0/tests/generate-recipes.py
Johan B.W. de Vries 670532059a Feat: Adds mapclear, mapgetkey, mapsetkey
Feat: Error on undefined function

Fix: All ids are now prefix to prevent native var clashes.
This was already done on it2, but now also in it0 and it1.
Redid it2 to match.

Fix: generate-recipes would not complain on missing exp.

Fix: Adds documentation and test for not

Chore: __check helper function for ease of use in it0, it1.

Chore: some reordering to match more between iterations.
2025-05-04 18:06:04 +02:00

123 lines
3.4 KiB
Python

import glob
import os
import sys
STAGE0_MAP = {
'it0': '.py',
'it1': '.py',
'it2': '.c',
}
class Rule:
def __init__(self, target: str, prerequisites: list[str], recipe: list[str]) -> None:
self.target = target
self.prerequisites = prerequisites
self.recipe = recipe
def make_lines(self):
return [
self.target + ': ' + ' '.join(self.prerequisites),
] + [
'\t' + line
for line in self.recipe
] + ['']
def get_file_list():
return sorted(glob.glob('test_*/*.lang0'))
def make_rules(file_path, lang0it):
result: list[Rule] = []
stdin = file_path.replace('.lang0', '.stdin')
exp_cmperr = file_path.replace('.lang0', '.exp.cmperr')
exp_stderr = file_path.replace('.lang0', '.exp.stderr')
exp_stdout = file_path.replace('.lang0', '.exp.stdout')
act_cmperr = 'build/' + file_path.replace('.lang0', f'.{lang0it}.cmperr')
act_stderr = 'build/' + file_path.replace('.lang0', f'.{lang0it}.stderr')
act_stdout = 'build/' + file_path.replace('.lang0', f'.{lang0it}.stdout')
act_result = 'build/' + file_path.replace('.lang0', f'.{lang0it}.result')
program = 'build/' + file_path.replace('.lang0', f'.{lang0it}')
program_stage0 = program + STAGE0_MAP[lang0it]
if os.path.isfile(exp_cmperr):
# No need to try to run the program
exp_list = [exp_cmperr]
act_list = [act_cmperr]
elif os.path.isfile(exp_stdout) or os.path.isfile(exp_stderr):
result.append(Rule(
act_stdout,
[program] + ([stdin] if os.path.isfile(stdin) else []),
[
'-' + (f'cat {stdin} | ' if os.path.isfile(stdin) else 'echo x | ')
+ f'{program} 1> {act_stdout} 2> {act_stderr}',
]
))
exp_list = [exp_stdout, exp_stderr]
act_list = [act_stdout, act_stderr]
else:
assert False, f'Missing expectations for {file_path}'
result.append(Rule(
act_result,
([program_stage0] if os.path.isfile(exp_cmperr) else [act_stdout]) + [
x
for x in exp_list
if os.path.isfile(x)
],
[
'rm -f $@',
] + [
f'-diff {exp_file} {act_file} >> $@'
for exp_file, act_file in zip(exp_list, act_list, strict=True)
if os.path.isfile(exp_file)
] + [
f'-diff /dev/null {act_file} >> $@'
for exp_file, act_file in zip(exp_list, act_list, strict=True)
if not os.path.isfile(exp_file)
]
))
return result
def main(program, write_to, *lang0it):
rule_list_list = [
make_rules(file_path, it)
for file_path in get_file_list()
for it in lang0it
]
result_targets = [
rule.target
for rule_list in rule_list_list
for rule in rule_list
if rule.target.endswith('.result')
]
rule_list_list.append([Rule(
'verify-results',
result_targets,
[
'@echo Finding failed test results...',
'@find $^ -not -empty -print -exec false {} +',
'@echo All tests passed.'
]
)])
data = '\n'.join(
line
for rule_list in rule_list_list
for rule in rule_list
for line in rule.make_lines()
)
with open(write_to, 'wt', encoding='ASCII') as fil:
fil.write(data)
if __name__ == '__main__':
main(*sys.argv)