mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Generate schema for checkmate
This commit is contained in:
parent
f78919cd2e
commit
358681a464
9 changed files with 1022 additions and 57 deletions
262
crates/compiler/checkmate_schema/src/lib.rs
Normal file
262
crates/compiler/checkmate_schema/src/lib.rs
Normal file
|
@ -0,0 +1,262 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use schemars::{schema::RootSchema, schema_for, JsonSchema};
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub enum Constraint {}
|
||||
|
||||
#[derive(Serialize, JsonSchema, Debug, PartialEq)]
|
||||
pub struct Variable(pub u32);
|
||||
|
||||
macro_rules! impl_content {
|
||||
($($name:ident { $($arg:ident: $ty:ty,)* },)*) => {
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub enum Content {
|
||||
$(
|
||||
$name {
|
||||
$($arg: $ty),*
|
||||
},
|
||||
)*
|
||||
}
|
||||
|
||||
impl Content {
|
||||
$(
|
||||
#[allow(non_snake_case)]
|
||||
pub fn $name($($arg: $ty),*) -> Self {
|
||||
Self::$name { $($arg),* }
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_content! {
|
||||
Flex {
|
||||
name: Option<String>,
|
||||
},
|
||||
Rigid {
|
||||
name: String,
|
||||
},
|
||||
FlexAble {
|
||||
name: Option<String>,
|
||||
abilities: Vec<Symbol>,
|
||||
},
|
||||
RigidAble {
|
||||
name: String,
|
||||
abilities: Vec<Symbol>,
|
||||
},
|
||||
Recursive {
|
||||
name: Option<String>,
|
||||
structure: Variable,
|
||||
},
|
||||
LambdaSet {
|
||||
solved: Vec<ClosureType>,
|
||||
unspecialized: Vec<UnspecializedClosureType>,
|
||||
recursion_var: Option<Variable>,
|
||||
ambient_function: Variable,
|
||||
},
|
||||
Alias {
|
||||
name: Symbol,
|
||||
variables: AliasTypeVariables,
|
||||
real_variable: Variable,
|
||||
kind: AliasKind,
|
||||
},
|
||||
Apply {
|
||||
symbol: Symbol,
|
||||
variables: Vec<Variable>,
|
||||
},
|
||||
Function {
|
||||
arguments: Vec<Variable>,
|
||||
lambda_type: Variable,
|
||||
ret: Variable,
|
||||
},
|
||||
Record {
|
||||
fields: HashMap<String, RecordField>,
|
||||
extension: Variable,
|
||||
},
|
||||
Tuple {
|
||||
elements: HashMap<u32, Variable>,
|
||||
extension: Variable,
|
||||
},
|
||||
TagUnion {
|
||||
tags: HashMap<String, Vec<Variable>>,
|
||||
extension: TagUnionExtension,
|
||||
},
|
||||
FunctionOrTagUnion {
|
||||
functions: Vec<Symbol>,
|
||||
tags: Vec<String>,
|
||||
extension: TagUnionExtension,
|
||||
},
|
||||
RecursiveTagUnion {
|
||||
recursion_var: Variable,
|
||||
tags: HashMap<String, Vec<Variable>>,
|
||||
extension: TagUnionExtension,
|
||||
},
|
||||
EmptyRecord {},
|
||||
EmptyTuple {},
|
||||
EmptyTagUnion {},
|
||||
RangedNumber {
|
||||
range: NumericRange,
|
||||
},
|
||||
Error {},
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct ClosureType {
|
||||
pub function: Symbol,
|
||||
pub environment: Vec<Variable>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct UnspecializedClosureType {
|
||||
pub specialization: Variable,
|
||||
pub ability_member: Symbol,
|
||||
pub lambda_set_region: u8,
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub enum AliasKind {
|
||||
Structural,
|
||||
Opaque,
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct AliasTypeVariables {
|
||||
pub type_variables: Vec<Variable>,
|
||||
pub lambda_set_variables: Vec<Variable>,
|
||||
pub infer_ext_in_output_position_variables: Vec<Variable>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct RecordField {
|
||||
pub kind: RecordFieldKind,
|
||||
pub field_type: Variable,
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
#[serde(tag = "kind")]
|
||||
pub enum RecordFieldKind {
|
||||
Demanded,
|
||||
Required { rigid: bool },
|
||||
Optional { rigid: bool },
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
#[serde(tag = "kind")]
|
||||
pub enum TagUnionExtension {
|
||||
Openness(Variable),
|
||||
Any(Variable),
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct NumericRange {
|
||||
pub kind: NumericRangeKind,
|
||||
pub signed: bool,
|
||||
pub min_width: u32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub enum NumericRangeKind {
|
||||
Int,
|
||||
AnyNum,
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct Rank(pub u32);
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct Descriptor {
|
||||
pub content: Content,
|
||||
pub rank: Rank,
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub struct Symbol(
|
||||
// TODO: should this be module ID + symbol?
|
||||
pub String,
|
||||
);
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub enum UnificationMode {
|
||||
Eq,
|
||||
Present,
|
||||
LambdaSetSpecialization,
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub enum Event {
|
||||
Top(Vec<Event>),
|
||||
VariableEvent(VariableEvent),
|
||||
Unification {
|
||||
left: Variable,
|
||||
right: Variable,
|
||||
mode: UnificationMode,
|
||||
success: Option<bool>,
|
||||
subevents: Vec<Event>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Serialize, JsonSchema)]
|
||||
pub enum VariableEvent {
|
||||
Unify {
|
||||
from: Variable,
|
||||
to: Variable,
|
||||
},
|
||||
SetDescriptor {
|
||||
variable: Variable,
|
||||
rank: Option<Rank>,
|
||||
content: Option<Content>,
|
||||
},
|
||||
}
|
||||
|
||||
impl From<VariableEvent> for Event {
|
||||
fn from(event: VariableEvent) -> Event {
|
||||
Event::VariableEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
impl Event {
|
||||
pub fn append(&mut self, event: Event) -> usize {
|
||||
let list = self.subevents_mut().unwrap();
|
||||
let index = list.len();
|
||||
list.push(event);
|
||||
index
|
||||
}
|
||||
|
||||
pub fn appendable(&self) -> bool {
|
||||
self.subevents().is_some()
|
||||
}
|
||||
|
||||
pub fn index(&mut self, index: usize) -> &mut Event {
|
||||
&mut self.subevents_mut().unwrap()[index]
|
||||
}
|
||||
|
||||
pub fn schema() -> RootSchema {
|
||||
schema_for!(Event)
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_subevents {
|
||||
($($pat:pat => $body:expr,)*) => {
|
||||
impl Event {
|
||||
fn subevents(&self) -> Option<&Vec<Event>> {
|
||||
match self {$(
|
||||
$pat => $body,
|
||||
)*}
|
||||
}
|
||||
|
||||
fn subevents_mut(&mut self) -> Option<&mut Vec<Event>> {
|
||||
match self {$(
|
||||
$pat => $body,
|
||||
)*}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_subevents! {
|
||||
Event::Top(events) => Some(events),
|
||||
Event::Unification { subevents, .. } => Some(subevents),
|
||||
Event::VariableEvent(_) => None,
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue