Example #1
0
File: eqc.py Project: robbje/eis
    def __init__(
            self,
            params=[],
            eqc=lambda w,
            p: 0,
            name="",
            pNames="",
            jac=[],
            constraints=[]):
        """Constructor for a CircuitTree node

            params: a list of numerical values
            eqc: frequency dependent equivalent circuit function
            name: name of the element
            pNames: names of the elements' parameters
            jac: elements jacobian vector of parameters
            """

        Node.__init__(self)
        self.p = params
        self.eqc = eqc
        self.name = name
        self.pNames = pNames
        self.jac = jac
        self.constraints = constraints
Example #2
0
 def verify_valid_arguments(self, node: parser.Node) -> None:
     for i in range(self.num_params):
         if not self.context.arguments[i].is_satisfied_by(
                 self.parameters[i]):
             node.compile_error(
                 "Could not reify generic method: '%s' does not satisfy '%s'"
                 % (self.parameters[i], self.context.arguments[i]))
Example #3
0
    def setup_class(self):
        # Constants
        self.int_node_one = Node(vtype=v.INTEGER_VALUE, syn_value=1)
        self.int_node_two = Node(vtype=v.INTEGER_VALUE, syn_value=2)
        self.int_node_three = Node(vtype=v.INTEGER_VALUE, syn_value=3)

        # Variables
        self.x = Node(vtype=v.IDENTIFIER, symbol='x')
        self.y = Node(vtype=v.IDENTIFIER, symbol='y')
        self.z = Node(vtype=v.IDENTIFIER, symbol='z')

        # z = x + y
        self.int_node_add = Node(vtype=v.ADD, children=(self.x, self.y))
        self.assignment_node = Node(vtype=v.ASSIGNMENT, children=[self.z, self.int_node_add])

        # return z
        self.z_statement = Node(vtype=v.STATEMENT, children=[self.z,])
        self.return_node = Node(vtype=v.RETURN_STATEMENT, syn_value=self.z_statement)

        # Functions
        self.sum_function = Function(return_type=v.INTEGER_VALUE,
                                     symbol='sum',
                                     parameter_pairs=((self.x, v.INTEGER_VALUE),
                                                      (self.y, v.INTEGER_VALUE)),
                                     statements=[self.assignment_node])

        self.sum_with_return_function = Function(return_type=v.INTEGER_VALUE,
                                                 symbol='sum_with_return',
                                                 parameter_pairs=((self.x, v.INTEGER_VALUE),
                                                               (self.y, v.INTEGER_VALUE)),
                                                 statements=[self.assignment_node,
                                                          self.return_node,
                                                          ])
Example #4
0
 def test_assignment(self):
     x_node = Node(vtype=v.IDENTIFIER, symbol='x')
     val_node = self.int_node_two
     assignment_node = Node(vtype=v.ASSIGNMENT, children=[x_node, val_node])
     backend.walk_ast(assignment_node)
     symbol_record = backend.scopes[-1][x_node.symbol]
     eq_(symbol_record, val_node)
Example #5
0
 def method_signature_strict(
         self, name: str, node: parser.Node) -> "emitter.MethodSignature":
     ret = self.method_signature_optional(name)
     if ret is None:
         node.compile_error("Invalid member method name '%s'" % name)
     assert ret is not None
     return ret
Example #6
0
 def test_boolean_op_or(self):
     node = Node(vtype=v.OR,
                 children=[self.int_node_zero, self.int_node_neg_one])
     backend.walk_ast(node)
     eq_(node.syn_value, True)
     node = Node(vtype=v.OR,
                 children=[self.int_node_zero, self.int_node_zero])
     backend.walk_ast(node)
     eq_(node.syn_value, False)
Example #7
0
 def test_boolean_op_not(self):
     node = Node(vtype=v.NOT, children=[self.int_node_zero])
     backend.walk_ast(node)
     eq_(node.syn_value, True)
     node = Node(vtype=v.NOT, children=[self.string_node_empty])
     backend.walk_ast(node)
     eq_(node.syn_value, True)
     node = Node(vtype=v.NOT, children=[self.float_node_neg_one])
     backend.walk_ast(node)
     eq_(node.syn_value, False)
Example #8
0
 def resolve_interface_strict(
         self,
         node: parser.Node,
         generic_type_context: Optional[GenericTypeContext],
         allow_raw: bool = False) -> InterfaceType:
     ret = self.resolve_strict(node,
                               generic_type_context,
                               allow_raw=allow_raw)
     if not isinstance(ret, InterfaceType):
         node.compile_error(
             "Type resolves to %s where an interface was expected" % ret)
     return ret
Example #9
0
 def resolve_to_signature(
     self, node: parser.Node, scope: "emitter.Scopes",
     generic_type_context: Optional[GenericTypeContext]
 ) -> "emitter.MethodSignature":
     if util.get_flattened(
             node
     ) is not None and self.program.get_method_signature_optional(
             util.nonnull(util.get_flattened(node))) is not None:
         return self.program.get_method_signature(
             util.nonnull(util.get_flattened(node)))
     if node.i("ident"):
         node.compile_error(
             "Attempt to call an identifier that doesn't resolve to a method"
         )
         # Unreachable
         return None  # type: ignore
     elif node.i("."):
         typ = self.decide_type(node[0], scope, generic_type_context)
         if not node[1].i("ident"):
             raise ValueError("This is a compiler bug")
         if not isinstance(typ, AbstractCallableType):
             node.compile_error(
                 "Attempt to call a member of something that isn't callable"
             )
         return typ.method_signature_strict(node[1].data_strict, node)
     else:
         node.compile_error(
             "Attempt to call something that can't be called")
         # Unreachable
         return None  # type: ignore
Example #10
0
    def setup_class(self):
        # Constants
        self.int_node_one = Node(vtype=v.INTEGER_VALUE, syn_value=1)
        self.int_node_two = Node(vtype=v.INTEGER_VALUE, syn_value=2)
        self.int_node_three = Node(vtype=v.INTEGER_VALUE, syn_value=3)

        # Variables
        self.x = Node(vtype=v.IDENTIFIER, symbol='x')
        self.y = Node(vtype=v.IDENTIFIER, symbol='y')
        self.z = Node(vtype=v.IDENTIFIER, symbol='z')

        # z = x + y
        self.int_node_add = Node(vtype=v.ADD, children=(self.x, self.y))
        self.assignment_node = Node(vtype=v.ASSIGNMENT,
                                    children=[self.z, self.int_node_add])

        # Functions
        self.sum_function = Function(return_type=v.INTEGER_VALUE,
                                     parameter_pairs=((self.x,
                                                       v.INTEGER_VALUE),
                                                      (self.y,
                                                       v.INTEGER_VALUE)),
                                     expressions=[
                                         self.assignment_node,
                                     ])
Example #11
0
 def test_scopeless_add(self):
     scopeless_add_node = Node(vtype=v.ADD, children=(self.int_node_one, self.int_node_two))
     scopeless_add_function = Function(return_type=v.INTEGER_VALUE,
                                        symbol="add",
                                        parameter_pairs=(),
                                        statements=[scopeless_add_node,])
     scopeless_add_function.execute()
Example #12
0
 def test_int_add(self):
     int_node_add = Node(vtype=v.ADD,
                         children=[self.int_node_one, self.int_node_two])
     backend.walk_ast(int_node_add)
     eq_(int_node_add.syn_value, 3)
     int_node_neg_two = Node(
         vtype=v.ADD,
         children=[self.int_node_neg_one, self.int_node_neg_one])
     int_node_neg_four = Node(vtype=v.ADD,
                              children=[int_node_neg_two, int_node_neg_two])
     int_node_four = Node(vtype=v.ADD,
                          children=[self.int_node_two, self.int_node_two])
     int_node_result = Node(vtype=v.ADD,
                            children=[int_node_four, int_node_neg_four])
     backend.walk_ast(int_node_result)
     eq_(int_node_result.syn_value, 0)
Example #13
0
    def resolves(self, node: parser.Node, program: "emitter.Program") -> bool:
        def flatten_qualified(nod: parser.Node) -> str:
            if nod.i("ident"):
                return nod.data_strict
            else:
                return "%s.%s" % (flatten_qualified(
                    nod[0]), flatten_qualified(nod[1]))

        if not node.i("ident") and not node.i("."):
            return False

        name = flatten_qualified(node)

        for search_path in program.search_paths:
            if "%s%s" % (search_path, name) == self.name:
                return True
        return False
Example #14
0
def node(name):
    """
    >>> document()
    Node(name='document', attrs={}, elems=[])
    >>> document('a', 'b', 'c')
    Node(name='document', attrs={}, elems=['a', 'b', 'c'])
    """
    return lambda *elems: Node(name, elems=list(elems))
Example #15
0
 def parse(self):
     # print(self.text_box.get())
     scanner(self.text_box.get())
     lst_tokens = tokenizer(file='output.txt')
     init_node = Node()
     parser = Parser(lst_tokens)
     parser.parents.append(init_node.index)
     parser.program()
     parser.draw_tree()
Example #16
0
 def add_type_argument_from_node(self, node: parser.Node) -> None:
     extends: Optional[ClazzType] = None
     if node.has_child("extends"):
         extends_uncasted = self.types.resolve_strict(
             node["extends"][0], self)
         if not isinstance(extends_uncasted, ClazzType):
             node["extends"].compile_error(
                 "Cannot add an extends constraint of something that isn't a class"
             )
         extends = extends_uncasted
     implements: List[InterfaceType] = []
     if node.has_child("implements"):
         for interface in node["implements"]:
             resolved_type = self.types.resolve_strict(interface, self)
             if not isinstance(resolved_type, InterfaceType):
                 interface.compile_error(
                     "Cannot add an implements constraint of something that isn't a class"
                 )
             implements.append(resolved_type)
     self.add_type_argument(node["ident"].data_strict, extends, implements)
Example #17
0
 def resolves(self, node: parser.Node, program: "emitter.Program") -> bool:
     if node.i("ident") or node.i("."):
         return any([
             self.name == path + util.nonnull(util.get_flattened(node))
             for path in program.search_paths
         ])
     if self.signature.generic_type_context is None:
         return False
     if not node.i("<>"):
         return False
     if not any([
             self.name == path + util.nonnull(util.get_flattened(node[0]))
             for path in program.search_paths
     ]):
         return False
     for i in range(len(node) - 1):
         if not self.signature.generic_type_context.arguments[i].resolves(
                 node[i + 1], program):
             return False
     return True
Example #18
0
 def resolve(self,
             node: parser.Node,
             generic_type_context: Optional[GenericTypeContext],
             fail_silent: bool = False,
             allow_raw: bool = False) -> Optional[AbstractType]:
     for typ in self.types:
         if typ.resolves(node, self.program):
             if not allow_raw and isinstance(
                     typ, ClazzType) and typ.signature.is_raw_type:
                 node.compile_error("Cannot use raw types directly")
             return typ
     if node.i("["):
         element_type = self.resolve(node[0],
                                     generic_type_context,
                                     fail_silent=fail_silent)
         if element_type is None:
             if not fail_silent:
                 # TypeSystem.resolve will never return None if fail_silent == True
                 raise ValueError("This is a compiler bug")
             return None
         return self.get_array_type(element_type)
     elif node.i("<>"):
         # We've got to create a new specialization of the class signature
         # because evidently the required one doesn't exist.
         generic_class_type = self.resolve(node[0],
                                           generic_type_context,
                                           fail_silent=fail_silent,
                                           allow_raw=True)
         if generic_class_type is None:
             # We know fail_silent == True
             return None
         if not isinstance(generic_class_type, ClazzType):
             # Yes, I really mean isinstance, not .is_class()
             node.compile_error(
                 "Cannot provide generic type arguments to a type that isn't a class"
             )
         type_arguments: List[AbstractType] = []
         for type_argument_node in node.children[1:]:
             argument = self.resolve(type_argument_node,
                                     generic_type_context,
                                     fail_silent=fail_silent)
             if argument is None:
                 # We know fail_silent == True
                 return None
             type_arguments.append(argument)
         return generic_class_type.specialize(type_arguments, node)
     if generic_type_context is not None:
         ret = generic_type_context.resolve_optional(node, self.program)
         if ret is not None:
             return ret
     if not fail_silent:
         raise TypingError(
             node, "Could not resolve type: '%s' ('%s')" %
             (node, util.get_flattened(node)))
     else:
         return None
Example #19
0
    def get_targets(self):
        """Return a disctionary representing the access request of the query.

        :return: A dictionary of the table-column pairs the query accesses.
        """
        def _back_to_common_state(root, node):
            if not root:
                return node

            node.state.cols.extend(root.state.cols)
            node.state.tables.extend(root.state.tables)

            for child in root.childs:
                _back_to_common_state(child, node)

            return node

        node = _back_to_common_state(self.root, Node())

        known_tables = {table.normalized for table in node.state.tables}
        return to_dict(node, known_tables)
Example #20
0
    def complete(self, prefix):
        """
		Try to complete a given prefix
		"""
        self._log.debug("complete: '%s'" % prefix)

        #proposals = [LaTeXTemplateProposal(Template("Hello[${One}][${Two}][${Three}]"), "Hello[Some]"), LaTeXProposal("\\world")]

        fragment = Node(Node.DOCUMENT)
        parser = PrefixParser()

        try:
            parser.parse(prefix, fragment)

            modelParser = PrefixModelParser(self._language_model)
            proposals = modelParser.parse(fragment)

            self._log.debug("Generated %s proposals" % len(proposals))

            return proposals

        except Exception, e:
            self._log.debug(e)
Example #21
0
	def parse(self, s = None, row = 1, col = 1):

		def updatePos(s, row, col):
			rows = s.count("\n")
			if rows:
				row += rows
				col = len(s[s.rfind("\n") + 1:])

			else:
				col += len(s)

			return row, col

		assert self.startDelimiter
		assert self.endDelimiter
		assert self.startBlock
		assert self.altBlock
		assert self.endBlock

		assert self.startBlock != self.endBlock

		block = Node("tblock")
		blocks = []

		while s:
			#print("s = %r" %s)

			start = s.find(self.startDelimiter)
			if start < 0:
				break

			end = s.find(self.endDelimiter, start + len(self.startDelimiter))
			if end < 0:
				break

			if start > 0:
				row, col = updatePos(s[:start], row, col)
				block.children.append(Node("tstring", s[:start]))

			start += len(self.startDelimiter)
			expr = s[start:end]
			end += len(self.endDelimiter)

			if self.replaceCharRefs:
				for find, repl in {
					"&gt;": ">",
				    "&lt;": "<"
				}.items():
					expr = expr.replace(find, repl)

			#print("expr   = %r %d %d" % (expr, row, col))

			if expr.startswith(self.startBlock):
				row, col = updatePos(self.startDelimiter, row, col)

				expr = expr[len(self.startBlock):]

				try:
					node = super(Template, self).parse(expr)
				except ParseException as e:
					raise ParseException(row + e.row - 1, col + e.col - 1, e.expecting)

				blocks.append((node, block, None))
				block = Node("tblock")

			elif expr.startswith(self.altBlock):
				if not blocks:
					raise ParseException(row, col, "Alternative block without opening block")

				node, nblock, ablock = blocks[-1]
				if ablock:
					raise ParseException(row, col, "Multiple alternative blocks are not allowed")

				blocks[-1] = (node, nblock, block)

				row, col = updatePos(self.startDelimiter + expr, row, col)

				block = Node("tblock")

			elif expr.startswith(self.endBlock):
				if not blocks:
					raise ParseException(row, col, "Closing block without opening block")

				row, col = updatePos(self.startDelimiter + expr, row, col)

				node, nblock, ablock = blocks.pop()
				if ablock:
					nblock.children.append(Node("tloop", children=[node, ablock, block]))
				else:
					nblock.children.append(Node("tloop", children=[node, block, None]))

				block = nblock

			else:
				row, col = updatePos(self.startDelimiter, row, col)

				try:
					node = super(Template, self).parse(expr)
				except ParseException as e:
					raise ParseException(row + e.row - 1, col + e.col - 1, e.expecting)

				row, col = updatePos(expr, row, col)
				block.children.append(node)

			row, col = updatePos(self.endDelimiter, row, col)

			s = s[end:]

		if blocks:
			raise ParseException(row, col, "%d blocks are still open, expecting %s" % (len(blocks), "".join([("%s%s%s" % (self.startDelimiter, self.endBlock, self.endDelimiter)) for b in blocks])))

		if s:
			block.children.append(Node("tstring", s))

		self.ast = block
Example #22
0
 def test_defaults(self):
     assert Node('') == Node('', {}, [])
Example #23
0
 def flatten_qualified(nod: parser.Node) -> str:
     if nod.i("ident"):
         return nod.data_strict
     else:
         return "%s.%s" % (flatten_qualified(
             nod[0]), flatten_qualified(nod[1]))
Example #24
0
 def resolves(self, node: parser.Node, program: "emitter.Program") -> bool:
     return node.i("[]") and self.parent_type.resolves(node[0], program)
Example #25
0
def constructUVWRecurse(node,uvw):
    """Recursive build function for the LTL->UVW translation.
       Returns a pair of UVW set of starting states and an "EXIT" condition in BDD form.
       The latter can be None if this is undefined.
       """

    # Cache lookup
    thisNodePolish = node.toPolishLTL()
    if thisNodePolish in uvw.labelToStateAndActivatingMapper:
        return uvw.labelToStateAndActivatingMapper[thisNodePolish]

    # Case Missing: F(a & F b)

    # 1. See if this is non-temporal
    nt = parseNonTemporalSubformula(node,uvw)
    if not nt is None:
        if nt!=uvw.ddMgr.false:
            newStateNo = uvw.addStateButNotNewListOfTransitionsForTheNewState(node.toPolishLTL(),node)
            uvw.transitions.append([(0,~nt)])
            uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([newStateNo],nt)
            return ([newStateNo],nt)
        else:
            uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([0],nt)
            return ([0],nt)

    # 2. Cover the "Globally something case" -> Phi
    if node.value == NodeTypes.GLOBALLY:
        assert len(node.children)==1
        (uvwSubnodes,exitCondition) = constructUVWRecurse(node.children[0],uvw)
        newStateNo = uvw.addStateButNotNewListOfTransitionsForTheNewState(node.toPolishLTL(),False)
        uvw.transitions.append([(a,b) for k in uvwSubnodes for (a,b) in uvw.transitions[k]]+[(newStateNo,uvw.ddMgr.true)])
        uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([newStateNo],None)
        return ([newStateNo],None)

    # 3. Cover the "Next something case" -> Phi
    if node.value == NodeTypes.NEXT:
        assert len(node.children)==1
        (uvwSubnodes,exitCondition) = constructUVWRecurse(node.children[0],uvw)
        newStateNo = uvw.addStateButNotNewListOfTransitionsForTheNewState(node.toPolishLTL(),False)
        uvw.transitions.append([(a,uvw.ddMgr.true) for a in uvwSubnodes])
        uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([newStateNo],None)
        return ([newStateNo],None)

    # 4. Cover the "And" case -- not atomic --> Phi
    if node.value == NodeTypes.AND:
        newStates = reduce(lambda x,y: (x[0]+y[0],x[1]), [constructUVWRecurse(a,uvw) for a in node.children])[0]
        uvw.labelToStateAndActivatingMapper[thisNodePolish] = (newStates,None)
        return (newStates,None)

    # 4. Cover the "Or" case -- could be Phi or Psi
    if node.value == NodeTypes.OR:

        # Operate pairwise
        if len(node.children)==1:
            return constructUVWRecurse(node.children[0],uvw)

        (initialA,filterA) = constructUVWRecurse(node.children[0],uvw)
        if len(node.children)==2:
            (initialB,filterB) = constructUVWRecurse(node.children[1],uvw)
        else:
            (initialB,filterB) = constructUVWRecurse(Node(NodeTypes.OR,node.children[1:]),uvw)

        # Product -- Init
        todo = [(a,b) for a in initialA for b in initialB]
        mapper = {}
        for (a,b) in todo:
            mapper[(a,b)] = uvw.addStateButNotNewListOfTransitionsForTheNewState("|| "+uvw.stateNames[a]+" "+uvw.stateNames[b],uvw.rejecting[a] and uvw.rejecting[b])

        # Product -- iterate through todo list.
        while len(todo)>0:
            thisOne = todo[0]
            todo = todo[1:]

            # Go through all products
            outTrans = []
            for (targetA,condA) in uvw.transitions[thisOne[0]]:
                for (targetB,condB) in uvw.transitions[thisOne[1]]:
                    if (condA & condB)!=uvw.ddMgr.false:
                        if not (targetA,targetB) in mapper:
                            mapper[(targetA,targetB)] = uvw.addStateButNotNewListOfTransitionsForTheNewState("|| "+uvw.stateNames[targetA]+" "+uvw.stateNames[targetB],uvw.rejecting[targetA] and uvw.rejecting[targetB])
                            todo.append((targetA,targetB))
                        outTrans.append((mapper[(targetA,targetB)],condA & condB))
            uvw.transitions.append(outTrans)

        # Done!
        if (filterA is None) or (filterB is None):
            uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([mapper[(a,b)] for a in initialA for b in initialB],None)
            return ([mapper[(a,b)] for a in initialA for b in initialB],None)
        else:
            uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([mapper[(a,b)] for a in initialA for b in initialB],filterA | filterB)
            return ([mapper[(a,b)] for a in initialA for b in initialB],filterA | filterB)

    # 5. Finally
    if node.value == NodeTypes.FINALLY:
        (subnodes,activator) = constructUVWRecurse(node.children[0],uvw)
        newStateNo = uvw.addStateButNotNewListOfTransitionsForTheNewState(node.toPolishLTL(),True)
        uvw.transitions.append([(newStateNo,~activator)])
        uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([newStateNo],activator)
        return ([newStateNo],activator)

    # 5. Until
    if node.value == NodeTypes.UNTIL:
        (rightPartNodes,rightPartActivator) = constructUVWRecurse(node.children[1],uvw)
        (leftPartNodes,leftPartActivator) = constructUVWRecurse(Node(NodeTypes.OR,[node.children[0],node.children[1]]),uvw)
        if not rightPartActivator is None: # Could be a "Maidl's grammar extension"
            newStateNo = uvw.addStateButNotNewListOfTransitionsForTheNewState(node.toPolishLTL(),True)
            uvw.transitions.append([(newStateNo,~rightPartActivator)]+[(a,b) for k in leftPartNodes for (a,b) in uvw.transitions[k]])
            uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([newStateNo],rightPartActivator)
            return ([newStateNo],rightPartActivator)

    # 5. Release
    if node.value == NodeTypes.RELEASE:
        # In a release node, when the release happens, the guarded condition still needs to hold.
        (leftPartNodes,leftPartActivator) = constructUVWRecurse(node.children[0],uvw)
        (leftPartNodes,doesnotMatter) = constructUVWRecurse(node.children[1],uvw)
        # (leftPartNodes,leftPartActivatorIgnored) = constructUVWRecurse(Node(NodeTypes.AND,[node.children[0],node.children[1]]),uvw) # TODO: Check if we can just use the leftPartNodesa
        (rightPartNodes,rightPartActivator) = constructUVWRecurse(Node(NodeTypes.OR,[node.children[0],node.children[1]]),uvw)
        assert not leftPartActivator is None
        newStateNo = uvw.addStateButNotNewListOfTransitionsForTheNewState(node.toPolishLTL(),False)
        uvw.transitions.append([(newStateNo,~leftPartActivator)]+[(a,b) for k in rightPartNodes for (a,b) in uvw.transitions[k]]+[(a,b & leftPartActivator) for k in leftPartNodes for (a,b) in uvw.transitions[k]])
        uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([newStateNo],leftPartActivator)
        return ([newStateNo],leftPartActivator)

    # 6. Cover Maidl's (p & Phi) U (!p & Phi) case
    if node.value == NodeTypes.UNTIL:

        # Restructure childrenA
        if node.children[0].value == NodeTypes.AND:
            allChildrenA = [constructUVWRecurse(a,uvw) for a in node.children[0].children]
        else:
            allChildrenA = [constructUVWRecurse(node.children[0],uvw)]

        if node.children[1].value == NodeTypes.AND:
            # Let's see if we can use Maidl's case
            allChildrenB = [constructUVWRecurse(a,uvw) for a in node.children[1].children]

            # Merge into the relevant cases
            nonTemporalA = None
            nonTemporalB = None
            failed = False # If matching has failed
            activA = uvw.ddMgr.true
            activB = uvw.ddMgr.true

            # Handle Children A
            for (uvwSubnodes,exitCondition) in allChildrenA:
                isTemporal = True
                for subnode in uvwSubnodes:
                    if len(uvw.transitions[subnode])==0:
                        return constructUVWRecurse(node.children[1],uvw)
                    elif len(uvw.transitions[subnode])==1:
                        (k,l) = uvw.transitions[subnode][0]
                        if k!=0:
                            isTemporal = False
                        else:
                            activA &= ~l
                if not isTemporal:
                    if nonTemporalA is None:
                        nonTemporalA = (uvwSubnodes,exitCondition)
                    else:
                        failed = True

            # Handle Children B
            for (uvwSubnodes,exitCondition) in allChildrenB:
                isTemporal = True
                for subnode in uvwSubnodes:
                    if len(uvw.transitions[subnode])==0:
                        return constructUVWRecurse([0],None) # Cannot exit
                    elif len(uvw.transitions[subnode])==1:
                        (k,l) = uvw.transitions[subnode][0]
                        if k!=0:
                            isTemporal = False
                        else:
                            activB &= ~l
                if not isTemporal:
                    if nonTemporalB is None:
                        nonTemporalB = (uvwSubnodes,exitCondition)
                    else:
                        failed = True

            # Did we get a split?
            if (not failed) and ((activA & activB)==uvw.ddMgr.false):

                # Then build new node!
                newStateNo = uvw.addStateButNotNewListOfTransitionsForTheNewState(node.toPolishLTL(),True)
                uvw.transitions.append([(newStateNo,activA)])
                if not (((~activA) & (~activB))==uvw.ddMgr.false):
                    uvw.transitions[-1].append((0,(~activA) & (~activB)))
                for (uvwSubnodes,exitCondition) in allChildrenA:
                    for subnode in uvwSubnodes:
                        for (target,cond) in uvw.transitions[subnode]:
                            # print ("L",target,(cond & ~activB).to_expr())
                            uvw.transitions[-1].append((target,cond & activA))
                for (uvwSubnodes,exitCondition) in allChildrenB:
                    for subnode in uvwSubnodes:
                        for (target,cond) in uvw.transitions[subnode]:
                            # print ("K",target,(cond & activB).to_expr())
                            uvw.transitions[-1].append((target,cond & activB))

                # print("Final Transitions:")
                # for (a,b) in uvw.transitions[-1]:
                #     print (a,b.to_expr())
                uvw.labelToStateAndActivatingMapper[thisNodePolish] = ([newStateNo],None)
                return ([newStateNo],None)


    raise Exception("Unsupported Node Type for to UVW translation: "+str(node.value))
Example #26
0
concatenation = Node("concatenation"
                     , Seq(ident_or_term_or_groups, NotNeed(","), TRef("rhs", grammar=cur_grammar, flat=True))
                     , flat_eq_name=True, grammar=cur_grammar)

alteration = Node("alteration"
                  , Seq(ident_or_term_or_groups, NotNeed("|"), TRef("rhs", grammar=cur_grammar, flat=True))
                  , flat_eq_name=True, grammar=cur_grammar)

rhs = Node("rhs", Or( concatenation
                    , alteration
                    , groups
                    , ident_or_term)
           , grammar=cur_grammar)

rule = Node("rule", Seq(lhs, NotNeed("="), rhs, NotNeed(";")), grammar=cur_grammar)
grammar = Node("ebnf_grammar", ZeroOrMore(rule), grammar=cur_grammar)


if __name__ == '__main__':
    space = Node("space", Concat(OneOrMore(Or(" ", "\t", "\n"))), skip=True)
    comment = Node("comment", Seq("(", "*"
                                  , Node("text", Concat(ZeroOrMore(Not(Seq("*", ")")))))
                                  , "*", ")")
                   , skip=True)
    skip_pattern = OneOrMore(Or(space, comment))

    tr = TextReader(open("ebnf_test.txt"), skip_pattern=skip_pattern)

    #SetRecursionLimit(5000)

    rslt = grammar.read_from(tr)
Example #27
0
 def eval_expr(self, node: parser.Node) -> InterpreterValueAny:
     # TODO: Support referencing other static variables
     # Bitmask for 64-bit computation
     bitmask = 0xffffffffffffffff
     if node.i("number"):
         return self.create_int_value(int(node.data_strict))
     elif node.i("true"):
         return self.true
     elif node.i("false"):
         return self.false
     elif node.i("null"):
         return self.null
     elif node.of("+", "*", "^", "&", "|"):
         lhs = self.eval_expr(node[0])
         rhs = self.eval_expr(node[1])
         if not isinstance(lhs, InterpreterValueInteger) or not isinstance(
                 rhs, InterpreterValueInteger):
             raise typesys.TypingError(
                 node,
                 "Attempt to perform arithmetic on something that isn't an integers"
             )
         if node.i("+"):
             ret = lhs.value + rhs.value
         elif node.i("*"):
             ret = lhs.value * rhs.value
         elif node.i("^"):
             ret = lhs.value ^ rhs.value
         elif node.i("&"):
             ret = lhs.value & rhs.value
         elif node.i("|"):
             ret = lhs.value | rhs.value
         return self.create_int_value(ret & bitmask)
     elif node.of("and", "or"):
         lhs = self.eval_expr(node[0])
         rhs = self.eval_expr(node[1])
         if not isinstance(lhs, InterpreterValueBoolean) or not isinstance(
                 rhs, InterpreterValueBoolean):
             raise typesys.TypingError(
                 node,
                 "Attempt to perform logical operation on something that isn't an integers"
             )
         if node.i("and"):
             ret = lhs.value and rhs.value
         elif node.i("or"):
             ret = lhs.value or rhs.value
         return self.true if ret else self.false
     elif node.i("not"):
         val = self.eval_expr(node[0])
         if not isinstance(val, InterpreterValueBoolean):
             raise typesys.TypingError(
                 node,
                 "Attempt to perform logical operation on something that isn't an integers"
             )
         return self.false if val.value else self.true
     elif node.of(">=", "<=", "<", ">"):
         lhs = self.eval_expr(node[0])
         rhs = self.eval_expr(node[1])
         if not isinstance(lhs, InterpreterValueInteger) or not isinstance(
                 rhs, InterpreterValueInteger):
             raise typesys.TypingError(
                 node,
                 "Attempt to perform arithmetic on something that isn't an integers"
             )
         lhs_value = self.normalize_negative(lhs.value)
         rhs_value = self.normalize_negative(rhs.value)
         if node.i(">="):
             ret = lhs_value >= rhs_value
         elif node.i("<="):
             ret = lhs_value <= rhs_value
         elif node.i("<"):
             ret = lhs_value < rhs_value
         elif node.i(">"):
             ret = lhs_value > rhs_value
         else:
             raise ValueError("This is a compiler bug")
         return self.true if ret else self.false
     elif node.of("==", "!="):
         lhs = self.eval_expr(node[0])
         rhs = self.eval_expr(node[1])
         if not lhs.type.is_assignable_to(
                 rhs.type) and not rhs.type.is_assignable_to(lhs.type):
             raise typesys.TypingError(
                 node,
                 "Incomparable types: '%s' and '%s'" % (lhs.type, rhs.type))
         return self.true if lhs.equals(rhs) ^ (
             True if node.i("!=") else False) else self.false
     elif node.i("-") and len(node) == 2:
         lhs = self.eval_expr(node[0])
         rhs = self.eval_expr(node[1])
         if not isinstance(lhs, InterpreterValueInteger) or not isinstance(
                 rhs, InterpreterValueInteger):
             raise typesys.TypingError(
                 node,
                 "Attempt to perform arithmetic on something that isn't an integers"
             )
         return self.create_int_value((lhs.value - rhs.value) & bitmask)
     elif (node.i("-") and len(node) == 1) or node.i("~"):
         val = self.eval_expr(node[0])
         if not isinstance(val, InterpreterValueInteger):
             raise typesys.TypingError(
                 node, "Attempt to negate something that isn't an integer")
         return self.create_int_value(
             (-val.value if node.i("-") else ~val.value) & bitmask)
     elif node.i("/"):
         lhs = self.eval_expr(node[0])
         rhs = self.eval_expr(node[1])
         if not isinstance(lhs, InterpreterValueInteger) or not isinstance(
                 rhs, InterpreterValueInteger):
             raise typesys.TypingError(
                 node,
                 "Attempt to perform arithmetic on something that isn't an integers"
             )
         lhs_value = lhs.value
         rhs_value = rhs.value
         # Make sure, if our value is negative, we're dividing by a
         # negative rather than a very large value (due to two's
         # complement)
         lhs_value = self.normalize_negative(lhs_value)
         rhs_value = self.normalize_negative(rhs_value)
         res = lhs_value // rhs_value
         if res * rhs.value != lhs.value:
             # Python rounds toward negative infinity, whereas C
             # (and thus our language) rounds toward 0.
             if res < 0:
                 res += 1
         return self.create_int_value(res & bitmask)
     elif node.i("["):
         typ = self.program.types.decide_type(node, emitter.Scopes(), None)
         if not isinstance(typ, typesys.ArrayType):
             raise ValueError("This is a compiler bug.")
         # All of our typechecking has already been taken care of in
         # the logic in typesys there
         result_values: List[AbstractInterpreterValue] = []
         for child in node:
             result_values.append(self.eval_expr(child))
         return self.create_array_value(typ, result_values)
     elif node.i("arrinst"):
         typ = self.program.types.decide_type(node, emitter.Scopes(), None)
         if not isinstance(typ, typesys.ArrayType):
             raise ValueError("This is a compiler bug.")
         # Same thing, all of our typechecking is delegated to typesys
         array_len = self.eval_expr(node[1])
         if not isinstance(array_len, InterpreterValueInteger):
             raise typesys.TypingError(
                 node[1], "Type of array length must be an integer")
         if array_len.value > 1024:
             node.warn(
                 "Statically creating a very large array, this will make your bytecode file very large: %d"
                 % array_len.value)
         arrinst_result_values: List[AbstractInterpreterValue]
         if isinstance(typ.parent_type, typesys.IntType):
             arrinst_result_values = [self.create_int_value(0)
                                      ] * array_len.value
         elif isinstance(typ.parent_type, typesys.BoolType):
             arrinst_result_values = [self.false] * array_len.value
         else:
             arrinst_result_values = [self.null] * array_len.value
         return self.create_array_value(typ, arrinst_result_values)
     elif node.i("#"):
         val = self.eval_expr(node[0])
         if not isinstance(val, InterpreterValueArray):
             raise typesys.TypingError(
                 node[0],
                 "Cannot find length of something that isn't an array")
         return self.create_int_value(len(val.value))
     elif node.i("access"):
         lhs = self.eval_expr(node[0])
         rhs = self.eval_expr(node[1])
         if not isinstance(lhs, InterpreterValueArray):
             raise typesys.TypingError(
                 node[0],
                 "Can't access an element of something that isn't an array")
         if not isinstance(rhs, InterpreterValueInteger):
             raise typesys.TypingError(node[1],
                                       "Array indices must be integers")
         return lhs.value[rhs.value]
     else:
         node.compile_error("Cannot evaluate expression at compile-time")
Example #28
0
 def test_ints_equal(self):
     int_node_equal = Node(vtype=v.EQUAL,
                           children=[self.int_node_one, self.int_node_one])
     backend.walk_ast(int_node_equal)
     eq_(int_node_equal.syn_value, True)
Example #29
0
    def walk_ast(self, root, siblings=None, parent=None):

        # not popping b/c we only pop when *destroying* scope
        # (here we are just modifying)
        scope = backend.scopes[-1]

        # this is obviously not extentable since the content of an arg for a function
        # can be an arbitrary expression, this is just to get something working
        # ---
        # Another issue is that this won't work recurssively --> we have to think a
        # little bit more about how we should recursively evaulate this function
        # what should it return / how should it interact with syn_value
        # ---

        # Here we're evaluating all the children that are stored in a node before we
        # evaluate the node itself, doing a proper post-order traversal of the nodes.
        # Also, since we are iterating through the nodes of the tree using the 'in'
        # operator, we are doing a L-attributed evaluation as well, letting us get
        # inherited as well as syntysized values.
        # The only issue here is that we have to have some mechanism to know who the
        # children are at out level (and our parent) for the inherited attributes,
        # so we'll probably pass them in.

        if root != None:
            if root.vtype == v.FUNCTION_DEFINITION:
                scope[root.symbol] = root
                # root.syn_value = evaluate_function(f=root, scope=scope,
                #                                    args=[child.syn_value for child in root.children])
            elif root.vtype == v.FUNCTION_CALL:
                scp = backend.find(root.symbol)
                if not scp:
                    raise NameError, "Function '{}' does not exist".format(
                        root.symbol)
                # evaluating expressions passed into function before calling function
                for child in root.children:
                    backend.walk_ast(child)
                func = scp[root.symbol]
                if func.vtype == v.AGENT:
                    agent = copy.deepcopy(func)
                    self.agent_list.append(agent)
                    backend.scopes.append(agent.scope)
                    for st in agent.statements:
                        backend.walk_ast(st)
                    agent.create.execute(*root.children)
                    root.syn_value = agent
                    backend.scopes.pop()
                else:
                    root.syn_value = func.execute(*root.children)
            elif root.vtype == v.RETURN_STATEMENT:
                if root.children:
                    backend.walk_ast(root.children[0])
                    root.syn_value = root.children[0].syn_value
                else:
                    root.syn_value = None
            elif root.vtype in first_order_ops:
                for kid in root.children:
                    backend.walk_ast(kid)
                root.syn_value = first_order_ops[root.vtype](
                    *[child.syn_value for child in root.children])
                root.syn_vtype = root.children[0].syn_vtype
            elif root.vtype in boolean_ops:
                for kid in root.children:
                    backend.walk_ast(kid)
                root.syn_value = boolean_ops[root.vtype](
                    *[child.syn_value for child in root.children])
                root.syn_vtype = root.children[0].syn_vtype
            elif root.vtype in equality_ops:
                for kid in root.children:
                    backend.walk_ast(kid)
                root.syn_value = equality_ops[root.vtype](*[
                    child.syn_value for child in root.children
                ])  # does this break for len(root.children) > 2?
                root.syn_vtype = root.children[0].syn_vtype

            # Assignment
            elif root.vtype == v.ASSIGNMENT:
                if root.children[0].vtype == v.IMPLICIT_PARAM:
                    obj = root.children[0].children[0]
                    inner = root.children[0].children[1]
                    scp = backend.find(obj.symbol)
                    val_scp = scp[obj.symbol].scope
                    backend.walk_ast(root.children[1])
                    assign(val_scp, (inner, root.children[1]))
                else:
                    scp = backend.find(root.children[0].symbol)
                    if not scp:
                        raise NameError, "Variable '{}' does not exist".format(
                            root.children[0].symbol)
                    for child in root.children:
                        backend.walk_ast(child)
                    # this should have been disambiguated in the frontend
                    try:  # list assignment
                        grandchild = root.children[0].children[0]
                        for child in grandchild.children:
                            backend.walk_ast(child)
                        assert grandchild.vtype == v.BRACKET_ACCESS
                        depths = grandchild.syn_value
                        list_assign(scp, root.children)
                    except IndexError:  # not a list assignment
                        assign(
                            scp,
                            root.children)  # scopes modified via side effect

            elif root.vtype == v.IDENTIFIER:
                scp = backend.find(root.symbol)
                for kid in root.children:
                    backend.walk_ast(kid)

                # list access
                try:
                    root.children[0].vtype == v.BRACKET_ACCESS
                    # identifier as index
                    iden = root.children[0].children[0]
                    backend.walk_ast(iden)
                    root.children[0].syn_value = [iden.syn_value]
                    item = scp[root.symbol].get(
                        indexes=root.children[0].syn_value)
                    root.syn_value = item.syn_value
                    root.syn_vtype = item.syn_vtype
                # simple element access
                except IndexError:  # scp[root.symbol]:
                    root.syn_value = scp[root.symbol].syn_value
                    root.syn_vtype = scp[root.symbol].syn_vtype

            # Declaration
            elif root.vtype == v.DECLARATION:
                scp = backend.find(root.symbol)
                # if scp:
                #     raise Exception, "Symbol '{}' cannot be re-declared".format(root.symbol)
                from parser import Node, List
                # We store different Node types acc. to the root syn_vtype
                if root.syn_vtype == v.LIST_TYPE:
                    depths = []
                    for d in root.children[1].depths:
                        if isinstance(d, int):
                            depths.append(d)
                        else:
                            scp = backend.find(d)
                            depths.append(scp[d].syn_value)
                    syn_vtype = root.children[1].syn_vtype
                    none_obj = List(symbol=root.symbol,
                                    depths=depths,
                                    syn_vtype=syn_vtype)
                elif len(root.children) == 0:  # inside declaration assignment
                    # sorry, this is necessary b/c of wonkiness in the AST:
                    none_obj = Node(symbol=root.symbol,
                                    vtype=v.IDENTIFIER,
                                    syn_vtype=root.syn_vtype,
                                    syn_value=None)
                else:
                    assert len(root.children) > 0
                    identifier = root.children[0]
                    none_obj = Node(symbol=identifier.symbol,
                                    vtype=identifier.vtype,
                                    syn_vtype=root.syn_vtype,
                                    syn_value=None)
                scope[root.symbol] = none_obj

            elif root.vtype == v.DECLARATION_ASSIGNMENT:
                for child in root.children:
                    backend.walk_ast(child)
            elif root.vtype == v.IF:
                root.execute_if()
            elif root.vtype == v.PIF:
                root.execute_pif()
            elif root.vtype == v.WHILE:
                root.execute_while()
            elif root.vtype == v.REPEAT:
                root.execute_repeat()
            elif root.vtype == v.PROGRAM:
                for kid in root.children:
                    backend.walk_ast(kid)
            elif root.vtype == v.STATEMENT_LIST:
                for kid in root.children:
                    backend.walk_ast(kid)
            elif root.vtype == v.STATEMENT:
                for kid in root.children:
                    backend.walk_ast(kid)
                # for debugging
                # print root.children, backend.scopes
            elif root.vtype in v.RETURN_STATEMENT:
                root.syn_value = backend.walk_ast(root.children)
            elif root.vtype == v.BRACKET_ACCESS:
                pass
            elif root.vtype == v.AGENT_LIST:
                if root.children:
                    for child in root.children:
                        backend.walk_ast(child)
            elif root.vtype == v.AGENT:
                backend.scopes[-1][root.symbol] = root
            elif root.vtype == v.ENVIRONMENT:
                for child in root.children:
                    backend.walk_ast(child)
            elif root.vtype == v.POPULATE:
                backend.populate = root
            elif root.vtype == v.ACTION:
                backend.action = root
            elif root.vtype == v.TERMINATE:
                if root.children:
                    for child in root.children:
                        backend.walk_ast(child)
            elif root.vtype == v.INVARIANT_CLAUSE:
                freq = root.syn_value
                backend.invariants[freq].append(root)
            elif root.vtype == v.ANALYSIS:
                self.analysis = root
            elif root.vtype == v.WEIGHTED_VALUE_STAT:
                for kid in root.children:
                    backend.walk_ast(kid.children[1])
                root.syn_value = weighted_value(
                    [k.children[0].syn_value for k in root.children],
                    [k.children[1] for k in root.children]).syn_value
            elif root.vtype == v.IMPLICIT_PARAM:
                obj = root.children[0]
                inner = root.children[1]
                scp = backend.find(obj.symbol)
                val_scp = scp[obj.symbol].scope
                val = val_scp[inner.symbol]
                backend.scopes.append(val_scp)
                if inner.vtype == v.FUNCTION_CALL:
                    backend.walk_ast(inner)
                    root.syn_value = inner.syn_value
                else:
                    root.syn_value = val.syn_value
                backend.scopes.pop()
            else:
                pass  # @todo

        return root.syn_value
Example #30
0
    def decide_type(
            self,
            expr: parser.Node,
            scope: "emitter.Scopes",
            generic_type_context: Optional[GenericTypeContext],
            suppress_coercing_void_warning: bool = False) -> AbstractType:
        if expr.i("as"):
            return self.resolve_strict(expr[1], generic_type_context)
        elif expr.i("instanceof"):
            return self.bool_type
        elif expr.of("+", "*", "-", "^", "&", "|", "%",
                     "/") and len(expr) == 2:
            lhs_type = self.decide_type(expr[0], scope, generic_type_context)
            rhs_type = self.decide_type(expr[1], scope, generic_type_context)
            if not lhs_type.is_numerical():
                raise TypingError(expr[0],
                                  "Type %s is not numerical" % lhs_type)

            if not rhs_type.is_numerical():
                raise TypingError(expr[1],
                                  "Type %s is not numerical" % rhs_type)

            if not lhs_type.is_assignable_from(
                    rhs_type) or not lhs_type.is_assignable_to(rhs_type):
                raise TypingError(
                    expr,
                    "Types %s and %s are incompatible for arithmetic operation"
                    % (lhs_type, rhs_type))

            return lhs_type
        elif expr.of(">=", "<=", ">", "<"):
            lhs_type = self.decide_type(expr[0], scope, generic_type_context)
            rhs_type = self.decide_type(expr[1], scope, generic_type_context)
            if not lhs_type.is_numerical():
                raise TypingError(expr[0],
                                  "Type %s is not numerical" % lhs_type)

            if not rhs_type.is_numerical():
                raise TypingError(expr[1],
                                  "Type %s is not numerical" % rhs_type)

            if not lhs_type.is_assignable_from(
                    rhs_type) or not lhs_type.is_assignable_to(rhs_type):
                raise TypingError(
                    expr,
                    "Types %s and %s are incompatible for arithmetic comparison"
                    % (lhs_type, rhs_type))

            return self.bool_type
        elif expr.of("==", "!="):
            lhs_type = self.decide_type(expr[0], scope, generic_type_context)
            rhs_type = self.decide_type(expr[1], scope, generic_type_context)
            if not lhs_type.is_assignable_to(
                    rhs_type) and not rhs_type.is_assignable_to(lhs_type):
                raise TypingError(
                    expr,
                    "Incomparable types: '%s' and '%s'" % (lhs_type, rhs_type))
            return self.bool_type
        elif expr.i("number"):
            return self.int_type
        elif expr.of("and", "or"):
            lhs_type = self.decide_type(expr[0], scope, generic_type_context)
            rhs_type = self.decide_type(expr[1], scope, generic_type_context)
            if not lhs_type.is_boolean():
                raise TypingError(expr[0], "Type %s is not boolean" % lhs_type)

            if not rhs_type.is_boolean():
                raise TypingError(expr[0], "Type %s is not boolean" % rhs_type)

            return self.bool_type
        elif expr.i("not"):
            type = self.decide_type(expr[0], scope, generic_type_context)
            if not type.is_boolean():
                raise TypingError(expr[0], "Type %s is not boolean" % type)
            return self.bool_type
        elif expr.of("~", "-") and len(expr) == 1:
            type = self.decide_type(expr[0], scope, generic_type_context)
            if not type.is_numerical():
                raise TypingError(expr[0], "Type %s is not numerical" % type)
            return self.int_type
        elif expr.of("ident", ".") \
                and util.get_flattened(expr) is not None \
                and self.program.static_variables.has_variable(util.nonnull(util.get_flattened(expr))):
            return self.program.static_variables.resolve_variable(
                util.nonnull(util.get_flattened(expr))).type
        elif expr.i("ident"):
            return scope.resolve(expr.data_strict, expr).type
        elif expr.of("true", "false"):
            return self.bool_type
        elif expr.i("null"):
            return self.void_type
        elif expr.i("["):
            # For now, everything must be the same type, except for nulls
            # interspersed. Later this will change.
            current_type = None
            if len(expr) == 0:
                expr.compile_error(
                    "Zero-length arrays must be instantiated with the arbitrary-length instantiation syntax"
                )
            for child in expr:
                current_child_type: AbstractType = self.decide_type(
                    child, scope, generic_type_context)
                if current_type is None:
                    if not current_child_type.is_void():
                        current_type = current_child_type
                    else:
                        continue

                # This is to make the typechecker happy
                # We know this is safe because of the previous if-statement
                current_type_not_none: AbstractType = current_type

                while current_type_not_none.get_supertype(
                ) is not None and not current_child_type.is_assignable_to(
                        current_type_not_none):
                    current_type = current_type_not_none.get_supertype()
                if not current_child_type.is_assignable_to(
                        current_type_not_none):
                    raise TypingError(
                        child,
                        "Could not reconcile type %s" % (current_child_type))

            if current_type is None:
                expr.compile_error(
                    "Cannot have an array literal comprising only null values, use arbitrary-length instantiation syntax instead"
                )
                # Unreachable
                return None  # type: ignore
            else:
                return self.get_array_type(current_type)
        elif expr.i("arrinst"):
            return self.get_array_type(
                self.resolve_strict(expr[0], generic_type_context))
        elif expr.i("#"):
            if not self.decide_type(expr[0], scope,
                                    generic_type_context).is_array():
                raise TypingError(
                    expr[0],
                    "Can't decide length of something that isn't an array")
            return self.int_type
        elif expr.i("access"):
            lhs_type = self.decide_type(expr[0], scope, generic_type_context)
            if not lhs_type.is_array():
                raise TypingError(
                    expr,
                    "Attempt to access element of something that isn't an array"
                )
            assert isinstance(lhs_type, ArrayType)
            return lhs_type.parent_type
        elif expr.i("call"):
            # TODO: Move method call typechecking in here from emitter.py.
            signature = self.resolve_to_signature(expr[0], scope,
                                                  generic_type_context)
            if len(expr["typeargs"]) != (
                    len(signature.generic_type_context.arguments)
                    if signature.generic_type_context is not None else 0):
                expr.compile_error(
                    "Wrong number of type arguments (expected %s, got %s)" %
                    (len(signature.generic_type_context.arguments)
                     if signature.generic_type_context is not None else 0,
                     len(expr["typeargs"])))
            signature = signature.specialize([
                self.resolve_strict(typ, generic_type_context)
                for typ in expr["typeargs"]
            ], self.program, expr["typeargs"])
            if signature is not None:
                if (not suppress_coercing_void_warning) and isinstance(
                        signature.returntype, VoidType):
                    expr.warn("Coercing void")
                return signature.returntype
            if expr[0].i("."):
                dot_node = expr[0]
                lhs_type = self.decide_type(dot_node[0], scope)
                if not lhs_type.is_clazz():
                    raise TypingError(
                        dot_node[1],
                        "Attempt to call a method on non-class type '%s'" %
                        lhs_type)
                signature = lhs_type.method_signature(dot_node[1].data)
            if signature is None:
                expr.compile_error("Unknown method name '%s'" % expr[0].data)
            if (not suppress_coercing_void_warning) and isinstance(
                    signature.returntype, VoidType):
                expr.warn("Coercing void")
            return signature.returntype
        elif expr.i("new"):
            ret = self.resolve_strict(expr[0],
                                      generic_type_context,
                                      allow_raw=True)
            # Why not .is_class()? Because we can't instantiate generic type parameters.
            if not isinstance(ret, ClazzType):
                raise TypingError(expr[0], "Type %s is not a class" % ret)
            type_arguments: List[AbstractType] = []
            for argument in expr["typeargs"]:
                type_arguments.append(
                    self.resolve_strict(argument, generic_type_context))
            ret = ret.specialize(type_arguments, expr)
            return ret
        elif expr.i("."):
            # Ternary operator to satisfy typechecker (if-else statement would effectively require phi node which is ugly)
            lhs_typ: AbstractType = \
                (scope.resolve(expr[0].data_strict, expr[0]).type) if expr[0].i("ident") \
                else self.decide_type(expr[0], scope, generic_type_context)
            if not lhs_typ.is_clazz():
                expr.compile_error(
                    "Attempt to access an attribute of something that isn't a class"
                )
            assert isinstance(lhs_typ, ClazzType)
            return lhs_typ.type_of_property(expr[1].data_strict, expr)
        elif expr.i("string"):
            string_type = self.get_string_type()
            if string_type is None:
                expr.compile_error(
                    "Cannot use string literal without an implementation of stdlib.String"
                )
            return string_type
        elif expr.i("super"):
            # TODO: This is horribly ugly
            typ = scope.resolve("this", expr).type
            if not isinstance(typ, ClazzType):
                expr.compile_error("Variable `this` isn't a class type")
            parent_type = typ.get_supertype()
            if parent_type is None:
                expr.compile_error(
                    "Attempt to reference superclass in a class without a superclass"
                )
            return parent_type
        else:
            raise ValueError(
                "Expression not accounted for in typesys. This is a compiler bug."
            )
Example #31
0
pn_concatenation = Node("pn_concatenation"
                        , Seq(pn_ident_or_term_or_pn_groups, NotNeed(","), TRef("pn_rhs", grammar=cur_grammar, flat=True))
                        , flat_eq_name=True, grammar=cur_grammar)

pn_alteration = Node("pn_alteration"
                     , Seq(pn_ident_or_term_or_pn_groups, NotNeed("|"), TRef("pn_rhs", grammar=cur_grammar, flat=True))
                     , flat_eq_name=True, grammar=cur_grammar)

pn_rhs = Node("pn_rhs", Or(pn_concatenation
                           , pn_alteration
                           , pn_groups
                           , pn_ident_or_term)
              , grammar=cur_grammar)

pn_rule = Node("pn_rule", Seq(pn_lhs, NotNeed("="), pn_rhs, NotNeed(";")), grammar=cur_grammar)
pn_grammar = Node("ebnf_grammar", ZeroOrMore(pn_rule), grammar=cur_grammar)


#token_iterator = TokenIterator(TextReader(open("test1.txt"))
#                               , tt_list, tt_skip_list)
#token_reader = TokenReader(token_iterator)
#token_reader = TokenReader(TokenIterator(TextReader(open("test1.txt")), tt_list, tt_skip_list))


if __name__ == '__main__':
    # SetRecursionLimit(5000)
    # lexing with tokens reduces recursion level
    rslt = pn_grammar.read_from(token_reader)
    thing_pprint(rslt.readedlist)
Example #32
0
with test('load grammar'):
    g1 = parser.Grammar(fg1)

with test('continuations'):
    test.eq(sorted(repr(r) for r in g1.continuations('Aux')), [
        'Root -> Aux.$0.$1 NP.$0 VP.$1.-', 'VP.$0.$1 -> Aux.$0.$2 VP.$2.$1',
        'VP.$0.- -> Aux.$0.pred AdjP', 'VP.$0.- -> Aux.$0.pred NP.*'
    ])

with test('g1.lexicon.parts'):
    test.eq(sorted(str(pos) for pos in g1.lexicon.parts('be')),
            ['Aux.base.enp', 'Aux.base.ing', 'Aux.base.pred'])

with test('Node'):
    if hasattr(parser, 'Node'): from parser import Node
    v = Node(C('V.sg.t.*'), 'chases', 2, 3)
    test.eq(v.cat, ('V', 'sg', 't', '*'))
    test.eq(v.i, 2)
    test.eq(v.j, 3)

with test('e.__str__'):
    e = parser.Edge(rule, [v], ('sg', '*'))
    test.eq(str(e), 'VP.$0 -> [2 V.sg.t.* 3] * NP.* PP.$1 : sg *')

with test('e.__repr__'):
    test.eq(repr(e), '<Edge VP.$0 -> [2 V.sg.t.* 3] * NP.* PP.$1 : sg *>')

with test('p.reset'):
    p = parser.Parser(g0)
    p.reset('this dog barks'.split())
    test.eq(p.chart, {})
Example #33
0
 def type_of_property(self, name: str, node: parser.Node) -> AbstractType:
     ret = self.type_of_property_optional(name)
     if ret is None:
         node.compile_error("Invalid property name '%s' for type '%s'" %
                            (name, self.name))
     return ret