emflow-artifact / artifact / control_flows / Control_Flow.py
Control_Flow.py
Raw
import abc
from abc import abstractmethod

class Control_Flow(abc.ABC):
    '''ABSTRACT METHOD. Defines a control flow. There are two mandatory overrides; control_flow() returns a list of the required control flow, clock_cycles() defines the number of basic blocks per clock cycle'''

    def __init__(self):
        self.__pointer = 0
    
    @property
    @abstractmethod
    def control_flow(self):
        raise NotImplementedError

    @property
    @abstractmethod
    def clock_cycles(self):
        raise NotImplementedError
    
    def get_basicBlocks(self):
        '''This supports blocks that are not trained to handle variable length instructions (e.g brne, breq, etc.)'''
        origBlocks = self.clock_cycles()
        newBlocks = {}

        for block in origBlocks:
            if block[0:2] == '0x':
                #add the block to the return list because it is an actual block
                newBlocks[block] = origBlocks[block]
        return newBlocks

    def __iter__(self):
        self.__pointer = 0
        return self
    
    def __next__(self):
        if self.__pointer < len(self):
            item = self.control_flow()[self.__pointer]
            self.__pointer += 1
            return item
        else:
            raise StopIteration

    def __getitem__(self,item):
        return self.clock_cycles()[item]

    def __str__(self):
        return str(self.control_flow())

    def __len__(self):
        return len(self.control_flow())


class Distance_Sensor(Control_Flow):
    '''The Arduino distance sensor Control Flow. '''
    def __init__(self):
        super().__init__()

    #override, 0x6ea and 0x6f4 are the same condense
    def control_flow(self):
        return ['0x6e4',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6eb',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6ea',
                '0x6f5',
                '0x31e',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
            ]

    #override
    def clock_cycles(self):
        '''Returns the clock cycles for each basic block in the form. {'block',[# of clock cycles]}.
        Args:
            None: None
        Returns:
            Dict[str,list[int]]: The block with the number of clock cycles in a list. '''
        return {'0x6e4':[7],
                '0x6ea':[4],
                '0x6eb':[10],
                '0x6f5':[9],
                '0x31e':[14],
                '0xnops':[6]}


class CSUMEX(Control_Flow):
    '''The Arduino Checksum Control Flow.'''
    def __init__(self):
        super().__init__()

    #override
    def control_flow(self):
        return [
                '0x1be',
                '0x0ea',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '2',
                '0x0f0',
                '0x0fa',
                '1',
                '0x100',
                'nops',
                'nops',
                'nops',
                'nops',
                'nops'
        ]

    #override
    def clock_cycles(self):
        '''Returns the clock cycles for each basic block in the form. {'block',[# of clock cycles]}.
        Args:
            None: None
        Returns:
            Dict[str,list[int]]: The block with the number of clock cycles in a list. '''
        return {'0x1be':[4],
                '0x0ea':[4],
                '0x0f0':[6],
                '0x0fa':[3],
                '0x100':[2],
                '2'  :[2],
                '1'  :[1],
                'nops':[35]
                }


class Syringe(Control_Flow):
    '''This is the Arduino Syringe Control Flow.'''
    def __init__(self):
        super().__init__()

    #override, 0x6ea and 0x6f4 are the same condense
    def control_flow(self):
        return ['0x544',
                '0x54c',
                '0x1be',
                '0x1e4',
                '0x1ec',
                '1',
                '0x216',
                '0x20a',
                '1',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x557',
                '0x1be',
                '0x1e4',
                '0x1ec',
                '2',
                '0x206',
                '0x20a',
                '1',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x568',
                '0x54c',

                '0x1be',
                '0x1e4',
                '0x1ec',
                '1',
                '0x216',
                '0x20a',
                '1',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x557',
                '0x1be',
                '0x1e4',
                '0x1ec',
                '2',
                '0x206',
                '0x20a',
                '1',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x556',
                '0x568',
                '0x54c',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
                ]

    #override
    def clock_cycles(self):
        '''Returns the clock cycles for each basic block in the form. {'block',[# of clock cycles]}.
        Args:
            None: None
        Returns:
            Dict[str,list[int]]: The block with the number of clock cycles in a list. '''
        return {'0x544':[4],
                '0x54c':[6],
                '0x1be':[28],
                '0x1e4':[4],
                '0x1ec':[16],
                '0x216':[5],
                '0x20a':[13],
                '0x556':[4],
                '0x557':[9],
                '0x206':[2],
                '0x568':[9],
                '1':[1],
                '2':[2],
                '0xnops':[6]
                }


class Coffee(Control_Flow):
    '''The Arduino Coffee Control Flow.'''
    def __init__(self):
        super().__init__()

    #override
    def control_flow(self):
        return ['0x836',
                '0x86c',
                '0x88c',
                '0x8ba',
                '0x7c8',
                '0x7d0',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
        ]

    #override
    def clock_cycles(self):
        '''Returns the clock cycles for each basic block in the form. {'block',[# of clock cycles]}.
        Args:
            None: None
        Returns:
            Dict[str,list[int]]: The block with the number of clock cycles in a list. '''
        return {'0x836':[27],
                '0x86c':[6],
                '0x88c':[23],
                '0x8ba':[5],
                '0x7c8':[3],
                '0x7d0':[6],
                '0xnops':[6],
                }
    
class Soldering(Control_Flow):
    '''The Arduino Soldering Control Flow. '''
    def __init__(self):
        super().__init__()

    #override
    def control_flow(self):
        return ['0x4f0',
                '0x534',
                '0x538',
                '0x556',
                '0x6ef6',
                '0x68f2',
                '0x695c',
                '0x68f6',
                '0x6f00',
                '0x58e',
                '0x6ef6',
                '0x68f2',
                '0x695c',
                '0x68f6',
                '0x6f00',
                '0x59e',
                '0x5bf',
                '0x5ea', 
                '0x5e6', 
                '2',
                '0x5e6', 
                '2',
                '0x5e6', 
                '2',
                '0x5e6', 
                '2',
                '0x5e6', 
                '2',
                '0x5e6', 
                '2',
                '0x5e6', 
                '2',
                '0x5e6', 
                '2',
                '0x5e6', 
                '2',
                '0x5e6', 
                '1',
                '0x5ee',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops'
        ]

    #override
    def clock_cycles(self):
        '''Returns the clock cycles for each basic block in the form. {'block',[# of clock cycles]}.
        Args:
            None: None
        Returns:
            Dict[str,list[int]]: The block with the number of clock cycles in a list. '''
        return {'0x4f0':[39],
                '0x534':[3],
                '0x538':[5],
                '0x556':[34],
                '0x6ef6':[9],
                '0x68f2':[4],
                '0x695c':[22],
                '0x68f6':[15],
                '0x6f00':[19],
                '0x58e':[10],
                '0x59e':[16],
                '0x5bf':[21],
                '0x5ea':[3],
                '0x5e6':[3],
                '0x5ee':[16],
                '0xnops':[6],
                '2':[2],
                '1':[1]
                }

    
class Syringe_Pico(Control_Flow):
    '''The Syringe Pico Control Flow.'''
    def __init__(self):
        super().__init__()

    #override
    def control_flow(self):
        return ['0x384',
                '0x388',
                '0x38e',
                '0x400',
                '0x392',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '1',
                '0x38e',
                '0x400',
                '0x392',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '1',
                '0x3a4',
                '2',
                '0x38e',
                '0x400',
                '0x392',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '1',
                '0x38e',
                '0x400',
                '0x392',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '2',
                '0x394',
                '1',
                '0x3a4',
                '1',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
        ]

    #override
    def clock_cycles(self):
        '''Returns the clock cycles for each basic block in the form. {'block',[# of clock cycles]}.
        Args:
            None: None
        Returns:
            Dict[str,list[int]]: The block with the number of clock cycles in a list. '''
        return {'0x384':[2],
                '0x388':[3],
                '0x38e':[3],
                '0x400':[8],
                '0x392':[1],
                '0x394':[2],
                '0x3a4':[2],
                '0xnops':[6],
                '2':[2],
                '1':[1]
                }
    
class Syringe_Serial(Control_Flow):
    '''The Syringe Serial. Models the follwing Assembly:\n

    '''
    def __init__(self):
        super().__init__()

    #override
    def control_flow(self):
        return ['0x2078',
                '0x1614',
                '0x1664',
                '0x166e',
                '0x1642',
                '0x2eb6',
                '0x2eb8',
                '2',
                '0x2eb8', 
                '2',
                '0x2eb8', 
                '2',
                '0x2eb8', 
                '2',
                '0x2eb8', 
                '2',
                '0x2eb8', 
                '2',
                '0x2eb8', 
                '2',
                '0x2eb8', 
                '2',
                '0x2eb8', 
                '2',
                '0x2eb8',  
                '1',
                '0x2ec2',
                '0x1652',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
                '0xnops',
        ]

    #override
    def clock_cycles(self):
        '''Returns the clock cycles for each basic block in the form. {'block',[# of clock cycles]}.
        Args:
            None: None
        Returns:
            Dict[str,list[int]]: The block with the number of clock cycles in a list. '''
        return {'0x2078':[8],
                '0x1614':[19],
                '0x1664':[3],
                '0x166e':[5],
                '0x1642':[11],
                '0x2eb6':[2],
                '0x2eb8':[5],
                '0x2ec2':[4],
                '0x1652':[15],
                '0xnops':[6],
                '2':[2],
                '1':[1]
                }
    
class Servo(Control_Flow):
    '''The Servo Control Flow. Models the follwing Assembly:\n

    '''
    def __init__(self):
        super().__init__()

    #override
    def control_flow(self):
        return ['0x792',
                '0x16f0',
                '0x14a',
                '0x14e',
                '0x152',
                '0x156',
                '0x15e',
                '0xnops',
        ]

    #override
    def clock_cycles(self):
        '''Returns the clock cycles for each basic block in the form. {'block',[# of clock cycles]}.
        Args:
            None: None
        Returns:
            Dict[str,list[int]]: The block with the number of clock cycles in a list. '''
        return {'0x792': [18],
                '0x16f0':[8],
                '0x14a': [5],
                '0x14e': [3],
                '0x152': [4],
                '0x156': [2],
                '0x15e': [4],
                '0xnops':[32]
                }
    
class Servo_Pico(Control_Flow):
    '''The Servo Control Flow. Models the follwing Assembly:\n

    '''
    def __init__(self):
        super().__init__()

    #override
    def control_flow(self):
        return ['2',
                '0x3ac',
                '0x3c2',
                '0x3bc',
                '0x462',
                '0x476',
                '0x5780',
                '0x578e',
                '3',
                '0xnops',

        ]

    #override
    def clock_cycles(self):
        '''Returns the clock cycles for each basic block in the form. {'block',[# of clock cycles]}.
        Args:
            None: None
        Returns:
            Dict[str,list[int]]: The block with the number of clock cycles in a list. '''
        return {'0x3ac': [3],
                '0x3c2': [3],
                '0x3bc': [9],
                '0x462': [5],
                '0x476': [3],
                '0x5780': [10],
                '0x578e': [7],
                '0xnops':[32],
                '2':[2],
                '3':[3]
                }


if __name__=='__main__':
    pass