diff --git a/README.markdown b/README.markdown index 9bd8c03..d92e455 100644 --- a/README.markdown +++ b/README.markdown @@ -27,7 +27,7 @@ kll ### Kiibohd Controller Usage ```bash -kll.py --config --base --partial --partial +kll --config --base --partial --partial ``` See `kll --help` for the most up to date documentation diff --git a/common/stage.py b/common/stage.py index c04b213..1ffeb1f 100644 --- a/common/stage.py +++ b/common/stage.py @@ -864,7 +864,7 @@ class OperationSpecificsStage( Stage ): ( 'AnimationStart', ( r'A\[', ) ), ( 'CodeBegin', ( r'\[', ) ), ( 'CodeEnd', ( r'\]', ) ), - ( 'Position', ( r'r?[xyz]:[0-9]+(.[0-9]+)?', ) ), + ( 'Position', ( r'r?[xyz]:-?[0-9]+(.[0-9]+)?', ) ), ( 'Comma', ( r',', ) ), ( 'Dash', ( r'-', ) ), @@ -887,7 +887,7 @@ class OperationSpecificsStage( Stage ): ( 'ScanCodeStart', ( r'S\[', ) ), ( 'CodeBegin', ( r'\[', ) ), ( 'CodeEnd', ( r'\]', ) ), - ( 'Position', ( r'r?[xyz]:[0-9]+(.[0-9]+)?', ) ), + ( 'Position', ( r'r?[xyz]:-?[0-9]+(.[0-9]+)?', ) ), ( 'PixelOperator', ( r'(\+:|-:|>>|<<)', ) ), ( 'String', ( r'"[^"]*"', ) ), @@ -897,7 +897,7 @@ class OperationSpecificsStage( Stage ): ( 'Dash', ( r'-', ) ), ( 'Plus', ( r'\+', ) ), ( 'Parenthesis', ( r'\(|\)', ) ), - ( 'Percent', ( r'0|([1-9][0-9]*)%', ) ), + ( 'Percent', ( r'(0|([1-9][0-9]*))%', ) ), ( 'Number', ( r'-?(0x[0-9a-fA-F]+)|(0|([1-9][0-9]*))', ) ), ( 'Name', ( r'[A-Za-z_][A-Za-z_0-9]*', ) ), ] diff --git a/emitters/kiibohd/kiibohd.py b/emitters/kiibohd/kiibohd.py index 5ba3ddf..44f1bc5 100644 --- a/emitters/kiibohd/kiibohd.py +++ b/emitters/kiibohd/kiibohd.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 ''' -KLL Kiibohd .h File Emitter +KLL Kiibohd .h/.c File Emitter ''' # Copyright (C) 2016 by Jacob Alexander @@ -238,10 +238,12 @@ class Kiibohd( Emitter, TextEmitter ): variables = full_context.query( 'AssignmentExpression', 'Variable' ) for dkey, dvalue in sorted( defines.data.items() ): if dvalue.name in variables.data.keys(): - self.fill_dict['Defines'] += "\n#define {0} {1}".format( - dvalue.association, - variables.data[ dvalue.name ].value.replace( '\n', ' \\\n' ), - ) + # TODO Handle arrays + if not isinstance( variables.data[ dvalue.name ].value, list ): + self.fill_dict['Defines'] += "\n#define {0} {1}".format( + dvalue.association, + variables.data[ dvalue.name ].value.replace( '\n', ' \\\n' ), + ) else: print( "{0} '{1}' not defined...".format( WARNING, dvalue.name ) ) diff --git a/examples/assignment.kll b/examples/assignment.kll index c4794c1..5db85d6 100644 --- a/examples/assignment.kll +++ b/examples/assignment.kll @@ -3,3 +3,7 @@ Array[] = a b c "b c" 3; Index[5] = "this text" thing; # Single element Index[6] = moar; +Variable => Variable_define; +Array => Array_define; +Index => Index_define; + diff --git a/examples/leds.kll b/examples/leds.kll index 757d7f7..f7974ea 100644 --- a/examples/leds.kll +++ b/examples/leds.kll @@ -54,6 +54,10 @@ A[BLEEdsing2, 8] <= U"B"(40,50,0x60); A[BLEEdsing2, 9] <= S120(40,50,0x60); A[BLEEdsing2, 10] <= S[0x10](40,50,0x60); +A[RainbowFillInterp] <= start, interp:on; +A[RainbowFillInterp, 1] <= P[c:20%](255,255,0), P[c:40%](255,0,0), P[c:60%](127,0,255), P[c:80%](0,0,255); +A[RainbowFillInterp, 2] <= P[c:0%](0,255,0), P[c:20%](255,255,0), P[c:40%](255,0,0), P[c:60%](127,0,255), P[c:80%](0,0,255); + # Animation Triggers myCapability => myFunc( myArg1 : 1, myArg2 : 4 ); A[BLEEdsing, 3] : myCapability( 0x8, 0x25 ); diff --git a/funcparserlib/parser.py b/funcparserlib/parser.py index 061206d..df294d6 100644 --- a/funcparserlib/parser.py +++ b/funcparserlib/parser.py @@ -151,7 +151,7 @@ class Parser(object): tok = tokens[max] else: tok = '' - raise NoParseError('%s: %s' % (e.msg, tok), e.state) + raise NoParseError('%s: %s' % (e.msg, tok), e.state, tok) def __add__(self, other): """Parser(a, b), Parser(a, c) -> Parser(a, _Tuple(b, c)) @@ -265,9 +265,10 @@ class State(object): class NoParseError(Exception): - def __init__(self, msg='', state=None): + def __init__(self, msg='', state=None, token=None): self.msg = msg self.state = state + self.token = token # Next token def __str__(self): return self.msg @@ -294,7 +295,7 @@ def finished(tokens, s): if s.pos >= len(tokens): return None, s else: - raise NoParseError('should have reached ', s) + raise NoParseError('should have reached ', s, tokens[s.pos]) finished.name = 'finished' @@ -344,7 +345,7 @@ def some(pred): else: if debug: log.debug('failed "%s", state = %s' % (t, s)) - raise NoParseError('got unexpected token', s) + raise NoParseError('got unexpected token', s, t) _some.name = '(some)' return _some diff --git a/kll.py b/kll.py index 097bf15..95b3c81 100755 --- a/kll.py +++ b/kll.py @@ -149,10 +149,14 @@ def tokenize( string ): ( 'LedCodeStart', ( r'LED\[', ) ), ( 'ScanCode', ( r'S((0x[0-9a-fA-F]+)|([0-9]+))', ) ), ( 'ScanCodeStart', ( r'S\[', ) ), + ( 'PixelCodeStart', ( r'P\[.*', ) ), # Discarded, needs KLL 0.5 + ( 'AnimationStart', ( r'A\[.*', ) ), # Discarded, needs KLL 0.5 + ( 'CodeStart', ( r'\[', ) ), ( 'CodeEnd', ( r'\]', ) ), ( 'String', ( r'"[^"]*"', ) ), ( 'SequenceString', ( r"'[^']*'", ) ), - ( 'Operator', ( r'=>|:\+|:-|::|:|=', ) ), + ( 'Position', ( r'r?[xyz]:-?[0-9]+(.[0-9]+)?', ) ), + ( 'Operator', ( r'<=|=>|:\+|:-|::|:|=', ) ), ( 'Number', ( r'(-[ \t]*)?((0x[0-9a-fA-F]+)|(0|([1-9][0-9]*)))', VERBOSE ) ), ( 'Comma', ( r',', ) ), ( 'Dash', ( r'-', ) ), @@ -167,6 +171,9 @@ def tokenize( string ): # Tokens to filter out of the token stream useless = ['Space', 'Comment'] + # Discarded expresssions (KLL 0.4+) + useless.extend( ['PixelCodeStart', 'AnimationStart'] ) + tokens = make_tokenizer( specs ) return [x for x in tokens( string ) if x.type not in useless] @@ -596,6 +603,7 @@ sysCode = tokenType('SysCode') >> make_sysCode none = tokenType('None') >> make_none name = tokenType('Name') number = tokenType('Number') >> make_number +position = tokenType('Position') comma = tokenType('Comma') dash = tokenType('Dash') plus = tokenType('Plus') @@ -606,7 +614,8 @@ seqString = tokenType('SequenceString') >> make_seqString unseqString = tokenType('SequenceString') >> make_unseqString # For use with variables # Code variants -code_end = tokenType('CodeEnd') +code_start = tokenType('CodeStart') +code_end = tokenType('CodeEnd') # Scan Codes scanCode_start = tokenType('ScanCodeStart') @@ -669,7 +678,7 @@ resultCode_outerList = ( ( capFunc_sequence >> optionExpansion ) | none ) >> #| = ; variable_contents = name | content | string | number | comma | dash | unseqString -variable_expression = name + skip( operator('=') ) + oneplus( variable_contents ) + skip( eol ) >> set_variable +variable_expression = name + skip( maybe( code_start + maybe( number ) + code_end ) ) + skip( operator('=') ) + oneplus( variable_contents ) + skip( eol ) >> set_variable #| => ; capability_arguments = name + skip( operator(':') ) + number + skip( maybe( comma ) ) @@ -683,11 +692,14 @@ operatorTriggerResult = operator(':') | operator(':+') | operator(':-') | operat scanCode_expression = triggerCode_outerList + operatorTriggerResult + resultCode_outerList + skip( eol ) >> map_scanCode usbCode_expression = triggerUSBCode_outerList + operatorTriggerResult + resultCode_outerList + skip( eol ) >> map_usbCode +### Ignored expressions +ignore_expression = scanCode_expanded | scanCode + operator('<=') + oneplus( position + maybe( skip( comma ) )) + eol + def parse( tokenSequence ): """Sequence(Token) -> object""" # Top-level Parser - expression = scanCode_expression | usbCode_expression | variable_expression | capability_expression | define_expression + expression = ignore_expression | scanCode_expression | usbCode_expression | variable_expression | capability_expression | define_expression kll_text = many( expression ) kll_file = maybe( kll_text ) + skip( finished ) @@ -708,8 +720,10 @@ def processKLLFile( filename ): try: tree = parse( tokenSequence ) except (NoParseError, KeyError) as err: - print ( "{0} Parsing error in '{1}' - {2}".format( ERROR, filename, err ) ) - sys.exit( 1 ) + # Ignore data association expressions KLL 0.4+ required + if err.token.value != '<=': + print ( "{0} Parsing error in '{1}' - {2}".format( ERROR, filename, err ) ) + sys.exit( 1 ) ### Misc Utility Functions ###