diff --git a/assembler/Makefile b/assembler/Makefile deleted file mode 100644 index f4d0917..0000000 --- a/assembler/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -.PHONY: test -test: - python3 -m pytest test/ diff --git a/assembler/assembler/__init__.py b/assembler/assembler/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/assembler/assembler/assembler.py b/assembler/assembler/assembler.py deleted file mode 100644 index 8302f94..0000000 --- a/assembler/assembler/assembler.py +++ /dev/null @@ -1,311 +0,0 @@ -from collections import deque - -from .context import FileContext -from .tokenize import Tokenizer, WHITESPACE -from .opcodes import make_opcodes -from .util import can_be_mark, can_convert_to_int, autoint, int16_2_bytes -from .directives import SetDirective - -class ParsingError(Exception): - pass - -class Assembler(object): - """ - This class is used for generating bytecode from a file containing assembly. - - Also required is the memory definition of the interpreter given as a dict:: - - { - "registers": , - "memory": , - "program_memory": - } - - And the definition of the commands. This is a list of dicts:: - - [ - { - "mnemonic": , - "args": [ - ("register"|"memory"|"program_memory"|"direct_input"), ... - ] - } - ] - - The method ``parse`` will parse the input file and ``bindump`` will dump the binary - bytecode into a file. - """ - def __init__(self, file_, memory_definition, command_definition, custom_directives): - self._file_context = FileContext(file_) - self._code_objects = deque() - self._memory_definition = memory_definition - self._command_definition = command_definition - self._word_count = 0 - self._marks = {} - - self._opcodes = make_opcodes([cmd["mnemonic"] for cmd in command_definition]) - self._commands_by_mnemonic = {cmd["mnemonic"]: cmd for cmd in command_definition} - self._tokenizer = Tokenizer(self._file_context) - - self._directives = {"set": SetDirective()} - self._directives.update(custom_directives) - - def parse(self): - try: - for token in self._tokenizer: - - # Comments - if(token == ";"): - while(token != "\n"): - token = next(self._tokenizer) - continue - - # Commands - if(token in self._commands_by_mnemonic): - self.parse_command(token) - continue - - # Directives - if(token == "."): - self.parse_directive() - continue - - # The default is trying to parse a mark - if(not can_be_mark(token)): - self.raise_unexpected_token(token - , "comment, command, directive or mark" - , token) - self.parse_mark(token) - except StopIteration: - raise ParsingError("Unexpected EOF while parsing.") - - for mark, mark_data in self._marks.items(): - if(mark_data["target"] < 0): - raise ParsingError("Mark {} undefined. Referenced in lines: {}".format( - mark - , mark_data["references"])) - - self._code_objects = [self._marks[c]["target"] if c in self._marks else c - for c in self._code_objects ] - - def bindump(self, file_): - # FIXME: - # Make this work for tons of data. - # Or is that necessary? - # TODO: - # Figure out whether/what improovements are necessary here - length = int16_2_bytes(len(self._code_objects)) - if(len(self._code_objects).bit_length() > 16): - raise ValueError("Program size excceeds 2^16.") - file_.write(length) - for word in self._code_objects: - file_.write(int16_2_bytes(word)) - - - def parse_mark(self, token): - should_be_colon = next(self._tokenizer) - - if(should_be_colon != ":"): - self.raise_unexpected_token(token, "':'", should_be_colon) - - should_be_newline = next(self._tokenizer) - if(should_be_newline != "\n"): - self.raise_unexpected_token(token + ":", "'\\n'", should_be_newline) - - if(token in self._marks): - if(self._marks[token]["target"] != -1): - raise ParsingError("Error in line {} column {} mark already defined: '{}'. Previous was in line {}.".format( - self._file_context._line - , self._column - , token - , self._marks[token]["target_line"])) - self._marks[token]["target"] = self._word_count - self._marks[token]["target_line"] = self._file_context._line - - else: - self._marks[token] = { - "target": self._word_count - , "target_line": self._file_context._line - , "references": [] - } - - - def parse_directive(self): - should_be_name = next(self._tokenizer) - - if(not should_be_name in self._directives): - self.raise_unexpected_token(".", "directive name", should_be_name) - - should_be_whitespace = next(self._tokenizer) - if(not should_be_whitespace in WHITESPACE): - self.raise_unexpected_token(should_be_name, "' '", should_be_whitespace) - - words = self._directives[should_be_name].parse(self, self._tokenizer) - - self._word_count += len(words) - self._code_objects.extend(words) - - should_be_newline = next(self._tokenizer) - if(should_be_newline != "\n"): - self.raise_unexpected_token(".", "newline", should_be_newline) - - - - - def parse_command(self, cmd): - # We have no arguments - if(not self._commands_by_mnemonic[cmd]["args"]): - self._code_objects.append(self._opcodes[cmd]) - self._word_count += 1 - token = next(self._tokenizer) - if(token != "\n"): - self.raise_unexpected_token(cmd, "newline", token) - return - - # Small argument must be treated separately - should_be_whitespace = next(self._tokenizer) - if(should_be_whitespace not in WHITESPACE - or should_be_whitespace == "\n"): - self.raise_unexpected_token(cmd, "' '", should_be_whitespace) - - should_be_an_argument = next(self._tokenizer) - argument = self.check_and_convert_argument(cmd - , should_be_an_argument - , self._commands_by_mnemonic[cmd]["args"][0]) - self._word_count += 1 - # NOTE: - # The Small Argument is stored within the first word (!) - self._code_objects.append(self._opcodes[cmd] | (argument & 0xffff)) - - - # All the 16bit arguments - for argument in self._commands_by_mnemonic[cmd]["args"][1:]: - should_be_comma = next(self._tokenizer) - if(should_be_comma != ","): - self.raise_unexpected_token(cmd, "','", should_be_comma) - - self._word_count += 1 - self._code_objects.append( - self.check_and_convert_argument( - cmd - , next(self._tokenizer) - , argument)) - - should_be_newline = next(self._tokenizer) - if(should_be_newline != "\n"): - self.raise_unexpected_token(cmd, "newline", should_be_newline) - - - def raise_unexpected_token(self, after, expected, got): - raise ParsingError("Error in line {} column {} after '{}': expected {}, got '{}'".format( - self._file_context._line - , self._file_context._column - , after - , expected - , got)) - - def raise_invalid_address(self, after, memtype, maxval, got): - raise ParsingError("Error in line {} column {} after '{}': value {} is invalid for {} (max is {})".format( - self._file_context._line - , self._file_context._column - , after - , got - , memtype - , maxval)) - - def check_and_convert_argument(self, cmd, argument, argument_definition): - if(argument_definition == "register"): - if(not argument.startswith("r")): - self.raise_unexpected_token(cmd, "register name", argument) - register_offset = argument[1:] - raise_could_not_convert_register_offset = False - try: - register_offset = int(register_offset) - except: - raise_could_not_convert_register_offset = True - - if(raise_could_not_convert_register_offset): - self.raise_unexpected_token(cmd, "register name", argument) - - if(register_offset > self._memory_definition["registers"] - or register_offset < 0): - self.raise_invalid_address(cmd - , "register" - , self._memory_definition["registers"] - , register_offset) - - return register_offset - - if(argument_definition == "memory"): - if(not can_convert_to_int(argument)): - self.raise_unexpected_token(cmd, "integer address", argument) - argument = autoint(argument) - - if(argument < 0 or argument > self._memory_definition["memory"]): - self.raise_invalid_address(cmd - , "memory" - , self._memory_definition["memory"] - , argument) - return argument - - if(argument_definition == "program_memory"): - # Non-integer Argument. - if(not can_convert_to_int(argument)): - # Just nonsense. - if(not can_be_mark(argument)): - self.raise_unexpected_token(cmd, "integer address or mark", argument) - # The Mark has appeared before. - if(argument in self._marks): - # Add this line to the references. - self._marks[argument]["references"].append(self._file_context._line) - # The target is already known. Insert it now. - if(self._marks[argument]["target"] != -1): - return self._marks[argument]["target"] - # The target is unknown. - return argument - # The Mark has not appeared before. - self._marks[argument] = { - "target": -1 - , "target_line": 0 - , "references": [self._file_context._line] - } - # Target is obviously unknown. - return argument - - - # Integer argument. - argument = autoint(argument) - - if(argument < 0 or argument > self._memory_definition["program_memory"]): - self.raise_invalid_address(cmd - , "program_memory" - , self._memory_definition["program_memory"] - , argument) - return argument - - # This is direct input (default). - - # Integer - if(can_convert_to_int(argument)): - return autoint(argument) - - # This is nonsense. - if(not can_be_mark(argument)): - self.raise_unexpected_token(cmd, "integer, char or mark", argument) - - # It is a Mark. - if(argument in self._marks): - if(self._marks[argument]["target"] >= 0): - self._marks[argument]["references"].append(self._file_context._line) - return self._marks[argument]["target"] - self._marks[argument]["references"].append(self._file_context._line) - return argument - - self._marks[argument] = { - "target": -1 - , "target_line": 0 - , "references": [self._file_context._line] - } - - return argument - diff --git a/assembler/assembler/context.py b/assembler/assembler/context.py deleted file mode 100644 index 3863a00..0000000 --- a/assembler/assembler/context.py +++ /dev/null @@ -1,28 +0,0 @@ -from collections import deque - -class FileContext(object): - def __init__(self, file_): - self._file = file_ - self._line = 0 - self._column = 0 - self._column_stack = deque() - - def getc(self): - c = self._file.read(1) - if(c == "\n"): - self._line += 1 - self._column_stack.append(self._column) - self._column = 0 - else: - self._column += 1 - - return c - - def ungetc(self, c): - self._file.seek(self._file.tell() - 1, 0) - if(c == "\n"): - self._line -= 1 - self._column = self._column_stack.pop() - else: - self._column -= 1 - diff --git a/assembler/assembler/directives.py b/assembler/assembler/directives.py deleted file mode 100644 index a03383d..0000000 --- a/assembler/assembler/directives.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -Directives for explicitly modifying the program memory. -""" - -from abc import ABC, abstractmethod -from collections import deque - -from .util import can_convert_to_int, autoint - -class AbstractDirective(ABC): - @abstractmethod - def parse(self, assembler, tokenizer): - """ - Parse the directive by converting the text to a list of words. - Returns a list of 16bit words. - """ - pass - - - -class SetDirective(AbstractDirective): - def parse(self, assembler, tokenizer): - words = deque() - should_be_bracket = next(tokenizer) - if(not should_be_bracket == "["): - assembler.raise_unexpected_token(".set", "'['", should_be_bracket) - - while(True): - should_be_value = next(tokenizer) - if(not can_convert_to_int(should_be_value)): - assembler.raise_unexpected_token(".set" - , "integer or character value" - , should_be_value) - words.append(autoint(should_be_value)) - - comma_or_bracket = next(tokenizer) - if(not comma_or_bracket in (",", "]")): - assembler.raise_unexpected_token(".set" - , "',' or ']'" - , comma_or_bracket) - - if(comma_or_bracket == "]"): - break - return list(words) diff --git a/assembler/assembler/opcodes.py b/assembler/assembler/opcodes.py deleted file mode 100644 index 15c9ba3..0000000 --- a/assembler/assembler/opcodes.py +++ /dev/null @@ -1,33 +0,0 @@ - - -class Autoinserter(object): - def __init__(self): - self.mayor = 2 - self.minor = 1 - def __next__(self): - """Generate the next opcode""" - # 10bit opcode - opcode = 0b1111111111 - - # Calculate this opcode. - opcode *= self.minor - opcode //= self.mayor - - # The lower 6 bits are reserved. - opcode <<= 6 - # 16 bits in total. Should not matter. - opcode &= 0xffff - - # Update the state. - self.minor = (self.minor + 2) % self.mayor - if(self.minor == 1): - self.mayor *= 2 - - return opcode - def __iter__(self): - return self - -def make_opcodes(mnemonics_in_order): - - ai = Autoinserter() - return {mnemonic: opcode for (mnemonic, opcode) in zip(mnemonics_in_order, ai)} diff --git a/assembler/assembler/tokenize.py b/assembler/assembler/tokenize.py deleted file mode 100644 index 71be23f..0000000 --- a/assembler/assembler/tokenize.py +++ /dev/null @@ -1,55 +0,0 @@ -from collections import deque - -WHITESPACE = {" ", "\t", "\n", "\r"} -TOKENS_END_OF_WORD = WHITESPACE | {";", ":", ",", ".", "[", "]"} - -TOKENS_EXPECT_NEWLINE = {":", "]"} - - -class Tokenizer(object): - def __init__(self, context): - self._context = context - self._expect_newline = False - self._expect_whitespace = False - - def __iter__(self): - return self - def __next__(self): - """ - Return the next token. - """ - - current_token = deque() - - while(True): - c = self._context.getc() - - # Sometimes we need the explicit newline. - if(self._expect_newline and c == "\n"): - self._expect_newline = False - return c - - # Skip multiple whitespaces. - if(c in WHITESPACE and not current_token): - if(self._expect_whitespace): - self._expect_whitespace = False - return c - continue - - if(c in TOKENS_END_OF_WORD): - if(current_token): - self._context.ungetc(c) - if(c in WHITESPACE): - self._expect_whitespace = True - return "".join(current_token) - else: - if(c in TOKENS_EXPECT_NEWLINE): - self._expect_newline = True - return c - - if(not c): - raise StopIteration() - - current_token.append(c) - - diff --git a/assembler/assembler/util.py b/assembler/assembler/util.py deleted file mode 100644 index e5d4630..0000000 --- a/assembler/assembler/util.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -Utility functions used for parsing. -""" -import struct - - -def can_be_mark(argument): - """ - The ``argument`` can be interpreted as a Mark. - """ - a = ord("a") - a_z = [chr(a + i) for i in range(26)] - A = ord("A") - A_Z = [chr(A + i) for i in range(26)] - null = ord("0") - null_9 = [chr(null + i) for i in range(10)] - - if(not argument[0] in a_z): - return False - - for char in argument[1:]: - if(not (char in a_z - or char in A_Z - or char in null_9 - or char == "_")): - return False - return True - - - -def can_convert_to_int(value): - """ - ``value`` can be converted to an integer. - - **Note** that this returns ``True`` if the value is a - character definition like ``'a'``. - """ - if(value.startswith("0x")): - try: - int(value[2:], 16) - return True - except: - return False - - if(value.startswith("0b")): - try: - int(value[2:], 2) - return True - except: - return False - - if(value.startswith("'") and value.endswith("'")): - if(len(value) == 3): - return True - if(len(value) == 4): - if(value[1:-1] in {"\\n", "\\r", "\\t"}): - return True - return False - - try: - int(value) - return True - except: - return False - -def autoint(value): - """ - Convert ``value`` to an integer automatically. - """ - escape_sequences = {"\\n": "\n", "\\r": "\r", "\\t":"\t"} - if(value.startswith("0x")): - return int(value[2:], 16) - - if(value.startswith("0b")): - return int(value[2:], 2) - - if(value.startswith("'") and value.endswith("'")): - if(len(value) == 3): - return ord(value[1:-1]) - if(len(value) == 4): - if(value[1:-1] in escape_sequences): - return ord(escape_sequences[value[1:-1]]) - - return int(value) - - -def int16_2_bytes(value): - """ - Return the bytes representation of a 16bit unsigned - integer in 8bit words. - """ - if(value < 0): - return struct.pack("> -endobj -2 0 obj -<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >> -endobj -3 0 obj -<< /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >> -endobj -4 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 13 0 R /XYZ 62.69291 636.0236 0 ] /Rect [ 62.69291 687.0236 178.2829 699.0236 ] /Subtype /Link /Type /Annot >> -endobj -5 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 13 0 R /XYZ 62.69291 636.0236 0 ] /Rect [ 527.0227 687.7736 532.5827 699.7736 ] /Subtype /Link /Type /Annot >> -endobj -6 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 13 0 R /XYZ 62.69291 525.0236 0 ] /Rect [ 62.69291 669.0236 197.7229 681.0236 ] /Subtype /Link /Type /Annot >> -endobj -7 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 13 0 R /XYZ 62.69291 525.0236 0 ] /Rect [ 527.0227 669.7736 532.5827 681.7736 ] /Subtype /Link /Type /Annot >> -endobj -8 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 13 0 R /XYZ 62.69291 414.0236 0 ] /Rect [ 62.69291 651.0236 213.8229 663.0236 ] /Subtype /Link /Type /Annot >> -endobj -9 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 13 0 R /XYZ 62.69291 414.0236 0 ] /Rect [ 527.0227 651.7736 532.5827 663.7736 ] /Subtype /Link /Type /Annot >> -endobj -10 0 obj -<< /BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font >> -endobj -11 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 13 0 R /XYZ 62.69291 528.5236 0 ] /Rect [ 515.3527 333.0236 532.1177 345.0236 ] /Subtype /Link /Type /Annot >> -endobj -12 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 13 0 R /XYZ 62.69291 528.5236 0 ] /Rect [ 62.69291 321.0236 168.2829 333.0236 ] /Subtype /Link /Type /Annot >> -endobj -13 0 obj -<< /Annots [ 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 11 0 R 12 0 R ] /Contents 21 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 20 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -14 0 obj -<< /Outlines 16 0 R /PageLabels 22 0 R /PageMode /UseNone /Pages 20 0 R /Type /Catalog >> -endobj -15 0 obj -<< /Author () /CreationDate (D:20181006214730+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20181006214730+00'00') /Producer (ReportLab PDF Library - www.reportlab.com) - /Subject (\(unspecified\)) /Title (BCI Bytecode) /Trapped /False >> -endobj -16 0 obj -<< /Count 3 /First 17 0 R /Last 19 0 R /Type /Outlines >> -endobj -17 0 obj -<< /Dest [ 13 0 R /XYZ 62.69291 636.0236 0 ] /Next 18 0 R /Parent 16 0 R /Title (Assembly and Bytecode) >> -endobj -18 0 obj -<< /Dest [ 13 0 R /XYZ 62.69291 525.0236 0 ] /Next 19 0 R /Parent 16 0 R /Prev 17 0 R /Title (The Dynamic Instruction Set) >> -endobj -19 0 obj -<< /Dest [ 13 0 R /XYZ 62.69291 414.0236 0 ] /Parent 16 0 R /Prev 18 0 R /Title (Byte Code Interpreter Definition) >> -endobj -20 0 obj -<< /Count 1 /Kids [ 13 0 R ] /Type /Pages >> -endobj -21 0 obj -<< /Length 3790 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 741.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 4 Tm /F2 20 Tf 24 TL 169.9349 0 Td (BCI Bytecode) Tj T* -169.9349 0 Td ET -Q -Q -q -1 0 0 1 62.69291 708.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Contents) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 648.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 0 39 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Assembly and Bytecode) Tj T* ET -Q -Q -q -1 0 0 1 397.8898 39 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (1) Tj T* -66.44 0 Td ET -Q -Q -q -1 0 0 1 0 21 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (The Dynamic Instruction Set) Tj T* ET -Q -Q -q -1 0 0 1 397.8898 21 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (1) Tj T* -66.44 0 Td ET -Q -Q -q -1 0 0 1 0 3 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Byte Code Interpreter Definition) Tj T* ET -Q -Q -q -1 0 0 1 397.8898 3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (1) Tj T* -66.44 0 Td ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 615.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Assembly and Bytecode) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 585.0236 cm -q -BT 1 0 0 1 0 14 Tm 3.309982 Tw 12 TL /F1 10 Tf 0 0 0 rg (Unlike machine code \(and other bytecode\) BCI bytecode has dynamic opcodes. This means that) Tj T* 0 Tw (bytecode is ) Tj /F2 10 Tf (not ) Tj /F1 10 Tf (necessarily portable.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 567.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (This makes sense since the BCI instruction set can be extended for applications.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 537.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .742619 Tw (If one wants to share code that should run on any BCI it should be shared as assembly. The assembler) Tj T* 0 Tw (will then use the local interpreter definition and generate suiting bytecode.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 504.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (The Dynamic Instruction Set) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 474.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.093876 Tw (The BCI comes with a set of prepared instructions. These are complete and provide a way to do basic) Tj T* 0 Tw (operations like routines, loops and branching.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 444.0236 cm -q -BT 1 0 0 1 0 14 Tm .743672 Tw 12 TL /F1 10 Tf 0 0 0 rg (The methods are organized in a binary tree internally. To build the tree in a comfortable way there is an) Tj T* 0 Tw (autoinserter that can insert up to ) Tj /F3 10 Tf 0 0 0 rg (1023 ) Tj /F1 10 Tf 0 0 0 rg (methods into the tree.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 426.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The autoinserter creates the opcode basing on the order of the method that he inserts.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 393.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Byte Code Interpreter Definition) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 351.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL 1.843555 Tw (A Bytecode Interpreter Definition consists of two mayor parts: The memory definition that defines the) Tj T* 0 Tw 1.896098 Tw (number of data registers \(up to 63\), the number of memory words \(up to 65535\) and the number of) Tj T* 0 Tw (program memory words \(up to 65535\).) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 321.0236 cm -q -BT 1 0 0 1 0 14 Tm .464985 Tw 12 TL /F1 10 Tf 0 0 0 rg (The second part defines the commands. The definition contains bot the order of the commands \(see ) Tj 0 0 .501961 rg (The) Tj T* 0 Tw (Dynamic Instruction Set) Tj 0 0 0 rg (\) and the required arguments.) Tj T* ET -Q -Q - -endstream -endobj -22 0 obj -<< /Nums [ 0 23 0 R ] >> -endobj -23 0 obj -<< /S /D /St 1 >> -endobj -xref -0 24 -0000000000 65535 f -0000000075 00000 n -0000000130 00000 n -0000000240 00000 n -0000000355 00000 n -0000000526 00000 n -0000000697 00000 n -0000000868 00000 n -0000001039 00000 n -0000001210 00000 n -0000001381 00000 n -0000001490 00000 n -0000001662 00000 n -0000001834 00000 n -0000002106 00000 n -0000002215 00000 n -0000002489 00000 n -0000002566 00000 n -0000002692 00000 n -0000002837 00000 n -0000002974 00000 n -0000003038 00000 n -0000006885 00000 n -0000006929 00000 n -trailer -<< /ID - % ReportLab generated PDF document -- digest (http://www.reportlab.com) - [(\003\236V\37247z\240'\2312!\276\204\362\214) (\003\236V\37247z\240'\2312!\276\204\362\214)] - /Info 15 0 R /Root 14 0 R /Size 24 >> -startxref -6966 -%%EOF diff --git a/assembler/bytecode.rst b/assembler/bytecode.rst deleted file mode 100644 index ea2f634..0000000 --- a/assembler/bytecode.rst +++ /dev/null @@ -1,46 +0,0 @@ -BCI Bytecode -************* - -.. contents:: - -Assembly and Bytecode -===================== - -Unlike machine code (and other bytecode) BCI bytecode has -dynamic opcodes. This means that bytecode is **not** -necessarily portable. - -This makes sense since the BCI instruction set can be -extended for applications. - -If one wants to share code that should run on any BCI it -should be shared as assembly. The assembler will then use -the local interpreter definition and generate suiting -bytecode. - -The Dynamic Instruction Set -=========================== - -The BCI comes with a set of prepared instructions. These are -complete and provide a way to do basic operations like -routines, loops and branching. - -The methods are organized in a binary tree internally. To -build the tree in a comfortable way there is an autoinserter -that can insert up to ``1023`` methods into the tree. - -The autoinserter creates the opcode basing on the order of -the method that he inserts. - -Byte Code Interpreter Definition -================================ - -A Bytecode Interpreter Definition consists of two mayor -parts: The memory definition that defines the number of data -registers (up to 63), the number of memory words (up to -65535) and the number of program memory words (up to 65535). - -The second part defines the commands. The definition -contains bot the order of the commands (see `The Dynamic -Instruction Set`_) and the required arguments. - diff --git a/assembler/language.pdf b/assembler/language.pdf deleted file mode 100644 index 0c9f798..0000000 --- a/assembler/language.pdf +++ /dev/null @@ -1,881 +0,0 @@ -%PDF-1.4 -%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com -1 0 obj -<< /F1 2 0 R /F2 3 0 R /F3 14 0 R >> -endobj -2 0 obj -<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >> -endobj -3 0 obj -<< /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >> -endobj -4 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 15 0 R /XYZ 62.69291 600.0236 0 ] /Rect [ 62.69291 687.0236 299.9529 699.0236 ] /Subtype /Link /Type /Annot >> -endobj -5 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 15 0 R /XYZ 62.69291 600.0236 0 ] /Rect [ 527.0227 687.7736 532.5827 699.7736 ] /Subtype /Link /Type /Annot >> -endobj -6 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 15 0 R /XYZ 62.69291 224.2236 0 ] /Rect [ 62.69291 669.0236 154.3629 681.0236 ] /Subtype /Link /Type /Annot >> -endobj -7 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 15 0 R /XYZ 62.69291 224.2236 0 ] /Rect [ 527.0227 669.7736 532.5827 681.7736 ] /Subtype /Link /Type /Annot >> -endobj -8 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 16 0 R /XYZ 62.69291 380.0236 0 ] /Rect [ 62.69291 651.0236 114.3629 663.0236 ] /Subtype /Link /Type /Annot >> -endobj -9 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 16 0 R /XYZ 62.69291 380.0236 0 ] /Rect [ 527.0227 651.7736 532.5827 663.7736 ] /Subtype /Link /Type /Annot >> -endobj -10 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 16 0 R /XYZ 62.69291 329.0236 0 ] /Rect [ 62.69291 633.0236 91.59291 645.0236 ] /Subtype /Link /Type /Annot >> -endobj -11 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 16 0 R /XYZ 62.69291 329.0236 0 ] /Rect [ 527.0227 633.7736 532.5827 645.7736 ] /Subtype /Link /Type /Annot >> -endobj -12 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /XYZ 62.69291 765.0236 0 ] /Rect [ 62.69291 615.0236 118.2529 627.0236 ] /Subtype /Link /Type /Annot >> -endobj -13 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 18 0 R /XYZ 62.69291 765.0236 0 ] /Rect [ 527.0227 615.7736 532.5827 627.7736 ] /Subtype /Link /Type /Annot >> -endobj -14 0 obj -<< /BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font >> -endobj -15 0 obj -<< /Annots [ 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R ] /Contents 28 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 27 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -16 0 obj -<< /Contents 29 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 27 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >> - /Type /Page >> -endobj -17 0 obj -<< /Border [ 0 0 0 ] /Contents () /Dest [ 16 0 R /XYZ 62.69291 332.5236 0 ] /Rect [ 62.69291 680.7736 91.59291 692.7736 ] /Subtype /Link /Type /Annot >> -endobj -18 0 obj -<< /Annots [ 17 0 R ] /Contents 30 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 27 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 - /Trans << >> /Type /Page >> -endobj -19 0 obj -<< /Outlines 21 0 R /PageLabels 31 0 R /PageMode /UseNone /Pages 27 0 R /Type /Catalog >> -endobj -20 0 obj -<< /Author () /CreationDate (D:20181006214702+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20181006214702+00'00') /Producer (ReportLab PDF Library - www.reportlab.com) - /Subject (\(unspecified\)) /Title (BCI Assembly Language) /Trapped /False >> -endobj -21 0 obj -<< /Count 5 /First 22 0 R /Last 26 0 R /Type /Outlines >> -endobj -22 0 obj -<< /Dest [ 15 0 R /XYZ 62.69291 600.0236 0 ] /Next 23 0 R /Parent 21 0 R /Title (Commands, Small Arguments and Big Arguments) >> -endobj -23 0 obj -<< /Dest [ 15 0 R /XYZ 62.69291 224.2236 0 ] /Next 24 0 R /Parent 21 0 R /Prev 22 0 R /Title (Built-In Commands) >> -endobj -24 0 obj -<< /Dest [ 16 0 R /XYZ 62.69291 380.0236 0 ] /Next 25 0 R /Parent 21 0 R /Prev 23 0 R /Title (Comments) >> -endobj -25 0 obj -<< /Dest [ 16 0 R /XYZ 62.69291 329.0236 0 ] /Next 26 0 R /Parent 21 0 R /Prev 24 0 R /Title (Marks) >> -endobj -26 0 obj -<< /Dest [ 18 0 R /XYZ 62.69291 765.0236 0 ] /Parent 21 0 R /Prev 25 0 R /Title (Direct Input) >> -endobj -27 0 obj -<< /Count 3 /Kids [ 15 0 R 16 0 R 18 0 R ] /Type /Pages >> -endobj -28 0 obj -<< /Length 6815 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 741.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 4 Tm /F2 20 Tf 24 TL 117.6949 0 Td (BCI Assembly Language) Tj T* -117.6949 0 Td ET -Q -Q -q -1 0 0 1 62.69291 708.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Contents) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 612.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -q -1 0 0 1 0 75 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Commands, Small Arguments and Big Arguments) Tj T* ET -Q -Q -q -1 0 0 1 397.8898 75 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (1) Tj T* -66.44 0 Td ET -Q -Q -q -1 0 0 1 0 57 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Built-In Commands) Tj T* ET -Q -Q -q -1 0 0 1 397.8898 57 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (1) Tj T* -66.44 0 Td ET -Q -Q -q -1 0 0 1 0 39 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Comments) Tj T* ET -Q -Q -q -1 0 0 1 397.8898 39 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (2) Tj T* -66.44 0 Td ET -Q -Q -q -1 0 0 1 0 21 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Marks) Tj T* ET -Q -Q -q -1 0 0 1 397.8898 21 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (2) Tj T* -66.44 0 Td ET -Q -Q -q -1 0 0 1 0 3 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F2 10 Tf 0 0 .501961 rg (Direct Input) Tj T* ET -Q -Q -q -1 0 0 1 397.8898 3 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL 66.44 0 Td (3) Tj T* -66.44 0 Td ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 579.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Commands, Small Arguments and Big Arguments) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 549.0236 cm -q -BT 1 0 0 1 0 14 Tm .87311 Tw 12 TL /F1 10 Tf 0 0 0 rg (A command in BCI Assembly is a word starting with an alphabetic character \() Tj /F3 10 Tf 0 0 0 rg (a..zA..Z) Tj /F1 10 Tf 0 0 0 rg (\) following by a) Tj T* 0 Tw (sequence of alphanumeric characters \() Tj /F3 10 Tf 0 0 0 rg (a..zA..Z0..9) Tj /F1 10 Tf 0 0 0 rg (\). This word will be converted to a 10bit opcode.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 519.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.147882 Tw (Embedded in the 16bits of a word there is also a 6bit small argument. If a command has no small) Tj T* 0 Tw (argument these bits will be zeroed. In the assembly the command will be only one word, for example:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 485.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (cli) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 453.8236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .345988 Tw (If the command has a small argument, the 6 bit will be filled with the small argument. In the assembly the) Tj T* 0 Tw (small argument is separated by one whitespace, for example:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 420.6236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (inc r0) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 376.6236 cm -q -BT 1 0 0 1 0 26 Tm .629431 Tw 12 TL /F1 10 Tf 0 0 0 rg (Any other arguments are stored in further words and have thus a width of 16bits. They are separated by) Tj T* 0 Tw 2.211751 Tw (commas \() Tj /F3 10 Tf 0 0 0 rg (,) Tj /F1 10 Tf 0 0 0 rg (\) from both the first and any other arguments. It is recommended to only add one more) Tj T* 0 Tw (argument.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 358.6236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Example for one big argument:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 325.4236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 24 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (ldi r0, 0xdead) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 293.4236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.571318 Tw (It might be useful to have more arguments for other applications, like double precision floating points.) Tj T* 0 Tw (Example \(not implemented\):) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 236.2236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 48 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 26 Tm /F3 10 Tf 12 TL (lddfi r0, 0xdead, 0xbeef) Tj T* (; load double precision floating point) Tj T* (; to r0 and r1) Tj T* ET -Q -Q -Q -Q -Q -q -1 0 0 1 62.69291 203.2236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Built-In Commands) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 185.2236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (ldi) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj (,) Tj ( ) Tj (<) Tj (ba) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 170.2236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Load the value ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (ba) Tj (> ) Tj /F1 10 Tf 0 0 0 rg (into register ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (>) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 154.2236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (ld) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj (,) Tj ( ) Tj (<) Tj (ba) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 139.2236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Load the value of the memory cell at ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (ba) Tj (> ) Tj /F1 10 Tf 0 0 0 rg (into register ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (>) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 123.2236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (st) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj (,) Tj ( ) Tj (<) Tj (ba) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 108.2236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Store the value of register ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (> ) Tj /F1 10 Tf 0 0 0 rg (into the memory cell at ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (ba) Tj (>) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 92.22362 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (inc) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 77.22362 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Increment the value of register ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (>) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q - -endstream -endobj -29 0 obj -<< /Length 7261 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 753.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (dec) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 738.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Decrement the value of register ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (>) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 722.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (add|sub|mul|div) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj (,) Tj ( ) Tj (<) Tj (ba) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 695.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 14 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 14 Tm 1.127318 Tw 12 TL /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (>) Tj ( ) Tj (=) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj ( ) Tj (+|-|*|/) Tj ( ) Tj (<) Tj (ba) Tj (> ) Tj /F1 10 Tf 0 0 0 rg (where ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (> ) Tj /F1 10 Tf 0 0 0 rg (and ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (ba) Tj (> ) Tj /F1 10 Tf 0 0 0 rg (are registers. Write the overflow into the) Tj T* 0 Tw (status register.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 679.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (gt|ge|lt|le|eq) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 652.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 14 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 14 Tm 2.431098 Tw 12 TL /F1 10 Tf 0 0 0 rg (Check if the value of register ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (> ) Tj /F1 10 Tf 0 0 0 rg (is ) Tj /F3 10 Tf 0 0 0 rg (>) Tj (|) Tj (>) Tj (=|) Tj (<) Tj (|) Tj (<) Tj (=|== ) Tj /F1 10 Tf 0 0 0 rg (to ) Tj /F3 10 Tf 0 0 0 rg (0) Tj /F1 10 Tf 0 0 0 rg (. Set the status register to ) Tj /F3 10 Tf 0 0 0 rg (1 ) Tj /F1 10 Tf 0 0 0 rg (if it) Tj T* 0 Tw (evaluates true, else to ) Tj /F3 10 Tf 0 0 0 rg (0) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 636.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (not) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 621.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If the status register is ) Tj /F3 10 Tf 0 0 0 rg (0 ) Tj /F1 10 Tf 0 0 0 rg (set it to ) Tj /F3 10 Tf 0 0 0 rg (1) Tj /F1 10 Tf 0 0 0 rg (, else set it to ) Tj /F3 10 Tf 0 0 0 rg (0) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 605.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (jmp) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 590.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Set the program counter to the value of register ) Tj /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (>) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 574.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (call) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 547.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 14 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 14 Tm .797633 Tw 12 TL /F1 10 Tf 0 0 0 rg (Push the current program counter on the stack and set the program counter to the value of register) Tj T* 0 Tw /F3 10 Tf 0 0 0 rg (<) Tj (sa) Tj (>) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 531.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (ret) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 516.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Pop the previously pushed program counter from the stack.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 500.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (stop) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 485.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Write ) Tj /F3 10 Tf 0 0 0 rg (1 ) Tj /F1 10 Tf 0 0 0 rg (into the shutdown register. This will cause the interpreter to halt.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 469.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F3 10 Tf 12 TL (cl) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 454.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Write ) Tj /F3 10 Tf 0 0 0 rg (0 ) Tj /F1 10 Tf 0 0 0 rg (into the status register.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 438.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (cjmp) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 423.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If there not a ) Tj /F3 10 Tf 0 0 0 rg (0 ) Tj /F1 10 Tf 0 0 0 rg (in the status register, ) Tj /F3 10 Tf 0 0 0 rg (jmp <) Tj (sa) Tj (>) Tj /F1 10 Tf 0 0 0 rg (, else continue execution.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 407.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F3 10 Tf 0 0 0 rg (ccall) Tj ( ) Tj (<) Tj (sa) Tj (>) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 392.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Like ) Tj /F3 10 Tf 0 0 0 rg (cjmp) Tj ( ) Tj (<) Tj (sa) Tj (> ) Tj /F1 10 Tf 0 0 0 rg (but with ) Tj /F3 10 Tf 0 0 0 rg (call ) Tj /F1 10 Tf 0 0 0 rg (instead.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 359.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Comments) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 341.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Comments start with a ) Tj /F3 10 Tf 0 0 0 rg (; ) Tj /F1 10 Tf 0 0 0 rg (at the beginning of the line and end at the end of the line.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 308.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Marks) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 278.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .467485 Tw (Marks represent a special location of the assembly code. The assembler keeps track of those marks and) Tj T* 0 Tw (they can be used as immediate input.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 236.0236 cm -q -BT 1 0 0 1 0 26 Tm 2.869983 Tw 12 TL /F1 10 Tf 0 0 0 rg (A mark is defined by a single word, starting with an alphabetic character \() Tj /F3 10 Tf 0 0 0 rg (a..zA...Z) Tj /F1 10 Tf 0 0 0 rg (\) containing) Tj T* 0 Tw 2.330814 Tw (alphanumeric characters and underscores \() Tj /F3 10 Tf 0 0 0 rg (a..zA..Z0..9_) Tj /F1 10 Tf 0 0 0 rg (\) followed by a colon \() Tj /F3 10 Tf 0 0 0 rg (:) Tj /F1 10 Tf 0 0 0 rg (\) and a newline) Tj T* 0 Tw (character.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 218.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Example:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 100.8236 cm -q -q -1 0 0 1 0 0 cm -q -1 0 0 1 6.6 6.6 cm -q -.662745 .662745 .662745 RG -.5 w -.960784 .960784 .862745 rg -n -6 -6 468.6898 108 re B* -Q -q -0 0 0 rg -BT 1 0 0 1 0 86 Tm /F3 10 Tf 12 TL (ldi r0, this_is_a_mark) Tj T* (ldi r1, 0xfefe) Tj T* (ldi r2, 0xefef) Tj T* T* (this_is_a_mark:) Tj T* (add r2, r1) Tj T* (; this will result in an infinite loop.) Tj T* (jmp r0) Tj T* ET -Q -Q -Q -Q -Q - -endstream -endobj -30 0 obj -<< /Length 2972 >> -stream -1 0 0 1 0 0 cm BT /F1 12 Tf 14.4 TL ET -q -1 0 0 1 62.69291 744.0236 cm -q -BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Direct Input) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 726.0236 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The core instruction set contains the ) Tj /F3 10 Tf 0 0 0 rg (ldi ) Tj /F1 10 Tf 0 0 0 rg (command that can be used to load data into a register directly.) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 696.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 2.501318 Tw (The first \(big\) argument of this command is always a 16bit word. The assembler can automatically) Tj T* 0 Tw (generate the correct value if the argument is provided in the following ways:) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 680.0236 cm -q -0 0 .501961 rg -0 0 .501961 RG -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (Marks) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 665.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The assembler inserts the absolute offset of the Mark.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 649.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (A decimal value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 634.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (The assembler inserts the value \(i.e. ) Tj /F3 10 Tf 0 0 0 rg (ldi) Tj ( ) Tj (r0, 12) Tj /F1 10 Tf 0 0 0 rg (\).) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 618.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (A hexadecimal value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 603.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If the argument starts with ) Tj /F3 10 Tf 0 0 0 rg (0x ) Tj /F1 10 Tf 0 0 0 rg (the assembler will interpret the argument as hexadecimal.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 587.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (A binary value) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 572.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 2 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (If the argument starts with ) Tj /F3 10 Tf 0 0 0 rg (0b ) Tj /F1 10 Tf 0 0 0 rg (the assembler will interpret the value as binary.) Tj T* ET -Q -Q -q -Q -Q -q -1 0 0 1 62.69291 556.0236 cm -q -0 0 0 rg -BT 1 0 0 1 0 2 Tm /F2 10 Tf 12 TL (A character) Tj T* ET -Q -Q -q -1 0 0 1 62.69291 529.0236 cm -0 0 0 rg -BT /F1 10 Tf 12 TL ET -BT 1 0 0 1 0 14 Tm T* ET -q -1 0 0 1 20 0 cm -q -BT 1 0 0 1 0 14 Tm .82811 Tw 12 TL /F1 10 Tf 0 0 0 rg (If the argument is either a single character surrounded by two ) Tj /F3 10 Tf 0 0 0 rg (' ) Tj /F1 10 Tf 0 0 0 rg (characters or any unicode escape) Tj T* 0 Tw (sequence surrounded by ) Tj /F3 10 Tf 0 0 0 rg (' ) Tj /F1 10 Tf 0 0 0 rg (characters the assembler will insert the integer representation.) Tj T* ET -Q -Q -q -Q -Q - -endstream -endobj -31 0 obj -<< /Nums [ 0 32 0 R 1 33 0 R 2 34 0 R ] >> -endobj -32 0 obj -<< /S /D /St 1 >> -endobj -33 0 obj -<< /S /D /St 2 >> -endobj -34 0 obj -<< /S /D /St 3 >> -endobj -xref -0 35 -0000000000 65535 f -0000000075 00000 n -0000000130 00000 n -0000000240 00000 n -0000000355 00000 n -0000000526 00000 n -0000000697 00000 n -0000000868 00000 n -0000001039 00000 n -0000001210 00000 n -0000001381 00000 n -0000001553 00000 n -0000001725 00000 n -0000001897 00000 n -0000002069 00000 n -0000002178 00000 n -0000002464 00000 n -0000002674 00000 n -0000002846 00000 n -0000003075 00000 n -0000003184 00000 n -0000003467 00000 n -0000003544 00000 n -0000003692 00000 n -0000003827 00000 n -0000003953 00000 n -0000004076 00000 n -0000004193 00000 n -0000004271 00000 n -0000011143 00000 n -0000018461 00000 n -0000021490 00000 n -0000021552 00000 n -0000021589 00000 n -0000021626 00000 n -trailer -<< /ID - % ReportLab generated PDF document -- digest (http://www.reportlab.com) - [(\372\(\217\316\222\3169q\222\376\355\325c1\302>) (\372\(\217\316\222\3169q\222\376\355\325c1\302>)] - /Info 20 0 R /Root 19 0 R /Size 35 >> -startxref -21663 -%%EOF diff --git a/assembler/language.rst b/assembler/language.rst deleted file mode 100644 index c7f53b5..0000000 --- a/assembler/language.rst +++ /dev/null @@ -1,180 +0,0 @@ -BCI Assembly Language -********************* - -.. contents:: - -Commands, Small Arguments and Big Arguments -=========================================== - -A command in BCI Assembly is a word starting with an -alphabetic character (``a..zA..Z``) following by a sequence -of alphanumeric characters (``a..zA..Z0..9``). -This word will be converted to a 10bit opcode. - -Embedded in the 16bits of a word there is also a 6bit small -argument. If a command has no small argument these bits will -be zeroed. In the assembly the command will be only one -word, for example:: - - cli - -If the command has a small argument, the 6 bit will be -filled with the small argument. In the assembly the small -argument is separated by one whitespace, for example:: - - inc r0 - -Any other arguments are stored in further words and have -thus a width of 16bits. They are separated by commas (``,``) -from both the first and any other arguments. -It is recommended to only add one more argument. - -Example for one big argument:: - - ldi r0, 0xdead - -It might be useful to have more arguments for other -applications, like double precision floating points. -Example (not implemented):: - - lddfi r0, r1, 0xdead, 0xbeef - ; load double precision floating point - ; to r0 and r1 - -Register Names -============== - -Only data registers can be accessed directly. They are -prefixed with a ``r`` and are indexed starting with ``0``. - -Examples: ``r0, r1, r2, ..., r11, r12`` - - -Built-In Commands -================= - -``ldi , `` - Load the value ```` into register ````. - -``ld , `` - Load the value of the memory cell at ```` into - register ````. - -``st , `` - Store the value of register ```` into the memory - cell at ````. - -``inc `` - Increment the value of register ````. - -``dec `` - Decrement the value of register ````. - -``add|sub|mul|div , `` - `` = +|-|*|/ `` where ```` and - ```` are registers. Write the overflow into the - status register. - -``gt|ge|lt|le|eq `` - Check if the value of register ```` is - ``>|>=|<|<=|==`` to ``0``. Set the status register - to ``1`` if it evaluates true, else to ``0``. - -``not`` - If the status register is ``0`` set it to ``1``, - else set it to ``0``. - -``jmp `` - Set the program counter to the value of register - ````. - -``call `` - Push the current program counter on the stack and - set the program counter to the value of register ````. - -``ret`` - Pop the previously pushed program counter from the stack. - -``stop`` - Write ``1`` into the shutdown register. This will - cause the interpreter to halt. -``cl`` - Write ``0`` into the status register. - -``cjmp `` - If there not a ``0`` in the status register, ``jmp - ``, else continue execution. - -``ccall `` - Like ``cjmp `` but with ``call`` instead. - -Comments -======== - -Comments start with a ``;`` at the beginning of the line and -end at the end of the line. - -Marks -===== - -Marks represent a special location of the assembly code. The -assembler keeps track of those marks and they can be used as -immediate input. - -A mark is defined by a single word, starting with an -alphabetic character (``a..zA...Z``) containing alphanumeric -characters and underscores (``a..zA..Z0..9_``) followed by -a colon (``:``) and a newline character. - -Example:: - - ldi r0, this_is_a_mark - ldi r1, 0xfefe - ldi r2, 0xefef - - this_is_a_mark: - add r2, r1 - ; this will result in an infinite loop. - jmp r0 - - -Direct Input -============ - -The core instruction set contains the ``ldi`` command that -can be used to load data into a register directly. - -The first (big) argument of this command is always a 16bit -word. The assembler can automatically generate the correct -value if the argument is provided in the following ways: - -`Marks`_ - The assembler inserts the absolute offset of the - Mark. -A decimal value - The assembler inserts the value (i.e. ``ldi r0, - 12``). -A hexadecimal value - If the argument starts with ``0x`` the assembler - will interpret the argument as hexadecimal. -A binary value - If the argument starts with ``0b`` the assembler - will interpret the value as binary. -A character - If the argument is either a single character - surrounded by two ``'`` characters or any unicode - escape sequence surrounded by ``'`` characters the - assembler will insert the integer representation. - -Explicit Data Programming -========================= - -One can explicitly set data in the program memory by using -the ``.set`` directive. It uses the following semantics:: - - ".set" "[" {,} "]" - -Where ```` is a `Direct Input`_ value. The assembler -will insert the data at exactly the location where the -``.set`` appears. The assembler ignores any whitespace or -newline characters between the brackets ``[]``. diff --git a/assembler/test/conftest.py b/assembler/test/conftest.py deleted file mode 100644 index 9825dfd..0000000 --- a/assembler/test/conftest.py +++ /dev/null @@ -1,101 +0,0 @@ -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/assembler/test/test_010_filecontext.py b/assembler/test/test_010_filecontext.py deleted file mode 100644 index e8340a4..0000000 --- a/assembler/test/test_010_filecontext.py +++ /dev/null @@ -1,24 +0,0 @@ -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/assembler/test/test_011_tokenize.py b/assembler/test/test_011_tokenize.py deleted file mode 100644 index 590d13f..0000000 --- a/assembler/test/test_011_tokenize.py +++ /dev/null @@ -1,71 +0,0 @@ -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" - ] - -def test_tokenize_4(): - data = ''' - ldi r0, 0xfefe - test_mark: - ldi r1, 0xefef - ''' - data = StringIO(data) - tokenizer = Tokenizer(FileContext(data)) - - result = list(tokenizer) - - assert result == [ - "ldi", " ", "r0", ",", "0xfefe", "\n" - , "test_mark", ":", "\n" - , "ldi", " ", "r1", ",", "0xefef", "\n" - ] diff --git a/assembler/test/test_012_opcodes.py b/assembler/test/test_012_opcodes.py deleted file mode 100644 index 2b7ba68..0000000 --- a/assembler/test/test_012_opcodes.py +++ /dev/null @@ -1,14 +0,0 @@ -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/assembler/test/test_013_util.py b/assembler/test/test_013_util.py deleted file mode 100644 index 6c316bc..0000000 --- a/assembler/test/test_013_util.py +++ /dev/null @@ -1,40 +0,0 @@ -from assembler.util import can_be_mark, can_convert_to_int, autoint, int16_2_bytes - - -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") - -def test_int16_2_bytes(): - assert int16_2_bytes(2) == b"\x02\00" - assert int16_2_bytes(0x0200) == b"\x00\x02" - assert int16_2_bytes(-1) == b"\xff\xff" diff --git a/assembler/test/test_020_basic_parsing.py b/assembler/test/test_020_basic_parsing.py deleted file mode 100644 index 0b1a569..0000000 --- a/assembler/test/test_020_basic_parsing.py +++ /dev/null @@ -1,68 +0,0 @@ -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] - -def test_mark(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, test_mark - ldi r1, 0xfe - test_mark: - add r0, r1 - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - assembler.parse() - - - assert assembler._code_objects == [32704 | 0, 4 - , 32704 | 1, 0xfe - , 40896 | 0, 1] - - -def test_set_directive(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, test_mark - ldi r1, 0xfe - test_mark: - .set [0xfe, 0xef, - 10, 20, - 'a', 'b', - '\\n', 0b10] - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - assembler.parse() - - - assert assembler._code_objects == [32704 | 0, 4 - , 32704 | 1, 0xfe - , 0xfe, 0xef - , 10, 20 - , ord("a"), ord("b") - , ord("\n"), 0b10] - diff --git a/assembler/test/test_021_parsing_failures.py b/assembler/test/test_021_parsing_failures.py deleted file mode 100644 index 3a64168..0000000 --- a/assembler/test/test_021_parsing_failures.py +++ /dev/null @@ -1,210 +0,0 @@ -from io import StringIO -import pytest - -from assembler.assembler import Assembler, ParsingError - -def test_missing_comma(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, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_missing_newline(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, {}) - - with pytest.raises(ParsingError): - assembler.parse() - - - -def test_additional_comma1(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, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_additional_comma2(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, {}) - - with pytest.raises(ParsingError): - assembler.parse() - - - -def test_bad_mark1(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, 0xfe - this_is_a_bad_mark - ldi r1, 0xfe - add r0, r1 - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_bad_mark2(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, 0xfe - This_is_a_bad_mark: - ldi r1, 0xfe - add r0, r1 - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_bad_mark3(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, 0xfe - 0this_is_a_bad_mark: - ldi r1, 0xfe - add r0, r1 - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_bad_mark4(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, this_is_a_missing_mark - ldi r1, 0xfe - add r0, r1 - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_bad_mark5(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, this_is_a_missing_mark: - ldi r1, 0xfe - add r0, r1 - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_bad_directive1(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, 0 - ldi r1, 0xfe - add r0, r1 - .set data [0x00, 0x10] - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_bad_directive2(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, 0 - ldi r1, 0xfe - add r0, r1 - .set[0x00, 0x10] - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_bad_directive3(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, 0 - ldi r1, 0xfe - add r0, r1 - .set [0x00, 0x10,] - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - - with pytest.raises(ParsingError): - assembler.parse() - -def test_bad_directive4(basic_machine_definition): - memory_definition, command_defintion = basic_machine_definition - - data = StringIO( - ''' - ldi r0, 0 - ldi r1, 0xfe - add r0, r1 - .set [0x00, 0x10 - ''' - ) - assembler = Assembler(data, memory_definition, command_defintion, {}) - - with pytest.raises(ParsingError): - assembler.parse() - diff --git a/interpreter/Makefile b/interpreter/Makefile deleted file mode 100644 index 73f7ffb..0000000 --- a/interpreter/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -CC=gcc -objects= stack.o method_dispatcher/method_dispatcher.o interpreter/core_methods.o interpreter/interpreter.o - -all: $(objects) test - -CFLAG= -c -O -o - -%.o: %.c - $(CC) $(CFLAG) $@ $< - -.PHONY: test - -test: - cd test && make - cd method_dispatcher/test && make - cd interpreter/test && make - -clean: - - rm $(objects) diff --git a/interpreter/base.h b/interpreter/base.h deleted file mode 100644 index 31c918f..0000000 --- a/interpreter/base.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef bci_base_h__ -#define bci_base_h__ -#include -#include "stack.h" - -#define BCI_CORE_NUM_REG 40 - -// Note that void * state will later be casted to -// machine_state_t. -typedef char (* bci_core_method_t)(uint8_t small_arg - , void * state); - - -#define BCI_CORE_RESULT_RESERVED_BITS 0b11000000 -#define BCI_CORE_RESULT_APPLICATION_BITS 0b00111111 - -#define BCI_CORE_SMALL_ARG_MASK 0b0000000000111111 -#define BCI_CORE_OPCODE_MASK 0b1111111111000000 - -#endif diff --git a/interpreter/interpreter/core_methods.c b/interpreter/interpreter/core_methods.c deleted file mode 100644 index b7c26a2..0000000 --- a/interpreter/interpreter/core_methods.c +++ /dev/null @@ -1,370 +0,0 @@ -#include "core_methods.h" - -#define BCI_CORE_REGISTER_CHECK(var) if(var > BCI_CORE_NUM_REG) return 1 - -// #1 -> $0 -char bci_cm_ldi(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - - uint16_t arg; - char res; - res = machine_state_t_get_word(state, state->program_counter + 1, &arg); - if(res) - { - return res; - } - - state->data_reg[small_arg] = arg; - - return machine_state_t_default_afterexec(state, 1); -} - -// @($1) -> $0 -char bci_cm_ld(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - - uint16_t arg; - char res; - res = machine_state_t_get_word(state, state->program_counter + 1, &arg); - if(res) - { - return res; - } - - BCI_CORE_REGISTER_CHECK(arg); - arg = state->data_reg[arg]; - - res = machine_state_t_get_mem(state, arg, &arg); - if(res) - { - return res; - } - state->data_reg[small_arg] = arg; - - return machine_state_t_default_afterexec(state, 1); -} - -// $0 -> @($1) -char bci_cm_st(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - char res; - - uint16_t arg; - res = machine_state_t_get_word(state, state->program_counter + 1, &arg); - if(res) - { - return res; - } - - BCI_CORE_REGISTER_CHECK(arg); - arg = state->data_reg[arg]; - - res = machine_state_t_set_mem(state, arg, state->data_reg[small_arg]); - if(res) - { - return res; - } - - return machine_state_t_default_afterexec(state, 1); -} - -// $0 + 1 -> $0 -char bci_cm_inc(uint8_t small_arg, machine_state_t state) -{ - int32_t result; - BCI_CORE_REGISTER_CHECK(small_arg); - result = state->data_reg[small_arg] + 1; - state->data_reg[small_arg] = result & 0xffff; - state->status_reg = result >> 16; - return machine_state_t_default_afterexec(state, 0); -} - -// $0 - 1 -> $0 -char bci_cm_dec(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - int32_t result = state->data_reg[small_arg] - 1; - state->data_reg[small_arg] = result & 0xffff; - state->status_reg = result >> 16; - return machine_state_t_default_afterexec(state, 0); -} - -// $0 + $1 -> $0 -char bci_cm_add(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - uint16_t arg; - char res; - res = machine_state_t_get_word(state, state->program_counter + 1, &arg); - if(res) - { - return res; - } - - BCI_CORE_REGISTER_CHECK(arg); - int32_t result = state->data_reg[small_arg] + state->data_reg[arg]; - state->data_reg[small_arg] = result & 0xffff; - state->status_reg = result >> 16; - - return machine_state_t_default_afterexec(state, 1); -} - - -// $0 - $1 -> $0 -char bci_cm_sub(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - uint16_t arg; - char res; - res = machine_state_t_get_word(state, state->program_counter + 1, &arg); - if(res) - { - return res; - } - - BCI_CORE_REGISTER_CHECK(arg); - int32_t result = state->data_reg[small_arg] - state->data_reg[arg]; - - state->data_reg[small_arg] = result & 0xffff; - state->status_reg = result >> 16; - - return machine_state_t_default_afterexec(state, 1); -} - - -// $0 * $1 -> $0 -char bci_cm_mul(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - uint16_t arg; - char res; - res = machine_state_t_get_word(state, state->program_counter + 1, &arg); - if(res) - { - return res; - } - - BCI_CORE_REGISTER_CHECK(arg); - int32_t result = state->data_reg[small_arg] * state->data_reg[arg]; - state->data_reg[small_arg] = result & 0xffff; - state->status_reg = result >> 16; - return machine_state_t_default_afterexec(state, 1); -} - -// $0 / $1 -> $0 -char bci_cm_div(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - uint16_t arg; - char res; - res = machine_state_t_get_word(state, state->program_counter + 1, &arg); - if(res) - { - return res; - } - - BCI_CORE_REGISTER_CHECK(arg); - int32_t result = state->data_reg[small_arg] / state->data_reg[arg]; - state->data_reg[small_arg] = result & 0xffff; - state->status_reg = result >> 16; - return machine_state_t_default_afterexec(state, 1); -} - - -// if($0 > 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_gt(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - - if(state->data_reg[small_arg] > 0) - { - state->status_reg = 1; - } - else - { - state->status_reg = 0; - } - return machine_state_t_default_afterexec(state, 0); -} - -// if($0 >= 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_ge(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - - if(state->data_reg[small_arg] >= 0) - { - state->status_reg = 1; - } - else - { - state->status_reg = 0; - } - return machine_state_t_default_afterexec(state, 0); -} -// if($0 < 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_lt(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - - if(state->data_reg[small_arg] < 0) - { - state->status_reg = 1; - } - else - { - state->status_reg = 0; - } - return machine_state_t_default_afterexec(state, 0); -} -// if($0 <= 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_le(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - - if(state->data_reg[small_arg] <= 0) - { - state->status_reg = 1; - } - else - { - state->status_reg = 0; - } - return machine_state_t_default_afterexec(state, 0); -} -// if($0 == 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_eq(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - - if(state->data_reg[small_arg] == 0) - { - state->status_reg = 1; - } - else - { - state->status_reg = 0; - } - return machine_state_t_default_afterexec(state, 0); -} - -// $0 -> $pc; 0 -> $st_reg -char bci_cm_jmp(uint8_t small_arg, machine_state_t state) -{ - BCI_CORE_REGISTER_CHECK(small_arg); - uint16_t arg = state->data_reg[arg]; - - state->status_reg = 0; - state->program_counter = arg; - return 0; -} - -// if($st_reg): $0 -> $pc; 0 -> $st_reg -// else: do nothing -char bci_cm_cjmp(uint8_t small_arg, machine_state_t state) -{ - uint16_t arg = small_arg; - BCI_CORE_REGISTER_CHECK(small_arg); -#ifdef DEBUG - printf("MSG: cjmp: arg=0x%x (=0x%x)\n", arg, state->data_reg[arg]); -#endif - arg = state->data_reg[arg]; - - if(state->status_reg) - { - state->program_counter = arg; - state->status_reg = 0; - return 0; - } - - return machine_state_t_default_afterexec(state, 0); -} -// $pc -> @stack -// $0 -> $pc -char bci_cm_call(uint8_t small_arg, machine_state_t state) -{ - uint16_t arg; - BCI_CORE_REGISTER_CHECK(small_arg); - arg = state->data_reg[arg]; - - char res = bci_stack_t_push(&(state->stack), state->program_counter); - if(res) - { - return res; - } - state->program_counter = arg; - return 0; -} -// if($st_reg): $pc -> @stack; $0 -> $pc; 0 -> $st_reg -// else: do nothing -char bci_cm_ccall(uint8_t small_arg, machine_state_t state) -{ - uint16_t arg; - char res; - BCI_CORE_REGISTER_CHECK(small_arg); - arg = state->data_reg[small_arg]; - - if(state->status_reg) - { - state->program_counter = arg; - res = bci_stack_t_push(&(state->stack), state->program_counter); - if(res) - { - return res; - } - return 0; - } - - state->status_reg = 0; - return machine_state_t_default_afterexec(state, 0); -} -// @stack -> $pc -char bci_cm_ret(uint8_t small_arg, machine_state_t state) -{ - uint16_t result; - char res = bci_stack_t_pop(&(state->stack), &result); - if(res) - { - return res; - } - - state->program_counter = result; - return 0; -} - -// 0 -> $st_reg -char bci_cm_cl(uint8_t small_arg, machine_state_t state) -{ - state->status_reg = 0; - return machine_state_t_default_afterexec(state, 0); -} - -// 1 -> $su_reg -char bci_cm_stop(uint8_t small_arg, machine_state_t state) -{ - state->shutdown_reg = 1; - return machine_state_t_default_afterexec(state, 0); -} - -// if($st_reg): 0 -> $st_reg -// else: 1 -> $st_reg -char bci_cm_not(uint8_t small_arg, machine_state_t state) -{ - if(state->status_reg) - { - state->status_reg = 0; - } - else - { - state->status_reg = 1; - } - return machine_state_t_default_afterexec(state, 0); -} diff --git a/interpreter/interpreter/core_methods.h b/interpreter/interpreter/core_methods.h deleted file mode 100644 index e36892a..0000000 --- a/interpreter/interpreter/core_methods.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef bci_core_methods_h__ -#define bci_core_methods_h__ -#include "interpreter.h" - - -/* - * This library brings a set of essential core methods. - * */ - - -/* - * Naming conventions: - * - * x = 0, 1, 2, 3...: arguments. - * 0: small_arg (6 bit) - * 1, 2, ...: 16 bit optional arguments - * - * $x: value of data register x - * @x: value of memory word x - * #x: value of argument x - * 0, 1, 2, ...: integer 0, 1, 2, ... - * - * -> write result in register/word on the right - * - * st_reg: status register - * su_reg: shutdown register - * pc: program counter - * - * stack: the builtin stack - * */ - -// #1 -> $0 -char bci_cm_ldi(uint8_t small_arg, machine_state_t state); - -// @($1) -> $0 -char bci_cm_ld(uint8_t small_arg, machine_state_t state); - -// $0 -> @($1) -char bci_cm_st(uint8_t small_arg, machine_state_t state); - - -// NOTES on inc, dec, add, sub, mul, div: -// -// These methods will store the overflow-word in $st_reg. - - -// $0 + 1 -> $0 -char bci_cm_inc(uint8_t small_arg, machine_state_t state); - -// $0 - 1 -> $0 -char bci_cm_dec(uint8_t small_arg, machine_state_t state); - -// $0 + $1 -> $0 -char bci_cm_add(uint8_t small_arg, machine_state_t state); - -// $0 - $1 -> $0 -char bci_cm_sub(uint8_t small_arg, machine_state_t state); - -// $0 * $1 -> $0 -char bci_cm_mul(uint8_t small_arg, machine_state_t state); - -// $0 / $1 -> $0 -char bci_cm_div(uint8_t small_arg, machine_state_t state); - -// if($0 > 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_gt(uint8_t small_arg, machine_state_t state); - -// if($0 >= 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_ge(uint8_t small_arg, machine_state_t state); - -// if($0 < 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_lt(uint8_t small_arg, machine_state_t state); - -// if($0 <= 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_le(uint8_t small_arg, machine_state_t state); - -// if($0 == 0): 1 -> $st_reg -// else: 0 -> $st_reg -char bci_cm_eq(uint8_t small_arg, machine_state_t state); - -// if($st_reg): 0 -> $st_reg -// else: 1 -> $st_reg -char bci_cm_not(uint8_t small_arg, machine_state_t state); - -// $1 -> $pc -char bci_cm_jmp(uint8_t small_arg, machine_state_t state); - -// if($st_reg): $1 -> $pc -// else: do nothing -char bci_cm_cjmp(uint8_t small_arg, machine_state_t state); - -// $pc -> @stack -// $0 -> $pc -char bci_cm_call(uint8_t small_arg, machine_state_t state); - -// if($st_reg): $pc -> @stack; $0 -> $pc -// else: do nothing -char bci_cm_ccall(uint8_t small_arg, machine_state_t state); - -// @stack -> $pc -char bci_cm_ret(uint8_t small_arg, machine_state_t state); - -// 0 -> $st_reg -char bci_cm_cl(uint8_t small_arg, machine_state_t state); - -// 1 -> $su_reg -char bci_cm_stop(uint8_t small_arg, machine_state_t state); - - -#endif diff --git a/interpreter/interpreter/interpreter.c b/interpreter/interpreter/interpreter.c deleted file mode 100644 index 4089fdd..0000000 --- a/interpreter/interpreter/interpreter.c +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include - -#include "interpreter.h" - - - -machine_state_t machine_state_t_new( void * cache_function_data - , size_t program_size - , size_t cache_size - , size_t memory_size - , size_t (* cache_block)(uint16_t * cache - , uint16_t offset - , size_t cache_size - , void * cache_function_data) - , dispatch_tree_t method_dispatcher) -{ - - machine_state_t state = malloc(sizeof(struct machine_state_s)); - if(!state) - { - return NULL; - } - uint16_t * cache = calloc(sizeof(uint16_t), cache_size); - if(!cache) - { - free(state); - return NULL; - } - uint16_t * memory = calloc(sizeof(uint16_t), memory_size); - if(!memory) - { - free(state); - free(cache); - return NULL; - } - - - state->program_size = program_size; - state->cache = cache; - state->cache_block = cache_block; - state->cache_size = cache_size; - state->cache_loaded = 0; - state->cache_offset = 0; - state->cache_function_data = cache_function_data; - - state->program_counter = 0; - state->status_reg = 0; - state->shutdown_reg = 0; - int i; - for(i = 0; i < BCI_CORE_NUM_REG; i++) - { - state->data_reg[i] = 0; - } - state->stack = NULL; - - state->memory = memory; - state->memory_size = memory_size; - - state->method_dispatcher = method_dispatcher; - - return state; -} - -void machine_state_t_del(machine_state_t state) -{ - free(state->cache); - free(state->memory); - dispatch_tree_t_del(state->method_dispatcher); - bci_stack_t_del(&(state->stack)); - free(state); -} - - -char update_cache(machine_state_t state, uint16_t offset) -{ - // Calculate a clever offset for caching. - uint16_t cache_offset = offset; - if((cache_offset + state->cache_size) - > state->program_size) - { - if(state->program_size < state->cache_size) - { - cache_offset = 0; - } - else - { - cache_offset = state->program_size - state->cache_size; - } - } - size_t cached = state->cache_block(state->cache - , cache_offset - , state->cache_size - , state->cache_function_data); - - if(cached != state->cache_size) - { - #ifdef DEBUG - printf("ERROR: should have cached %zu words, but got %zu.\n", state->cache_size, cached); - #endif - return 1; - } - state->cache_offset = cache_offset; - state->cache_loaded = 1; - return 0; -} - -char machine_state_t_get_word(machine_state_t state, uint16_t offset, uint16_t * result) -{ - - // This would be bad. - if(offset >= state->program_size) - { - return 0b01000000 | 1; - } - - // Calculate the in-cache offset of the desired offset. - int32_t in_cache_offset = offset - state->cache_offset; - - // Check if we need to update the cache. - if( in_cache_offset < 0 - || !(state->cache_loaded) - ) - { - if(update_cache(state, offset)) - { - #ifdef DEBUG - printf("ERROR: failed to update cache\n"); - #endif - state->error = 0b01000000 | 2; - return 0b01000000 | 2; - } - // Re-calculate the in-cache offset - in_cache_offset = offset - state->cache_offset; - } - - *result = state->cache[in_cache_offset]; - return 0; - -} - -char machine_state_t_exec_cycle(machine_state_t state) -{ - char res = 0; - uint16_t opcode; - res = machine_state_t_get_word(state, state->program_counter, &opcode); - - if(res) - { - return res; - } - -#ifdef DEBUG - printf("MSG: opcode = 0x%x, small_arg = 0x%x\n" - , opcode & BCI_CORE_OPCODE_MASK - , opcode & BCI_CORE_SMALL_ARG_MASK); -#endif - - bci_core_method_t method = dispatch_tree_t_dispatch( - state->method_dispatcher - , opcode & BCI_CORE_OPCODE_MASK); - if(!method) - { - state->error = res; - return 0b10000000 | 1; - } - - return BCI_CORE_RESULT_APPLICATION_BITS - & method( opcode & BCI_CORE_SMALL_ARG_MASK - , state); - -} - - -char machine_state_t_default_afterexec(machine_state_t state, uint8_t argc) -{ - state->program_counter += 1 + argc; - return 0; -} - - -char machine_state_t_get_mem(machine_state_t state, uint16_t offset, uint16_t * result) -{ - if(offset > state->memory_size) - { - state->error = 0b01000000 | 15; - return 0b01000000 | 15; - } - - *result = state->memory[offset]; - return 0; -} -char machine_state_t_set_mem(machine_state_t state, uint16_t offset, uint16_t data) -{ - if(offset > state->memory_size) - { - state->error = 0b01000000 | 15; - return 0b01000000 | 15; - } - - state->memory[offset] = data; - return 0; -} - - - - -char machine_state_t_exec(machine_state_t state) -{ - char status = 0; - while((!status) && (!state->shutdown_reg)) - { - status = machine_state_t_exec_cycle(state); - } - state->error = status; - return status; -} diff --git a/interpreter/interpreter/interpreter.h b/interpreter/interpreter/interpreter.h deleted file mode 100644 index 4829148..0000000 --- a/interpreter/interpreter/interpreter.h +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef bci_interpreter_h__ -#define bci_interpreter_h__ - -#include -#include "../base.h" -#include "../method_dispatcher/method_dispatcher.h" -#include "../stack.h" - -typedef struct machine_state_s -{ - // The size of the program in 16-bit words - uint16_t program_size; - void * cache_function_data; - - size_t cache_size; - uint16_t cache_offset; - uint16_t * cache; - size_t (* cache_block)(uint16_t * cache - , uint16_t offset - , size_t cache_size - , void * cache_function_data); - char cache_loaded; - - uint16_t program_counter; - uint16_t status_reg; - // Any non-zero value in this register will - // break the program execution. - uint16_t shutdown_reg; - uint16_t data_reg[BCI_CORE_NUM_REG]; - bci_stack_t stack; - - size_t memory_size; - uint16_t * memory; - - - dispatch_tree_t method_dispatcher; - - // Possible Error Codes: - // 0b01xxxxxx: memory related internal error - // 0b10xxxxxx: core method related internal error - // 0b00xxxxxx: application related internal error - // - // - // 0b01000000 | 1: Program offset out of bounds - // 0b01000000 | 2: Failed to cache new data - // 0b01000000 | 15: Memory offset out of bounds - // - // - // 0b10000000 | 1: Unknown opcode - char error; - -} * machine_state_t; - -machine_state_t machine_state_t_new( void * cache_function_data - , size_t program_size - , size_t cache_size - , size_t memory_size - , size_t (* cache_block)(uint16_t * cache - , uint16_t offset - , size_t cache_size - , void * cache_function_data) - , dispatch_tree_t method_dispatcher); - -void machine_state_t_del(machine_state_t state); - -/* - * This function essentially executes one cycle of the machine execution. - * It will fetch the opcode and argument, dispatch the method and execute it. - * - * Also this will update the cache if needed. - * - * Possible return codes: - * - * - 0bxyXXXXXX - * Error while executing the cycle. - * - 0b01XXXXXX - * Error in the internal memory management (i.e. program counter out - * of bounds) - * - 0b01000000 | 1: program_counter or argument offset > program_size - * - 0b01000000 | 2: failed to cache new data - * - * - 0b10XXXXXX - * Error while dispatching the method - * - 0b10000000 | 1: unknown opcode - * - * - 0b00XXXXXX - * XXXXXX is the return value of the bci_core_method_t method. - * */ -char machine_state_t_exec_cycle(machine_state_t state); - - -/* - * Runs ``machine_state_t_exec_cycle`` until either this function - * returns a non-zero value or a non-zero value is stored in - * ``state->shutdown_reg``. - * Sets ``state->error`` to the last return value of ``machine_state_t_exec_cycle`` - * and returns it. - * */ -char machine_state_t_exec(machine_state_t state); - -/* - * Do the default updates on the machine state. - * This will be basically increasing the program counter. - * */ -char machine_state_t_default_afterexec(machine_state_t state, uint8_t argc); - -/* - * Get the word at offset in the program memory. - * Returns 0 on success, a non-zero value otherwise. - * - * It will set state->error appropiately. - * */ -char machine_state_t_get_word(machine_state_t state, uint16_t offset, uint16_t * result); - -/* - * Get the word at offset in the RAM-alike memory. - * Works like machine_state_t_get_word. - * */ -char machine_state_t_get_mem(machine_state_t state, uint16_t offset, uint16_t * result); -char machine_state_t_set_mem(machine_state_t state, uint16_t offset, uint16_t data); -#endif diff --git a/interpreter/interpreter/test/Makefile b/interpreter/interpreter/test/Makefile deleted file mode 100644 index 6703b38..0000000 --- a/interpreter/interpreter/test/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -CC=gcc - -all: test_interpreter - -interpreter: clean - $(CC) -g ../../stack.c ../interpreter.c ../core_methods.c ../../method_dispatcher/method_dispatcher.c test_interpreter.c -o interpreter - -test_interpreter: interpreter - valgrind ./interpreter - - - -clean: - diff --git a/interpreter/interpreter/test/test_interpreter.c b/interpreter/interpreter/test/test_interpreter.c deleted file mode 100644 index 62db833..0000000 --- a/interpreter/interpreter/test/test_interpreter.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include "../interpreter.h" -#include "../core_methods.h" -#include "../../method_dispatcher/method_dispatcher.h" - -size_t copy_cache(uint16_t * cache - , uint16_t offset - , size_t cache_size - , void * cache_function_data); - -int main(void) -{ - dispatch_tree_t tree = dispatch_tree_t_new(); - dispatch_tree_autoinserter_t inserter = dispatch_tree_autoinserter_t_new(tree); - uint16_t ldi = dispatch_tree_autoinserter_t_insert(inserter, (bci_core_method_t) bci_cm_ldi); - uint16_t add = dispatch_tree_autoinserter_t_insert(inserter, (bci_core_method_t) bci_cm_add); - - uint16_t * program = calloc(sizeof(uint16_t), 20); - program[0] = ldi; - program[1] = 0xfefe; - program[2] = ldi | 1; - program[3] = 2; - program[4] = ldi | 2; - program[5] = 3; - program[6] = add | 1; - program[7] = 2; - - machine_state_t state = machine_state_t_new( - program - , 8 - , 20 - , 20 - , copy_cache - , tree); - - machine_state_t_exec_cycle(state); - machine_state_t_exec_cycle(state); - machine_state_t_exec_cycle(state); - machine_state_t_exec_cycle(state); - printf("data_reg[0]: %x\n", state->data_reg[0]); - assert(state->data_reg[0] == 0xfefe); - printf("data_reg[1]: %x\n", state->data_reg[1]); - assert(state->data_reg[1] == 5); - printf("data_reg[2]: %x\n", state->data_reg[2]); - assert(state->data_reg[2] == 3); - printf("program_counter: %d\n", state->program_counter); - assert(state->program_counter == 8); - dispatch_tree_autoinserter_t_del(inserter); - machine_state_t_del(state); - free(program); - return 0; -} - -size_t copy_cache(uint16_t * cache - , uint16_t offset - , size_t cache_size - , void * cache_function_data) -{ - size_t i; - for(i = 0; i < cache_size; i++) - { - printf("\tCP [%zd]->[%zd]: %x\n", i + offset, i, ((uint16_t *) cache_function_data)[i + offset]); - cache[i] = ((uint16_t *) cache_function_data)[i + offset]; - } - return i; -} - diff --git a/interpreter/method_dispatcher/method_dispatcher.c b/interpreter/method_dispatcher/method_dispatcher.c deleted file mode 100644 index e26c553..0000000 --- a/interpreter/method_dispatcher/method_dispatcher.c +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include "method_dispatcher.h" - - -dispatch_tree_t dispatch_tree_t_new(void) -{ - dispatch_tree_t tree = malloc(sizeof(struct dispatch_tree_s)); - tree->root = NULL; - return tree; -} - -void dispatch_tree_t_del(dispatch_tree_t tree) -{ - dispatch_tree_node_t_del(tree->root); - free(tree); -} - -dispatch_tree_node_t dispatch_tree_node_t_new(uint16_t word - , bci_core_method_t method) -{ - dispatch_tree_node_t node = malloc(sizeof(struct dispatch_tree_node_s)); - node->higher = NULL; - node->lower = 0; - node->method = method; - node->word = word; - return node; -} - -void dispatch_tree_node_t_del(dispatch_tree_node_t node) -{ - if(node->higher) - { - dispatch_tree_node_t_del(node->higher); - } - if(node->lower) - { - dispatch_tree_node_t_del(node->lower); - } - free(node); -} - -char dispatch_tree_t_insert(dispatch_tree_t tree - , uint16_t word - , bci_core_method_t method) -{ - dispatch_tree_node_t new_node = dispatch_tree_node_t_new(word, method); - if(!new_node) - { - return 1; - } - // explicitly handle empty tree - if(!tree->root) - { - tree->root = new_node; - return 0; - } - - // non-empty tree - dispatch_tree_node_t this_node = tree->root; - dispatch_tree_node_t parent_node = NULL; - // search for place - do - { - parent_node = this_node; - if(parent_node->word < word) - { - this_node = parent_node->higher; - continue; - } - if(parent_node->word > word) - { - this_node = parent_node->lower; - continue; - } - if(parent_node->word == word) - { - // we already have that key. - return 2; - } - - } - while(this_node); - if(parent_node->word < word) - { - parent_node->higher = new_node; - } - if(parent_node->word > word) - { - parent_node->lower = new_node; - } - - return 0; - -} - - -bci_core_method_t dispatch_tree_t_dispatch(dispatch_tree_t tree - , uint16_t word) -{ - dispatch_tree_node_t this_node = tree->root; - while(this_node) - { - if(this_node->word < word) - { - this_node = this_node->higher; - continue; - } - if(this_node->word > word) - { - this_node = this_node->lower; - continue; - } - if(this_node->word == word) - { - return this_node->method; - } - } - return NULL; -} - -dispatch_tree_autoinserter_t dispatch_tree_autoinserter_t_new(dispatch_tree_t tree) -{ - dispatch_tree_autoinserter_t autoinserter = malloc( - sizeof(struct dispatch_tree_autoinserter_s)); - if(!autoinserter) - { - return NULL; - } - autoinserter->mayor = 2; - autoinserter->minor = 1; - autoinserter->tree = tree; - return autoinserter; -} - -void dispatch_tree_autoinserter_t_del(dispatch_tree_autoinserter_t autoinserter) -{ - free(autoinserter); -} - - -uint16_t dispatch_tree_autoinserter_t_insert( - dispatch_tree_autoinserter_t autoinserter - , bci_core_method_t method) -{ - uint16_t opcode = 0b1111111111; - opcode *= autoinserter->minor; - opcode /= autoinserter->mayor; - opcode <<= 6; - - dispatch_tree_t_insert(autoinserter->tree, opcode, method); - - autoinserter->minor = (autoinserter->minor + 2) % autoinserter->mayor; - if(autoinserter->minor == 1) - { - autoinserter->mayor *= 2; - } - return opcode; -} diff --git a/interpreter/method_dispatcher/method_dispatcher.h b/interpreter/method_dispatcher/method_dispatcher.h deleted file mode 100644 index 6b6dac9..0000000 --- a/interpreter/method_dispatcher/method_dispatcher.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef bci_method_dispatcher_h__ -#define bci_method_dispatcher_h__ - -#include -#include "../base.h" - -typedef struct dispatch_tree_node_s -{ - struct dispatch_tree_node_s * higher; - struct dispatch_tree_node_s * lower; - uint16_t word; - bci_core_method_t method; -} * dispatch_tree_node_t; - -typedef struct dispatch_tree_s -{ - dispatch_tree_node_t root; -} * dispatch_tree_t; - -dispatch_tree_t dispatch_tree_t_new(void); -/* - * This deletes the tree and will invoke dispatch_tree_node_t_del on - * tree->root (which will delete all the other nodes recursively). - * If you want to keep nodes you have to explicityl remove the reference to - * them by setting them to NULL. - * */ -void dispatch_tree_t_del(dispatch_tree_t tree); - - -dispatch_tree_node_t dispatch_tree_node_t_new(uint16_t word - , bci_core_method_t method); -/* - * This deletes the node an will invoke dispatch_tree_node_t_del on - * node->higher and node->lower. If you want to keep those nodes - * you have to explicitly clear the reference by setting them to NULL. - * */ -void dispatch_tree_node_t_del(dispatch_tree_node_t node); - - -/* - * Insert a new key-value-pair into the tree. - * - * Return codes: - * 0: OK - * 1: out of memory - * 2: key already in tree - * */ -char dispatch_tree_t_insert(dispatch_tree_t tree - , uint16_t word - , bci_core_method_t method); - - -bci_core_method_t dispatch_tree_t_dispatch(dispatch_tree_t tree - , uint16_t word); - - - -typedef struct dispatch_tree_autoinserter_s -{ - uint16_t mayor; - uint16_t minor; - dispatch_tree_t tree; -} * dispatch_tree_autoinserter_t; - -dispatch_tree_autoinserter_t dispatch_tree_autoinserter_t_new(dispatch_tree_t tree); -void dispatch_tree_autoinserter_t_del(dispatch_tree_autoinserter_t autoinserter); - -/* - * This function inserts a new method into the tree and automatically - * chooses the optimal word to prevent degeneration. - * - * NOTE: - * When inserting mutliple methods this function acts deterministic, - * IF AND ONLY IF the order of the methods is not changed. - * - * The assembler will bring an analogous function that allows one - * to determine the opcodes of the methods. - * - * NOTE: - * This algorithm will not work for more that 1023 registered opcodes. - * This limit is however considered acceptable. - * - * */ -uint16_t dispatch_tree_autoinserter_t_insert( - dispatch_tree_autoinserter_t autoinserter - , bci_core_method_t method); -#endif diff --git a/interpreter/method_dispatcher/test/Makefile b/interpreter/method_dispatcher/test/Makefile deleted file mode 100644 index c9fc7c9..0000000 --- a/interpreter/method_dispatcher/test/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -CC=gcc - -all: test_method_dispatcher - -method_dispatcher: clean - $(CC) -g ../method_dispatcher.c test_method_dispatcher.c -o method_dispatcher - -test_method_dispatcher: method_dispatcher - valgrind ./method_dispatcher - - - -clean: - -rm method_dispatcher diff --git a/interpreter/method_dispatcher/test/test_method_dispatcher.c b/interpreter/method_dispatcher/test/test_method_dispatcher.c deleted file mode 100644 index 917e901..0000000 --- a/interpreter/method_dispatcher/test/test_method_dispatcher.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include "../method_dispatcher.h" - -char m1(uint8_t small_arg, void * state); -char m2(uint8_t small_arg, void * state); -char m3(uint8_t small_arg, void * state); -char m4(uint8_t small_arg, void * state); -char m5(uint8_t small_arg, void * state); - -int main(void) -{ - printf("sizeof struct dispatch_tree_node_s: %zd\n", sizeof(struct dispatch_tree_node_s)); - dispatch_tree_t tree = dispatch_tree_t_new(); - - dispatch_tree_t_insert(tree, 3 << 6, m3); - dispatch_tree_t_insert(tree, 2 << 6, m2); - dispatch_tree_t_insert(tree, 1 << 6, m1); - dispatch_tree_t_insert(tree, 4 << 6, m4); - dispatch_tree_t_insert(tree, 5 << 6, m5); - - int i; - for(i = 1; i < 6; i++) - { - dispatch_tree_t_dispatch(tree, i << 6)(i, NULL); - } - dispatch_tree_t_del(tree); - - - bci_core_method_t methods[5] = {m1, m2, m3, m4, m5}; - tree = dispatch_tree_t_new(); - dispatch_tree_autoinserter_t inserter = dispatch_tree_autoinserter_t_new(tree); - for(i = 0; i < 5; i++) - { - printf("%u\n", dispatch_tree_autoinserter_t_insert(inserter, methods[i])); - } - dispatch_tree_autoinserter_t_del(inserter); - dispatch_tree_t_del(tree); - - return 0; -} - - - -char m1(uint8_t small_arg, void * state) -{ - printf("m1: %d\n", small_arg); -} -char m2(uint8_t small_arg, void * state) -{ - printf("m2: %d\n", small_arg); -} -char m3(uint8_t small_arg, void * state) -{ - printf("m3: %d\n", small_arg); -} -char m4(uint8_t small_arg, void * state) -{ - printf("m4: %d\n", small_arg); -} -char m5(uint8_t small_arg, void * state) -{ - printf("m5: %d\n", small_arg); -} diff --git a/interpreter/stack.c b/interpreter/stack.c deleted file mode 100644 index 97d4a8c..0000000 --- a/interpreter/stack.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include "stack.h" - -char bci_stack_t_push(bci_stack_t * stack, uint16_t value) -{ - bci_stack_t node = malloc(sizeof(struct bci_stack_s)); - if(!node) - { - return 1; - } - node->next = *stack; - node->value = value; - *stack = node; - return 0; -} -char bci_stack_t_pop(bci_stack_t * stack, uint16_t * result) -{ - bci_stack_t this_node; - if(!*stack) - { - return 1; - } - this_node = *stack; - *result = this_node->value; - *stack = this_node->next; - free(this_node); - return 0; -} - -void bci_stack_t_del(bci_stack_t * stack) -{ - bci_stack_t this_node; - - while(*stack) - { - this_node = *stack; - *stack = this_node->next; - free(this_node); - } -} diff --git a/interpreter/stack.h b/interpreter/stack.h deleted file mode 100644 index 0522db0..0000000 --- a/interpreter/stack.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef bci_stack_h__ -#define bci_stack_h__ - -#include - -typedef struct bci_stack_s -{ - struct bci_stack_s * next; - uint16_t value; -} * bci_stack_t; - -char bci_stack_t_push(bci_stack_t * stack, uint16_t value); -char bci_stack_t_pop(bci_stack_t * stack, uint16_t * result); - -/* - * Deletes the entire (!) stack. - * - * */ -void bci_stack_t_del(bci_stack_t * stack); -#endif diff --git a/interpreter/test/Makefile b/interpreter/test/Makefile deleted file mode 100644 index a90518d..0000000 --- a/interpreter/test/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -CC=gcc - -all: test_stack - -stack: clean - $(CC) -g ../stack.c test_stack.c -o stack - -test_stack: stack - valgrind ./stack - -clean: - -rm stack diff --git a/interpreter/test/test_stack.c b/interpreter/test/test_stack.c deleted file mode 100644 index 328c35c..0000000 --- a/interpreter/test/test_stack.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include "../stack.h" -#include - -int main(void) -{ - bci_stack_t stack = NULL; - int i; - uint16_t res; - char status = 0; - - - for(i = 0; i < 10; i++) - { - bci_stack_t_push(&stack, (uint16_t) i); - } - --i; - while(!status) - { - status = bci_stack_t_pop(&stack, &res); - if(!status) - { - assert(res == i--); - } - } - - - for(i = 0; i < 10; i++) - { - bci_stack_t_push(&stack, (uint16_t) i); - } - bci_stack_t_del(&stack); - return 0; -}