diff --git a/test/conftest.py b/test/conftest.py new file mode 100644 index 0000000..9825dfd --- /dev/null +++ b/test/conftest.py @@ -0,0 +1,101 @@ +import pytest + +@pytest.fixture +def basic_machine_definition(): + return ( + { + "registers": 20 + , "memory": 100 + , "program_memory": 500 + } + , [ + { + "mnemonic": "ldi" + , "args": ["register", "direct_input"] + } + , { + "mnemonic": "ld" + , "args": ["register", "register"] + } + , { + "mnemonic": "st" + , "args": ["register", "register"] + } + , { + "mnemonic": "inc" + , "args": ["register"] + } + , { + "mnemonic": "dec" + , "args": ["register"] + } + , { + "mnemonic": "add" + , "args": ["register", "register"] + } + , { + "mnemonic": "sub" + , "args": ["register", "register"] + } + , { + "mnemonic": "mul" + , "args": ["register", "register"] + } + , { + "mnemonic": "div" + , "args": ["register", "register"] + } + , { + "mnemonic": "gt" + , "args": ["register"] + } + , { + "mnemonic": "ge" + , "args": ["register"] + } + , { + "mnemonic": "lt" + , "args": ["register"] + } + , { + "mnemonic": "le" + , "args": ["register"] + } + , { + "mnemonic": "eq" + , "args": ["register"] + } + , { + "mnemonic": "not" + , "args": [] + } + , { + "mnemonic": "jmp" + , "args": ["register"] + } + , { + "mnemonic": "call" + , "args": ["register"] + } + , { + "mnemonic": "ret" + , "args": [] + } + , { + "mnemonic": "stop" + , "args": [] + } + , { + "mnemonic": "cl" + , "args": [] + } + , { + "mnemonic": "cjmp" + , "args": ["register"] + } + , { + "mnemonic": "ccall" + , "args": ["register"] + } + ] + ) diff --git a/test/test_010_filecontext.py b/test/test_010_filecontext.py new file mode 100644 index 0000000..e8340a4 --- /dev/null +++ b/test/test_010_filecontext.py @@ -0,0 +1,24 @@ +from io import StringIO +from assembler.context import FileContext + + +def test_getc_ungetc(): + data = StringIO("abc\ndefg") + context = FileContext(data) + + assert context.getc() == "a" + assert context.getc() == "b" + assert context._line == 0 + assert context._column == 2 + assert context.getc() == "c" + assert context.getc() == "\n" + assert context.getc() == "d" + assert context._line == 1 + assert context._column == 1 + + context.ungetc("d") + context.ungetc("\n") + + assert context._column == 3 + assert context._line == 0 + assert context.getc() == "\n" diff --git a/test/test_011_tokenize.py b/test/test_011_tokenize.py new file mode 100644 index 0000000..2a2955c --- /dev/null +++ b/test/test_011_tokenize.py @@ -0,0 +1,54 @@ +from io import StringIO +from assembler.tokenize import Tokenizer +from assembler.context import FileContext + +def test_tokenize_1(): + data = ''' + ldi r0, 0xfefe + ldi r1, 0xefef + add r0, r1 + ''' + data = StringIO(data) + tokenizer = Tokenizer(FileContext(data)) + + result = list(tokenizer) + + assert result == [ + "ldi", " ", "r0", ",", "0xfefe", "\n" + , "ldi", " ", "r1", ",", "0xefef", "\n" + , "add", " ", "r0", ",", "r1", "\n" + ] + +def test_tokenize_2(): + data = ''' + ; This is a comment + + ldi r0, 0xfefe + ''' + data = StringIO(data) + tokenizer = Tokenizer(FileContext(data)) + + result = list(tokenizer) + + assert result == [ + ";", "This", " ", "is", " ", "a", " ", "comment", "\n" + , "ldi", " ", "r0", ",", "0xfefe", "\n" + ] + + +def test_tokenize_3(): + data = ''' + ldi r0, 0xfefe + string: + .set ['h', 'e', 'l', 'l', 'o'] + ''' + data = StringIO(data) + tokenizer = Tokenizer(FileContext(data)) + + result = list(tokenizer) + + assert result == [ + "ldi", " ", "r0", ",", "0xfefe", "\n" + , "string", ":", "\n" + , ".", "set", " ", "[", "'h'", ",", "'e'", ",", "'l'", ",", "'l'", ",", "'o'", "]", "\n" + ] diff --git a/test/test_012_opcodes.py b/test/test_012_opcodes.py new file mode 100644 index 0000000..2b7ba68 --- /dev/null +++ b/test/test_012_opcodes.py @@ -0,0 +1,14 @@ +from assembler.opcodes import make_opcodes + + +def test_make_opcodes(): + mnemonics = ["ldi", "ld", "st", "add", "mul"] + + opcodes = make_opcodes(mnemonics) + + assert opcodes == {"ldi": 32704 + , "ld" : 16320 + , "st": 49088 + , "add": 8128 + , "mul": 24512 + } diff --git a/test/test_013_util.py b/test/test_013_util.py new file mode 100644 index 0000000..32a5c5f --- /dev/null +++ b/test/test_013_util.py @@ -0,0 +1,35 @@ +from assembler.util import can_be_mark, can_convert_to_int, autoint + + +def test_can_be_mark(): + assert can_be_mark("this_is_a_mark") == True + assert can_be_mark("this_is_a_mark0") == True + assert can_be_mark("tHIS0") == True + + assert can_be_mark("This_is_not_a_mark") == False + assert can_be_mark("0this_is_no_mark") == False + assert can_be_mark("this#is_no_mark") == False + +def test_can_convert_to_int(): + assert can_convert_to_int("0xfe") == True + assert can_convert_to_int("0xFE") == True + assert can_convert_to_int("10") == True + assert can_convert_to_int("0b100") == True + assert can_convert_to_int("'a'") == True + assert can_convert_to_int("'\\n'") == True + + + assert can_convert_to_int("0xfg") == False + assert can_convert_to_int("0xFG") == False + assert can_convert_to_int("10a") == False + assert can_convert_to_int("0b20") == False + assert can_convert_to_int("'aa'") == False + assert can_convert_to_int("'\\z'") == False + +def test_autoint(): + assert autoint("0xfe") == 0xfe + assert autoint("0xFE") == 0xfe + assert autoint("10") == 10 + assert autoint("0b1010101") == 0b1010101 + assert autoint("'a'") == ord("a") + assert autoint("'\\n'") == ord("\n") diff --git a/test/test_020_basic_parsing.py b/test/test_020_basic_parsing.py new file mode 100644 index 0000000..9e89eb9 --- /dev/null +++ b/test/test_020_basic_parsing.py @@ -0,0 +1,22 @@ +from io import StringIO +import pytest + +from assembler.assembler import Assembler + + +def test_commands(basic_machine_definition): + memory_definition, command_defintion = basic_machine_definition + + data = StringIO( + ''' + ldi r0, 0xfe + ldi r1, 0xfe + add r0, r1 + ''' + ) + assembler = Assembler(data, memory_definition, command_defintion, {}) + assembler.parse() + + assert assembler._code_objects == [32704, 0, 0xfe + , 32704, 1, 0xfe + , 40896, 0, 1]