Ejemplo n.º 1
0
def test_array_lib(array_class=project_12.ARRAY_CLASS,
                   platform=BUNDLED_PLATFORM,
                   simulator='codegen'):
    # Note: this one's not so useful interactively, but easier to view anyway
    array_test = _parse_jack_file("examples/project_12/ArrayTest.jack",
                                  platform)

    translator = platform.translator()

    translator.preamble()

    translate_jack(translator, platform, array_class)

    _translate_dependencies(translator, platform, ["Memory"])

    translate_jack(translator, platform, array_test)

    translator.finish()

    translator.check_references()

    computer = run(platform.chip, simulator=simulator)
    translator.asm.run(platform.assemble,
                       computer,
                       stop_cycles=10_000,
                       debug=True)

    assert computer.peek(8000) == 222
    assert computer.peek(8001) == 122
    assert computer.peek(8002) == 100
    assert computer.peek(8003) == 10
Ejemplo n.º 2
0
def test_sys_lib(sys_class=project_12.SYS_CLASS,
                 platform=BUNDLED_PLATFORM,
                 simulator='codegen'):
    sys_test = _parse_jack_file("examples/project_12/SysTest.jack", platform)

    translator = platform.translator()

    translator.preamble()

    translate_jack(translator, platform, sys_class)

    # Dependencies:
    translate_library(translator, platform, "Memory")
    translate_library(translator, platform, "Math")
    translate_library(translator, platform, "Screen")
    translate_library(translator, platform, "Output")
    translate_library(translator, platform, "Keyboard")
    translate_library(translator, platform, "Array")
    translate_library(translator, platform, "String")

    translate_jack(translator, platform, sys_test)

    translator.finish()

    translator.check_references()

    computer = run(platform.chip, simulator=simulator)

    # translator.asm.run(platform.assemble, computer, stop_cycles=10_000, debug=True)
    translator.asm.trace(platform.assemble, computer, stop_cycles=1_000_000)

    # TODO: assert what?
    assert False
Ejemplo n.º 3
0
def translate_library(translator, platform, class_name):
    """Locate a class by name from the "OS" library provided with the Platform, and load it
    for use as a dependency.
    """

    matching = [cl for cl in platform.library if cl.name == class_name]
    if len(matching) == 1:
        translate_jack(translator, platform, matching[0])
    else:
        raise Exception(
            f"Could not find a class {class_name!r} in the platform's library ({[cl.name for cl in platform.library]})"
        )
Ejemplo n.º 4
0
def test_screen_lib(screen_class=project_12.SCREEN_CLASS,
                    platform=BUNDLED_PLATFORM,
                    simulator='codegen'):
    screen_test = _parse_jack_file("examples/project_12/ScreenTest.jack",
                                   platform)

    translator = platform.translator()

    translator.preamble()

    translate_jack(translator, platform, screen_class)

    # Dependencies; note: need Sys.init to intialize Screen, but don't want the built-in implementation.
    translate_library(translator, platform, "Array")
    translate_library(translator, platform, "Memory")
    translate_library(translator, platform, "Math")
    translate_jack(translator, platform,
                   minimal_sys_lib(["Memory", "Math", "Screen"], platform))

    translate_jack(translator, platform, screen_test)

    translator.finish()

    translator.check_references()

    computer = run(platform.chip, simulator=simulator)

    translator.asm.run(platform.assemble,
                       computer,
                       stop_cycles=10_000_000,
                       debug=True)
    # translator.asm.run(platform.assemble, computer, stop_cycles=100_000, debug=True)
    # translator.asm.trace(platform.assemble, computer, stop_cycles=10_000_000)
    # translator.asm.trace(platform.assemble, computer, stop_cycles=100_000)

    dump_screen(computer)  # For debugging

    # If you have failures here, try running
    # `./computer.py examples/project_12/ScreenTest.jack` and see if looks like a house.
    # If later assertions fail, maybe your impl is too slow and it's just not finished after
    # 10 million cycles. See the trace logging.

    # Spot check some groups of pixels:
    assert [computer.peek_screen(220 * 32 + w)
            for w in range(32)] == [-1] * 32, "ground all filled"

    assert computer.peek_screen(100 * 32 + 20) == -1, "house filled"
    assert computer.peek_screen(160 * 32 + 22) == 0, "door cleared"

    assert computer.peek_screen(
        64 * 32 + 19) != 0, "along left roof line (at least one pixel)"
    assert computer.peek_screen(
        50 * 32 + 22) != 0, "along right roof line (at least one pixel)"

    assert computer.peek_screen(6 * 32 + 8) == 1 << 12, "12 o-clock ray tip"
    assert computer.peek_screen(114 * 32 + 8) == 1 << 12, "6 o-clock ray tip"
    assert computer.peek_screen(60 * 32 + 5) == -64, "9 o-clock ray tip"
    assert computer.peek_screen(60 * 32 + 12) == 7, "3 o-clock ray tip"
Ejemplo n.º 5
0
def test_math_lib(math_class=project_12.MATH_CLASS,
                  platform=BUNDLED_PLATFORM,
                  simulator='codegen'):
    math_test = _parse_jack_file("examples/project_12/MathTest.jack", platform)

    translator = platform.translator()
    translator.preamble()

    translate_jack(translator, platform, math_class)

    translate_jack(translator, platform, minimal_sys_lib(["Math"], platform))

    translate_jack(translator, platform, math_test)

    translator.finish()

    translator.check_references()

    computer = run(platform.chip, simulator=simulator)

    translator.asm.run(platform.assemble,
                       computer,
                       stop_cycles=300_000,
                       debug=True)
    # translator.asm.trace(platform.assemble, computer, stop_cycles=300_000)

    assert computer.peek(8000) == 6, "multiply(2, 3)"
    assert computer.peek(8001) == -180, "multiply(6, -30)"
    assert computer.peek(8002) == -18000, "multiply(-180, 100)"
    assert computer.peek(8003) == -18000, "multiply(1, -18000)"
    assert computer.peek(8004) == 0, "multiply(-18000, 0)"

    assert computer.peek(8005) == 3, "divide(9, 3)"
    assert computer.peek(8006) == -3000, "divide(-18000, 6)"
    assert computer.peek(8007) == 0, "divide(32766, -32767)"

    assert computer.peek(8008) == 3, "sqrt(9)"
    assert computer.peek(8009) == 181, "sqrt(32767)"

    assert computer.peek(8010) == 123, "min(3445, 123)"
    assert computer.peek(8011) == 123, "max(123, -345)"
    assert computer.peek(8012) == 27, "abs(27)"
    assert computer.peek(8013) == 32767, "abs(-32767)"

    # Additional cases:
    assert computer.peek(8014) == 3000, "30000/10"
    assert computer.peek(8015) == -3276, "-32767/10"
    assert computer.peek(8016) == -32768, "abs(-32768)"
    assert computer.peek(8017) == 771, "12345/16"
    assert computer.peek(8018) == -771, "-12345/16"
Ejemplo n.º 6
0
def test_output_lib(output_class=project_12.OUTPUT_CLASS,
                    platform=BUNDLED_PLATFORM,
                    simulator='codegen'):
    output_test = _parse_jack_file("examples/project_12/OutputTest.jack",
                                   platform)

    translator = platform.translator()

    translator.preamble()

    translate_jack(translator, platform, output_class)

    # Dependencies; note: need Sys.init to intialize Output, but don't want the built-in implementation.
    translate_library(translator, platform, "Array")
    translate_library(translator, platform, "Memory")
    translate_library(translator, platform, "String")
    translate_library(translator, platform, "Math")
    translate_jack(translator, platform,
                   minimal_sys_lib(["Memory", "Math", "Output"], platform))

    translate_jack(translator, platform, output_test)

    translator.finish()

    translator.check_references()

    computer = run(platform.chip, simulator=simulator)

    # translator.asm.run(platform.assemble, computer, stop_cycles=1_000_000, debug=True)
    translator.asm.trace(platform.assemble, computer, stop_cycles=1_000_000)

    # Spot check the screen RAM:

    # A few lines from the A in the upper left:
    assert computer.peek_screen(0 * 32 + 0) == 30
    assert computer.peek_screen(1 * 32 + 0) == 51
    assert computer.peek_screen(4 * 32 + 0) == 63

    # The top line of the adjacent characters "6" and "7":
    assert computer.peek_screen((2 * 11) * 32 + 3) == (63 << 8) | 28
Ejemplo n.º 7
0
def test_string_lib(string_class=project_12.STRING_CLASS,
                    platform=BUNDLED_PLATFORM,
                    simulator='codegen'):
    string_test = _parse_jack_file("examples/project_12/StringTest.jack",
                                   platform)

    translator = platform.translator()

    translator.preamble()

    translate_jack(translator, platform, string_class)

    translate_jack(translator, platform, minimal_output_lib(platform))

    _translate_dependencies(translator, platform, ["Array", "Memory", "Math"])

    translate_jack(translator, platform, string_test)

    translator.finish()

    translator.check_references()

    computer = run(platform.chip, simulator=simulator)

    output_stream = StringWriter()
    translator.asm.run(platform.assemble,
                       computer,
                       stop_cycles=500_000,
                       tty=output_stream,
                       debug=True)
    # translator.asm.trace(platform.assemble, computer, stop_cycles=500_000, tty=output_stream)

    output_lines = "".join(output_stream.strs).split("\n")
    assert output_lines == [
        "new,appendChar: abcde", "setInt: 12345", "setInt: -32767",
        "length: 5", "charAt[2]: 99", "setCharAt(2,'-'): ab-de",
        "eraseLastChar: ab-d", "intValue: 456", "intValue: -32123",
        "backSpace: 129", "doubleQuote: 34", "newLine: 128", ""
    ]
Ejemplo n.º 8
0
def test_memory_lib(memory_class=project_12.MEMORY_CLASS,
                    platform=BUNDLED_PLATFORM,
                    simulator='codegen'):
    # Note: this one's not so useful interactively, but easier to view anyway
    memory_test = _parse_jack_file("examples/project_12/MemoryTest.jack",
                                   platform)

    translator = platform.translator()

    translator.preamble()

    translate_jack(translator, platform, memory_class)

    # Dependencies; note: need Sys.init to intialize Memory, but don't want the built-in implementation.
    translate_library(translator, platform, "Array")
    translate_jack(translator, platform, minimal_sys_lib("Memory", platform))

    translate_jack(translator, platform, memory_test)

    translator.finish()

    translator.check_references()

    computer = run(platform.chip, simulator=simulator)

    # translator.asm.run(platform.assemble, computer, stop_cycles=10_000, debug=True)
    translator.asm.trace(platform.assemble, computer, stop_cycles=10_000)

    # print_free_list(computer)

    assert computer.peek(8000) == 333
    assert computer.peek(8001) == 334
    assert computer.peek(8002) == 222
    assert computer.peek(8003) == 122
    assert computer.peek(8004) == 100
    assert computer.peek(8005) == 10
Ejemplo n.º 9
0
def _translate_dependencies(translator, platform, libs):
    translate_jack(translator, platform, minimal_sys_lib(libs, platform))
    for lib in libs:
        translate_library(translator, platform, lib)
Ejemplo n.º 10
0
def test_keyboard_lib(keyboard_class=project_12.KEYBOARD_CLASS,
                      platform=BUNDLED_PLATFORM,
                      simulator='codegen'):
    keyboard_test = _parse_jack_file("examples/project_12/KeyboardTest.jack",
                                     platform)

    translator = platform.translator()

    translator.preamble()

    translate_jack(translator, platform, keyboard_class)

    translate_jack(translator, platform, minimal_output_lib(platform))
    _translate_dependencies(translator, platform,
                            ["Array", "Memory", "Math", "String"])

    translate_jack(translator, platform, keyboard_test)

    translator.finish()

    translator.check_references()

    computer = run(platform.chip, simulator=simulator)

    # TODO: put this stop-start running into a utility somewhere (translate.py?)
    # Also, make it smarter about how long to wait. Maybe: wait_for_output(), which
    # will run a lot of cycles if needed, but stops not long after the output shows
    # up.

    asm, _, _ = platform.assemble(translator.asm)
    computer.init_rom(asm)

    output = ""

    def crank(cycles=100_000):
        """Run for a while, checking the tty for output every few cycles."""
        nonlocal output
        for _ in range(cycles // 100):
            computer.ticktock(cycles=100)
            computer.ticktock()
            c = computer.get_tty()
            if c != 0:
                if c == 128:
                    output += "\n"
                else:
                    output += chr(c)

    def type_key(code):
        computer.set_keydown(code)
        crank()
        computer.set_keydown(0)
        crank()

    crank(1_000_000)

    assert output.endswith("Please press the 'Page Down' key")

    type_key(137)  # page down

    assert output.endswith("Please press the number '3': ")

    type_key(ord("3"))

    assert "Please press the number '3': 3\nok\n" in output

    type_key(ord("J"))
    type_key(ord("A"))
    type_key(ord("C"))
    type_key(ord("C"))
    type_key(129)  # backspace
    type_key(ord("K"))
    type_key(128)  # newline

    # Note: the backspace is ignored by the TTY-only Output impl.
    assert "Please type 'JACK' and press enter: JACCK\nok\n" in output

    for c in "-32123":
        type_key(ord(c))
    type_key(128)  # newline

    assert output.endswith("Test completed successfully")