@@ -68,18 +68,24 @@ bool ps_parse_statement(ps_compiler *compiler, ps_ast_block *block, ps_ast_node
6868 * 'END'
6969 * NB: ';' or '.' or whatever after END is analyzed in the caller
7070 */
71- bool ps_parse_compound_statement (ps_compiler * compiler , ps_ast_block * block , ps_ast_statement_list * * statement_list )
71+ bool ps_parse_compound_statement (ps_compiler * compiler , ps_ast_block * block , ps_ast_node * * statement )
7272{
73- PARSE_BEGIN ("COMPOUND_STATEMENT " , "" );
73+ PARSE_BEGIN ("STATEMENT " , "COMPOUND " );
7474
75+ // 'BEGIN'
7576 EXPECT_TOKEN (PS_TOKEN_BEGIN );
7677 READ_NEXT_TOKEN
77- if (lexer -> current_token .type != PS_TOKEN_END &&
78- !ps_parse_statement_list (compiler , block , statement_list , PS_TOKEN_END ))
78+
79+ // [ STATEMENT [ ';' STATEMENT ]* ] [ ';' ]
80+ ps_ast_statement_list * statement_list = NULL ;
81+ if (!ps_parse_statement_list (compiler , block , & statement_list , PS_TOKEN_END ))
7982 TRACE_ERROR ("STATEMENT_LIST" )
83+
84+ // 'END'
8085 EXPECT_TOKEN (PS_TOKEN_END )
8186 READ_NEXT_TOKEN
8287
88+ * statement = (ps_ast_node * )statement_list ;
8389 PARSE_END ("OK" )
8490}
8591
@@ -171,8 +177,12 @@ bool ps_parse_compound_statement(ps_compiler *compiler, ps_ast_block *block, ps_
171177 */
172178bool ps_parse_assignment (ps_compiler * compiler , ps_ast_block * block , ps_ast_node * * statement , ps_symbol * variable )
173179{
174- PARSE_BEGIN ("ASSIGNMENT" , "" )
180+ PARSE_BEGIN ("STATEMENT" , "ASSIGNMENT" )
181+ ps_ast_assignment * assignment = NULL ;
182+ ps_ast_node * expression = NULL ;
183+ ps_ast_node * lvalue = NULL ;
175184
185+ // IDENTIFIER
176186 if (variable -> kind == PS_SYMBOL_KIND_CONSTANT )
177187 {
178188 compiler -> error = PS_ERROR_ASSIGN_TO_CONST ;
@@ -185,6 +195,7 @@ bool ps_parse_assignment(ps_compiler *compiler, ps_ast_block *block, ps_ast_node
185195 ps_compiler_set_message (compiler , "Symbol '%s' is not a variable" , variable -> name );
186196 TRACE_ERROR ("VARIABLE" );
187197 }
198+
188199 if (compiler -> debug >= COMPILER_DEBUG_VERBOSE )
189200 fprintf (stderr , "\nINFO\tASSIGNMENT: #1 variable '%s' type is '%s'\n" , variable -> name ,
190201 ps_type_definition_get_name (variable -> value -> type -> value -> data .t ));
@@ -197,32 +208,52 @@ bool ps_parse_assignment(ps_compiler *compiler, ps_ast_block *block, ps_ast_node
197208 }
198209 else
199210 {
211+ // ':='
200212 EXPECT_TOKEN (PS_TOKEN_ASSIGN );
201213 READ_NEXT_TOKEN
202- ps_ast_node * expression = NULL ;
214+ // EXPRESSION
203215 if (!ps_parse_expression (compiler , block , & expression ))
204216 TRACE_ERROR ("EXPRESSION1 ");
205217 if (compiler - > debug >= COMPILER_DEBUG_VERBOSE )
206218 fprintf (stderr , "\nINFO \tASSIGNMENT : #2 variable '%s' type is '%s'\n", variable->name,
207219 ps_type_definition_get_name (variable -> value -> type -> value -> data .t ));
208- ps_ast_variable_simple * lvalue =
209- ps_ast_create_variable_simple (start_line , start_column , PS_AST_LVALUE_SIMPLE , variable );
220+ // AST NODE => ASSIGNMENT(LVALUE, EXPRESSION)
221+ lvalue = ( ps_ast_node * ) ps_ast_create_variable_simple (start_line , start_column , PS_AST_LVALUE_SIMPLE , variable );
210222 if (lvalue == NULL )
211223 RETURN_ERROR (PS_ERROR_OUT_OF_MEMORY )
212- ps_ast_assignment * assignment =
213- ps_ast_create_assignment (start_line , start_column , (ps_ast_node * )lvalue , expression );
214- if (assignment == NULL )
215- RETURN_ERROR (PS_ERROR_OUT_OF_MEMORY )
216- * statement = (ps_ast_node * )assignment ;
217224 }
218225
226+ * assignment = ps_ast_create_assignment (start_line , start_column , lvalue , expression );
227+ if (assignment == NULL )
228+ RETURN_ERROR (PS_ERROR_OUT_OF_MEMORY )
229+ * statement = (ps_ast_node * )assignment ;
230+
219231 PARSE_END ("OK" )
220232}
221233
234+ /**
235+ * Parse
236+ * 'READ' | 'READLN' [ '('
237+ * variable [ ',' variable ] ]*
238+ * ')' ] ;
239+ * Next steps:
240+ * Read from text file:
241+ * 'READ' | 'READLN' [ '('
242+ * [ file_variable ',' ]
243+ * variable [ ',' variable ]*
244+ * ')' ] ;
245+ * Read from binary file:
246+ * 'READ' '('
247+ * file_variable ',' variable
248+ * ')' ;
249+ */
222250bool ps_parse_read_or_readln (ps_compiler * compiler , ps_ast_block * block , ps_ast_node * statement , bool newline )
223251{
252+ (void )compiler ;
253+ (void )block ;
254+ (void )statement ;
224255 (void )newline ;
225- PARSE_BEGIN ("READ_OR_READLN " , "" )
256+ PARSE_BEGIN ("STATEMENT " , "READ_OR_READLN " )
226257 RETURN_ERROR (PS_ERROR_NOT_IMPLEMENTED )
227258}
228259
@@ -246,7 +277,7 @@ bool ps_parse_read_or_readln(ps_compiler *compiler, ps_ast_block *block, ps_ast_
246277 */
247278bool ps_parse_write_or_writeln (ps_compiler * compiler , ps_ast_block * block , bool newline , ps_ast_call * call )
248279{
249- PARSE_BEGIN ("WRITE_OR_WRITELN " , "" );
280+ PARSE_BEGIN ("STATEMENT " , "WRITE_OR_WRITELN " );
250281
251282 size_t n_args = 0 ;
252283 ps_ast_node * args [8 ] = {0 };
@@ -316,8 +347,6 @@ bool ps_parse_write_or_writeln(ps_compiler *compiler, ps_ast_block *block, bool
316347 call = ps_ast_create_call (lexer -> start_line , lexer -> start_column , PS_AST_PROCEDURE_CALL ,
317348 newline ? & ps_system_procedure_writeln : & ps_system_procedure_write , n_args ,
318349 n_args > 0 ? args : NULL );
319- if (!ps_compiler_add_statement (compiler , block , (ps_ast_node * )call ))
320- TRACE_ERROR ("ADD STATEMENT" )
321350
322351 PARSE_END ("OK" )
323352}
@@ -328,9 +357,9 @@ bool ps_parse_write_or_writeln(ps_compiler *compiler, ps_ast_block *block, bool
328357 * - variable: assignment
329358 * - procedure: procedure call
330359 */
331- bool ps_parse_assignment_or_procedure_call (ps_compiler * compiler , ps_ast_block * block , ps_ast_node * statement )
360+ bool ps_parse_assignment_or_procedure_call (ps_compiler * compiler , ps_ast_block * block , ps_ast_node * * statement )
332361{
333- PARSE_BEGIN ("ASSIGNMENT_OR_PROCEDURE_CALL " , "" );
362+ PARSE_BEGIN ("STATEMENT " , "ASSIGNMENT OR PROCEDURE CALL " );
334363 ps_identifier identifier ;
335364 ps_symbol * symbol ;
336365 ps_identifier result_identifier = "RESULT" ;
@@ -361,18 +390,23 @@ bool ps_parse_assignment_or_procedure_call(ps_compiler *compiler, ps_ast_block *
361390 switch (symbol -> kind )
362391 {
363392 case PS_SYMBOL_KIND_VARIABLE :
364- if (!ps_parse_assignment (compiler , block , symbol ))
393+ if (!ps_parse_assignment (compiler , block , statement , symbol ))
365394 TRACE_ERROR ("ASSIGNMENT" )
366395 break ;
367396 case PS_SYMBOL_KIND_CONSTANT :
368397 ps_compiler_set_message (compiler , "Constant '%s' cannot be assigned" , symbol -> name );
369398 RETURN_ERROR (PS_ERROR_ASSIGN_TO_CONST )
370399 case PS_SYMBOL_KIND_PROCEDURE :
371- if (!ps_parse_procedure_or_function_call (compiler , block , symbol , NULL ))
400+ if (!ps_parse_procedure_or_function_call (compiler , block , statement , symbol ))
372401 TRACE_ERROR ("PROCEDURE_CALL" )
373402 break ;
374403 case PS_SYMBOL_KIND_FUNCTION :
375- // Assignment to function name = assignment to Result
404+ // Assignment to function name => assignment to Result
405+ if (strcmp (block -> name , identifier ) != 0 )
406+ {
407+ ps_compiler_set_message (compiler ,"" ,block -> name ,identifier );
408+ RETURN_ERROR (PS_ERROR_UNEXPECTED_TOKEN );
409+ }
376410 symbol = ps_compiler_find_symbol (compiler , block , result_identifier , true);
377411 if (symbol == NULL )
378412 RETURN_ERROR (PS_ERROR_SYMBOL_NOT_FOUND )
@@ -392,7 +426,7 @@ bool ps_parse_assignment_or_procedure_call(ps_compiler *compiler, ps_ast_block *
392426 */
393427bool ps_parse_if_then_else (ps_compiler * compiler , ps_ast_block * block , ps_ast_node * statement )
394428{
395- PARSE_BEGIN ("IF " , "" )
429+ PARSE_BEGIN ("STATEMENT " , "IF_THEN_ELSE " )
396430
397431 ps_ast_node * condition = NULL ;
398432 ps_ast_node * then_branch = NULL ;
@@ -427,7 +461,7 @@ bool ps_parse_if_then_else(ps_compiler *compiler, ps_ast_block *block, ps_ast_no
427461 */
428462bool ps_parse_repeat_until (ps_compiler * compiler , ps_ast_block * block , ps_ast_node * statement )
429463{
430- PARSE_BEGIN ("REPEAT_UNTIL " , "" );
464+ PARSE_BEGIN ("STATEMENT " , "REPEAT_UNTIL " );
431465
432466 ps_ast_statement_list * body = NULL ;
433467 ps_ast_node * condition = NULL ;
@@ -458,7 +492,7 @@ bool ps_parse_repeat_until(ps_compiler *compiler, ps_ast_block *block, ps_ast_no
458492 */
459493bool ps_parse_while_do (ps_compiler * compiler , ps_ast_block * block , ps_ast_node * statement )
460494{
461- PARSE_BEGIN ("WHILE_DO ", "");
495+ PARSE_BEGIN ("STATEMENT ", "WHILE_DO ");
462496
463497 ps_ast_node * condition = NULL;
464498
@@ -491,7 +525,7 @@ bool ps_parse_while_do(ps_compiler *compiler, ps_ast_block *block, ps_ast_node *
491525 */
492526bool ps_parse_for_do (ps_compiler * compiler , ps_ast_block * block , ps_ast_node * statement )
493527{
494- PARSE_BEGIN ("FOR_DO ", "");
528+ PARSE_BEGIN ("STATEMENT ", "FOR_DO ");
495529
496530 ps_value start = {.type = & ps_system_none , .data .v = NULL};
497531 ps_value finish = {.type = & ps_system_none , .data .v = NULL};
@@ -551,12 +585,13 @@ bool ps_parse_for_do(ps_compiler *compiler, ps_ast_block *block, ps_ast_node *st
551585}
552586
553587/**
554- * Parse statement sequence, stopping at "stop" token (e.g. END, ELSE, UNTIL)
588+ * Parse statement sequence, stopping at "stop" token (END or UNTIL)
589+ * skip/ignore ';' before end
555590 */
556591bool ps_parse_statement_list (ps_compiler * compiler , ps_ast_block * block , ps_ast_statement_list * * statement_list ,
557592 ps_token_type stop )
558593{
559- PARSE_BEGIN ("STATEMENT_LIST ", "");
594+ PARSE_BEGIN ("STATEMENT ", "STATEMENT_LIST ");
560595
561596 // Empty block?
562597 if (lexer - > current_token .type == stop )
@@ -569,8 +604,9 @@ bool ps_parse_statement_list(ps_compiler *compiler, ps_ast_block *block, ps_ast_
569604 {
570605 // Let's go!
571606 ps_ast_node * statement = NULL;
572- ps_ast_node * statements [ 256 ];
607+ // Up to 256 statements for now
573608 size_t count = 0 ;
609+ ps_ast_node * statements [256 ];
574610 bool loop = true;
575611 do
576612 {
@@ -592,6 +628,7 @@ bool ps_parse_statement_list(ps_compiler *compiler, ps_ast_block *block, ps_ast_
592628 else
593629 RETURN_ERROR (PS_ERROR_UNEXPECTED_TOKEN )
594630 } while (loop );
631+ // Create statement list and copy statements into it
595632 * statement_list = ps_ast_create_statement_list (start_line , start_column , count );
596633 if (* statement_list == NULL )
597634 RETURN_ERROR (PS_ERROR_OUT_OF_MEMORY )
@@ -609,7 +646,7 @@ bool ps_parse_statement_list(ps_compiler *compiler, ps_ast_block *block, ps_ast_
609646bool ps_parse_statement_or_compound_statement (ps_compiler * compiler , ps_ast_block * block ,
610647 ps_ast_statement_list * statement_list )
611648{
612- PARSE_BEGIN ("STATEMENT_OR_COMPOUND_STATEMENT " , "" );
649+ PARSE_BEGIN ("STATEMENT " , "STATEMENT_OR_COMPOUND_STATEMENT " );
613650
614651 if (lexer -> current_token .type == PS_TOKEN_BEGIN )
615652 {
0 commit comments