Archived
1
0

Adding list to tuple conversion and USBCode to Capabiltiy conversion.

This commit is contained in:
Jacob Alexander 2014-09-06 12:35:22 -07:00
parent 2d76b5a6ca
commit a005ad49ad
4 changed files with 113 additions and 46 deletions

View File

@ -60,6 +60,11 @@ class Backend:
self.tagList.append( item ) self.tagList.append( item )
# USB Code Capability Name
def usbCodeCapability( self ):
return "usbKeyOut";
# Processes content for fill tags and does any needed dataset calculations # Processes content for fill tags and does any needed dataset calculations
def process( self, capabilities ): def process( self, capabilities ):
## Capabilities ## ## Capabilities ##

View File

@ -2,16 +2,21 @@ Name = colemak;
Author = "HaaTa (Jacob Alexander) 2014"; Author = "HaaTa (Jacob Alexander) 2014";
KLL = 0.3; KLL = 0.3;
usbKeyOut => Output_usbCodeSend_capability( usbCode : 1 );
myCapability2 => myFunc2(); myCapability2 => myFunc2();
myCapability3 => myFunc3( myArg1 : 2 ); myCapability3 => myFunc3( myArg1 : 2 );
myCapability => myFunc( myArg1 : 1, myArg2 : 4 ); myCapability => myFunc( myArg1 : 1, myArg2 : 4 );
S0x3 : myCapability2(); S0x3 : myCapability2();
S0x4 : myCapability( 0x8, 0x25 );
S0x12 : U[122] + U[123];
S0x6 : 'abcdDfF'; S0x6 : 'abcdDfF';
S0x40 : U[0x1]; S0x40 : U[0x1];
S0x40 : U[0x1-0x4]; S0x40 : U[0x1-0x4];
S0x0B : U["Esc"]; S0x0B : U["Esc"];
S0x0B :+ U["Q"];
S[ 0x7 - 0x9 ] : U"6"; S[ 0x7 - 0x9 ] : U"6";
S[ 0x7 - 0x9 ], S[0x2,0x3] : U"6"; S[ 0x7 - 0x9 ], S[0x2,0x3] : U"6";
S[ 0x2 - 0x9, 0x10 ] : U"r"; S[ 0x2 - 0x9, 0x10 ] :+ U"r";
S0x0B :- U["Esc"];

104
kll.py
View File

@ -83,9 +83,9 @@ def processCommandLineArgs():
help="Specify .kll files to generate partial map, multiple files per flag.\n" help="Specify .kll files to generate partial map, multiple files per flag.\n"
"Each -p defines another partial map.\n" "Each -p defines another partial map.\n"
"Base .kll files (that define the scan code maps) must be defined for each partial map." ) "Base .kll files (that define the scan code maps) must be defined for each partial map." )
pArgs.add_argument( '-t', '--template', type=str, default="templateKeymap.h", pArgs.add_argument( '-t', '--template', type=str, default="templates/kiibohdKeymap.h",
help="Specify template used to generate the keymap.\n" help="Specify template used to generate the keymap.\n"
"Default: templateKeymap.h" ) "Default: templates/kiibohdKeymap.h" )
pArgs.add_argument( '-o', '--output', type=str, default="templateKeymap.h", pArgs.add_argument( '-o', '--output', type=str, default="templateKeymap.h",
help="Specify output file. Writes to current working directory by default.\n" help="Specify output file. Writes to current working directory by default.\n"
"Default: generatedKeymap.h" ) "Default: generatedKeymap.h" )
@ -133,10 +133,10 @@ def tokenize( string ):
( 'CodeEnd', ( r'\]', ) ), ( 'CodeEnd', ( r'\]', ) ),
( 'String', ( r'"[^"]*"', VERBOSE ) ), ( 'String', ( r'"[^"]*"', VERBOSE ) ),
( 'SequenceString', ( r"'[^']*'", ) ), ( 'SequenceString', ( r"'[^']*'", ) ),
( 'Operator', ( r'=>|:\+|:-|:|=', ) ),
( 'Comma', ( r',', ) ), ( 'Comma', ( r',', ) ),
( 'Dash', ( r'-', ) ), ( 'Dash', ( r'-', ) ),
( 'Plus', ( r'\+', ) ), ( 'Plus', ( r'\+', ) ),
( 'Operator', ( r'=>|:|=', ) ),
( 'Parenthesis', ( r'\(|\)', ) ), ( 'Parenthesis', ( r'\(|\)', ) ),
( 'Number', ( r'-?(0x[0-9a-fA-F]+)|(0|([1-9][0-9]*))', VERBOSE ) ), ( 'Number', ( r'-?(0x[0-9a-fA-F]+)|(0|([1-9][0-9]*))', VERBOSE ) ),
( 'Name', ( r'[A-Za-z_][A-Za-z_0-9]*', ) ), ( 'Name', ( r'[A-Za-z_][A-Za-z_0-9]*', ) ),
@ -155,8 +155,7 @@ def tokenize( string ):
### Parsing ### ### Parsing ###
## Map Arrays ## Map Arrays
scanCode_map = [ None ] * 0xFF # Define 8 bit address width macros_map = Macros()
usbCode_map = [ None ] * 0xFF # Define 8 bit address width
variable_dict = dict() variable_dict = dict()
capabilities_dict = Capabilities() capabilities_dict = Capabilities()
@ -301,6 +300,9 @@ eol = a( Token( 'EndOfLine', ';' ) )
def listElem( item ): def listElem( item ):
return [ item ] return [ item ]
def listToTuple( items ):
return tuple( items )
# Flatten only the top layer (list of lists of ...) # Flatten only the top layer (list of lists of ...)
def oneLayerFlatten( items ): def oneLayerFlatten( items ):
mainList = [] mainList = []
@ -357,26 +359,72 @@ def optionExpansion( sequences ):
return expandedSequences return expandedSequences
# Converts USB Codes into Capabilities
def usbCodeToCapability( items ):
# Items already converted to variants using optionExpansion
for variant in range( 0, len( items ) ):
# Sequence of Combos
for sequence in range( 0, len( items[ variant ] ) ):
for combo in range( 0, len( items[ variant ][ sequence ] ) ):
# Only convert if an integer, otherwise USB Code doesn't need converting
if isinstance( items[ variant ][ sequence ][ combo ], int ):
# Use backend capability name and a single argument
items[ variant ][ sequence ][ combo ] = tuple( [ backend.usbCodeCapability(), tuple( [ items[ variant ][ sequence ][ combo ] ] ) ] )
return items
## Evaluation Rules ## Evaluation Rules
def eval_scanCode( trigger, result ): def eval_scanCode( triggers, operator, results ):
# Convert to lists of lists of lists to tuples of tuples of tuples # Convert to lists of lists of lists to tuples of tuples of tuples
trigger = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in trigger ) # Tuples are non-mutable, and can be used has index items
result = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in result ) triggers = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in triggers )
results = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in results )
# Add to the base scanCode map, overwrite if already defined # Iterate over all combinations of triggers and results
# if scanCode_map[ trigger ] != None: for trigger in triggers:
# print ( "ScanCodeMap - Replacing '{0}' with '{1}' -> {2}".format( scanCode_map[ trigger ], result, trigger ) ) for result in results:
# scanCode_map[ trigger ] = result # Append Case
if operator == ":+":
macros_map.appendScanCode( trigger, result )
def eval_usbCode( trigger, result ): # Remove Case
# Check if trigger is list elif operator == ":-":
macros_map.removeScanCode( trigger, result )
# Add to the base usbCode map, overwrite if already defined # Replace Case
if usbCode_map[ trigger ] != None: elif operator == ":":
print ( "USBCodeMap - Replacing '{0}' with '{1}' -> {2}".format( usbCode_map[ trigger ], result, trigger ) ) macros_map.replaceScanCode( trigger, result )
usbCode_map[ trigger ] = result
print ( trigger ) print ( triggers )
print ( results )
def eval_usbCode( triggers, operator, results ):
# Convert to lists of lists of lists to tuples of tuples of tuples
# Tuples are non-mutable, and can be used has index items
triggers = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in triggers )
results = tuple( tuple( tuple( sequence ) for sequence in variant ) for variant in results )
# Iterate over all combinations of triggers and results
for trigger in triggers:
scanCodes = macros_map.lookupUSBCodes( trigger )
for scanCode in scanCodes:
for result in results:
# Append Case
if operator == ":+":
macros_map.appendScanCode( scanCode, result )
# Remove Case
elif operator == ":-":
macros_map.removeScanCode( scanCode, result )
# Replace Case
elif operator == ":":
macros_map.replaceScanCode( scanCode, result )
#print ( triggers )
print ( results )
def eval_variable( name, content ): def eval_variable( name, content ):
# Content might be a concatenation of multiple data types, convert everything into a single string # Content might be a concatenation of multiple data types, convert everything into a single string
@ -435,15 +483,15 @@ usbCode_combo = oneplus( ( usbCode_expanded | usbCode_elem ) + skip( maybe
usbCode_sequence = oneplus( ( usbCode_combo | seqString ) + skip( maybe( comma ) ) ) >> oneLayerFlatten usbCode_sequence = oneplus( ( usbCode_combo | seqString ) + skip( maybe( comma ) ) ) >> oneLayerFlatten
# Capabilities # Capabilities
capFunc_arguments = number + skip( maybe( comma ) ) capFunc_arguments = many( number + skip( maybe( comma ) ) ) >> listToTuple
capFunc_elem = name + skip( parenthesis('(') ) + many( capFunc_arguments ) + skip( parenthesis(')') ) >> listElem capFunc_elem = name + skip( parenthesis('(') ) + capFunc_arguments + skip( parenthesis(')') ) >> listElem
capFunc_combo = oneplus( ( usbCode_expanded | usbCode_elem | capFunc_elem ) + skip( maybe( plus ) ) ) >> listElem capFunc_combo = oneplus( ( usbCode_expanded | usbCode_elem | capFunc_elem ) + skip( maybe( plus ) ) ) >> listElem
capFunc_sequence = oneplus( ( capFunc_combo | seqString ) + skip( maybe( comma ) ) ) >> oneLayerFlatten capFunc_sequence = oneplus( ( capFunc_combo | seqString ) + skip( maybe( comma ) ) ) >> oneLayerFlatten
# Trigger / Result Codes # Trigger / Result Codes
triggerCode_outerList = scanCode_sequence >> optionExpansion triggerCode_outerList = scanCode_sequence >> optionExpansion
triggerUSBCode_outerList = usbCode_sequence >> optionExpansion triggerUSBCode_outerList = usbCode_sequence >> optionExpansion >> usbCodeToCapability
resultCode_outerList = capFunc_sequence >> optionExpansion resultCode_outerList = capFunc_sequence >> optionExpansion >> usbCodeToCapability
## Main Rules ## Main Rules
@ -457,8 +505,9 @@ capability_arguments = name + skip( operator(':') ) + number + skip( maybe( com
capability_expression = name + skip( operator('=>') ) + name + skip( parenthesis('(') ) + many( capability_arguments ) + skip( parenthesis(')') ) + skip( eol ) >> set_capability capability_expression = name + skip( operator('=>') ) + name + skip( parenthesis('(') ) + many( capability_arguments ) + skip( parenthesis(')') ) + skip( eol ) >> set_capability
#| <trigger> : <result>; #| <trigger> : <result>;
scanCode_expression = triggerCode_outerList + skip( operator(':') ) + resultCode_outerList + skip( eol ) >> map_scanCode operatorTriggerResult = operator(':') | operator(':+') | operator(':-')
usbCode_expression = triggerUSBCode_outerList + skip( operator(':') ) + resultCode_outerList + skip( eol ) #>> map_usbCode scanCode_expression = triggerCode_outerList + operatorTriggerResult + resultCode_outerList + skip( eol ) >> map_scanCode
usbCode_expression = triggerUSBCode_outerList + operatorTriggerResult + resultCode_outerList + skip( eol ) #>> map_usbCode
def parse( tokenSequence ): def parse( tokenSequence ):
"""Sequence(Token) -> object""" """Sequence(Token) -> object"""
@ -489,15 +538,14 @@ if __name__ == '__main__':
data = file.read() data = file.read()
tokenSequence = tokenize( data ) tokenSequence = tokenize( data )
print ( pformat( tokenSequence ) ) print ( pformat( tokenSequence ) ) # Display tokenization
tree = parse( tokenSequence ) tree = parse( tokenSequence )
#print ( tree ) #print ( tree )
#print ( scanCode_map )
#print ( usbCode_map )
print ( variable_dict ) print ( variable_dict )
print ( capabilities_dict ) print ( capabilities_dict )
# TODO Move # TODO Move
#macros_map.usbCodeToCapability( backend.usbCodeCapability() )
backend.process( capabilities_dict ) backend.process( capabilities_dict )
# Successful Execution # Successful Execution

View File

@ -84,31 +84,40 @@ class Macros:
self.layer = 0 self.layer = 0
# Macro Storage # Macro Storage
self.macros = [ [] ] self.macros = [ dict() ]
def __repr__( self ):
return "{0}".format( self.macros )
def setLayer( self, layer ): def setLayer( self, layer ):
self.layer = layer self.layer = layer
# Use for ScanCode trigger macros # Use for ScanCode trigger macros
def appendScanCode( self, trigger, result ): def appendScanCode( self, trigger, result ):
self.macros[ self.layer ][ trigger ] = result if not trigger in self.macros[ self.layer ]:
self.replaceScanCode( trigger, result )
else:
self.macros[ self.layer ][ trigger ].append( result )
# Use for USBCode trigger macros # Remove the given trigger/result pair
# An extra lookup is required def removeScanCode( self, trigger, result ):
def appendUSBCode( self, trigger, result ): # Remove all instances of the given trigger/result pair
noSuccess = True while result in self.macros[ self.layer ][ trigger ]:
self.macros[ self.layer ][ trigger ].remove( result )
# Replaces the given trigger with the given result
# If multiple results for a given trigger, clear, then add
def replaceScanCode( self, trigger, result ):
self.macros[ self.layer ][ trigger ] = [ result ]
# Return a list of ScanCode triggers with the given USB Code trigger
def lookupUSBCodes( self, usbCode ):
scanCodeList = []
# Scan current layer for USB Codes
for macro in self.macros[ self.layer ].keys(): for macro in self.macros[ self.layer ].keys():
# USB Code Found if usbCode == self.macros[ self.layer ][ macro ]:
if trigger == self.macros[ self.layer ][ macro ]: scanCodeList.append( macro )
print ( "USBCode - Replacing '{0}' with '{1}' -> '{2}'".format( trigger, macro, result ) )
self.macros[ self.layer ][ macro ] = result
noSuccess = False
# Only show warning if no replacements were done return scanCodeList
if noSuccess:
print ( "Warning: '{1}' USB Code not found in layer {1}".format( trigger, self.layer ) )
return False
return True