예제 #1
0
 def pair_type(self, items, meta):
     assert len(items) >= 2
     assert isinstance(items[0], T.Base)
     assert isinstance(items[1], T.Base)
     optional = False
     if len(items) > 2:
         if items[2].value == "?":
             optional = True
     return T.Pair(items[0], items[1], optional)
예제 #2
0
파일: _parser.py 프로젝트: prihoda/miniwdl
    def type(self, items, meta):
        quantifiers = set()
        if len(items) > 1 and isinstance(items[-1], set):
            quantifiers = items.pop()
        param = items[1] if len(items) > 1 else None
        param2 = items[2] if len(items) > 2 else None

        if items[0].value == "Array":
            if not param or param2:
                raise Err.InvalidType(sp(self.filename, meta),
                                      "Array must have one type parameter")
            if quantifiers - set(["optional", "nonempty"]):
                raise Err.ValidationError(
                    sp(self.filename, meta),
                    "invalid type quantifier(s) for Array")
            return T.Array(param, "optional" in quantifiers, "nonempty"
                           in quantifiers)
        if "nonempty" in quantifiers:
            raise Err.InvalidType(
                sp(self.filename, meta),
                "invalid type quantifier(s) for " + items[0].value)

        atomic_types = {
            "Int": T.Int,
            "Float": T.Float,
            "Boolean": T.Boolean,
            "String": T.String,
            "File": T.File,
        }
        if items[0].value in atomic_types:
            if param or param2:
                raise Err.InvalidType(
                    sp(self.filename, meta),
                    items[0] + " type doesn't accept parameters")
            return atomic_types[items[0].value]("optional" in quantifiers)

        if items[0].value == "Map":
            if not (param and param2):
                raise Err.InvalidType(sp(self.filename, meta),
                                      "Map must have two type parameters")
            return T.Map((param, param2), "optional" in quantifiers)

        if items[0].value == "Pair":
            if not (param and param2):
                raise Err.InvalidType(sp(self.filename, meta),
                                      "Pair must have two type parameters")
            return T.Pair(param, param2, "optional" in quantifiers)

        if param or param2:
            raise Err.InvalidType(sp(self.filename, meta),
                                  "Unexpected type parameter(s)")

        return T.StructInstance(items[0].value, "optional" in quantifiers)
예제 #3
0
 def infer_type(self, expr: E.Apply) -> T.Base:
     if len(expr.arguments) != 2:
         raise Error.WrongArity(expr, 2)
     arg0ty: T.Base = expr.arguments[0].type
     if not isinstance(arg0ty, T.Array) or (expr._check_quant and arg0ty.optional):
         raise Error.StaticTypeMismatch(expr.arguments[0], T.Array(T.Any()), arg0ty)
     if isinstance(arg0ty.item_type, T.Any):
         # TODO: error for 'indeterminate type'
         raise Error.EmptyArray(expr.arguments[0])
     arg1ty: T.Base = expr.arguments[1].type
     if not isinstance(arg1ty, T.Array) or (expr._check_quant and arg1ty.optional):
         raise Error.StaticTypeMismatch(expr.arguments[1], T.Array(T.Any()), arg1ty)
     if isinstance(arg1ty.item_type, T.Any):
         # TODO: error for 'indeterminate type'
         raise Error.EmptyArray(expr.arguments[1])
     return T.Array(
         T.Pair(arg0ty.item_type, arg1ty.item_type),
         nonempty=(arg0ty.nonempty or arg1ty.nonempty),
     )
예제 #4
0
 def _infer_type(self, type_env: Env.Types) -> T.Base:
     self.left.infer_type(type_env, self._check_quant)
     self.right.infer_type(type_env, self._check_quant)
     return T.Pair(self.left.type, self.right.type)