Skip to content

Commit 7134f61

Browse files
committed
AST WIP
1 parent 1d4582c commit 7134f61

1 file changed

Lines changed: 110 additions & 2 deletions

File tree

src/ps_ast_test.c

Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ bool ps_ast_test_delete_interpreter(ps_interpreter *interpreter, ps_ast_block *b
131131

132132
/**
133133
* @brief Test minimal Pascal program
134-
* L/C 12345678901234567890
134+
* L/C 123456789012345678901234567890123456789012345678901234567890
135135
* 1 Program Minimal;
136136
* 2 Begin
137137
* 3 End.
@@ -508,6 +508,112 @@ bool ps_ast_test_while_do()
508508
return true;
509509
}
510510

511+
/**
512+
* @brief Test Repeat-Until Pascal program
513+
* L/C 123456789012345678901234567890123456789012345678901234567890
514+
* 1 Program RepeatUntil;
515+
* 2 Var I: Integer;
516+
* 3 Begin
517+
* 4 I := 5;
518+
* 5 Repeat
519+
* 6 I := I - 1;
520+
* 7 Until I = 0;
521+
* 8 End.
522+
*/
523+
bool ps_ast_test_repeat_until()
524+
{
525+
bool result;
526+
527+
ps_ast_block *block_program = ps_ast_test_create_block_program("REPEATUNTIL");
528+
ASSERT_RETURN_FALSE(block_program != NULL);
529+
530+
ps_interpreter *interpreter = ps_ast_test_create_interpreter(block_program);
531+
ASSERT_RETURN_FALSE(interpreter != NULL);
532+
533+
ps_ast_debug_line(0, "Create variable symbol I of type Integer and add it to the symbol tables");
534+
ps_value value_i = {.allocated = false, .type = &ps_system_integer, .data.i = 0};
535+
ps_symbol *symbol_i = ps_symbol_alloc(PS_SYMBOL_KIND_VARIABLE, "I", &value_i);
536+
result = ps_interpreter_add_symbol(interpreter, symbol_i);
537+
ASSERT_RETURN_FALSE(result);
538+
ps_symbol_table_error error = ps_symbol_table_add(block_program->symbols, symbol_i);
539+
ASSERT_RETURN_FALSE(error == PS_SYMBOL_TABLE_ERROR_NONE);
540+
block_program->n_vars = 1;
541+
542+
ps_ast_debug_line(0, "Create a statement list with 2 statements (I := 5; Repeat loop)");
543+
block_program->statement_list = ps_ast_create_statement_list(4, 5, 2);
544+
ASSERT_RETURN_FALSE(block_program->statement_list != NULL);
545+
546+
ps_ast_debug_line(0, "Create the first assignment statement I := 5;");
547+
ps_ast_variable_simple *variable_i_init = ps_ast_create_variable_simple(4, 5, PS_AST_LVALUE_SIMPLE, symbol_i);
548+
ASSERT_RETURN_FALSE(variable_i_init != NULL);
549+
ps_value value_i_5 = {.allocated = false, .type = &ps_system_integer, .data.i = 5};
550+
ps_ast_value *rvalue_i_5 = ps_ast_create_rvalue_const(4, 10, value_i_5);
551+
ASSERT_RETURN_FALSE(rvalue_i_5 != NULL);
552+
ps_ast_assignment *assignment_i_init =
553+
ps_ast_create_assignment(4, 5, (ps_ast_node *)variable_i_init, (ps_ast_node *)rvalue_i_5);
554+
ASSERT_RETURN_FALSE(assignment_i_init != NULL);
555+
block_program->statement_list->statements[0] = (ps_ast_node *)assignment_i_init;
556+
557+
ps_ast_debug_line(0, "Create the REPEAT loop body: I := I - 1");
558+
ps_ast_statement_list *repeat_body = ps_ast_create_statement_list(6, 9, 1);
559+
ASSERT_RETURN_FALSE(repeat_body != NULL);
560+
ps_ast_variable_simple *variable_i_body = ps_ast_create_variable_simple(6, 9, PS_AST_LVALUE_SIMPLE, symbol_i);
561+
ASSERT_RETURN_FALSE(variable_i_body != NULL);
562+
ps_ast_variable_simple *rvalue_i_body = ps_ast_create_variable_simple(6, 19, PS_AST_RVALUE_SIMPLE, symbol_i);
563+
ASSERT_RETURN_FALSE(rvalue_i_body != NULL);
564+
ps_value value_i_1 = {.allocated = false, .type = &ps_system_integer, .data.i = 1};
565+
ps_ast_value *rvalue_i_1 = ps_ast_create_rvalue_const(6, 23, value_i_1);
566+
ASSERT_RETURN_FALSE(rvalue_i_1 != NULL);
567+
ps_ast_binary_operation *i_minus_1 =
568+
ps_ast_create_binary_operation(6, 21, PS_OP_SUB, (ps_ast_node *)rvalue_i_body, (ps_ast_node *)rvalue_i_1);
569+
ASSERT_RETURN_FALSE(i_minus_1 != NULL);
570+
ps_ast_assignment *assignment_i_body =
571+
ps_ast_create_assignment(6, 9, (ps_ast_node *)variable_i_body, (ps_ast_node *)i_minus_1);
572+
ASSERT_RETURN_FALSE(assignment_i_body != NULL);
573+
repeat_body->statements[0] = (ps_ast_node *)assignment_i_body;
574+
575+
ps_ast_debug_line(0, "Create the REPEAT condition I = 0");
576+
ps_ast_variable_simple *rvalue_i_cond = ps_ast_create_variable_simple(7, 10, PS_AST_RVALUE_SIMPLE, symbol_i);
577+
ASSERT_RETURN_FALSE(rvalue_i_cond != NULL);
578+
ps_value value_i_0 = {.allocated = false, .type = &ps_system_integer, .data.i = 0};
579+
ps_ast_value *rvalue_i_0 = ps_ast_create_rvalue_const(7, 14, value_i_0);
580+
ASSERT_RETURN_FALSE(rvalue_i_0 != NULL);
581+
ps_ast_binary_operation *repeat_condition =
582+
ps_ast_create_binary_operation(7, 12, PS_OP_EQ, (ps_ast_node *)rvalue_i_cond, (ps_ast_node *)rvalue_i_0);
583+
ASSERT_RETURN_FALSE(repeat_condition != NULL);
584+
585+
ps_ast_debug_line(0, "Create the REPEAT statement");
586+
ps_ast_repeat *repeat_statement = ps_ast_create_repeat(5, 5, repeat_body, (ps_ast_node *)repeat_condition);
587+
ASSERT_RETURN_FALSE(repeat_statement != NULL);
588+
block_program->statement_list->statements[1] = (ps_ast_node *)repeat_statement;
589+
590+
ps_ast_debug_line(0, "Debug print the program");
591+
ps_ast_debug = true;
592+
ps_ast_debug_line(0, "================================================================");
593+
ps_ast_debug_node(0, (ps_ast_node *)block_program);
594+
ps_ast_debug_line(0, "================================================================");
595+
596+
ps_ast_debug_line(0, "Run the program and check that it returns true");
597+
result = ps_ast_run_program(interpreter, block_program);
598+
ps_ast_debug_line(0, "Interpreter error: %s", ps_error_get_message(interpreter->error));
599+
ps_ast_debug_line(0, "Interpreter message: %s", interpreter->message);
600+
ASSERT_RETURN_FALSE(result);
601+
602+
ps_ast_debug_line(0, "Check that variable I has the expected value 0 (loop condition became true)");
603+
ASSERT_RETURN_FALSE(symbol_i->value != NULL);
604+
ASSERT_RETURN_FALSE(symbol_i->value->type == &ps_system_integer);
605+
ps_ast_debug_line(0, "Variable I value: %d", symbol_i->value->data.i);
606+
ASSERT_RETURN_FALSE(symbol_i->value->data.i == 0);
607+
608+
ps_symbol_table_dump(stderr, NULL, block_program->symbols);
609+
610+
ps_ast_test_delete_interpreter(interpreter, block_program);
611+
612+
ps_ast_test_delete_block_program(block_program);
613+
614+
return true;
615+
}
616+
511617
/**
512618
* @brief Test For-Do Pascal program
513619
* L/C 123456789012345678901234567890123456789012345678901234567890
@@ -629,7 +735,7 @@ bool ps_ast_test_for_do()
629735
/**
630736
* @brief Test Hello Pascal program
631737
* 0 1 2 3
632-
* L/C 123456789012345678901234567890
738+
* L/C 123456789012345678901234567890123456789012345678901234567890
633739
* 1 Program Hello;
634740
* 2 Begin
635741
* 3 WriteLn('Hello, World!');
@@ -718,6 +824,8 @@ bool ps_ast_test()
718824
ps_ast_debug_line(0, "****************************************************************");
719825
result &= ps_ast_test_while_do();
720826
ps_ast_debug_line(0, "****************************************************************");
827+
result &= ps_ast_test_repeat_until();
828+
ps_ast_debug_line(0, "****************************************************************");
721829
result &= ps_ast_test_for_do();
722830
ps_ast_debug_line(0, "****************************************************************");
723831
result &= ps_ast_test_hello();

0 commit comments

Comments
 (0)