Skip to main content

mech_syntax/
functions.rs

1#[macro_use]
2use crate::*;
3
4#[cfg(not(feature = "no-std"))] use core::fmt;
5#[cfg(feature = "no-std")] use alloc::fmt;
6#[cfg(feature = "no-std")] use alloc::string::String;
7#[cfg(feature = "no-std")] use alloc::vec::Vec;
8use nom::{
9  IResult,
10  branch::alt,
11  sequence::tuple as nom_tuple,
12  combinator::{opt, eof},
13  multi::{many1, many_till, many0, separated_list1,separated_list0},
14  Err,
15  Err::Failure
16};
17
18// function_define := identifier, "(", list0(list_separator, function_arg), ")", "=", (function_out_args | function_out_arg), define_operator, list1((whitespace1 | statement_separator), statement), period ;
19pub fn function_define(input: ParseString) -> ParseResult<FunctionDefine> {
20  let ((input, name)) = identifier(input)?;
21  let ((input, _)) = left_parenthesis(input)?;
22  let ((input, input_args)) = separated_list0(list_separator, function_arg)(input)?;
23  let ((input, _)) = right_parenthesis(input)?;
24  let ((input, _)) = whitespace0(input)?;
25  match function_define_match_arms(input.clone(), name.clone(), input_args.clone()) {
26    Ok((input, fxn_def)) => Ok((input, fxn_def)),
27    Err(_) => function_define_statements(input, name, input_args),
28  }
29}
30
31fn function_define_statements(
32  input: ParseString,
33  name: Identifier,
34  input_args: Vec<FunctionArgument>,
35) -> ParseResult<FunctionDefine> {
36  let ((input, _)) = equal(input)?;
37  let ((input, _)) = whitespace0(input)?;
38  let ((input, output)) = alt((function_out_args,function_out_arg))(input)?;
39  let ((input, _)) = define_operator(input)?;
40  let ((input, statements)) = separated_list1(alt((whitespace1,statement_separator)), statement)(input)?;
41  let ((input, _)) = period(input)?;
42  Ok((input,FunctionDefine{name,input: input_args,output,statements,match_arms: vec![]}))
43}
44
45fn function_define_match_arms(
46  input: ParseString,
47  name: Identifier,
48  input_args: Vec<FunctionArgument>,
49) -> ParseResult<FunctionDefine> {
50  let (input, _) = transition_operator(input)?;
51  let (input, _) = whitespace0(input)?;
52  let (input, output_kind) = kind_annotation(input)?;
53  let output_src_range = output_kind
54    .tokens()
55    .first()
56    .map(|token| token.src_range.clone())
57    .unwrap_or_default();
58  let output = vec![FunctionArgument {
59    name: Identifier {
60      name: Token::new(TokenKind::Identifier, output_src_range, vec!['_']),
61    },
62    kind: output_kind,
63  }];
64  let (input, _) = many1(alt((whitespace1, statement_separator)))(input)?;
65  let (input, match_arms) = many1(function_match_arm)(input)?;
66  let (input, _) = opt(period)(input)?;
67  Ok((input, FunctionDefine {
68    name,
69    input: input_args,
70    output,
71    statements: vec![],
72    match_arms,
73  }))
74}
75
76fn function_match_arm(input: ParseString) -> ParseResult<FunctionMatchArm> {
77  let (input, _) = whitespace0(input)?;
78  let (input, _) = alt((box_t_left, box_bl, bar))(input)?;
79  let (input, _) = whitespace0(input)?;
80  let (input, pattern) = crate::state_machines::pattern(input)?;
81  let (input, _) = whitespace0(input)?;
82  let (input, _) = transition_operator(input)?;
83  let (input, _) = whitespace0(input)?;
84  let (input, expr) = expression(input)?;
85  let (input, _) = opt(alt((whitespace1, statement_separator)))(input)?;
86  Ok((input, FunctionMatchArm {
87    pattern,
88    expression: expr,
89  }))
90}
91
92// function_out_args := "(", list1(list_separator, function_arg), ")" ;
93pub fn function_out_args(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
94  let ((input, _)) = left_parenthesis(input)?;
95  let ((input, args)) = separated_list1(list_separator,function_arg)(input)?;
96  let ((input, _)) = right_parenthesis(input)?;
97  Ok((input, args))
98}
99
100// function_out_arg := function_arg ;
101pub fn function_out_arg(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
102  let ((input, arg)) = function_arg(input)?;
103  Ok((input, vec![arg]))
104}
105
106// function_arg := identifier, kind_annotation ;
107pub fn function_arg(input: ParseString) -> ParseResult<FunctionArgument> {
108  let ((input, name)) = identifier(input)?;
109  let ((input, kind)) = kind_annotation(input)?;
110  Ok((input, FunctionArgument{ name, kind }))
111}
112
113// argument_list := "(", list0(",", call_arg_with_biding | call_arg), ")" ;
114pub fn argument_list(input: ParseString) -> ParseResult<ArgumentList> {
115  let (input, _) = left_parenthesis(input)?;
116  let (input, args) = separated_list0(list_separator, alt((call_arg_with_binding,call_arg)))(input)?;
117  let (input, _) = right_parenthesis(input)?;
118  Ok((input, args))
119}
120
121// function_call := identifier, argument_list ;
122pub fn function_call(input: ParseString) -> ParseResult<FunctionCall> {
123  let (input, name) = identifier(input)?;
124  let (input, args) = argument_list(input)?;
125  Ok((input, FunctionCall{name,args} ))
126}
127
128// call_arg_with_binding := identifier, colon, expression ;
129pub fn call_arg_with_binding(input: ParseString) -> ParseResult<(Option<Identifier>,Expression)> {
130  let (input, arg_name) = identifier(input)?;
131  let (input, _) = whitespace0(input)?;
132  let (input, _) = colon(input)?;
133  let (input, _) = whitespace0(input)?;
134  let (input, expr) = expression(input)?;
135  Ok((input, (Some(arg_name), expr)))
136}
137
138// call_arg := expression ;
139pub fn call_arg(input: ParseString) -> ParseResult<(Option<Identifier>,Expression)> {
140  let (input, expr) = expression(input)?;
141  Ok((input, (None, expr)))
142}