Amo/src/parser/declaration.rs

113 lines
2.5 KiB
Rust
Raw Normal View History

2022-04-06 13:23:46 +00:00
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)?,
})
}
}