MCPcopy Create free account
hub / github.com/dev-formata-io/stof / parse_function

Function parse_function

src/parser/func.rs:23–86  ·  view source on GitHub ↗

Parse a function into a parse context.

(input: &'a str, context: &mut ParseContext)

Source from the content-addressed store, hash-verified

21
22/// Parse a function into a parse context.
23pub fn parse_function<'a>(input: &'a str, context: &mut ParseContext) -> IResult<&'a str, (), StofParseError> {
24 let mut func = Func::default();
25
26 // Doc comments & whitespace before a function definition
27 let (input, mut comments) = doc_comment(input)?;
28
29 let mut do_create_func;
30 let (input, (attrs, do_insert)) = parse_attributes(input, context)?;
31 for (k, v) in attrs { func.attributes.insert(k, v); }
32 do_create_func = do_insert;
33
34 let (input, more_comments) = doc_comment(input)?;
35 if more_comments.len() > 0 { if comments.len() > 0 { comments.push('\n'); } comments.push_str(&more_comments); }
36
37 let (input, (attrs, do_insert)) = parse_attributes(input, context)?;
38 for (k, v) in attrs { func.attributes.insert(k, v); }
39 do_create_func = do_create_func && do_insert;
40 let (input, _) = whitespace(input)?; // clean up anything more before signature...
41
42 let (input, async_fn) = opt(terminated(tag("async"), multispace0)).parse(input)?;
43 if async_fn.is_some() && !func.attributes.contains_key(ASYNC_FUNC_ATTR.as_str()) {
44 func.attributes.insert(ASYNC_FUNC_ATTR.to_string(), Val::Null);
45 }
46
47 let (input, _) = tag("fn").parse(input)?;
48 let (input, name) = preceded(multispace0, ident).parse(input).map_err(err_fail)?;
49 let (input, params) = delimited(char('('), separated_list0(char(','), alt((parameter, opt_parameter))), char(')')).parse(input).map_err(err_fail)?;
50 let (input, return_type) = opt(preceded(delimited(multispace0, tag("->"), multispace0), parse_type)).parse(input).map_err(err_fail)?;
51 let (input, instructions) = block(input).map_err(err_fail)?;
52
53 // Check do_create_func now after parse
54 if !do_create_func {
55 return Ok((input, ()));
56 }
57
58 for param in params { func.params.push_back(param); }
59 func.return_type = return_type.unwrap_or_default(); // default is void
60 func.instructions = instructions;
61
62 // Is this function an init function (has an #[init] attribute)?
63 // These functions will get called automatically when the context is dropped (after parse complete).
64 let mut init_func = false;
65 if func.attributes.contains_key("init") { init_func = true; }
66
67 // Instert the new function in the current parse context
68 //println!("({name}){{{func:?}}}");
69 let self_ptr = context.self_ptr();
70 let func_ref = context.graph.insert_stof_data(&self_ptr, name, Box::new(func), None).expect("failed to insert a parsed function into this context");
71
72 // Insert init if necessary
73 if init_func {
74 context.init_funcs.push(func_ref.clone());
75 }
76
77 // Insert the function doc comments also if requested
78 if context.profile.docs && comments.len() > 0 {
79 context.graph.insert_stof_data(&self_ptr, &format!("{name}_docs"), Box::new(FuncDoc {
80 docs: comments,

Callers 2

basic_funcFunction · 0.85
document_statementFunction · 0.85

Calls 14

defaultFunction · 0.85
doc_commentFunction · 0.85
parse_attributesFunction · 0.85
whitespaceFunction · 0.85
blockFunction · 0.85
insertMethod · 0.80
lenMethod · 0.80
as_strMethod · 0.80
insert_stof_dataMethod · 0.80
pushMethod · 0.45
parseMethod · 0.45
to_stringMethod · 0.45

Tested by 1

basic_funcFunction · 0.68