-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1571 from hylo-lang/array-buffer-init
Implement minimal support for generic buffers
- Loading branch information
Showing
58 changed files
with
925 additions
and
598 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/// Properties about the representation of a type or term. | ||
public struct ValueFlags: Hashable, OptionSet { | ||
|
||
public typealias RawValue = UInt8 | ||
|
||
public let rawValue: UInt8 | ||
|
||
public init(rawValue: UInt8) { | ||
self.rawValue = rawValue | ||
} | ||
|
||
/// Returns the union of `l` with `r`. | ||
public static func | (l: Self, r: Self) -> Self { | ||
l.union(r) | ||
} | ||
|
||
/// The type contains one or more error types. | ||
public static let hasError = ValueFlags(rawValue: 1 << 0) | ||
|
||
/// The type contains open type variables. | ||
public static let hasVariable = ValueFlags(rawValue: 1 << 1) | ||
|
||
/// The type contains skolemized variables. | ||
public static let hasSkolem = ValueFlags(rawValue: 1 << 2) | ||
|
||
/// The type is not canonical. | ||
public static let hasNonCanonical = ValueFlags(rawValue: 1 << 3) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import Utils | ||
|
||
/// A box wrapping a term. | ||
private protocol TermBox { | ||
|
||
/// Hashes the salient parts of the wrapped value into `hasher`. | ||
func hash(into hasher: inout Hasher) | ||
|
||
/// Returns whether the value wrapped inside `self` is equal to that wrapped inside `other`. | ||
func equals<Other: TermBox>(_ other: Other) -> Bool | ||
|
||
/// Returns the value wrapped inside `self` with its type erased. | ||
func unwrap() -> any TermProtocol | ||
|
||
/// Returns the value wrapped inside `self` as an instance of `T` or `nil` if that value has a | ||
/// different type. | ||
func unwrap<T: TermProtocol>(as: T.Type) -> T? | ||
|
||
} | ||
|
||
/// A box wrapping an instance of `Base`. | ||
private struct ConcreteTermBox<Base: TermProtocol>: TermBox { | ||
|
||
/// The value wrapped by this instance. | ||
let base: Base | ||
|
||
func hash(into hasher: inout Hasher) { | ||
base.hash(into: &hasher) | ||
} | ||
|
||
func equals<Other: TermBox>(_ other: Other) -> Bool { | ||
base == other.unwrap(as: Base.self) | ||
} | ||
|
||
func unwrap() -> any TermProtocol { | ||
base | ||
} | ||
|
||
func unwrap<T: TermProtocol>(as: T.Type) -> T? { | ||
base as? T | ||
} | ||
|
||
} | ||
|
||
/// The compile-time representation of the value of an expression. | ||
public struct AnyTerm { | ||
|
||
/// A shorthand for `^ErrorTerm()`. | ||
public static let error = ^ErrorTerm() | ||
|
||
/// The value wrapped by this instance. | ||
private var wrapped: TermBox | ||
|
||
/// Creates a type-erased container wrapping the given instance. | ||
/// | ||
/// - Parameter base: A type to wrap. | ||
public init<T: TermProtocol>(_ base: T) { | ||
if let t = base as? AnyTerm { | ||
self.wrapped = t.wrapped | ||
} else { | ||
self.wrapped = ConcreteTermBox(base: base) | ||
} | ||
} | ||
|
||
/// Accesses value wrapped by this instance. | ||
/// | ||
/// The `base` property can be cast back to its original type using one of the type casting | ||
/// operators (`as?`, `as!`, or `as`). | ||
public var base: any TermProtocol { | ||
wrapped.unwrap() | ||
} | ||
|
||
} | ||
|
||
extension AnyTerm: TermProtocol { | ||
|
||
public var flags: ValueFlags { base.flags } | ||
|
||
} | ||
|
||
extension AnyTerm: Equatable { | ||
|
||
/// Returns whether `l` is syntactically equal to `r`. | ||
public static func == (l: Self, r: Self) -> Bool { | ||
l.wrapped.equals(r.wrapped) | ||
} | ||
|
||
} | ||
|
||
extension AnyTerm: Hashable { | ||
|
||
public func hash(into hasher: inout Hasher) { | ||
wrapped.hash(into: &hasher) | ||
} | ||
|
||
} | ||
|
||
extension AnyTerm: CustomStringConvertible { | ||
|
||
public var description: String { String(describing: base) } | ||
|
||
} | ||
|
||
/// Creates a type-erased container wrapping the given instance. | ||
public prefix func ^ <T: TermProtocol>(_ base: T) -> AnyTerm { | ||
AnyTerm(base) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/// A box wrapping a concrete compile-time value. | ||
public struct ConcreteTerm: TermProtocol { | ||
|
||
/// The value of the term. | ||
public let value: AnyHashable | ||
|
||
/// Creates an instance with the given value. | ||
public init(wrapping value: AnyHashable) { | ||
self.value = value | ||
} | ||
|
||
public var flags: ValueFlags { .init() } | ||
|
||
} | ||
|
||
extension ConcreteTerm: CustomStringConvertible { | ||
|
||
public var description: String { "\(value)" } | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/// A term denoting a type checking error. | ||
public struct ErrorTerm: TermProtocol { | ||
|
||
public var flags: ValueFlags { .hasError } | ||
|
||
} | ||
|
||
extension ErrorTerm: CustomStringConvertible { | ||
|
||
public var description: String { "_" } | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import Utils | ||
|
||
/// A generic type parameter. | ||
public struct GenericTermParameter: TermProtocol { | ||
|
||
/// The declaration that introduces the parameter. | ||
public let decl: GenericParameterDecl.ID | ||
|
||
/// The name of the parameter. | ||
public let name: Incidental<String> | ||
|
||
/// Creates an instance denoting the generic type parameter declared by `decl`. | ||
public init(_ decl: GenericParameterDecl.ID, ast: AST) { | ||
self.decl = decl | ||
self.name = Incidental(ast[decl].baseName) | ||
} | ||
|
||
public var flags: ValueFlags { .hasSkolem } | ||
|
||
} | ||
|
||
extension GenericTermParameter: CustomStringConvertible { | ||
|
||
public var description: String { name.value } | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/// A protocol describing the API of a Hylo term. | ||
public protocol TermProtocol: Hashable { | ||
|
||
/// Properties about the representation of `self`. | ||
var flags: ValueFlags { get } | ||
|
||
} | ||
|
||
extension TermProtocol { | ||
|
||
/// Creates an instance with the value of `container.base` or returns `nil` if that value has | ||
/// a different type. | ||
public init?(_ container: AnyTerm) { | ||
if let t = container.base as? Self { | ||
self = t | ||
} else { | ||
return nil | ||
} | ||
} | ||
|
||
/// Creates an instance with the value of `container.base` or returns `nil` if either that value | ||
/// has a different type or `container` is `nil`. | ||
public init?(_ container: AnyTerm?) { | ||
if let t = container.flatMap(Self.init(_:)) { | ||
self = t | ||
} else { | ||
return nil | ||
} | ||
} | ||
|
||
/// Returns whether the specified flags are raised on this term. | ||
public subscript(fs: ValueFlags) -> Bool { flags.contains(fs) } | ||
|
||
} |
Oops, something went wrong.