Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support sum types #62

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions crates/core/src/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@ impl Member {
}
}

/// Index of a variant in an enum.
#[cfg_attr(test, derive(TS), ts(export))]
#[cfg_attr(
feature = "serde",
derive(Serialize, Deserialize),
serde(rename = "VariantId")
)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Variant(usize);

pub fn variant(id: usize) -> Variant {
Variant(id)
}

impl Variant {
pub fn variant(self) -> usize {
self.0
}
}

/// Index of an uninstantiated function reference in a definition context.
#[cfg_attr(test, derive(TS), ts(export))]
#[cfg_attr(
Expand Down
67 changes: 47 additions & 20 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ use ts_rs::TS;
pub enum Constraint {
/// Can be the `index` type of an `Array`.
Index,
/// Has a zero value and an addition operation.
Vector,
/// Can be the `scope` type of a `Ref`.
Scope,
/// Allows a `Ref` to be read when used as its `scope` type.
Read,
/// Allows a `Ref` to be accumulated into when used as its `scope` type.
Accum,
}

/// A type.
Expand All @@ -28,7 +28,6 @@ pub enum Constraint {
pub enum Ty {
Unit,
Bool,
/// Satisfies `Constraint::Vector`.
F64,
/// A nonnegative integer less than `size`. Satisfies `Constraint::Index`.
Fin {
Expand All @@ -37,25 +36,25 @@ pub enum Ty {
Generic {
id: id::Generic,
},
/// Satisfies `Constraint::Scope`.
/// May satisfy `Constraint::Read` or `Constraint::Accum` depending on the block.
Scope {
id: id::Block,
},
Ref {
/// Must satisfy `Constraint::Scope`.
scope: id::Ty,
inner: id::Ty,
},
/// Satisfies `Constraint::Vector` if `elem` does.
Array {
/// Must satisfy `Constraint::Index`.
index: id::Ty,
elem: id::Ty,
},
/// Satisfies `Constraint::Vector` if all `members` do.
Tuple {
members: Vec<id::Ty>,
},
Enum {
variants: Vec<id::Ty>,
},
}

/// Reference to a function, with types supplied for its generic parameters.
Expand Down Expand Up @@ -137,20 +136,24 @@ pub enum Expr {
members: Vec<id::Var>,
},

/// Index into an `Array`.
Index {
array: id::Var,
index: id::Var,
},
/// Access a member of a `Tuple`.
Member {
tuple: id::Var,
member: id::Member,
},

/// Index into a `Ref`.
Slice {
/// Must actually be a `Ref` of an array, not just an array.
array: id::Var,
index: id::Var,
},
/// Access a member of a `Ref`.
Field {
/// Must actually be a `Ref` of a tuple, not just a tuple.
tuple: id::Var,
Expand All @@ -166,34 +169,58 @@ pub enum Expr {
left: id::Var,
right: id::Var,
},
Select {
/// Must be of type `Bool`.
cond: id::Var,
then: id::Var,
els: id::Var,
},

Call {
func: id::Func,
arg: id::Var,
},
If {
cond: id::Var,
/// `arg` has type `Unit`.
then: id::Block,
/// `arg` has type `Unit`.
els: id::Block,
},

For {
/// Must satisfy `Constraint::Index`.
index: id::Ty,
/// `arg` has type `index`.
body: id::Block,
},
/// Scope for a `Ref` with `Constraint::Read`.
Read {
/// Contents of the `Ref`.
var: id::Var,
/// `arg` has type `Ref` with scope `body` and inner type same as `var`.
body: id::Block,
},
/// Scope for a `Ref` with `Constraint::Accum`.
Accum {
/// Final contents of the `Ref`.
var: id::Var,
/// Must satisfy `Constraint::Vector`.
vector: id::Ty,
/// `arg` has type `Ref` with scope `body` and inner type `vector`.
/// Topology of the `Ref`.
shape: id::Var,
/// `arg` has type `Ref` with scope `body` and inner type same as `shape`.
body: id::Block,
},

/// Accumulate into a `Ref`. Returned type is `Unit`.
/// Pattern-matching on an `Enum`.
Match {
var: id::Var,
branches: Vec<id::Block>,
},
/// Pattern-matching on a `Ref`.
Narrow {
var: id::Var,
branches: Vec<id::Block>,
},

/// Read from a `Ref` whose `scope` satisfies `Constraint::Read`.
Ask {
/// The `Ref`, which must be in scope.
var: id::Var,
},
/// Accumulate into a `Ref` whose `scope` satisfies `Constraint::Accum`. Returns `Unit`.
Add {
/// The `Ref`, which must be in scope.
accum: id::Var,
Expand Down