Example #1
0
    def simplify_line(self, line):
        ''' line: string
        returns: list
    '''
        changed = True
        depth = 0

        toks = line.split()
        try:
            while changed and depth < sg.max_recursive_depth:
                changed = False
                depth += 1
                toks, changed = self.group_args(toks, changed)
                #if sg.debug: sg.trace('changed = %s (toks = %s)' % (changed, toks))
                toks, changed = self.simplify_factors(toks, changed)
                #if sg.debug: sg.trace('changed = %s (toks = %s)' % (changed, toks))
                toks, changed = self.simplify_expansions(toks, changed)
                #if sg.debug: sg.trace('changed = %s (toks = %s)' % (changed, toks))
        except Exception as e:
            return [SilicaEvent('exception', exception=e)]

        if depth >= sg.max_recursive_depth:
            e = SilicaInternalError('Infinite loop detected, bailing out.')
            return [SilicaEvent('exception', exception=e)]

        #if sg.debug: sg.trace('line: %s' % toks)
        return toks
Example #2
0
 def toggledebug(sg, arglist):
     sg.toggle_debug()
     if sg.debug:
         msg = 'Debugging output enabled.'
     else:
         msg = 'Debugging output disabled.'
     return SilicaEvent('meta', message=msg)
Example #3
0
 def set_tempo(self, value, relative=False):
     if relative:
         self.set_tempo(self.tempo + value)
     else:
         if value < 20: value = 20
         if value > 400: value = 400
         self.tempo = value
     return SilicaEvent('tempo', notestate=self.makestate())
Example #4
0
 def set_vol(self, value, relative=False):
     if relative:
         self.set_vol(self.volume + value)
     else:
         if value < 0: value = 0
         if value > 16000: value = 16000
         self.volume = value
     return SilicaEvent('volume', notestate=self.makestate())
Example #5
0
 def rp(self):
     new = self.degree + 1
     if new == len(self.scale[-1]) + 1:
         new = 1
         if self.register < 9:
             self.register = self.register + 1
     self.degree = new
     self.deltadegree = 'raise'
     return SilicaEvent('pitch', notestate=self.makestate())
Example #6
0
 def lp(self):
     new = self.degree - 1
     if new == 0:
         new = len(self.scale[-1])
         if self.register > 0:
             self.register = self.register - 1
     self.degree = new
     self.deltadegree = 'lower'
     return SilicaEvent('pitch', notestate=self.makestate())
Example #7
0
    def define_macro(self, string):
        # = is syntactic sugar for >> begingroup ... endgroup
        splitter = '>>'
        if '=' in string:
            splitter = '='
        vals = string.split(splitter, 1)
        signature = vals[0].strip()
        if len(vals) == 2:
            body = vals[1].strip()

        if len(body) == 0:
            ex = SilicaSyntaxError(
                'Syntax error in macro definition: macro has no body.')
            return SilicaEvent('exception', exception=ex)

        vals = signature.split('(', 1)
        name = vals[0].strip().upper()

        if not self.valid_name(name):
            ex = SilicaNameError('The name %s is invalid in this context.' %
                                 name)
            return SilicaEvent('exception', exception=ex)

        args = None
        if len(vals) == 2:
            arglist = vals[1].strip()
            if len(arglist) > 0:
                if arglist[-1] != ')':
                    ex = SilicaSyntaxError(
                        'Syntax error in macro definition: unbounded arglist.')
                    return SilicaEvent('exception', exception=ex)
                else:
                    arglist = arglist[:-1]
                    arglist = arglist.split(',')
                    args = [a.strip() for a in arglist]

        if splitter == '=':
            body = 'begingroup ' + body + ' endgroup'
        sg.new_macro(name, body, args)
        return SilicaEvent('macro_def', message='Macro %s defined.' % name)
Example #8
0
 def change_scale(self, new_scale, relative=False):
     if relative:
         pitch = self.scale[-1].get_name_for_degree(self.degree)
         new_degree = new_scale.get_degree_for_name(pitch)
         if new_degree is None:
             # error!
             msg = 'Cannot change to scale %s relatively: pitch %s not in scale.' % (
                 new_scale.name, pitch)
             error = SilicaAlphabetError(msg)
             raise error
         else:
             self.degree = new_degree
             self.scale.append(new_scale)
     else:
         self.degree = 1
         self.scale.append(new_scale)
         self.deltadegree = 'same'
     return SilicaEvent('scale', notestate=self.makestate())
Example #9
0
 def pop_alphabet(self, relative=False):
     if len(self.scale) == 1:
         msg = 'Cannot pop alphabet: must leave one in stack.'
         error = SilicaAlphabetError(msg)
         raise error
     if relative:
         pitch = self.scale[-1].get_name_for_degree(self.degree)
         new_scale = self.scale[-2]
         new_degree = new_scale.get_degree_for_name(pitch)
         if new_degree is None:
             msg = 'Cannot pop to scale %s relatively: pitch %s not in scale.' % (
                 new_scale.name, pitch)
             error = SilicaAlphabetError(msg)
             raise error
         self.scale.pop()
         self.degree = new_degree
     else:
         self.scale.pop()
         self.degree = 1
         self.deltadegree = 'same'
     return SilicaEvent('scale', notestate=self.makestate())
Example #10
0
 def play(self):
     se = SilicaEvent('play', notestate=self.makestate())
     self.prevregister = self.register
     self.deltadegree = 'same'
     return se
Example #11
0
 def shrink(self, factor):
     self.duration /= factor
     return SilicaEvent('duration', notestate=self.makestate())
Example #12
0
    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
Example #13
0
 def endgroup(self):
     return SilicaEvent('endgroup', notestate=self.makestate())
Example #14
0
 def begingroup(self):
     return SilicaEvent('begingroup', notestate=self.makestate())
Example #15
0
 def popstate(self):
     if len(self.statestack) > 0:
         self.applystate(self.statestack.pop())
     return SilicaEvent('pushstate', notestate=self.makestate())
Example #16
0
 def pushstate(self):
     state = self.makestate()
     self.statestack.append(state)
     return SilicaEvent('pushstate', notestate=state)
Example #17
0
 def rest(self):
     return SilicaEvent('rest', notestate=self.makestate())
Example #18
0
 def expand(self, factor):
     self.duration *= factor
     return SilicaEvent('duration', notestate=self.makestate())
Example #19
0
 def change_instrument(self, instrument):
     self.instrument = instrument
     return SilicaEvent('instrument', notestate=self.makestate())