Esempio n. 1
0
 def infer_type(self, expr: E.Apply) -> T.Base:
     if len(expr.arguments) != 1:
         raise Error.WrongArity(expr, 1)
     expr.arguments[0].typecheck(T.Array(T.Any()))
     # TODO: won't handle implicit coercion from T to Array[T]
     assert isinstance(expr.arguments[0].type, T.Array)
     if expr.arguments[0].type.item_type is None:
         return T.Array(T.Any())
     if not isinstance(expr.arguments[0].type.item_type, T.Array):
         raise Error.StaticTypeMismatch(
             expr.arguments[0], T.Array(T.Array(T.Any())), expr.arguments[0].type
         )
     return expr.arguments[0].type
Esempio n. 2
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),
     )
Esempio n. 3
0
 def infer_type(self, expr: E.Apply) -> T.Base:
     if len(expr.arguments) != 1:
         raise Error.WrongArity(expr, 1)
     if not isinstance(expr.arguments[0].type, T.Array) or (
         expr.arguments[0]._check_quant and expr.arguments[0].type.optional
     ):
         raise Error.StaticTypeMismatch(
             expr.arguments[0], T.Array(T.Any()), expr.arguments[0].type
         )
     if isinstance(expr.arguments[0].type.item_type, T.Any):
         # TODO: error for 'indeterminate type'
         raise Error.EmptyArray(expr.arguments[0])
     ty = expr.arguments[0].type.item_type
     assert isinstance(ty, T.Base)
     return T.Array(ty.copy(optional=False))
Esempio n. 4
0
    def __init__(self):
        # language built-ins
        self._at = _At()
        self._land = _And()
        self._lor = _Or()
        self._negate = StaticFunction(
            "_negate", [T.Boolean()], T.Boolean(), lambda x: V.Boolean(not x.value)
        )
        self._add = _AddOperator()
        self._sub = _ArithmeticOperator("-", lambda l, r: l - r)
        self._mul = _ArithmeticOperator("*", lambda l, r: l * r)
        self._div = _ArithmeticOperator("/", lambda l, r: l // r)
        self._rem = StaticFunction(
            "_rem", [T.Int(), T.Int()], T.Int(), lambda l, r: V.Int(l.value % r.value)
        )
        self._eqeq = _ComparisonOperator("==", lambda l, r: l == r)
        self._neq = _ComparisonOperator("!=", lambda l, r: l != r)
        self._lt = _ComparisonOperator("<", lambda l, r: l < r)
        self._lte = _ComparisonOperator("<=", lambda l, r: l <= r)
        self._gt = _ComparisonOperator(">", lambda l, r: l > r)
        self._gte = _ComparisonOperator(">=", lambda l, r: l >= r)

        # static stdlib functions
        for (name, argument_types, return_type, F) in [
            ("floor", [T.Float()], T.Int(), lambda v: V.Int(math.floor(v.value))),
            ("ceil", [T.Float()], T.Int(), lambda v: V.Int(math.ceil(v.value))),
            ("round", [T.Float()], T.Int(), lambda v: V.Int(round(v.value))),
            ("length", [T.Array(T.Any())], T.Int(), lambda v: V.Int(len(v.value))),
            ("sub", [T.String(), T.String(), T.String()], T.String(), _sub),
            ("basename", [T.String(), T.String(optional=True)], T.String(), _basename),
            (
                "defined",
                [T.Any(optional=True)],
                T.Boolean(),
                lambda v: V.Boolean(not isinstance(v, V.Null)),
            ),
            # context-dependent:
            ("write_lines", [T.Array(T.String())], T.File(), _notimpl),
            ("write_tsv", [T.Array(T.Array(T.String()))], T.File(), _notimpl),
            ("write_map", [T.Map((T.Any(), T.Any()))], T.File(), _notimpl),
            ("write_json", [T.Any()], T.File(), _notimpl),
            ("stdout", [], T.File(), _notimpl),
            ("stderr", [], T.File(), _notimpl),
            ("glob", [T.String()], T.Array(T.File()), _notimpl),
            ("read_int", [T.File()], T.Int(), _notimpl),
            ("read_boolean", [T.File()], T.Boolean(), _notimpl),
            ("read_string", [T.File()], T.String(), _notimpl),
            ("read_float", [T.File()], T.Float(), _notimpl),
            ("read_array", [T.File()], T.Array(T.Any()), _notimpl),
            ("read_map", [T.File()], T.Map((T.Any(), T.Any())), _notimpl),
            ("read_lines", [T.File()], T.Array(T.Any()), _notimpl),
            ("read_tsv", [T.File()], T.Array(T.Array(T.String())), _notimpl),
            ("read_json", [T.File()], T.Any(), _notimpl),
        ]:
            setattr(self, name, StaticFunction(name, argument_types, return_type, F))

        # polymorphically typed stdlib functions which require specialized
        # infer_type logic
        self.range = _Range()
        self.prefix = _Prefix()
        self.size = _Size()
        self.select_first = _SelectFirst()
        self.select_all = _SelectAll()
        self.zip = _Zip()
        self.cross = _Zip()  # FIXME
        self.flatten = _Flatten()
        self.transpose = _Transpose()