@@ -2,8 +2,8 @@ use nom::{
22 branch:: alt,
33 bytes:: complete:: tag,
44 character:: complete:: { char, multispace0, multispace1} ,
5- combinator:: { map, opt} ,
6- error:: Error ,
5+ combinator:: { map, opt, map_res } ,
6+ error:: { Error , ErrorKind } ,
77 multi:: separated_list0,
88 sequence:: { delimited, preceded, tuple} ,
99 IResult ,
@@ -17,6 +17,7 @@ use crate::parser::parser_common::{
1717} ;
1818use crate :: parser:: parser_expr:: parse_expression;
1919use crate :: parser:: parser_type:: parse_type;
20+ use crate :: ir:: ast:: Type ; // TODO: Check if needed
2021
2122pub fn parse_statement ( input : & str ) -> IResult < & str , Statement > {
2223 alt ( (
@@ -27,6 +28,7 @@ pub fn parse_statement(input: &str) -> IResult<&str, Statement> {
2728 parse_while_statement,
2829 parse_for_statement,
2930 parse_assert_statement,
31+ parse_test_function_definition_statement, // FIXME: Being Implemented
3032 parse_function_definition_statement,
3133 ) ) ( input)
3234}
@@ -150,7 +152,7 @@ fn parse_assert_statement(input: &str) -> IResult<&str, Statement> {
150152}
151153
152154fn parse_function_definition_statement ( input : & str ) -> IResult < & str , Statement > {
153- map (
155+ map_res (
154156 tuple ( (
155157 keyword ( DEF_KEYWORD ) ,
156158 preceded ( multispace1, identifier) ,
@@ -171,12 +173,59 @@ fn parse_function_definition_statement(input: &str) -> IResult<&str, Statement>
171173 parse_block,
172174 ) ) ,
173175 |( _, name, args, _, t, block) | {
174- Statement :: FuncDef ( Function {
176+ if name. starts_with ( "test" ) {
177+ // Força falha aqui para evitar aceitar funções test_ no parser geral
178+ Err ( nom:: Err :: Error ( Error :: new ( name, ErrorKind :: Tag ) ) )
179+ } else {
180+ Ok ( Statement :: FuncDef ( Function {
181+ name : name. to_string ( ) ,
182+ kind : t,
183+ params : args,
184+ body : Some ( Box :: new ( block) ) ,
185+ } ) )
186+ }
187+ } ,
188+ ) ( input)
189+ }
190+
191+
192+ // TODO: Fazer testes para essa função de parser
193+ fn parse_test_function_definition_statement ( input : & str ) -> IResult < & str , Statement > {
194+ map_res (
195+ tuple ( (
196+ //keyword(DEF_KEYWORD),
197+ tag ( "def" ) ,
198+ preceded ( multispace1, identifier) ,
199+ //identifier,
200+ delimited (
201+ char:: <& str, Error <& str>>( LEFT_PAREN ) ,
202+ multispace0, // Permite `()` com espaços, mas sem argumentos
203+ char:: <& str, Error <& str>>( RIGHT_PAREN ) ,
204+ ) ,
205+ opt ( preceded (
206+ preceded ( multispace0, tag ( "->" ) ) ,
207+ preceded ( multispace0, parse_type) ,
208+ ) ) ,
209+ parse_block,
210+ ) ) ,
211+ |( _, name, _, opt_ret_type, block) | {
212+ if !name. starts_with ( "test" ) {
213+ return Err ( nom:: Err :: Error ( Error :: new ( name, ErrorKind :: Tag ) ) ) ;
214+ }
215+
216+ // Se tiver tipo declarado, só aceita Bool
217+ if let Some ( ret_type) = opt_ret_type {
218+ if ret_type != Type :: TBool {
219+ return Err ( nom:: Err :: Error ( Error :: new ( name, ErrorKind :: Tag ) ) ) ;
220+ }
221+ }
222+
223+ Ok ( Statement :: TestDef ( Function {
175224 name : name. to_string ( ) ,
176- kind : t ,
177- params : args ,
225+ kind : Type :: TBool , // Sempre bool (mesmo se não declarou)
226+ params : Vec :: new ( ) , // Nenhum argumento
178227 body : Some ( Box :: new ( block) ) ,
179- } )
228+ } ) )
180229 } ,
181230 ) ( input)
182231}
@@ -343,4 +392,79 @@ mod tests {
343392 let parsed = parse_formal_argument ( input) . unwrap ( ) . 1 ;
344393 assert_eq ! ( parsed, expected) ;
345394 }
395+
396+ #[ test]
397+ fn test_parse_test_function_definition_statement_valid ( ) {
398+ let input = "def test_example(): x = 1; end" ;
399+ let expected = Statement :: TestDef ( Function {
400+ name : "test_example" . to_string ( ) ,
401+ kind : Type :: TBool ,
402+ params : vec ! [ ] ,
403+ body : Some ( Box :: new ( Statement :: Block ( vec ! [
404+ Statement :: Assignment ( "x" . to_string( ) , Box :: new( Expression :: CInt ( 1 ) ) ) ,
405+ ] ) ) ) ,
406+ } ) ;
407+ let parsed = parse_test_function_definition_statement ( input) . unwrap ( ) . 1 ;
408+ assert_eq ! ( parsed, expected) ;
409+ }
410+
411+ #[ test]
412+ fn test_parse_test_function_definition_statement_with_spaces ( ) {
413+ let input = "def test_spaces( ): x = 2; end" ;
414+ let expected = Statement :: TestDef ( Function {
415+ name : "test_spaces" . to_string ( ) ,
416+ kind : Type :: TBool ,
417+ params : vec ! [ ] ,
418+ body : Some ( Box :: new ( Statement :: Block ( vec ! [
419+ Statement :: Assignment ( "x" . to_string( ) , Box :: new( Expression :: CInt ( 2 ) ) ) ,
420+ ] ) ) ) ,
421+ } ) ;
422+ let parsed = parse_test_function_definition_statement ( input) . unwrap ( ) . 1 ;
423+ assert_eq ! ( parsed, expected) ;
424+ }
425+
426+ #[ test]
427+ fn test_parse_test_function_definition_statement_args ( ) {
428+ let input = "def test_with_args(x: Int, y: Int): x = y; end" ;
429+
430+ // O parser deve falhar, pois funções de teste não podem ter argumentos.
431+ let parsed = parse_test_function_definition_statement ( input) ;
432+
433+ assert ! ( parsed. is_err( ) , "Funções de teste com argumentos devem ser rejeitadas" ) ;
434+ }
435+
436+ #[ test]
437+ fn test_parse_test_function_definition_statement_invalid_return_type ( ) {
438+ let input = "def test_with_invalid_return() -> Int: x = 2; end" ;
439+
440+ // O parser deve falhar, pois funções de teste não podem ter argumentos.
441+ let parsed = parse_test_function_definition_statement ( input) ;
442+
443+ assert ! ( parsed. is_err( ) , "Funções de teste não devem especificar tipo de retorno" ) ;
444+ }
445+
446+ #[ test]
447+ fn test_parse_test_function_definition_statement_valid_return_type ( ) {
448+ let input = "def test_with_valid_return() -> Boolean: x = 2; end" ;
449+ let expected = Statement :: TestDef ( Function {
450+ name : "test_with_valid_return" . to_string ( ) ,
451+ kind : Type :: TBool ,
452+ params : vec ! [ ] ,
453+ body : Some ( Box :: new ( Statement :: Block ( vec ! [
454+ Statement :: Assignment ( "x" . to_string( ) , Box :: new( Expression :: CInt ( 2 ) ) ) ,
455+ ] ) ) ) ,
456+ } ) ;
457+ let parsed = parse_test_function_definition_statement ( input) . unwrap ( ) . 1 ;
458+ assert_eq ! ( parsed, expected) ;
459+ }
460+ #[ test]
461+ #[ ignore]
462+ fn test_parse_function_definition_statement_reject_test_function ( ) {
463+ let input = "def test_function_rejected() -> Int: x = 2; end" ;
464+
465+ let parsed = parse_function_definition_statement ( input) ;
466+ assert ! ( parsed. is_err( ) , "Funções comuns não devem iniciar com 'test'" ) ;
467+ }
468+
469+
346470}
0 commit comments