def test_multiple_advanced(): """Test by parser fuzzing.""" decl = """fn b(a: *|[[|*s4|@3]@5]|, b:u2) -> |u4| { var a: [u4@4] = {1, 2, 3, 4}; a = 5 * (4 + (4 / 3)); if a < b {print(wew, lad);} x++; // we need a semicolon here n = *(0:::*u2); n[1+2]--; return f(a); }""" parse_source(decl)
def test_return_parse(): """Test that the return statement is parsed correctly.""" decl = emptyfn("return 1;") fn, = parse_source(decl) rtn_stmt = fn.body[0] assert isinstance(rtn_stmt, objects.statements.ReturnStmt)
def test_function_decl(): """Test function declarations and check the type of the parsed fn.""" decl = "fn func(a: u1, b: *u2, ...) -> u4 {};" body, = parse_source(decl) assert isinstance(body, objects.base.FunctionDecl) assert body._type == objects.types.Function( objects.types.Int('u4'), (objects.types.Int('u1'), objects.types.Pointer( objects.types.Int('u2'))), True, True)
def compile(input, out, reg_count, show_stats, debug_compiler, print_ir, print_hwin, print_offsets, no_include_std): colorama.init(autoreset=True) input = input.read() input = input.expandtabs(tabsize=4) if not input: print("No input", file=sys.stderr) exit(1) try: parsed = parse_source(input) except FailedParse as e: print("Failed to parse input: ", file=sys.stderr) info = e.buf.line_info(e.pos) line = info.line + 1 col = info.col + 1 text = info.text.rstrip() arrow_pos = re.sub(r"[^\t]", " ", text)[:info.col] text = text.expandtabs() above_lines = strip_newlines( e.buf.get_lines(max(line - 5, 0), line - 2)) error_line = e.buf.get_line(line - 1).rstrip("\n\r") below_lines = strip_newlines(e.buf.get_lines(line, line + 5)) # get line error is on, cut 5 lines above and 5 lines below # highlight error line, grey colour surrounding lines line_counter = count(max(line - 5, 1)) line = colored(str(line - 1), 'green') col = colored(str(col), 'green') print(f"Line {line}, Column: {col}: ", file=sys.stderr) if above_lines: print(colorama.Style.DIM + "\n".join(add_line_count(above_lines, line_counter)), file=sys.stderr) print(colorama.Style.BRIGHT + f"{next(line_counter):>3}| {error_line}\n {arrow_pos}^", file=sys.stderr) if below_lines: print(colorama.Style.DIM + "\n".join(add_line_count(below_lines, line_counter)), file=sys.stderr) exit(1) except CompileException as e: if debug_compiler: raise e from None print(e, file=sys.stderr) exit(1) if not no_include_std: import os stdlib_path = os.path.join(os.path.dirname(__file__), "stdlib.wew") with open(stdlib_path) as f: stdlib = f.read() parsed.extend(parse_source(stdlib)) compiler = base.Compiler() try: compiler.compile(parsed) except CompileException as e: if debug_compiler: raise e from None print(e, file=sys.stderr) exit(1) offsets, code = process_code(compiler, reg_count) if print_ir: print("\n\n".join("{}\n{}".format(i.identifier, i.pretty_print()) for i in compiler.compiled_objects)) if print_hwin: print("\n".join(map(str, code))) if print_offsets: pprint.pprint(offsets) compiled = assemble_instructions(code) if show_stats: print("Stats: \n ", end="") print("\n ".join(get_stats(compiler, compiled))) out.write(compiled)
def test_var_declaration(): """Test variable declarations.""" decl = "var a : (u2, *u4, *[s2], *[s4]) -> *(s2)" parse_source(decl)
def test_fn_in_fn(): """Test function declarations being impossible inside a function body.""" decl = emptyfn(emptyfn("")) with raises(FailedParse): parse_source(decl)
def test_if_stmt(): """Test the if statement.""" decl = emptyfn("if a != b {" " print(\"test\");" "}") parse_source(decl)
def test_fn_declaration(): """Test function definitions.""" decl = """fn b(a: *[[*s4@3]@5], b:u2) -> u4 { return 1; }""" parse_source(decl)