Skip to content

Commit

Permalink
[grammar] checked and unchecked enum/struct definitions
Browse files Browse the repository at this point in the history
Signed-off-by: Anqur <anqurvanillapy@gmail.com>
  • Loading branch information
anqurvanillapy committed Feb 27, 2024
1 parent fbbf488 commit e78ea12
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 32 deletions.
39 changes: 20 additions & 19 deletions rura-grammar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use winnow::{PResult, Parser};

use rura_parsing::keywords::{BOTTOM, TYPE, UNIT};
use rura_parsing::{
binary, braced, closure_parameters, constant, constructor_parameters, elidable, elidable_block,
expect, field, fmt_delimited, function_parameters, function_type, identifier, members,
binary, braced, closure_parameters, constant, constructor, constructor_parameters, elidable,
elidable_block, expect, field, fmt_delimited, function_parameters, function_type, identifier,
parenthesized, prefixed, primitive_type, qualified_name, reference_type, skip_space, tuple,
tuple_type, type_arguments, type_parameters, unary, unique_type, BinOp, Constant, Constructor,
Name, PrimitiveType, QualifiedName, UnOp,
Expand Down Expand Up @@ -80,8 +80,20 @@ impl Declaration<AST> {
pub enum Definition<T> {
Undefined,
Function(Box<T>),
Enum(HashMap<Name, Constructor<Name, T>>),
Struct(HashMap<Name, T>),
Enum(Enum<T>),
Struct(Struct<T>),
}

#[derive(Clone, Debug)]
pub enum Enum<T> {
Unchecked(Box<[Constructor<Name, T>]>),
Checked(HashMap<Name, Constructor<Name, T>>),
}

#[derive(Clone, Debug)]
pub enum Struct<T> {
Unchecked(Box<[(Name, T)]>),
Checked(HashMap<Name, T>),
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -328,7 +340,7 @@ fn function_declaration(i: &mut &str) -> PResult<Declaration<AST>> {
definition,
},
)
.context(expect("function"))
.context(expect("function declaration"))
.parse_next(i)
}

Expand All @@ -351,19 +363,8 @@ fn enum_declaration(i: &mut &str) -> PResult<Declaration<AST>> {
}

fn enum_definition(i: &mut &str) -> PResult<Definition<AST>> {
separated(
1..,
skip_space(constructor).map(|ctor| (ctor.name.clone(), ctor)),
elidable(","),
)
.map(|ctors: Vec<_>| Definition::Enum(ctors.into_iter().collect()))
.parse_next(i)
}

fn constructor(i: &mut &str) -> PResult<Constructor<Name, AST>> {
(identifier, skip_space(members(type_expression)))
.map(|(name, params)| Constructor { name, params })
.context(expect("constructor"))
separated(1.., skip_space(constructor(type_expression)), elidable(","))
.map(|ctors: Vec<_>| Definition::Enum(Enum::Unchecked(ctors.into_boxed_slice())))
.parse_next(i)
}

Expand All @@ -381,7 +382,7 @@ fn struct_declaration(i: &mut &str) -> PResult<Declaration<AST>> {

fn struct_definition(i: &mut &str) -> PResult<Definition<AST>> {
separated(1.., skip_space(field(type_expression)), elidable(","))
.map(|f: Vec<_>| Definition::Struct(f.into_iter().collect()))
.map(|f: Vec<_>| Definition::Struct(Struct::Unchecked(f.into_boxed_slice())))
.parse_next(i)
}

Expand Down
22 changes: 9 additions & 13 deletions rura-lir/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ use winnow::{PResult, Parser};

use rura_parsing::keywords::{BOTTOM, UNIT};
use rura_parsing::{
expect, function_type, identifier, keywords, members, opt_or_default, parenthesized,
constructor, expect, function_type, identifier, keywords, opt_or_default, parenthesized,
primitive_type, qualified_name, reference_type, skip_space, tuple_type, type_arguments,
type_parameters, ws_or_comment, BinOp, Constant, Member, UnOp,
};

use crate::lir::{
ArithMode, BinaryOp, Block, Bound, ClosureCreation, CtorCall, CtorDef, EliminationStyle,
FunctionCall, FunctionDef, FunctionPrototype, IfThenElse, InductiveEliminator,
InductiveTypeDef, Lir, MakeMutReceiver, Module, RefField, TraitExpr, UnaryOp,
ArithMode, BinaryOp, Block, Bound, ClosureCreation, CtorCall, EliminationStyle, FunctionCall,
FunctionDef, FunctionPrototype, IfThenElse, InductiveEliminator, InductiveTypeDef, Lir,
MakeMutReceiver, Module, RefField, TraitExpr, UnaryOp,
};
use crate::types::{LirType, TypeVar};
use crate::{Ident, QualifiedName};
Expand Down Expand Up @@ -731,21 +731,14 @@ fn parse_extern_function_def(i: &mut &str) -> PResult<FunctionPrototype> {
.parse_next(i)
}

fn parse_ctor_def(i: &mut &str) -> PResult<CtorDef> {
(identifier, skip_space(members(parse_lir_type)))
.map(|(name, params)| CtorDef { name, params })
.context(expect("constructor definition"))
.parse_next(i)
}

fn parse_inductive_type_def(i: &mut &str) -> PResult<InductiveTypeDef> {
let bounds = opt((
"where",
separated(1.., skip_space(parse_bounded_type_var), ","),
))
.context(expect("type bounds"))
.map(|x| Vec::into_boxed_slice(x.unwrap_or_default().1));
let ctors = separated(1.., skip_space(parse_ctor_def), ",")
let ctors = separated(1.., skip_space(constructor(parse_lir_type)), ",")
.context(expect("constructors"))
.map(Vec::into_boxed_slice);
(
Expand Down Expand Up @@ -812,9 +805,12 @@ pub fn parse_module(i: &mut &str) -> PResult<Module> {

#[cfg(test)]
mod test {
use rura_parsing::{eol_comment, PrimitiveType};
use winnow::ascii::digit0;

use rura_parsing::{eol_comment, PrimitiveType};

use crate::lir::CtorDef;

use super::*;
#[test]
fn test_eol_comment() {
Expand Down
10 changes: 10 additions & 0 deletions rura-parsing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,16 @@ where
.context(expect("unnamed members"))
}

pub fn constructor<'a, F, I, T>(typ: F) -> impl Parser<&'a str, Constructor<I, T>, ContextError>
where
F: Copy + Parser<&'a str, T, ContextError>,
I: From<&'a str>,
{
(identifier, skip_space(members(typ)))
.map(|(name, params)| Constructor { name, params })
.context(expect("constructor"))
}

pub fn function_parameters<'a, F, I, T, P>(typ: F) -> impl Parser<&'a str, Box<[P]>, ContextError>
where
F: Parser<&'a str, T, ContextError>,
Expand Down

0 comments on commit e78ea12

Please sign in to comment.