2121#include "ps_symbol_table.h"
2222#include "ps_system.h"
2323
24- // exit(EXIT_FAILURE);
25-
2624#define ASSERT_RETURN_FALSE (expr ) \
2725 do \
2826 { \
3432 } \
3533 } while (0)
3634
37- #define ASSERT_RETURN_NULL (expr ) \
35+ #define ASSERT_GOTO_CLEANUP (expr ) \
3836 do \
3937 { \
4038 if (!(expr)) \
4139 { \
4240 ps_ast_debug_line("Assertion failed: %s, function %s, file %s, line %d.", #expr, __func__, __FILE__, \
4341 __LINE__); \
44- return NULL; \
42+ goto cleanup; \
4543 } \
4644 } while (0)
4745
@@ -51,28 +49,31 @@ ps_ast_block *ps_ast_test_create_block_program(const char *name)
5149 ps_ast_block * block_program = ps_ast_create_block (1 , 1 , PS_AST_PROGRAM , name );
5250 if (block_program == NULL )
5351 return NULL ;
52+
53+ ps_ast_debug_line ("Create symbol table" );
5454 block_program -> symbols = ps_symbol_table_alloc (0 , 0 );
55- if (block_program -> symbols == NULL )
56- goto cleanup ;
55+ ASSERT_GOTO_CLEANUP (block_program -> symbols != NULL );
56+
5757 ps_symbol * symbol_program = ps_symbol_alloc (PS_SYMBOL_KIND_PROGRAM , name , NULL );
58- if (symbol_program == NULL )
59- goto cleanup ;
58+ ASSERT_GOTO_CLEANUP (symbol_program != NULL );
59+
6060 ps_symbol_table_error error = ps_symbol_table_add (block_program -> symbols , symbol_program );
61- if (error != PS_SYMBOL_TABLE_ERROR_NONE )
62- goto cleanup ;
61+ ASSERT_GOTO_CLEANUP (error == PS_SYMBOL_TABLE_ERROR_NONE );
62+
6363 ps_ast_debug_line ("Check that the PROGRAM node has the expected values" );
64- ASSERT_RETURN_NULL (block_program -> group == PS_AST_BLOCK );
65- ASSERT_RETURN_NULL (block_program -> kind == PS_AST_PROGRAM );
66- ASSERT_RETURN_NULL (block_program -> line == 1 );
67- ASSERT_RETURN_NULL (block_program -> column == 1 );
68- ASSERT_RETURN_NULL (strcmp (block_program -> name , name ) == 0 );
69- ASSERT_RETURN_NULL (block_program -> n_vars == 0 );
70- ASSERT_RETURN_NULL (block_program -> symbols != NULL );
71- ASSERT_RETURN_NULL (block_program -> n_executables == 0 );
72- ASSERT_RETURN_NULL (block_program -> executables == NULL );
73- ASSERT_RETURN_NULL (block_program -> statement_list == NULL );
74- ASSERT_RETURN_NULL (block_program -> signature == NULL );
75- ASSERT_RETURN_NULL (block_program -> result_type == NULL );
64+ ASSERT_GOTO_CLEANUP (block_program -> group == PS_AST_BLOCK );
65+ ASSERT_GOTO_CLEANUP (block_program -> kind == PS_AST_PROGRAM );
66+ ASSERT_GOTO_CLEANUP (block_program -> line == 1 );
67+ ASSERT_GOTO_CLEANUP (block_program -> column == 1 );
68+ ASSERT_GOTO_CLEANUP (strcmp (block_program -> name , name ) == 0 );
69+ ASSERT_GOTO_CLEANUP (block_program -> n_vars == 0 );
70+ ASSERT_GOTO_CLEANUP (block_program -> symbols != NULL );
71+ ASSERT_GOTO_CLEANUP (block_program -> n_executables == 0 );
72+ ASSERT_GOTO_CLEANUP (block_program -> executables == NULL );
73+ ASSERT_GOTO_CLEANUP (block_program -> statement_list == NULL );
74+ ASSERT_GOTO_CLEANUP (block_program -> signature == NULL );
75+ ASSERT_GOTO_CLEANUP (block_program -> result_type == NULL );
76+
7677 return block_program ;
7778cleanup :
7879 ps_ast_free_block (block_program );
@@ -91,21 +92,23 @@ ps_interpreter *ps_ast_test_create_interpreter(ps_ast_block *block_program)
9192{
9293 ps_ast_debug_line ("Create an interpreter" );
9394 ps_interpreter * interpreter = ps_interpreter_alloc (true, false, false);
94- ASSERT_RETURN_NULL (interpreter != NULL );
95+ ASSERT_GOTO_CLEANUP (interpreter != NULL );
9596
9697 ps_ast_debug_line ("Enter environment for the program %s" , block_program -> name );
97- ASSERT_RETURN_NULL (ps_interpreter_enter_environment (interpreter , block_program -> name , NULL , 0 , NULL ));
98+ ASSERT_GOTO_CLEANUP (ps_interpreter_enter_environment (interpreter , block_program -> name , NULL , 0 , NULL ));
9899
99100 ps_ast_debug_line ("Add PROGRAM symbol to the current environment symbol table" );
100101 ps_symbol * symbol_program = ps_symbol_table_get (block_program -> symbols , block_program -> name );
101- ASSERT_RETURN_NULL (symbol_program != NULL );
102- ASSERT_RETURN_NULL (symbol_program -> kind == PS_SYMBOL_KIND_PROGRAM );
103- ASSERT_RETURN_NULL (symbol_program -> system == false);
104- ASSERT_RETURN_NULL (symbol_program -> allocated == true);
105- ASSERT_RETURN_NULL (symbol_program -> value == NULL );
106- ASSERT_RETURN_NULL (ps_interpreter_add_symbol (interpreter , symbol_program ));
102+ ASSERT_GOTO_CLEANUP (symbol_program != NULL );
103+ ASSERT_GOTO_CLEANUP (symbol_program -> kind == PS_SYMBOL_KIND_PROGRAM );
104+ ASSERT_GOTO_CLEANUP (symbol_program -> system == false);
105+ ASSERT_GOTO_CLEANUP (symbol_program -> allocated == true);
106+ ASSERT_GOTO_CLEANUP (symbol_program -> value == NULL );
107+ ASSERT_GOTO_CLEANUP (ps_interpreter_add_symbol (interpreter , symbol_program ));
107108
108109 return interpreter ;
110+ cleanup :
111+ return NULL ;
109112}
110113
111114bool ps_ast_test_delete_interpreter (ps_interpreter * interpreter , ps_ast_block * block_program )
@@ -168,7 +171,6 @@ bool ps_ast_test_minimal()
168171bool ps_ast_test_assignment ()
169172{
170173 bool result ;
171- (void )result ; // silence unused variable warning with asserts
172174
173175 ps_ast_block * block_program = ps_ast_test_create_block_program ("ASSIGNMENT" );
174176 ASSERT_RETURN_FALSE (block_program != NULL );
@@ -273,31 +275,14 @@ bool ps_ast_test_assignment()
273275bool ps_ast_test_hello ()
274276{
275277 bool result ;
276- (void )result ; // silence unused variable warning with asserts
277-
278- ps_ast_debug_line ("Create an interpreter first as we may need it very soon" );
279- ps_interpreter * interpreter = ps_interpreter_alloc (true, false, false);
280- ASSERT_RETURN_FALSE (interpreter != NULL );
281278
282- ps_ast_debug_line ("Create a PROGRAM node with name 'HELLO' at line 1, column 1" );
283279 ps_ast_block * block_program = ps_ast_test_create_block_program ("HELLO" );
284280 ASSERT_RETURN_FALSE (block_program != NULL );
285281
286- ps_ast_debug_line ("Enter environment for the program block_program" );
287- result = ps_interpreter_enter_environment (interpreter , block_program -> name , NULL , 0 , NULL );
288- ASSERT_RETURN_FALSE (result );
289-
290- ps_ast_debug_line ("Create a PROGRAM symbol and add it to the current environment symbol table and the "
291- "block_program symbol table" );
292- ps_symbol * symbol = ps_symbol_alloc (PS_SYMBOL_KIND_PROGRAM , "HELLO" , NULL );
293- result = ps_interpreter_add_symbol (interpreter , symbol );
294- ASSERT_RETURN_FALSE (result );
295- ps_symbol_table_error error = ps_symbol_table_add (block_program -> symbols , symbol );
296- (void )error ; // silence unused variable warning
297- ASSERT_RETURN_FALSE (error == PS_SYMBOL_TABLE_ERROR_NONE );
282+ ps_interpreter * interpreter = ps_ast_test_create_interpreter (block_program );
283+ ASSERT_RETURN_FALSE (interpreter != NULL );
298284
299285 ps_ast_debug_line ("Create a statement list with one statement" );
300- // a PROCEDURE CALL to Writeln with one argument: a string value "Hello, World!"
301286 block_program -> statement_list = ps_ast_create_statement_list (3 , 5 , 1 );
302287 ASSERT_RETURN_FALSE (block_program -> statement_list != NULL );
303288
@@ -332,9 +317,14 @@ bool ps_ast_test_hello()
332317 result = ps_ast_run_program (interpreter , block_program );
333318 if (!result )
334319 {
335- fprintf (stderr , "Error running the program\n" );
320+ ps_ast_debug_line ("Error running the program: %s (%d)" , interpreter -> error ,
321+ ps_error_get_message (interpreter -> error ));
336322 }
337323
324+ ps_ast_debug_line ("Free symbol table for the program %s" , block_program -> name );
325+ ps_memory_free (PS_MEMORY_AST , block_program -> symbols );
326+ block_program -> symbols = NULL ;
327+
338328 ps_ast_debug_line ("Free program %s" , block_program -> name );
339329 block_program = (ps_ast_block * )ps_ast_free_block (block_program );
340330 ASSERT_RETURN_FALSE (block_program == NULL );
0 commit comments