@@ -2,22 +2,23 @@ use nom::{
22 branch:: alt,
33 bytes:: complete:: tag,
44 character:: complete:: { char, multispace0, multispace1} ,
5- combinator:: { map, opt, map_res } ,
6- error:: { Error , ErrorKind } ,
5+ combinator:: { map, opt} ,
6+ error:: Error ,
77 multi:: separated_list0,
88 sequence:: { delimited, preceded, tuple} ,
99 IResult ,
1010} ;
1111
12+ use crate :: ir:: ast:: Type ;
1213use crate :: ir:: ast:: { FormalArgument , Function , Statement } ;
1314use crate :: parser:: parser_common:: {
14- identifier, keyword, ASSERT_KEYWORD , COLON_CHAR , COMMA_CHAR , DEF_KEYWORD , ELSE_KEYWORD ,
15+ identifier, keyword, ASSERTEQ_KEYWORD , ASSERTFALSE_KEYWORD , ASSERTNEQ_KEYWORD ,
16+ ASSERTTRUE_KEYWORD , ASSERT_KEYWORD , COLON_CHAR , COMMA_CHAR , DEF_KEYWORD , ELSE_KEYWORD ,
1517 END_KEYWORD , EQUALS_CHAR , FOR_KEYWORD , FUNCTION_ARROW , IF_KEYWORD , IN_KEYWORD , LEFT_PAREN ,
1618 RIGHT_PAREN , SEMICOLON_CHAR , VAL_KEYWORD , VAR_KEYWORD , WHILE_KEYWORD ,
1719} ;
1820use crate :: parser:: parser_expr:: parse_expression;
19- use crate :: parser:: parser_type:: parse_type;
20- use crate :: ir:: ast:: Type ; // TODO: Check if needed
21+ use crate :: parser:: parser_type:: parse_type; // TODO: Check if needed
2122
2223pub fn parse_statement ( input : & str ) -> IResult < & str , Statement > {
2324 alt ( (
@@ -28,6 +29,10 @@ pub fn parse_statement(input: &str) -> IResult<&str, Statement> {
2829 parse_while_statement,
2930 parse_for_statement,
3031 parse_assert_statement,
32+ parse_asserteq_statement,
33+ parse_assertneq_statement,
34+ parse_assertfalse_statement,
35+ parse_asserttrue_statement,
3136 parse_test_function_definition_statement, // FIXME: Being Implemented
3237 parse_function_definition_statement,
3338 ) ) ( input)
@@ -151,8 +156,120 @@ fn parse_assert_statement(input: &str) -> IResult<&str, Statement> {
151156 ) ( input)
152157}
153158
159+ fn parse_asserteq_statement ( input : & str ) -> IResult < & str , Statement > {
160+ map (
161+ tuple ( (
162+ keyword ( ASSERTEQ_KEYWORD ) ,
163+ delimited (
164+ char:: <& str, Error <& str>>( LEFT_PAREN ) ,
165+ separated_list0 (
166+ tuple ( (
167+ multispace0,
168+ char:: <& str, Error <& str>>( COMMA_CHAR ) ,
169+ multispace0,
170+ ) ) ,
171+ parse_expression,
172+ ) ,
173+ char:: <& str, Error <& str>>( RIGHT_PAREN ) ,
174+ ) ,
175+ ) ) ,
176+ |( _, args) | {
177+ if args. len ( ) != 3 {
178+ panic ! ( "AssertEQ statement requires exactly 3 arguments" ) ;
179+ }
180+ Statement :: AssertEQ (
181+ Box :: new ( args[ 0 ] . clone ( ) ) ,
182+ Box :: new ( args[ 1 ] . clone ( ) ) ,
183+ Box :: new ( args[ 2 ] . clone ( ) ) ,
184+ )
185+ } ,
186+ ) ( input)
187+ }
188+
189+ fn parse_assertneq_statement ( input : & str ) -> IResult < & str , Statement > {
190+ map (
191+ tuple ( (
192+ keyword ( ASSERTNEQ_KEYWORD ) ,
193+ delimited (
194+ char:: <& str, Error <& str>>( LEFT_PAREN ) ,
195+ separated_list0 (
196+ tuple ( (
197+ multispace0,
198+ char:: <& str, Error <& str>>( COMMA_CHAR ) ,
199+ multispace0,
200+ ) ) ,
201+ parse_expression,
202+ ) ,
203+ char:: <& str, Error <& str>>( RIGHT_PAREN ) ,
204+ ) ,
205+ ) ) ,
206+ |( _, args) | {
207+ if args. len ( ) != 3 {
208+ panic ! ( "AssertNEQ statement requires exactly 3 arguments" ) ;
209+ }
210+ Statement :: AssertNEQ (
211+ Box :: new ( args[ 0 ] . clone ( ) ) ,
212+ Box :: new ( args[ 1 ] . clone ( ) ) ,
213+ Box :: new ( args[ 2 ] . clone ( ) ) ,
214+ )
215+ } ,
216+ ) ( input)
217+ }
218+
219+ fn parse_asserttrue_statement ( input : & str ) -> IResult < & str , Statement > {
220+ map (
221+ tuple ( (
222+ keyword ( ASSERTTRUE_KEYWORD ) ,
223+ delimited (
224+ char:: <& str, Error <& str>>( LEFT_PAREN ) ,
225+ separated_list0 (
226+ tuple ( (
227+ multispace0,
228+ char:: <& str, Error <& str>>( COMMA_CHAR ) ,
229+ multispace0,
230+ ) ) ,
231+ parse_expression,
232+ ) ,
233+ char:: <& str, Error <& str>>( RIGHT_PAREN ) ,
234+ ) ,
235+ ) ) ,
236+ |( _, args) | {
237+ if args. len ( ) != 2 {
238+ panic ! ( "AssertTrue statement requires exactly 2 arguments" ) ;
239+ }
240+ Statement :: AssertTrue ( Box :: new ( args[ 0 ] . clone ( ) ) , Box :: new ( args[ 1 ] . clone ( ) ) )
241+ } ,
242+ ) ( input)
243+ }
244+
245+ fn parse_assertfalse_statement ( input : & str ) -> IResult < & str , Statement > {
246+ map (
247+ tuple ( (
248+ keyword ( ASSERTFALSE_KEYWORD ) ,
249+ delimited (
250+ char:: <& str, Error <& str>>( LEFT_PAREN ) ,
251+ separated_list0 (
252+ tuple ( (
253+ multispace0,
254+ char:: <& str, Error <& str>>( COMMA_CHAR ) ,
255+ multispace0,
256+ ) ) ,
257+ parse_expression,
258+ ) ,
259+ char:: <& str, Error <& str>>( RIGHT_PAREN ) ,
260+ ) ,
261+ ) ) ,
262+ |( _, args) | {
263+ if args. len ( ) != 2 {
264+ panic ! ( "AssertFalse statement requires exactly 2 arguments" ) ;
265+ }
266+ Statement :: AssertFalse ( Box :: new ( args[ 0 ] . clone ( ) ) , Box :: new ( args[ 1 ] . clone ( ) ) )
267+ } ,
268+ ) ( input)
269+ }
270+
154271fn parse_function_definition_statement ( input : & str ) -> IResult < & str , Statement > {
155- map_res (
272+ map (
156273 tuple ( (
157274 keyword ( DEF_KEYWORD ) ,
158275 preceded ( multispace1, identifier) ,
@@ -173,59 +290,38 @@ fn parse_function_definition_statement(input: &str) -> IResult<&str, Statement>
173290 parse_block,
174291 ) ) ,
175292 |( _, name, args, _, t, block) | {
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 ( input, 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- }
293+ Statement :: FuncDef ( Function {
294+ name : name. to_string ( ) ,
295+ kind : t,
296+ params : args,
297+ body : Some ( Box :: new ( block) ) ,
298+ } )
187299 } ,
188300 ) ( input)
189301}
190302
191-
192- // TODO: Fazer testes para essa função de parser
303+ // TODO: alterar, não há mais necessidade de checar se o nome é test, usaremos uma keyword "test"
193304fn parse_test_function_definition_statement ( input : & str ) -> IResult < & str , Statement > {
194- map_res (
305+ map (
195306 tuple ( (
196307 //keyword(DEF_KEYWORD),
197- tag ( "def " ) ,
308+ tag ( "test " ) ,
198309 preceded ( multispace1, identifier) ,
199310 //identifier,
200311 delimited (
201312 char:: <& str, Error <& str>>( LEFT_PAREN ) ,
202313 multispace0, // Permite `()` com espaços, mas sem argumentos
203314 char:: <& str, Error <& str>>( RIGHT_PAREN ) ,
204315 ) ,
205- opt ( preceded (
206- preceded ( multispace0, tag ( "->" ) ) ,
207- preceded ( multispace0, parse_type) ,
208- ) ) ,
209316 parse_block,
210317 ) ) ,
211- |( _, name, _, opt_ret_type, block) | {
212- if !name. starts_with ( "test" ) {
213- return Err ( nom:: Err :: Error ( Error :: new ( input, 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 ( input, ErrorKind :: Tag ) ) ) ;
220- }
221- }
222-
223- Ok ( Statement :: TestDef ( Function {
318+ |( _, name, _, block) | {
319+ Statement :: TestDef ( Function {
224320 name : name. to_string ( ) ,
225- kind : Type :: TBool , // Sempre bool (mesmo se não declarou)
226- params : Vec :: new ( ) , // Nenhum argumento
321+ kind : Type :: TBool , // Sempre bool (mesmo se não declarou)
322+ params : Vec :: new ( ) , // Nenhum argumento
227323 body : Some ( Box :: new ( block) ) ,
228- } ) )
324+ } )
229325 } ,
230326 ) ( input)
231327}
@@ -395,76 +491,71 @@ mod tests {
395491
396492 #[ test]
397493 fn test_parse_test_function_definition_statement_valid ( ) {
398- let input = "def test_example(): x = 1; end" ;
494+ let input = "test test_example(): x = 1; end" ;
399495 let expected = Statement :: TestDef ( Function {
400496 name : "test_example" . to_string ( ) ,
401497 kind : Type :: TBool ,
402498 params : vec ! [ ] ,
403- body : Some ( Box :: new ( Statement :: Block ( vec ! [
404- Statement :: Assignment ( "x" . to_string( ) , Box :: new( Expression :: CInt ( 1 ) ) ) ,
405- ] ) ) ) ,
499+ body : Some ( Box :: new ( Statement :: Block ( vec ! [ Statement :: Assignment (
500+ "x" . to_string( ) ,
501+ Box :: new( Expression :: CInt ( 1 ) ) ,
502+ ) ] ) ) ) ,
406503 } ) ;
407504 let parsed = parse_test_function_definition_statement ( input) . unwrap ( ) . 1 ;
408505 assert_eq ! ( parsed, expected) ;
409506 }
410507
411508 #[ test]
412509 fn test_parse_test_function_definition_statement_with_spaces ( ) {
413- let input = "def test_spaces( ): x = 2; end" ;
510+ let input = "test test_spaces( ): x = 2; end" ;
414511 let expected = Statement :: TestDef ( Function {
415512 name : "test_spaces" . to_string ( ) ,
416513 kind : Type :: TBool ,
417514 params : vec ! [ ] ,
418- body : Some ( Box :: new ( Statement :: Block ( vec ! [
419- Statement :: Assignment ( "x" . to_string( ) , Box :: new( Expression :: CInt ( 2 ) ) ) ,
420- ] ) ) ) ,
515+ body : Some ( Box :: new ( Statement :: Block ( vec ! [ Statement :: Assignment (
516+ "x" . to_string( ) ,
517+ Box :: new( Expression :: CInt ( 2 ) ) ,
518+ ) ] ) ) ) ,
421519 } ) ;
422520 let parsed = parse_test_function_definition_statement ( input) . unwrap ( ) . 1 ;
423521 assert_eq ! ( parsed, expected) ;
424522 }
425523
426524 #[ test]
427525 fn test_parse_test_function_definition_statement_args ( ) {
428- let input = "def test_with_args(x: Int, y: Int): x = y; end" ;
429-
526+ let input = "test test_with_args(x: Int, y: Int): x = y; end" ;
527+
430528 // O parser deve falhar, pois funções de teste não podem ter argumentos.
431529 let parsed = parse_test_function_definition_statement ( input) ;
432-
433- assert ! ( parsed. is_err( ) , "Funções de teste com argumentos devem ser rejeitadas" ) ;
530+
531+ assert ! (
532+ parsed. is_err( ) ,
533+ "Funções de teste com argumentos devem ser rejeitadas"
534+ ) ;
434535 }
435-
536+
436537 #[ 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-
538+ fn test_parse_test_function_definition_statement_invalid_return ( ) {
539+ let input = "test test_with_invalid_return() -> Int: x = 2; end" ;
540+
440541 // O parser deve falhar, pois funções de teste não podem ter argumentos.
441542 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" ) ;
543+
544+ assert ! (
545+ parsed. is_err( ) ,
546+ "Funções de teste não devem especificar tipo de retorno"
547+ ) ;
444548 }
445-
549+
446550 #[ test]
447551 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- //FIXME: Mudança de teste para testar o commit do github MUDANÇA
552+ let input = "test test_with_valid_return() -> Boolean: x = 2; end" ;
469553
554+ let parsed = parse_test_function_definition_statement ( input) ;
555+ assert ! (
556+ parsed. is_err( ) ,
557+ "Funções de teste não devem especificar tipo de retorno"
558+ ) ;
559+ }
560+ //TODO: Implementar testes para os ASSERTS
470561}
0 commit comments