def c(self, snipname, snippath): options = DefaultOptions() options.stats_comment = False with open(snippath, 'rt', encoding='utf-8') as f: snippet = f.read() jspath = os.path.join(SNIPPETSDIR, snipname + ".js") if os.path.exists(jspath): with open(jspath, 'rt', encoding='utf-8') as f: options.extra_js_code = f.read() else: options.extra_js_code = "P.main();" # TODO this is a hellish monstrosity # ---- apply all directives --------------- directives_match = DIRECTIVE_REGEXP.search(snippet) if directives_match: for directive in directives_match.group(1).split(','): tokens = directive.split(maxsplit=1) self.assertEqual(2, len(tokens), tokens) k, v = tokens vtype = type(getattr(options, k)) if vtype == bool: v = v == 'True' else: v = vtype(v) setattr(options, k, v) # ---- find expected session if any --------------- session_match = SESSION_REGEXP.search(snippet) # ---- parse & check ---------------------- try: module = build_tree(options, path=None, buf=snippet) except CompilationFailed as cf: logged_errors = cf.errors else: logged_errors = [] snippet_errors = list(ERROR_REGEXP.finditer(snippet)) # ---- match errors ----------------------- # make sure the analysis raised as many errors as expected sc, lc = len(snippet_errors), len(logged_errors) self.assertEqual(sc, lc, "expected {} errors but {} were reported: {}" .format(sc, lc, logged_errors)) assert not logged_errors or not session_match,\ "expected a session but errors were raised" # check each error for i, error, match in zip(count(), logged_errors, snippet_errors): classname = match.group(1) if classname.startswith('kw:'): class_ = syntax.ExpectedKeyword else: class_ = getattr(syntax, classname, None) or getattr(semantic, classname) self.assertIsNotNone(class_, "unknown error class: '{}'".format(classname)) self.assertIs(error.__class__, class_, "wrong error found at error marker #{}".format(i)) self.assertEqual(error.pos.char, match.end(2), "error #{} wasn't reported at expected position (raised: {})" .format(i, error)) if class_ is syntax.ExpectedKeyword: raw_kws = classname[1+classname.find(':'):].split(',') expected_keywords = set(getattr(kw, r) for r in raw_kws) self.assertSetEqual(expected_keywords, set(error.expected_keywords)) # ---- stop there if there were any errors ------------- if snippet_errors: return # ---- compile to JS directly ---------------- js1 = translate_tree(options, module, 'js') # ---- compile to JS through regenerated LDA ----------- lda1 = translate_tree(options, module, 'lda') regen_module = build_tree(options, lda1) js2 = translate_tree(options, regen_module, 'js') # ---- both JS versions of the same program must end up identical # Instead of jumping through these hoops (LDA->LDA->JS), we could've # compared the original program with the regenerated LDA code, but then # we'd have to keep track of comments, whitespace, etc. In other words, # a ton of work for very little benefit. self.assertEqual(js1, js2) # ---- run JS ------------------------- if not module.algorithms: return if session_match: fragments = session_match.group('session').strip().split('|') snippet_output = ' '.join(f.strip() for f in fragments[0::2]) snippet_input = '\n'.join(f.strip() for f in fragments[1::2]) else: snippet_output = '' snippet_input = '' gotten_output = jsshell.run(js1, snippet_input) self.assertEqual(snippet_output, gotten_output.strip())
ap.add_argument('--ignore-case', '-c', action='store_true', help="""Ignorer la casse dans les identificateurs et les mot-clés""") ap.add_argument('--execute', '-x', action='store_true', help="""Exécuter le programme immédiatement s'il ne contient aucune erreur""") args = ap.parse_args() args.extra_js_code = "" args.stats_comment = True try: module = build_tree(args, None, args.path) except CompilationFailed as cf: for error in cf.errors: print(error.pretty(cf.buf), file=sys.stderr) sys.exit(1) if args.no_output: sys.exit(0) code = translate_tree(args, module, args.format) if args.execute: assert args.format == 'js', "on ne peut exécuter que du JavaScript !" import jsshell jsshell.run_interactive(code + "\nP.main();") elif args.output_file: with open(args.output_file, 'wt', encoding='utf8') as f: f.write(code) else: print(code)