Пример #1
0
    def is_valid_division(self, tree):
        if not type(tree) is self.treetype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(tree)) + ' is not ' + str(self.treetype) + '.')

        if not tree.data == 'division':
            return False

        if not tree.children[0].data == 'number':
            raise exceptions.ValidationError('Tree prefix incorrect: ' + str(tree.data) + ' given, number expected.')

        if not tree.children[1].data == 'number':
            raise exceptions.ValidationError('Tree prefix incorrect: ' + str(tree.data) + ' given, number expected.')

        if not len(tree.children) == 2:
            raise exceptions.SemanticError('2 children expected, ' + len(tree.children[0].children) + ' given.')

        if not int(tree.children[0].children[0].value) > 0:
            raise exceptions.SemanticError('Positive/nonzero value needed for division numerator.')

        denom = int(tree.children[1].children[0].value)
        validDenoms = [1, 2, 4, 8, 16, 32, 64, 128]
        if denom not in validDenoms:
            raise exceptions.DivisionError('Division denominator must be power of 2.')

        return True
Пример #2
0
    def is_valid_identifier(self, tree):
        if not type(tree) is self.treetype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(tree)) + ' is not ' + str(self.treetype) + '.')

        if not tree.data == 'id':
            return False

        theID = tree.children[0]
        length = len(theID)

        if length < 2:
            raise exceptions.SemanticError('At least 2 children expected, ' + len(tree.children[0].children) + ' given.')

        if theID[0] != '$':
            raise exceptions.SemanticError('Identifier must begin with \'$\'')

        if not theID[1].isalpha():
            raise exceptions.SemanticError('Identifier first non-$ must be alpha-non-numeric.')

        for i in range(2, length):
            idChar = theID[i]
            if not(idChar.isalnum() or idChar == '_' or idChar == '-'):
                raise exceptions.SemanticError('Identifier may only contain alphanumeric, _, and -.')

        return True
Пример #3
0
def _cmp(t):
    t1 = _typeof(t.children[0])
    t2 = _typeof(t.children[1])
    if t1.isInteger():
        if t2 == t1:
            return BoolType()
        else:
            raise exceptions.SemanticError(
                Position.fromAny(t),
                f"Incompatible types: {str(t1)} and {str(t2)}")
    else:
        raise exceptions.SemanticError(Position.fromAny(t),
                                       f"Wrong arithmetic type: {str(t1)}")
Пример #4
0
 def neg(self, tree):
     t = _typeof(tree.children[0])
     if t.isInteger():
         return t
     else:
         raise exceptions.SemanticError(
             Position.fromAny(tree), f"Wrong type for negation: {str(t)}")
Пример #5
0
 def lnot(self, tree):
     t = _typeof(tree.children[0])
     if t.isBool():
         return BoolType()
     else:
         raise exceptions.SemanticError(
             Position.fromAny(tree),
             f"Wrong type for logical not: {str(t)}")
Пример #6
0
def addsub(tree, op, pattern):
    a, b = tree.children
    if isinstance(a, Tree) or isinstance(b, Tree):
        return tree
    if a.getIndirLevel() > 0 or b.getIndirLevel() > 0:
        return tree
    if a.getType().isPointer():
        if not b.getType().isInteger():
            raise exceptions.SemanticError(
                Position.fromAny(tree),
                f"Cannot add {str(b.getType())} to a pointer")
    else:
        if a.getType() != b.getType():
            raise exceptions.SemanticError(
                Position.fromAny(tree), "Incompatible types in an expression")
    if not a.isConstNumber() or not b.isConstNumber():
        if not a.getType().isPointer():
            if a.getType().getSign():
                print(str(a))
                print(str(b))
                raise exceptions.SemanticError(Position.fromAny(tree),
                                               "Signed label? WTF is that? 1")
            return Value(Position.fromAny(tree), a.getType(), 0,
                         pattern.format(a.getSource(), b.getSource()), True)
        else:
            if b.isConstNumber() or not b.getType().getSign():
                sb = signExpand(b.getType(), b.getSource())
                memberSize = a.getType().deref().getReserveSize()
                return Value(Position.fromAny(tree), a.getType(), 0,
                             pattern.format(a.getSource(), sb * memberSize),
                             True)
            else:
                raise exceptions.SemanticError(Position.fromAny(tree),
                                               "Signed label? WTF is that? 2")
    elif not a.getType().isPointer():
        newType = a.getType()
        sa = signExpand(a.getType(), a.getSource())
        sb = signExpand(b.getType(), b.getSource())
        return _const(Position.fromAny(tree), newType, op(sa, sb))
    else:
        newType = a.getType()
        memberSize = a.getType().deref().getReserveSize()
        sa = signExpand(a.getType(), a.getSource())
        sb = signExpand(b.getType(), b.getSource())
        return _const(Position.fromAny(tree), newType, op(sa, sb * memberSize))
Пример #7
0
 def land(self, tree):
     t0 = _typeof(tree.children[0])
     t1 = _typeof(tree.children[1])
     if t0.isBool() and t1.isBool():
         return BoolType()
     else:
         raise exceptions.SemanticError(
             Position.fromAny(tree),
             f"Wrong types for logical and: {str(t0)}, {str(t1)}")
Пример #8
0
 def ne(self, tree):
     t0 = _typeof(tree.children[0])
     t1 = _typeof(tree.children[1])
     if t0 == t1:
         return BoolType()
     else:
         raise exceptions.SemanticError(
             Position.fromAny(tree),
             f"Incompatible types: {str(t0)}, {str(t1)}")
Пример #9
0
def _shift(t):
    t1 = _typeof(t.children[0])
    t2 = _typeof(t.children[1])
    if t1.isInteger() and t2.isInteger():
        return t1
    else:
        raise exceptions.SemanticError(
            Position.fromAny(t),
            f"Wrong types for bit shift: {str(t1)} and {str(t2)}")
Пример #10
0
    def note_to_signal(self, tree):
        if not self.is_valid_note(tree):
            raise exceptions.SemanticError(tree.data + ' given where note is expected.')

        signals = []
        # this function loops through the note's children and fills
        # out the necessary fields when it finds them.`
        notesig = {'type': 'note', 'note_name':'', 'length_num':0, 'length_denom':0}
        chordsig = {'type': 'chord', 'notes':[], 'length_num':0, 'length_denom':0}
        restsig = {'type': 'rest', 'length_num':0, 'length_denom':0}

        num = 0
        den = 0

        for i in tree.children:
            # children of a note: division, notename, --, chord, tuple
            if i == "--":
                restsig['length_num'] = int(num)
                restsig['length_denom'] = int(den)
                signals.append(restsig)
            elif i.data == 'division':
                num = i.children[0].children[0]
                den = i.children[1].children[0]
            elif i.data == 'notename':
                notesig['note_name'] = self.collect_notename(i)
                notesig['length_num'] = int(num)
                notesig['length_denom'] = int(den)
                signals.append(notesig)
            elif i.data == "chord":
                chordsig['notes'] = self.chord_to_signal(i)
                chordsig['length_num'] = int(num)
                chordsig['length_denom'] = int(den)
                signals.append(chordsig)
            elif i.data == "tuple":
                tupleItems = self.tuple_to_signal(i)
                itemCount = len(tupleItems)
                newDen = int(den) * itemCount
                for item in tupleItems:
                    if item['type'] == 'note':
                        tnotesig = {'type': 'note', 'note_name':'', 'length_num':0, 'length_denom':0}
                        tnotesig['note_name'] = item['value']
                        tnotesig['length_num'] = int(num)
                        tnotesig['length_denom'] = newDen
                        signals.append(tnotesig)
                    elif item['type'] == 'chord':
                        tchordsig = {'type': 'chord', 'notes':[], 'length_num':0, 'length_denom':0}
                        tchordsig['notes'] = item['value']
                        tchordsig['length_num'] = int(num)
                        tchordsig['length_denom'] = newDen
                        signals.append(tchordsig)
            else:
                raise exceptions.SignalConversionError('Invalid note given.')

        return signals
Пример #11
0
    def is_valid_noteitem(self, tree):
        if not type(tree) is self.treetype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(tree)) + ' is not ' + str(self.treetype) + '.')

        if not tree.data == 'noteitem':
            return False

        if not len(tree.children) == 1:
            raise exceptions.SemanticError('1 child expected, ' + len(tree.children[0].children) + ' given.')

        item = tree.children[0].data
        if item == 'note':
            return Semantic.is_valid_note(self, tree.children[0])
        elif item  == 'id':
            return Semantic.is_valid_identifier(self, tree.children[0])
        elif item == 'inlinedynamic':
            d = tree.children[0].children[0].lower()
            if d not in self.valid_levels:
                raise exceptions.DynamicError('Incorrect inline dynamic.')
        else:
            raise exceptions.SemanticError('Note, inline dynamic, or identifier expected, not given.')

        return True
Пример #12
0
    def is_valid_note(self, tree):
        if not type(tree) is self.treetype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(tree)) + ' is not ' + str(self.treetype) + '.')

        if tree.data != 'note':
            return False

        if len(tree.children[0].children) != 2:
            raise exceptions.SemanticError('2 children expected, ' + len(tree.children[0].children) + ' given.')

        if tree.children[0].data != 'division':
            raise exceptions.ValidationError('Tree prefix incorrect: ' + str(tree.data) + ' given, division expected.')

        if not self.is_valid_division(tree.children[0]):
            raise exceptions.SemanticError("Invalid Division")

        if type(tree.children[1]) == self.tokentype and tree.children[1].type == 'REST':
            return True

        if not self.is_valid_notename(tree.children[1]) and not self.is_valid_chord(tree.children[1]) and not self.is_valid_tuple(tree.children[1]):
            raise exceptions.SemanticError("Invalid notename or chord")

        return True
Пример #13
0
    def is_valid_instrumentation(self, tree):
        if not type(tree) is self.treetype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(tree)) + ' is not ' + str(self.treetype) + '.')

        if tree.data != 'instrumentation':
            return False
        if len(tree.children) < 1:
            raise exceptions.SemanticError('At least 1 child expected, ' + len(tree.children[0].children) + ' given.')

        child = tree.children
        if type(child[0]) == self.treetype:
            if not self.is_valid_identifier(child[0]):
                return False
            child[0] = self.variables[child[0].children[0]]
        if type(child[0]) != self.tokentype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(child[0])) + ' is not ' + str(self.tokentype) + '.')
        if child[0].type != 'INSTRUMENT':
            raise exceptions.ValidationError('Type mismatch: ' + child[0].type + ' is not INSTRUMENT.')

        for x in child[1:]:
            if not self.is_valid_noteitem(x):
                raise exceptions.SemanticError('Invalid Noteitem.')
        return True
Пример #14
0
    def measure_to_signal(self, tree):
        if not self.is_valid_measure(tree):
            raise exceptions.SemanticError("Invalid measure")
            return []

        signals = []
        signals.append({'type':'measure', 'start':True})
        for i in tree.children:
            if i.data == 'instrumentation':
                signals += self.instrumentation_to_signal(i)

        signals.append({'type':'measure', 'start':False})

        return signals
Пример #15
0
    def chord_to_signal(self, tree):
        if tree.data != 'chord':
            raise exceptions.SemanticError(tree.data + ' given where chord is expected.')

        notes = []

        for i in tree.children:
            # only children of a chord are notenames
            if i.data == 'notename':
                notes.append(self.collect_notename(i))
            else:
                raise exceptions.SignalConversionError('Invalid chord contents.')

        return notes
Пример #16
0
    def is_valid_chord(self, tree):
        if not type(tree) is self.treetype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(tree)) + ' is not ' + str(self.treetype) + '.')

        if not tree.data == 'chord':
            return False

        try:
            for child in tree.children:
                if not child.data == 'notename':
                    return False
                if not self.is_valid_notename(child):
                    raise SemanticError
        except:
            raise exceptions.SemanticError('Chords should only contain notes.')

        return True
Пример #17
0
def binary(tree, op, overrideType=None, typeChecker=sameTypeChecker):
    a, b = tree.children
    if isinstance(a, Tree) or isinstance(b, Tree):
        return tree
    elif not a.isConstNumber() or not b.isConstNumber():
        return tree
    else:
        if typeChecker(a, b):
            newType = a.getType()
            if overrideType is not None:
                newType = overrideType
            sa = signExpand(a.getType(), a.getSource())
            sb = signExpand(b.getType(), b.getSource())
            return _const(Position.fromAny(tree), newType, op(sa, sb))
        else:
            raise exceptions.SemanticError(
                Position.fromAny(tree), "Incompatible types in an expression")
Пример #18
0
    def tuple_to_signal(self, tree):
        if tree.data != 'tuple':
            raise exceptions.SemanticError(tree.data + ' given where tuple is expected.')

        # put dummy data in a tuple signal because we don't like them much

        notes = []

        for i in tree.children:
            if i.data == 'notename':
                notes.append({'type' : 'note', 'value' : self.collect_notename(i)})
            elif i.data == 'chord':
                notes.append({'type' : 'chord', 'value' : self.chord_to_signal(i)})
            else:
                raise exceptions.SignalConversionError('Invalid tuple contents.')

        return notes
Пример #19
0
    def is_valid_dynamic(self, tree):
        if not type(tree) is self.treetype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(tree)) + ' is not ' + str(self.treetype) + '.')
        if tree.data != 'dynamic':
            return False

        item = tree.children[0].data
        if item == 'inlinedynamic':
            d = tree.children[0].children[0].lower()
            if d not in self.valid_levels:
                raise exceptions.DynamicError('Incorrect inline dynamic.')
        elif item == 'id':
            return Semantic.is_valid_identifier(self, tree)
        else:
            raise exceptions.SemanticError('Inline dynamic or identifier expected, not given.')

        return True
Пример #20
0
    def noteitem_to_signal(self,tree):
        if not self.is_valid_noteitem(tree):
            raise exceptions.SemanticError(tree.data + ' given where noteitem is expected.')
            return False

        signals = []

        for i in tree.children:
            # possible noteitem children : note , inlinedynamic
            if i.data == 'note':
                signals += (self.note_to_signal(i))
            elif i.data == 'inlinedynamic':
                signals += (self.inlinedynamic_to_signal(i))
            else:
                raise exceptions.SignalConversionError('Invalid noteitem given.')

        return signals
Пример #21
0
    def instrumentation_to_signal(self, tree):
        if not self.is_valid_instrumentation(tree):
            raise exceptions.SemanticError(tree.data + ' given where instrumentation is expected.')

        signals = []
        name = tree.children[0]

        signals.append({'type':'instrument', 'name':str(name)})

        if tree.children[0] in instrumentToNumber:
            for i in tree.children[1:]:
                signals += self.noteitem_to_signal(i)
        else:
            raise exceptions.SignalConversionError('Invalid instrument given.')


        return signals
Пример #22
0
    def is_valid_tree(self, tree):
        if not type(tree) is self.treetype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(tree)) + ' is not ' + str(self.treetype) + '.')

        if tree.data != 'start':
            return False

        for i in range(len(tree.children[:-1])):
            if tree.children[i].data == 'id':
                if tree.children[i+1].data != 'rhs':
                    raise exceptions.ValidationError('Assignment right-hand side not found.')
            if tree.children[i].data == 'rhs':
                if tree.children[i-1].data != 'id':
                    raise exceptions.ValidationError('Assignment identifier not found.')
        if tree.children[-1].data != 'compose':
            raise exceptions.SemanticError('Compose statement not found.')
        return True
Пример #23
0
    def is_valid_notename(self, tree):
        if not type(tree) is self.treetype:
            raise exceptions.ValidationError('Type mismatch: ' + str(type(tree)) + ' is not ' + str(self.treetype) + '.')

        if not tree.data == 'notename':
            return False

        if not (len(tree.children) == 3 or len(tree.children) == 2):
            raise exceptions.SemanticError('2 or 3 children expected, ' + len(tree.children[0].children) + ' given.')

        n = tree.children[0]
        n.upper()
        validNoteLetters = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
        if n not in validNoteLetters:
            raise exceptions.NoteError('Invalid note letter.')

        if len(tree.children) == 3:
            #Has accidental
            if tree.children[1].data != 'accidental':
                raise exceptions.NoteError('Accidental expected, not given.')
            if tree.children[2].data != 'number':
                raise exceptions.NoteError('Octave number expected, not given')

            acc = tree.children[1].children[0].value
            if acc != '#' and acc != 'b':
                raise exceptions.NoteError('Incorrect accidental symbol given, \'b\' or \'#\' expected.')
            octave = int(tree.children[2].children[0].value)
            if 9 > octave < 0:
                raise exceptions.NoteError('Invalid note octave.')

        elif len(tree.children) == 2:
            #No accidental or rest
            if tree.children[1].data != 'number':
                raise exceptions.NoteError('Octave number expected, not given')
            octave = int(tree.children[1].children[0].value)
            if 9 > octave < 0:
                raise exceptions.NoteError('Invalid note octave.')
        else:
            #Invalid length
            raise exceptions.NoteError('Invalid note syntax')
            return False

        return True
Пример #24
0
 def is_valid_program(self, tree):
     if not type(tree) is self.treetype:
         raise exceptions.SemanticError("Not a tree")
Пример #25
0
 def p_arrow(self, tree):
     try:
         ts = _typeof(tree.children[0])
         return PtrType(ts.deref().getFieldType(tree.children[1]))
     except LookupError as e:
         raise exceptions.SemanticError(Position.fromAny(tree), str(e))