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
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), )
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))
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()