113 lines
2.5 KiB
Rust
113 lines
2.5 KiB
Rust
|
use std::mem::{Discriminant, discriminant};
|
||
|
|
||
|
use crate::token::Token;
|
||
|
|
||
|
use super::{Parsable, WrappedLexer, ParseError, absorb_token_or_error, types::{TightType, FullType}, expr::Expr};
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub enum Declaration {
|
||
|
Type {
|
||
|
name: String,
|
||
|
first_variants: Variant,
|
||
|
other_variants: Vec<Variant>,
|
||
|
},
|
||
|
/*Struct {
|
||
|
name: String,
|
||
|
typeargs: Vec<TypeArg>,
|
||
|
first_fields: Field,
|
||
|
other_fields: Vec<Field>,
|
||
|
},
|
||
|
Trait {
|
||
|
name: String,
|
||
|
typeargs: Vec<TypeArg>,
|
||
|
on: Option<CompositeType>,
|
||
|
},
|
||
|
Impl(ImplDecl),*/
|
||
|
Symbol {
|
||
|
name: String,
|
||
|
type_: FullType,
|
||
|
name2: String,
|
||
|
args: Vec<String>,
|
||
|
value: Expr,
|
||
|
},
|
||
|
Empty,
|
||
|
}
|
||
|
|
||
|
impl Parsable for Declaration {
|
||
|
fn expected() -> (Vec<Discriminant<Token>>, bool) {
|
||
|
(vec![
|
||
|
discriminant(&Token::Symbol("".to_string())),
|
||
|
discriminant(&Token::Type),
|
||
|
], false)
|
||
|
}
|
||
|
fn parse(l: &mut WrappedLexer) -> Result<Self, ParseError> {
|
||
|
let span = l.span();
|
||
|
match l.monch() {
|
||
|
// Type Symbol Assign <variant_decl> { VBar <variant_decl> }
|
||
|
Token::Type => {
|
||
|
let name = String::parse(l)?;
|
||
|
absorb_token_or_error(l, discriminant(&Token::Assign))?;
|
||
|
let first_variants = Variant::parse(l)?;
|
||
|
let mut other_variants = Vec::new();
|
||
|
while *l.curtok() == Token::VBar {
|
||
|
l.monch();
|
||
|
other_variants.push(Variant::parse(l)?);
|
||
|
}
|
||
|
Ok(Self::Type {
|
||
|
first_variants,
|
||
|
other_variants,
|
||
|
name,
|
||
|
})
|
||
|
},
|
||
|
// Symbol Colon <full_type> DeclarationStart Symbol { Symbol } Assign <expr>
|
||
|
Token::Symbol(name) => {
|
||
|
absorb_token_or_error(l, discriminant(&Token::Colon))?;
|
||
|
let type_ = FullType::parse(l)?;
|
||
|
absorb_token_or_error(l, discriminant(&Token::DeclarationStart))?;
|
||
|
let name2 = String::parse(l)?;
|
||
|
let args = Vec::parse(l)?;
|
||
|
absorb_token_or_error(l, discriminant(&Token::Assign))?;
|
||
|
let value = Expr::parse(l)?;
|
||
|
Ok(Self::Symbol {
|
||
|
name,
|
||
|
name2,
|
||
|
args,
|
||
|
type_,
|
||
|
value,
|
||
|
})
|
||
|
},
|
||
|
Token::EOF | Token::DeclarationStart => {
|
||
|
Ok(Self::Empty)
|
||
|
},
|
||
|
_ => {
|
||
|
Err(ParseError {
|
||
|
expected: Self::expected().0,
|
||
|
location: span,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct Variant {
|
||
|
name: String,
|
||
|
elements: Vec<TightType>,
|
||
|
}
|
||
|
|
||
|
impl Parsable for Variant {
|
||
|
fn expected() -> (Vec<Discriminant<Token>>, bool) {
|
||
|
(
|
||
|
vec![discriminant(&Token::Symbol(String::new()))],
|
||
|
false,
|
||
|
)
|
||
|
}
|
||
|
fn parse(l: &mut WrappedLexer) -> Result<Self, ParseError> {
|
||
|
// <variant_declaration> ::= Symbol { <grouped_type> }
|
||
|
Ok(Variant {
|
||
|
name: String::parse(l)?,
|
||
|
elements: Vec::parse(l)?,
|
||
|
})
|
||
|
}
|
||
|
}
|