class IoParserTest(unittest.TestCase): def setUp(self): logging.getLogger().addHandler(logging.NullHandler()) self.parser = Parser() def test_print(self): input_string = "assign y 100 print y print y" expected = [ Instruction(OpCode.MOVEQ, 100, "y"), Instruction(OpCode.MOVE, "y", Register.RESULT), Instruction(OpCode.OUT, IoOp.REGISTER, Register.RESULT), Instruction(OpCode.OUT, IoOp.PRINT, ' '), Instruction(OpCode.MOVE, "y", Register.RESULT), Instruction(OpCode.OUT, IoOp.REGISTER, Register.RESULT), Instruction(OpCode.OUT, IoOp.PRINT, ' ') ] actual = self.parser.parse(input_string) self.assertEqual( expected, actual, "print test failed: {} {}".format(expected, actual)) def test_println(self): input_string = 'println 10' expected = [ Instruction(OpCode.MOVEQ, 10, Register.RESULT), Instruction(OpCode.OUT, IoOp.REGISTER, Register.RESULT), Instruction(OpCode.OUT, IoOp.PRINT, os.linesep) ] actual = self.parser.parse(input_string) self.assertEqual( expected, actual, 'println test failed: {} {}'.format(expected, actual)) def test_printf(self): input_string = """ assign y 60 define z "hello" printf "{} {brightness} {} {} {y} {}" 500 saturation "there" z """ expected = [ Instruction(OpCode.MOVEQ, 60, "y"), Instruction(OpCode.CONSTANT, "z", "hello"), Instruction(OpCode.MOVEQ, 500, Register.RESULT), Instruction(OpCode.OUT, IoOp.REGISTER, Register.RESULT), Instruction(OpCode.MOVE, Register.SATURATION, Register.RESULT), Instruction(OpCode.OUT, IoOp.REGISTER, Register.RESULT), Instruction(OpCode.MOVEQ, "there", Register.RESULT), Instruction(OpCode.OUT, IoOp.REGISTER, Register.RESULT), Instruction(OpCode.MOVEQ, "hello", Register.RESULT), Instruction(OpCode.OUT, IoOp.REGISTER, Register.RESULT), Instruction( OpCode.OUT, IoOp.PRINTF, "{} {brightness} {} {} {y} {}") ] actual = self.parser.parse(input_string) self.assertEqual( expected, actual, "printf test failed: {} {}".format(expected, actual))
class ScriptJob(Job): def __init__(self): super().__init__() self._program = None self._parser = Parser() self._machine = Machine() @staticmethod def from_file(file_name): new_instance = ScriptJob() new_instance.load_file(file_name) return new_instance @staticmethod def from_string(script): new_instance = ScriptJob() new_instance.load_string(script) return new_instance def load_file(self, file_name): self._program = self._parser.load(file_name) if self._program is None: logging.error("{}, {}".format(file_name, self._parser.get_errors())) return self._program def load_string(self, input_string): self._program = self._parser.parse(input_string) if self._program is None: logging.error(self._parser.get_errors()) return self._program @property def program(self): return self._program @property def compile_errors(self): return self._parser.get_errors() def get_machine_state(self) -> MachineState: return self._machine.get_state() def execute(self): if self._program is not None: self._machine.reset() self._machine.run(self._program) def request_stop(self): self._machine.stop()
class ParserTest(unittest.TestCase): def setUp(self): logging.getLogger().addHandler(logging.NullHandler()) self.parser = Parser() def good_input(self, input_string): self.assertTrue(self.parser.parse(input_string)) def test_good_strings(self): input_strings = [ '#abcde \n hue 5 \n #efghi \n ', '', 'set "name with spaces"', 'define table "Table" set table', 'hue 5 saturation 10 set "Table"', 'hue 5 set all', 'get "Table"', 'get "Table" zone 0' ] for string in input_strings: self.assertIsNotNone(self.parser.parse(string), string) def test_bad_keyword(self): input_string = 'on "Top" on "Bottom" on\n"Middle" Frank' self.assertFalse(self.parser.parse(input_string)) self.assertIn('Unknown name: "Frank"', self.parser.get_errors()) def test_bad_number(self): input_string = "hue 5 saturation x" self.assertFalse(self.parser.parse(input_string)) self.assertIn('Unknown: "x"', self.parser.get_errors()) def test_single_zone(self): input_string = 'set "Strip" zone 7' expected = [ Instruction(OpCode.MOVEQ, "Strip", Register.NAME), Instruction(OpCode.MOVEQ, 7, Register.FIRST_ZONE), Instruction(OpCode.MOVEQ, None, Register.LAST_ZONE), Instruction(OpCode.MOVEQ, Operand.MZ_LIGHT, Register.OPERAND), ] actual = _filter(self.parser.parse(input_string)) self.assertEqual(expected, actual, "Single zone failed: {} {}".format(expected, actual)) def test_multi_zone(self): input_string = 'set "Strip" zone 3 5' expected = [ Instruction(OpCode.MOVEQ, "Strip", Register.NAME), Instruction(OpCode.MOVEQ, 3, Register.FIRST_ZONE), Instruction(OpCode.MOVEQ, 5, Register.LAST_ZONE), Instruction(OpCode.MOVEQ, Operand.MZ_LIGHT, Register.OPERAND), ] actual = _filter(self.parser.parse(input_string)) self.assertEqual(expected, actual, "Multi-zone failed: {} {}".format(expected, actual))
def main(): arg_parser = argparse.ArgumentParser() arg_parser.add_argument('file', help='name of the script file') args = arg_parser.parse_args() logging.basicConfig( level=logging.DEBUG, format='%(filename)s(%(lineno)d) %(funcName)s(): %(message)s') parser = Parser() parser_code = parser.load(args.file) loader = Loader() routines = {} loader.load(parser_code, routines) if loader.code is not None: inst_num = 0 for inst in loader.code: print('{:5d}: {}'.format(inst_num, inst)) inst_num += 1 else: print("Error parsing: {}".format(parser.get_errors()))
def __init__(self): super().__init__() self._program = None self._parser = Parser() self._machine = Machine()
def setUp(self): logging.getLogger().addHandler(logging.NullHandler()) self.parser = Parser()
def test_bad_break(self): script = "hue 5 saturation 6 break set all" parser = Parser() self.assertFalse(parser.parse(script)) self.assertEqual(parser.get_errors(), 'Line 1: Encountered "break" not inside loop.\n')