add range constraint type
This commit is contained in:
+21
-10
@@ -42,6 +42,7 @@ C_LONGDOUBLE :: Type(28)
|
||||
|
||||
BOOL :: Type(29)
|
||||
FLOAT :: Type(30)
|
||||
RANGE :: Type(31)
|
||||
|
||||
DYNAMIC_START :: Type(64)
|
||||
|
||||
@@ -57,6 +58,7 @@ Kind :: enum u8 {
|
||||
Void,
|
||||
Int_Constraint,
|
||||
Float_Constraint,
|
||||
Range_Constraint,
|
||||
Scalar,
|
||||
Array,
|
||||
Pointer,
|
||||
@@ -299,6 +301,8 @@ kind :: proc(value: Type, store: ^Store = nil) -> Kind {
|
||||
return .Int_Constraint
|
||||
case FLOAT:
|
||||
return .Float_Constraint
|
||||
case RANGE:
|
||||
return .Range_Constraint
|
||||
case BOOL:
|
||||
return .Scalar
|
||||
}
|
||||
@@ -338,15 +342,17 @@ is_bool :: proc(value: Type) -> bool {
|
||||
}
|
||||
|
||||
is_constraint :: proc(value: Type) -> bool {
|
||||
return value == INT || value == FLOAT
|
||||
return value == INT || value == FLOAT || value == RANGE
|
||||
}
|
||||
|
||||
// constraint_target reports the concrete type a constraint binding takes for an
|
||||
// inferred value, or INVALID if the value's numeric family is incompatible.
|
||||
// FLOAT accepts integers by defaulting them to f64: a constant integer becomes a
|
||||
// float literal in build_constant_expr, while a runtime integer then fails the
|
||||
// cross-family f64 coercion in coerce_expr (the intended mismatch error).
|
||||
constraint_target :: proc(constraint, inferred: Type) -> Type {
|
||||
// constraint_target reports the concrete type a constraint binding (local, or a
|
||||
// param/result monomorphized per call site) takes for an inferred value, or
|
||||
// INVALID if the value's family is incompatible. FLOAT accepts integers by
|
||||
// defaulting them to f64: a constant integer becomes a float literal in
|
||||
// build_constant_expr, while a runtime integer then fails the cross-family f64
|
||||
// coercion in coerce_expr (the intended mismatch error). RANGE accepts any range
|
||||
// type, keeping its inferred element type.
|
||||
constraint_target :: proc(constraint, inferred: Type, store: ^Store = nil) -> Type {
|
||||
switch constraint {
|
||||
case INT:
|
||||
return inferred if is_concrete_integer(inferred) else INVALID
|
||||
@@ -355,18 +361,22 @@ constraint_target :: proc(constraint, inferred: Type) -> Type {
|
||||
return inferred
|
||||
}
|
||||
return F64 if is_concrete_integer(inferred) else INVALID
|
||||
case RANGE:
|
||||
return inferred if is_range(inferred, store) else INVALID
|
||||
}
|
||||
return INVALID
|
||||
}
|
||||
|
||||
// constraint_accepts reports strict numeric-family membership, used when widening
|
||||
// a constraint binding across assignments (no integer-to-float defaulting here).
|
||||
constraint_accepts :: proc(constraint, concrete: Type) -> bool {
|
||||
// constraint_accepts reports strict family membership, used when widening a
|
||||
// constraint binding across assignments (no integer-to-float defaulting here).
|
||||
constraint_accepts :: proc(constraint, concrete: Type, store: ^Store = nil) -> bool {
|
||||
switch constraint {
|
||||
case INT:
|
||||
return is_concrete_integer(concrete)
|
||||
case FLOAT:
|
||||
return is_float(concrete)
|
||||
case RANGE:
|
||||
return is_range(concrete, store)
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -1175,6 +1185,7 @@ name :: proc(value: Type) -> string {
|
||||
case BOOL: return "bool"
|
||||
case INT: return "int"
|
||||
case FLOAT: return "float"
|
||||
case RANGE: return "range"
|
||||
case I8: return "i8"
|
||||
case I16: return "i16"
|
||||
case I32: return "i32"
|
||||
|
||||
Reference in New Issue
Block a user