Skip to content

Commit

Permalink
Add tests cases for tuple, range, slice
Browse files Browse the repository at this point in the history
  • Loading branch information
oovm committed Oct 24, 2023
1 parent 9aa646b commit e0aee7d
Show file tree
Hide file tree
Showing 17 changed files with 2,307 additions and 1,896 deletions.
14 changes: 11 additions & 3 deletions projects/valkyrie-parser/grammars/valkyrie.ygg
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,16 @@ atomic union InlineSuffix {
}
// === tuple === --------------------------------------------------------------------------------------------------
atomic class TupleCall {
WhiteSpace? OP_AND_THEN? WhiteSpace? TupleCallBody
WhiteSpace? OP_AND_THEN? WhiteSpace? TupleLiteral
}
class TupleCallBody {
'(' (MainExpression (COMMA MainExpression)* COMMA?)? ')'
class TupleLiteral {
'(' (TuplePair (COMMA TuplePair)* COMMA?)? ')'
}
class TuplePair {
(TupleKey Colon)? MainExpression
}
union TupleKey {
| Identifier
}
// === range === --------------------------------------------------------------------------------------------------
atomic class RangeCall {
Expand Down Expand Up @@ -313,6 +319,8 @@ atomic inline class RangeOmit {
}
// === atomic === --------------------------------------------------------------------------------------------------
union Atomic {
| TupleLiteral
| RangeLiteral
| Namepath
| Integer
| Boolean
Expand Down
699 changes: 426 additions & 273 deletions projects/valkyrie-parser/src/codegen/debug.ron

Large diffs are not rendered by default.

34 changes: 26 additions & 8 deletions projects/valkyrie-parser/src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ pub enum ValkyrieRule {
InlineTerm,
InlineSuffix,
TupleCall,
TupleCallBody,
TupleLiteral,
TuplePair,
TupleKey,
RangeCall,
RangeLiteral,
RangeAxis,
Expand Down Expand Up @@ -180,7 +182,9 @@ impl YggdrasilRule for ValkyrieRule {
Self::InlineTerm => "",
Self::InlineSuffix => "",
Self::TupleCall => "",
Self::TupleCallBody => "",
Self::TupleLiteral => "",
Self::TuplePair => "",
Self::TupleKey => "",
Self::RangeCall => "",
Self::RangeLiteral => "",
Self::RangeAxis => "",
Expand Down Expand Up @@ -564,15 +568,13 @@ pub enum MainPrefixNode {
pub enum MainSuffixNode {
InlineSuffix(InlineSuffixNode),
}

#[derive(Clone, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct InlineExpressionNode {
pub inline_term: Vec<InlineTermNode>,
pub main_infix: Vec<MainInfixNode>,
pub span: Range<u32>,
}

#[derive(Clone, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct InlineTermNode {
Expand All @@ -581,7 +583,6 @@ pub struct InlineTermNode {
pub main_prefix: Vec<MainPrefixNode>,
pub span: Range<u32>,
}

#[derive(Clone, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum InlineSuffixNode {
Expand All @@ -602,17 +603,32 @@ pub enum InlineSuffixNode {
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TupleCallNode {
pub op_and_then: Option<OpAndThenNode>,
pub tuple_call_body: TupleCallBodyNode,
pub tuple_literal: TupleLiteralNode,
pub white_space: Vec<WhiteSpaceNode>,
pub span: Range<u32>,
}
#[derive(Clone, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TupleCallBodyNode {
pub struct TupleLiteralNode {
pub comma: Vec<CommaNode>,
pub main_expression: Vec<MainExpressionNode>,
pub tuple_pair: Vec<TuplePairNode>,
pub span: Range<u32>,
}

#[derive(Clone, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct TuplePairNode {
// Missing rule Colon
pub main_expression: MainExpressionNode,
pub tuple_key: Option<TupleKeyNode>,
pub span: Range<u32>,
}

#[derive(Clone, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum TupleKeyNode {
Identifier(IdentifierNode),
}
#[derive(Clone, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RangeCallNode {
Expand Down Expand Up @@ -650,6 +666,8 @@ pub enum AtomicNode {
Boolean(BooleanNode),
Integer(IntegerNode),
Namepath(NamepathNode),
RangeLiteral(RangeLiteralNode),
TupleLiteral(TupleLiteralNode),
}
#[derive(Clone, Debug, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
Expand Down
76 changes: 66 additions & 10 deletions projects/valkyrie-parser/src/codegen/parse_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1452,7 +1452,6 @@ impl FromStr for InlineSuffixNode {
Self::from_cst(ValkyrieParser::parse_cst(input, ValkyrieRule::InlineSuffix)?)
}
}

#[automatically_derived]
impl YggdrasilNode for TupleCallNode {
type Rule = ValkyrieRule;
Expand All @@ -1464,15 +1463,14 @@ impl YggdrasilNode for TupleCallNode {
let _span = pair.get_span();
Ok(Self {
op_and_then: pair.take_tagged_option::<OpAndThenNode>(Cow::Borrowed("op_and_then")),
tuple_call_body: pair.take_tagged_one::<TupleCallBodyNode>(Cow::Borrowed("tuple_call_body"))?,
tuple_literal: pair.take_tagged_one::<TupleLiteralNode>(Cow::Borrowed("tuple_literal"))?,
white_space: pair
.take_tagged_items::<WhiteSpaceNode>(Cow::Borrowed("white_space"))
.collect::<Result<Vec<_>, _>>()?,
span: Range { start: _span.start() as u32, end: _span.end() as u32 },
})
}
}

#[automatically_derived]
impl FromStr for TupleCallNode {
type Err = YggdrasilError<ValkyrieRule>;
Expand All @@ -1481,9 +1479,8 @@ impl FromStr for TupleCallNode {
Self::from_cst(ValkyrieParser::parse_cst(input, ValkyrieRule::TupleCall)?)
}
}

#[automatically_derived]
impl YggdrasilNode for TupleCallBodyNode {
impl YggdrasilNode for TupleLiteralNode {
type Rule = ValkyrieRule;

fn get_range(&self) -> Option<Range<usize>> {
Expand All @@ -1493,20 +1490,71 @@ impl YggdrasilNode for TupleCallBodyNode {
let _span = pair.get_span();
Ok(Self {
comma: pair.take_tagged_items::<CommaNode>(Cow::Borrowed("comma")).collect::<Result<Vec<_>, _>>()?,
main_expression: pair
.take_tagged_items::<MainExpressionNode>(Cow::Borrowed("main_expression"))
.collect::<Result<Vec<_>, _>>()?,
tuple_pair: pair.take_tagged_items::<TuplePairNode>(Cow::Borrowed("tuple_pair")).collect::<Result<Vec<_>, _>>()?,
span: Range { start: _span.start() as u32, end: _span.end() as u32 },
})
}
}

#[automatically_derived]
impl FromStr for TupleLiteralNode {
type Err = YggdrasilError<ValkyrieRule>;

fn from_str(input: &str) -> Result<Self, YggdrasilError<ValkyrieRule>> {
Self::from_cst(ValkyrieParser::parse_cst(input, ValkyrieRule::TupleLiteral)?)
}
}

#[automatically_derived]
impl YggdrasilNode for TuplePairNode {
type Rule = ValkyrieRule;

fn get_range(&self) -> Option<Range<usize>> {
Some(Range { start: self.span.start as usize, end: self.span.end as usize })
}
fn from_pair(pair: TokenPair<Self::Rule>) -> Result<Self, YggdrasilError<Self::Rule>> {
let _span = pair.get_span();
Ok(Self {
// Missing rule Colon
main_expression: pair.take_tagged_one::<MainExpressionNode>(Cow::Borrowed("main_expression"))?,
tuple_key: pair.take_tagged_option::<TupleKeyNode>(Cow::Borrowed("tuple_key")),
span: Range { start: _span.start() as u32, end: _span.end() as u32 },
})
}
}

#[automatically_derived]
impl FromStr for TupleCallBodyNode {
impl FromStr for TuplePairNode {
type Err = YggdrasilError<ValkyrieRule>;

fn from_str(input: &str) -> Result<Self, YggdrasilError<ValkyrieRule>> {
Self::from_cst(ValkyrieParser::parse_cst(input, ValkyrieRule::TupleCallBody)?)
Self::from_cst(ValkyrieParser::parse_cst(input, ValkyrieRule::TuplePair)?)
}
}
#[automatically_derived]
impl YggdrasilNode for TupleKeyNode {
type Rule = ValkyrieRule;

fn get_range(&self) -> Option<Range<usize>> {
match self {
Self::Identifier(s) => s.get_range(),
}
}
fn from_pair(pair: TokenPair<Self::Rule>) -> Result<Self, YggdrasilError<Self::Rule>> {
let _span = pair.get_span();
if let Ok(s) = pair.take_tagged_one::<IdentifierNode>(Cow::Borrowed("identifier")) {
return Ok(Self::Identifier(s));
}
Err(YggdrasilError::invalid_node(ValkyrieRule::TupleKey, _span))
}
}

#[automatically_derived]
impl FromStr for TupleKeyNode {
type Err = YggdrasilError<ValkyrieRule>;

fn from_str(input: &str) -> Result<Self, YggdrasilError<ValkyrieRule>> {
Self::from_cst(ValkyrieParser::parse_cst(input, ValkyrieRule::TupleKey)?)
}
}
#[automatically_derived]
Expand Down Expand Up @@ -1619,6 +1667,8 @@ impl YggdrasilNode for AtomicNode {
Self::Boolean(s) => s.get_range(),
Self::Integer(s) => s.get_range(),
Self::Namepath(s) => s.get_range(),
Self::RangeLiteral(s) => s.get_range(),
Self::TupleLiteral(s) => s.get_range(),
}
}
fn from_pair(pair: TokenPair<Self::Rule>) -> Result<Self, YggdrasilError<Self::Rule>> {
Expand All @@ -1632,6 +1682,12 @@ impl YggdrasilNode for AtomicNode {
if let Ok(s) = pair.take_tagged_one::<NamepathNode>(Cow::Borrowed("namepath")) {
return Ok(Self::Namepath(s));
}
if let Ok(s) = pair.take_tagged_one::<RangeLiteralNode>(Cow::Borrowed("range_literal")) {
return Ok(Self::RangeLiteral(s));
}
if let Ok(s) = pair.take_tagged_one::<TupleLiteralNode>(Cow::Borrowed("tuple_literal")) {
return Ok(Self::TupleLiteral(s));
}
Err(YggdrasilError::invalid_node(ValkyrieRule::Atomic, _span))
}
}
Expand Down
42 changes: 35 additions & 7 deletions projects/valkyrie-parser/src/codegen/parse_cst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ pub(super) fn parse_cst(input: &str, rule: ValkyrieRule) -> OutputResult<Valkyri
ValkyrieRule::InlineTerm => parse_inline_term(state),
ValkyrieRule::InlineSuffix => parse_inline_suffix(state),
ValkyrieRule::TupleCall => parse_tuple_call(state),
ValkyrieRule::TupleCallBody => parse_tuple_call_body(state),
ValkyrieRule::TupleLiteral => parse_tuple_literal(state),
ValkyrieRule::TuplePair => parse_tuple_pair(state),
ValkyrieRule::TupleKey => parse_tuple_key(state),
ValkyrieRule::RangeCall => parse_range_call(state),
ValkyrieRule::RangeLiteral => parse_range_literal(state),
ValkyrieRule::RangeAxis => parse_range_axis(state),
Expand Down Expand Up @@ -1082,7 +1084,6 @@ fn parse_inline_term(state: Input) -> Output {
})
})
}

#[inline]
fn parse_inline_suffix(state: Input) -> Output {
state.rule(ValkyrieRule::InlineSuffix, |s| {
Expand Down Expand Up @@ -1139,14 +1140,14 @@ fn parse_tuple_call(state: Input) -> Output {
.and_then(|s| s.optional(|s| parse_white_space(s).and_then(|s| s.tag_node("white_space"))))
.and_then(|s| s.optional(|s| parse_op_and_then(s).and_then(|s| s.tag_node("op_and_then"))))
.and_then(|s| s.optional(|s| parse_white_space(s).and_then(|s| s.tag_node("white_space"))))
.and_then(|s| parse_tuple_call_body(s).and_then(|s| s.tag_node("tuple_call_body")))
.and_then(|s| parse_tuple_literal(s).and_then(|s| s.tag_node("tuple_literal")))
})
})
}

#[inline]
fn parse_tuple_call_body(state: Input) -> Output {
state.rule(ValkyrieRule::TupleCallBody, |s| {
fn parse_tuple_literal(state: Input) -> Output {
state.rule(ValkyrieRule::TupleLiteral, |s| {
s.sequence(|s| {
Ok(s)
.and_then(|s| builtin_text(s, "(", false))
Expand All @@ -1155,7 +1156,7 @@ fn parse_tuple_call_body(state: Input) -> Output {
s.optional(|s| {
s.sequence(|s| {
Ok(s)
.and_then(|s| parse_main_expression(s).and_then(|s| s.tag_node("main_expression")))
.and_then(|s| parse_tuple_pair(s).and_then(|s| s.tag_node("tuple_pair")))
.and_then(|s| builtin_ignore(s))
.and_then(|s| {
s.repeat(0..4294967295, |s| {
Expand All @@ -1166,7 +1167,7 @@ fn parse_tuple_call_body(state: Input) -> Output {
.and_then(|s| parse_comma(s).and_then(|s| s.tag_node("comma")))
.and_then(|s| builtin_ignore(s))
.and_then(|s| {
parse_main_expression(s).and_then(|s| s.tag_node("main_expression"))
parse_tuple_pair(s).and_then(|s| s.tag_node("tuple_pair"))
})
})
})
Expand All @@ -1184,6 +1185,31 @@ fn parse_tuple_call_body(state: Input) -> Output {
})
}
#[inline]
fn parse_tuple_pair(state: Input) -> Output {
state.rule(ValkyrieRule::TuplePair, |s| {
s.sequence(|s| {
Ok(s)
.and_then(|s| {
s.optional(|s| {
s.sequence(|s| {
Ok(s)
.and_then(|s| parse_tuple_key(s).and_then(|s| s.tag_node("tuple_key")))
.and_then(|s| builtin_ignore(s))
.and_then(|s| parse_colon(s).and_then(|s| s.tag_node("colon")))
})
})
})
.and_then(|s| builtin_ignore(s))
.and_then(|s| parse_main_expression(s).and_then(|s| s.tag_node("main_expression")))
})
})
}

#[inline]
fn parse_tuple_key(state: Input) -> Output {
state.rule(ValkyrieRule::TupleKey, |s| Err(s).or_else(|s| parse_identifier(s).and_then(|s| s.tag_node("identifier"))))
}
#[inline]
fn parse_range_call(state: Input) -> Output {
state.rule(ValkyrieRule::RangeCall, |s| {
s.sequence(|s| {
Expand Down Expand Up @@ -1367,6 +1393,8 @@ fn parse_range_omit(state: Input) -> Output {
fn parse_atomic(state: Input) -> Output {
state.rule(ValkyrieRule::Atomic, |s| {
Err(s)
.or_else(|s| parse_tuple_literal(s).and_then(|s| s.tag_node("tuple_literal")))
.or_else(|s| parse_range_literal(s).and_then(|s| s.tag_node("range_literal")))
.or_else(|s| parse_namepath(s).and_then(|s| s.tag_node("namepath")))
.or_else(|s| parse_integer(s).and_then(|s| s.tag_node("integer")))
.or_else(|s| parse_boolean(s).and_then(|s| s.tag_node("boolean")))
Expand Down
Loading

0 comments on commit e0aee7d

Please sign in to comment.