def valid_name(self, name): forbidden_chars = ['(', ')', ':', '=', '+', '-', ',', '>>'] for c in forbidden_chars: if c in name: return False element, etype = sg.get_token(name) if element and etype in ['primitive', 'metacommand', 'transform']: return False return True
def simplify_expansions(self, toks, changed): toks2 = [] changed = changed for tok in toks: n = tok arglist = None if '(' in tok: n, args = tok.split('(', 1) args = args[:-1] level = 0 curarg = '' arglist = [] for ch in args: if ch == ',' and level == 0: arglist.append(curarg.strip()) curarg = '' continue curarg = curarg + ch if ch == '(': level += 1 continue if ch == ')': level -= 1 continue arglist.append(curarg.strip()) #if sg.debug: sg.trace('arglist: %s' % arglist) element, etype = sg.get_token(n) if element is not None and etype == 'macro' and not self.mcmode: v = self.run_macro(element, arglist).split() for e in v: toks2.append(e) changed = True elif etype == 'metacommand' and self.mcmode: v = [self.run_metacommand(element, arglist)] # if sg.debug: sg.trace('meta: %s' % v) return v, False # short circut else: toks2.append(tok) #if sg.debug: sg.trace('toks2: %s' % toks2) return toks2, changed
def simplify_expansions(self, toks, changed): toks2 = [] changed = changed for tok in toks: n = tok arglist = None if '(' in tok: n,args = tok.split('(',1) args = args[:-1] level = 0 curarg = '' arglist = [] for ch in args: if ch == ',' and level == 0: arglist.append(curarg.strip()) curarg = '' continue curarg = curarg + ch if ch == '(': level += 1 continue if ch == ')': level -= 1 continue arglist.append(curarg.strip()) #if sg.debug: sg.trace('arglist: %s' % arglist) element, etype = sg.get_token(n) if element is not None and etype == 'macro' and not self.mcmode: v = self.run_macro(element, arglist).split() for e in v: toks2.append(e) changed = True elif etype == 'metacommand' and self.mcmode: v = [self.run_metacommand(element, arglist)] # if sg.debug: sg.trace('meta: %s' % v) return v,False # short circut else: toks2.append(tok) #if sg.debug: sg.trace('toks2: %s' % toks2) return toks2,changed
def parse_line(self, string, reset=True): if reset: self.reset_parsing_state() #@+<< metacommand mode >> #@+node:peckj.20140318084140.4613: *4* << metacommand mode >> if string.startswith('-'): self.mcmode = True #@-<< metacommand mode >> self.notestate = sg.note.makestate() # to recover from errors without affecting note.statestack #@+<< macro definition >> #@+node:peckj.20140318084140.4611: *4* << macro definition >> if '>>' in string or '=' in string: # define macro! event = self.define_macro(string) return [event] #@-<< macro definition >> #@+<< mode definition >> #@+node:peckj.20140318084140.4612: *4* << mode definition >> if '!!' in string: ## STUB # define mode! return [] #@-<< mode definition >> #@+<< auto invariance mode >> #@+node:peckj.20140318084140.4614: *4* << auto invariance mode >> if sg.auto_invariance: string = ' '.join(['pushstate', string, 'popstate']) #@-<< auto invariance mode >> toks = self.simplify_line(string) if len(toks) == 1 and type(toks[0]) is SilicaEvent: return toks out = [] #@+<< interpret tokens >> #@+node:peckj.20140318084140.4615: *4* << interpret tokens >> for tok in toks: #if sg.debug: print tok # should all be primitives + metacommands by now... try: element, etype = sg.get_token(tok) #if sg.debug: print (element, etype) if element is not None and etype is not None: v = self.fn_table[etype](element) if v is not None: # v may be a list, in which case, append them all separately if hasattr(v, '__iter__') and not isinstance(v, basestring): for e in v: out.append(e) else: out.append(v) else: raise SilicaInternalError('No fn_table type defined in parser for type %s' % etype) else: raise SilicaNameError('No token named %s exists in the current namespace' % tok) except Exception as e: sg.note.applystate(self.notestate) # exception occurred, the notestate must be reset return [SilicaEvent('exception', exception=e)] # only return the exception! #@-<< interpret tokens >> #@+<< groups balanced >> #@+node:peckj.20140318084140.4616: *4* << groups balanced >> if self.groups_are_balanced(out): return out else: e = SilicaGroupError('Groups are unbalanced.') sg.note.applystate(self.notestate) return [SilicaEvent('exception', exception=e)] #@-<< groups balanced >> return out
def parse_line(self, string, reset=True): if reset: self.reset_parsing_state() #@+<< metacommand mode >> #@+node:peckj.20140318084140.4613: *4* << metacommand mode >> if string.startswith('-'): self.mcmode = True #@-<< metacommand mode >> self.notestate = sg.note.makestate( ) # to recover from errors without affecting note.statestack #@+<< macro definition >> #@+node:peckj.20140318084140.4611: *4* << macro definition >> if '>>' in string or '=' in string: # define macro! event = self.define_macro(string) return [event] #@-<< macro definition >> #@+<< mode definition >> #@+node:peckj.20140318084140.4612: *4* << mode definition >> if '!!' in string: ## STUB # define mode! return [] #@-<< mode definition >> #@+<< auto invariance mode >> #@+node:peckj.20140318084140.4614: *4* << auto invariance mode >> if sg.auto_invariance: string = ' '.join(['pushstate', string, 'popstate']) #@-<< auto invariance mode >> toks = self.simplify_line(string) if len(toks) == 1 and type(toks[0]) is SilicaEvent: return toks out = [] #@+<< interpret tokens >> #@+node:peckj.20140318084140.4615: *4* << interpret tokens >> for tok in toks: #if sg.debug: print tok # should all be primitives + metacommands by now... try: element, etype = sg.get_token(tok) #if sg.debug: print (element, etype) if element is not None and etype is not None: v = self.fn_table[etype](element) if v is not None: # v may be a list, in which case, append them all separately if hasattr(v, '__iter__') and not isinstance( v, basestring): for e in v: out.append(e) else: out.append(v) else: raise SilicaInternalError( 'No fn_table type defined in parser for type %s' % etype) else: raise SilicaNameError( 'No token named %s exists in the current namespace' % tok) except Exception as e: sg.note.applystate( self.notestate ) # exception occurred, the notestate must be reset return [SilicaEvent('exception', exception=e)] # only return the exception! #@-<< interpret tokens >> #@+<< groups balanced >> #@+node:peckj.20140318084140.4616: *4* << groups balanced >> if self.groups_are_balanced(out): return out else: e = SilicaGroupError('Groups are unbalanced.') sg.note.applystate(self.notestate) return [SilicaEvent('exception', exception=e)] #@-<< groups balanced >> return out