Skip to content

Commit 4a1af4d

Browse files
committed
Alterado Parser de Test Functions e Implementado Parser de Asserts
Ainda falta implementar testes para os Asserts
1 parent 040373c commit 4a1af4d

3 files changed

Lines changed: 181 additions & 86 deletions

File tree

src/ir/ast.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,11 @@ pub enum Statement {
134134
For(Name, Box<Expression>, Box<Statement>),
135135
Block(Vec<Statement>),
136136
Sequence(Box<Statement>, Box<Statement>),
137-
Assert(Box<Expression>, Box<Expression>),
138-
AssertTrue(Box<Expression>, String),
139-
AssertFalse(Box<Expression>, String),
140-
AssertEQ(Box<Expression>, Box<Expression>, String),
141-
AssertNEQ(Box<Expression>, Box<Expression>, String),
137+
Assert(Box<Expression>, Box<Expression>), //Segundo expression deve ser String
138+
AssertTrue(Box<Expression>, Box<Expression>), //Segundo expression deve ser String
139+
AssertFalse(Box<Expression>, Box<Expression>), //Segundo expression deve ser String
140+
AssertEQ(Box<Expression>, Box<Expression>, Box<Expression>), //Terceiro expression deve ser String
141+
AssertNEQ(Box<Expression>, Box<Expression>, Box<Expression>), //Terceiro expression deve ser String
142142
TestDef(Function),
143143
ModTestDef(Name, Box<Statement>),
144144
AssertFails(String),

src/parser/parser_common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ pub const WHILE_KEYWORD: &str = "while";
3333
pub const FOR_KEYWORD: &str = "for";
3434
pub const IN_KEYWORD: &str = "in";
3535
pub const ASSERT_KEYWORD: &str = "assert";
36+
pub const ASSERTEQ_KEYWORD: &str = "asserteq";
37+
pub const ASSERTNEQ_KEYWORD: &str = "assertneq";
38+
pub const ASSERTTRUE_KEYWORD: &str = "asserttrue";
39+
pub const ASSERTFALSE_KEYWORD: &str = "assertfalse";
3640
pub const VAR_KEYWORD: &str = "var";
3741
pub const VAL_KEYWORD: &str = "val";
3842
pub const DEF_KEYWORD: &str = "def";

src/parser/parser_stmt.rs

Lines changed: 172 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -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;
1213
use crate::ir::ast::{FormalArgument, Function, Statement};
1314
use 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
};
1820
use 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

2223
pub 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+
154271
fn 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"
193304
fn 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

Comments
 (0)