Skip to content

Commit 6928a4f

Browse files
committed
AST WIP
1 parent d40d38f commit 6928a4f

2 files changed

Lines changed: 77 additions & 40 deletions

File tree

include/ps_parse_statement.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ extern "C"
1818
#endif
1919

2020
// clang-format off
21-
bool ps_parse_statement (ps_compiler *compiler, ps_ast_block *block, ps_ast_node *statement );
22-
bool ps_parse_compound_statement (ps_compiler *compiler, ps_ast_block *block, ps_ast_node *statement );
23-
bool ps_parse_assignment (ps_compiler *compiler, ps_ast_block *block, ps_ast_assignment *assignment , ps_symbol *variable );
24-
bool ps_parse_read_or_readln (ps_compiler *compiler, ps_ast_block *block, ps_ast_call *call , bool newline );
25-
bool ps_parse_write_or_writeln (ps_compiler *compiler, ps_ast_block *block, ps_ast_call *call , bool newline );
26-
bool ps_parse_assignment_or_procedure_call (ps_compiler *compiler, ps_ast_block *block, ps_ast_node *statement );
27-
bool ps_parse_if_then_else (ps_compiler *compiler, ps_ast_block *block );
28-
bool ps_parse_repeat_until (ps_compiler *compiler, ps_ast_block *block );
29-
bool ps_parse_while_do (ps_compiler *compiler, ps_ast_block *block );
30-
bool ps_parse_for_do (ps_compiler *compiler, ps_ast_block *block );
21+
bool ps_parse_statement (ps_compiler *compiler, ps_ast_block *block, ps_ast_node **statement );
22+
bool ps_parse_compound_statement (ps_compiler *compiler, ps_ast_block *block, ps_ast_statement_list **statement_list );
23+
bool ps_parse_assignment (ps_compiler *compiler, ps_ast_block *block, ps_ast_assignment **assignment , ps_symbol *variable );
24+
bool ps_parse_read_or_readln (ps_compiler *compiler, ps_ast_block *block, ps_ast_call **call , bool newline );
25+
bool ps_parse_write_or_writeln (ps_compiler *compiler, ps_ast_block *block, ps_ast_call **call , bool newline );
26+
bool ps_parse_assignment_or_procedure_call (ps_compiler *compiler, ps_ast_block *block, ps_ast_node **statement );
27+
bool ps_parse_if_then_else (ps_compiler *compiler, ps_ast_block *block, ps_ast_node **statement );
28+
bool ps_parse_repeat_until (ps_compiler *compiler, ps_ast_block *block, ps_ast_node **statement );
29+
bool ps_parse_while_do (ps_compiler *compiler, ps_ast_block *block, ps_ast_node **statement );
30+
bool ps_parse_for_do (ps_compiler *compiler, ps_ast_block *block, ps_ast_node **statement );
3131
bool ps_parse_statement_list (ps_compiler *compiler, ps_ast_block *block, ps_token_type stop );
3232
bool ps_parse_statement_or_compound_statement(ps_compiler *compiler, ps_ast_block *block );
3333
// clang-format on

src/ps_parse_statement.c

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
172178
bool 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+
*/
222250
bool 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
*/
247278
bool 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
*/
393427
bool 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
*/
428462
bool 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
*/
459493
bool 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
*/
492526
bool 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
*/
556591
bool 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_
609646
bool 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

Comments
 (0)