From 4a9628c0d9a3d26c1c1a97bbce4bda35cc654b5c Mon Sep 17 00:00:00 2001 From: Ph0enixKM Date: Sat, 3 Feb 2024 20:14:22 +0100 Subject: [PATCH] feat: add comment detection to function declarations --- src/modules/function/declaration.rs | 17 +++++++--- src/modules/function/declaration_utils.rs | 39 ++++++++++++++++++++++- src/modules/statement/comment_doc.rs | 2 +- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/modules/function/declaration.rs b/src/modules/function/declaration.rs index 62e697e6..ea36dd0f 100644 --- a/src/modules/function/declaration.rs +++ b/src/modules/function/declaration.rs @@ -3,6 +3,7 @@ use std::mem::swap; use heraclitus_compiler::prelude::*; use itertools::izip; +use crate::modules::statement::comment_doc::CommentDoc; use crate::modules::types::Type; use crate::modules::variable::variable_name_extensions; use crate::utils::cc_flags::get_ccflag_by_name; @@ -24,7 +25,8 @@ pub struct FunctionDeclaration { pub returns: Type, pub body: Block, pub id: usize, - pub is_public: bool + pub is_public: bool, + pub comment: Option } impl FunctionDeclaration { @@ -61,11 +63,18 @@ impl SyntaxModule for FunctionDeclaration { returns: Type::Generic, body: Block::new(), id: 0, - is_public: false + is_public: false, + comment: None } } fn parse(&mut self, meta: &mut ParserMetadata) -> SyntaxResult { + // Parse the function comment + if is_functions_comment_doc(meta) { + let mut comment = CommentDoc::new(); + syntax(meta, &mut comment)?; + self.comment = Some(comment); + } let mut flags = HashSet::new(); // Get all the user-defined compiler flags while let Ok(flag) = token_by(meta, |val| val.starts_with("#[")) { @@ -168,7 +177,7 @@ impl TranslateModule for FunctionDeclaration { // Parse the function body result.push(format!("function {name} {{")); if let Some(args) = self.set_args_as_variables(meta, function, &self.arg_refs) { - result.push(args); + result.push(args); } result.push(function.block.translate(meta)); result.push(meta.gen_indent() + "}"); @@ -178,4 +187,4 @@ impl TranslateModule for FunctionDeclaration { // Return the translation result.join("\n") } -} \ No newline at end of file +} diff --git a/src/modules/function/declaration_utils.rs b/src/modules/function/declaration_utils.rs index 1a5a8885..63d58fc8 100644 --- a/src/modules/function/declaration_utils.rs +++ b/src/modules/function/declaration_utils.rs @@ -25,6 +25,43 @@ pub fn skip_function_body(meta: &mut ParserMetadata) -> (usize, usize, bool) { (index_begin, index_end, is_failable) } +pub fn is_functions_comment_doc(meta: &mut ParserMetadata) -> bool { + let index = meta.get_index(); + let mut is_comment_doc = true; + // Multiple linebreaks are merged by heraclitus, so we need to check for them + let mut last_line = 0; + if let Some(tok) = meta.get_current_token() { + if !tok.word.starts_with("///") { + return false; + } + } + while let Some(tok) = meta.get_current_token() { + // If there was a longer line break, it means the comment ended + if !is_comment_doc && tok.pos.0 != last_line + 1 { + meta.set_index(index); + return false; + } + if tok.word.starts_with("///") { + is_comment_doc = true; + } + if tok.word.starts_with("\n") { + if is_comment_doc { + is_comment_doc = false; + last_line = tok.pos.0; + } else { + meta.set_index(index); + return false; + } + } + if tok.word.starts_with("fun") { + meta.set_index(index); + return true; + } + meta.increment_index(); + } + false +} + pub fn handle_existing_function(meta: &mut ParserMetadata, tok: Option) -> Result<(), Failure> { let name = tok.as_ref().unwrap().word.clone(); handle_identifier_name(meta, &name, tok.clone())?; @@ -60,4 +97,4 @@ pub fn handle_add_function(meta: &mut ParserMetadata, tok: Option, fun: F // If the function already exists, show an error None => error!(meta, tok, format!("Function '{}' already exists", name)) } -} \ No newline at end of file +} diff --git a/src/modules/statement/comment_doc.rs b/src/modules/statement/comment_doc.rs index e671573d..6ba053b4 100644 --- a/src/modules/statement/comment_doc.rs +++ b/src/modules/statement/comment_doc.rs @@ -5,7 +5,7 @@ use crate::translate::module::TranslateModule; #[derive(Debug, Clone)] pub struct CommentDoc { - value: String + pub value: String } impl SyntaxModule for CommentDoc {