Skip to content

Commit 895bead

Browse files
committed
AST WIP
1 parent 68fe9fc commit 895bead

7 files changed

Lines changed: 79 additions & 52 deletions

File tree

include/ps_parse.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ extern "C"
2020
/* src/ps_parse.c */
2121
bool ps_parse_start(ps_compiler *compiler, ps_ast_block *block_program);
2222

23-
/* src/ps_parse_executable.c */
24-
bool ps_parse_procedure_or_function_declaration(ps_compiler *compiler, ps_symbol_kind kind);
25-
bool ps_parse_procedure_or_function_call(ps_compiler *compiler, ps_ast_block *block, ps_ast_node *expression,
26-
ps_symbol *executable);
27-
bool ps_parse_variable_reference(ps_compiler *compiler, ps_symbol **variable);
28-
2923
#define PARSE_BEGIN(__PARSE__, __PLUS__) \
3024
ps_lexer *lexer = ps_parser_get_lexer(compiler->parser); \
3125
static char *visit = __PARSE__; \

include/ps_parse_executable.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
This file is part of the PascalScript Pascal interpreter.
3+
SPDX-FileCopyrightText: 2026 Christophe "CHiPs" Petit <chips44@gmail.com>
4+
SPDX-License-Identifier: LGPL-3.0-or-later
5+
*/
6+
7+
#ifndef _PS_PARSE_EXECUTABLE_H
8+
#define _PS_PARSE_EXECUTABLE_H
9+
10+
#include <stdint.h>
11+
12+
#include "ps_compiler.h"
13+
#include "ps_lexer.h"
14+
15+
#ifdef __cplusplus
16+
extern "C"
17+
{
18+
#endif
19+
20+
bool ps_parse_procedure_or_function_declaration(ps_compiler *compiler, ps_symbol_kind kind);
21+
bool ps_parse_procedure_or_function_call(ps_compiler *compiler, ps_ast_block *block, ps_ast_node *expression,
22+
ps_symbol *executable);
23+
bool ps_parse_variable_reference(ps_compiler *compiler, ps_ast_block *block, ps_symbol **variable);
24+
25+
#ifdef __cplusplus
26+
}
27+
#endif
28+
29+
#endif /* _PS_PARSE_EXECUTABLE_H */

src/ps_executable.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ char *ps_executable_get_kind_name(ps_executable_kind kind)
6868
return "PROCEDURE";
6969
default:
7070
snprintf(name, 15, "???%d???", kind);
71+
return name;
7172
}
7273
}
7374

src/ps_parse_declaration.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "ps_executable.h"
1010
#include "ps_memory.h"
1111
#include "ps_parse.h"
12+
#include "ps_parse_executable.h"
1213
#include "ps_parse_expression.h"
1314
#include "ps_parse_statement.h"
1415
#include "ps_parse_type.h"

src/ps_parse_executable.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "ps_lexer.h"
1414
#include "ps_parse.h"
1515
#include "ps_parse_declaration.h"
16+
#include "ps_parse_executable.h"
1617
#include "ps_parse_expression.h"
1718
#include "ps_parse_type.h"
1819
#include "ps_procedures.h"
@@ -39,27 +40,28 @@
3940
*/
4041
bool ps_parse_variable_reference(ps_compiler *compiler, ps_ast_block *block, ps_symbol **variable)
4142
{
42-
PARSE_BEGIN("EXECUTABLE", "VARIABLE_REFERENCE");
43+
PARSE_BEGIN("EXECUTABLE", "VARIABLE_REFERENCE")
4344
(void)start_line;
4445
(void)start_column;
4546

4647
ps_identifier identifier;
4748
ps_symbol *symbol;
4849

49-
*variable = NULL;
50-
EXPECT_TOKEN(PS_TOKEN_IDENTIFIER);
50+
// Re-check
51+
EXPECT_TOKEN(PS_TOKEN_IDENTIFIER)
5152
COPY_IDENTIFIER(identifier)
53+
READ_NEXT_TOKEN
54+
55+
// Existing symbol?
5256
symbol = ps_compiler_find_symbol(compiler, block, identifier, false);
5357
if (symbol == NULL)
54-
{
5558
RETURN_ERROR(PS_ERROR_SYMBOL_NOT_FOUND);
56-
}
59+
60+
// Variable?
5761
if (symbol->kind != PS_SYMBOL_KIND_VARIABLE)
58-
{
59-
RETURN_ERROR(PS_ERROR_EXPECTED_VARIABLE);
60-
}
62+
RETURN_ERROR(PS_ERROR_EXPECTED_VARIABLE)
63+
6164
*variable = symbol;
62-
READ_NEXT_TOKEN
6365

6466
PARSE_END("OK")
6567
}
@@ -68,20 +70,21 @@ bool ps_parse_variable_reference(ps_compiler *compiler, ps_ast_block *block, ps_
6870
* Visit parameter definition:
6971
* [ 'VAR' ] IDENTIFIER [ ',' IDENTIFIER ]* ':' TYPE_REFERENCE
7072
*
71-
* Add the parameter(s) to the signature and to the current environment.
73+
* Add the parameter(s) to the signature
7274
* Up to 8 parameters at once.
7375
*/
7476
bool ps_parse_parameter_definition(ps_compiler *compiler, ps_ast_block *block, ps_formal_signature *signature)
7577
{
7678
PARSE_BEGIN("EXECUTABLE", "PARAMETER_DEFINITION");
79+
(void)start_line;
80+
(void)start_column;
7781

7882
ps_identifier names[8] = {0};
79-
int index = -1;
80-
ps_symbol __attribute__((aligned(4))) *type_reference = NULL;
81-
bool byref;
83+
int index = 0;
84+
ps_symbol *type_reference = NULL;
85+
bool byref = false;
8286

8387
// Default is "by value"
84-
byref = false;
8588
if (lexer->current_token.type == PS_TOKEN_VAR || lexer->current_token.type == PS_TOKEN_OUT)
8689
{
8790
byref = true;
@@ -93,10 +96,10 @@ bool ps_parse_parameter_definition(ps_compiler *compiler, ps_ast_block *block, p
9396
{
9497
// Parameter name
9598
EXPECT_TOKEN(PS_TOKEN_IDENTIFIER);
96-
index += 1;
9799
if (index == 8)
98100
RETURN_ERROR(PS_ERROR_TOO_MANY_VARIABLES);
99101
COPY_IDENTIFIER(names[index])
102+
index += 1;
100103
// Check that the parameter name does not already exist in the other parameters
101104
// e.g. procedure P(a, b, a: Integer);
102105
for (int i = 0; i < index; i++)

src/ps_parse_expression.c

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,32 +10,30 @@
1010
#include "ps_array.h"
1111
#include "ps_functions.h"
1212
#include "ps_parse.h"
13+
#include "ps_parse_executable.h"
1314
#include "ps_parse_expression.h"
1415
#include "ps_parser.h"
1516
#include "ps_procedures.h"
1617
#include "ps_string.h"
1718
#include "ps_system.h"
1819

19-
// #define MODE_EXEC 0
20-
// static int mode = MODE_EXEC;
21-
2220
/**
23-
* This is the entry point for visiting all expressions.
21+
* This is the entry point for parsing all expressions.
2422
*/
2523
bool ps_parse_expression(ps_compiler *compiler, ps_ast_block *block, ps_ast_node **expression)
2624
{
2725
return ps_parse_or_expression(compiler, block, expression);
2826
}
2927

3028
/**
31-
* Visit
29+
* Parse
3230
* or_expression = and_expression { ( 'OR' | 'XOR' ) and_expression }
3331
* Goal:
3432
* make A < 1 OR A > 10 OR A = 5 OR ... work without parenthesis
3533
* AST:
3634
* A => A
3735
* A or B => binary_op(or, A, B)
38-
* A or B xor C => binary_op(xor, binary(or, A, B), C)
36+
* A or B xor C => binary_op(xor, binary_op(or, A, B), C)
3937
*/
4038
bool ps_parse_or_expression(ps_compiler *compiler, ps_ast_block *block, ps_ast_node **expression)
4139
{
@@ -78,7 +76,7 @@ bool ps_parse_or_expression(ps_compiler *compiler, ps_ast_block *block, ps_ast_n
7876
}
7977

8078
/**
81-
* Visit and expression:
79+
* Parse and expression:
8280
* relational_expression { 'AND' relational_expression }
8381
* Goal:
8482
* make A < 1 AND A > 10 AND B = 5 AND ... work without parenthesis
@@ -129,7 +127,7 @@ bool ps_parse_and_expression(ps_compiler *compiler, ps_ast_block *block, ps_ast_
129127
}
130128

131129
/**
132-
* Visit relational expression:
130+
* Parse relational expression:
133131
* simple_expression '<' | '<=' | '>' | '>=' | '=' | '<>' simple_expression
134132
* AST:
135133
* A => A
@@ -172,7 +170,7 @@ bool ps_parse_relational_expression(ps_compiler *compiler, ps_ast_block *block,
172170
}
173171

174172
/**
175-
* Visit simple expression:
173+
* Parse simple expression:
176174
* term [ '+' | '-' term ]*
177175
* NB: 'OR' | 'XOR' are accounted by or_expression
178176
* AST:
@@ -224,7 +222,7 @@ bool ps_parse_simple_expression(ps_compiler *compiler, ps_ast_block *block, ps_a
224222
}
225223

226224
/**
227-
* Visit term:
225+
* Parse term:
228226
* factor [ '*' | '/' | 'DIV' | 'MOD' | 'AND' | 'SHL' | 'SHR' | 'AS' factor ]*
229227
*/
230228
bool ps_parse_term(ps_compiler *compiler, ps_ast_block *block, ps_ast_node **expression)
@@ -315,22 +313,24 @@ bool ps_parse_factor_identifier_array(ps_compiler *compiler, ps_ast_block *block
315313
}
316314

317315
/**
318-
* @brief Visit constant or variable reference or function call
316+
* @brief Parse constant or variable reference or function call
319317
* @details
320318
* Actual:
321319
* constant reference = identifier
320+
* variable reference = identifier
322321
* function call = identifier [ '(' [ expression [ ',' expression ]* ]')' ]
323322
* Next step:
324323
* vector access
325324
* variable reference = identifier [ '[' expression ']' ]
326325
* multi-dimensional arrays instead of vectors
327326
* variable reference = identifier [ '[' expression [ ',' expression ]* ']' ]
328327
*/
329-
bool ps_parse_factor_identifier(ps_compiler *compiler, ps_ast_block *block, const char *identifier,
330-
ps_ast_node **factor)
328+
bool ps_parse_factor_identifier(ps_compiler *compiler, ps_ast_block *block, ps_ast_node **factor)
331329
{
332330
PARSE_BEGIN("FACTOR", "IDENTIFIER");
333331

332+
ps_identifier identifier;
333+
COPY_IDENTIFIER(identifier)
334334
ps_symbol *symbol = ps_compiler_find_symbol(compiler, block, identifier, false);
335335
if (symbol == NULL)
336336
RETURN_ERROR(PS_ERROR_SYMBOL_NOT_FOUND);
@@ -344,7 +344,7 @@ bool ps_parse_factor_identifier(ps_compiler *compiler, ps_ast_block *block, cons
344344
ps_symbol_get_kind_name(symbol->kind),
345345
ps_type_definition_get_name(symbol->value->type->value->data.t));
346346
}
347-
if (ps_value_is_array(symbol->value))
347+
isymbol(ps_value_is_array(symbol->value))
348348
{
349349
RETURN_ERROR(PS_ERROR_NOT_IMPLEMENTED)
350350
// if (!ps_parse_factor_identifier_array(compiler, block, symbol, factor))
@@ -372,7 +372,7 @@ bool ps_parse_factor_identifier(ps_compiler *compiler, ps_ast_block *block, cons
372372
}
373373

374374
/**
375-
* @brief Visit factor
375+
* @brief Parse factor
376376
* @details
377377
* factor = '(' , expression , ')'
378378
* | variable_reference
@@ -388,7 +388,6 @@ bool ps_parse_factor(ps_compiler *compiler, ps_ast_block *block, ps_ast_node **e
388388
PARSE_BEGIN("FACTOR", "");
389389

390390
ps_value factor_value = {.type = &ps_system_none, .data.v = NULL};
391-
ps_identifier identifier;
392391
ps_token_type unary_operator;
393392

394393
switch (lexer->current_token.type)
@@ -403,8 +402,7 @@ bool ps_parse_factor(ps_compiler *compiler, ps_ast_block *block, ps_ast_node **e
403402
break;
404403
// *** Identifier: variable, constant, function ***
405404
case PS_TOKEN_IDENTIFIER:
406-
COPY_IDENTIFIER(identifier)
407-
if (!ps_parse_factor_identifier(compiler, block, identifier, expression))
405+
if (!ps_parse_factor_identifier(compiler, block, expression))
408406
TRACE_ERROR("IDENTIFIER")
409407
break;
410408
// ***Literal values ***
@@ -457,12 +455,12 @@ bool ps_parse_factor(ps_compiler *compiler, ps_ast_block *block, ps_ast_node **e
457455
case PS_TOKEN_NOT:
458456
unary_operator = lexer->current_token.type;
459457
READ_NEXT_TOKEN
460-
ps_ast_node *operand = NULL;
461-
if (!ps_parse_factor(compiler, block, &operand))
458+
ps_ast_node **operand = NULL;
459+
if (!ps_parse_factor(compiler, block, operand))
462460
TRACE_ERROR("UNARY_MINUS_NOT");
463-
*expression = ps_ast_create_unary_operation(start_line, start_column,
464-
ps_operator_unary_from_token(lexer->current_token.type), &operand);
465-
break;
461+
ps_operator_unary unary_operator = ps_operator_unary_from_token(lexer->current_token.type);
462+
*expression = ps_ast_create_unary_operation(start_line, start_column, unary_operator, operand);
463+
PARSE_END("OK UNARY")
466464
default:
467465
RETURN_ERROR(PS_ERROR_UNEXPECTED_TOKEN)
468466
}
@@ -562,7 +560,7 @@ bool ps_parse_function_call_power(ps_compiler *compiler, ps_ast_block *block, ps
562560
}
563561

564562
/**
565-
* Visit system function call:
563+
* Parse system function call:
566564
* identifier [ '(' , expression | variable_reference [ ',' , expression | variable_reference ]* ')' ]
567565
*/
568566
bool ps_parse_function_call_system(ps_compiler *compiler, ps_ast_block *block, ps_ast_call **call,
@@ -574,7 +572,6 @@ bool ps_parse_function_call_system(ps_compiler *compiler, ps_ast_block *block, p
574572
ps_ast_node *args[2] = {NULL, NULL};
575573
ps_symbol *symbol = NULL;
576574

577-
// Handle specific function types with dedicated handlers
578575
if (function == &ps_system_function_random)
579576
{
580577
ps_ast_node *expression = NULL;
@@ -601,6 +598,7 @@ bool ps_parse_function_call_system(ps_compiler *compiler, ps_ast_block *block, p
601598
n_args = -1;
602599
if (!ps_parse_function_call_low_high(compiler, block, &symbol))
603600
TRACE_ERROR("LOW_HIGH")
601+
args[0] = symbol;
604602
}
605603
else if (function == &ps_system_function_power)
606604
{
@@ -650,7 +648,7 @@ bool ps_parse_function_call_system(ps_compiler *compiler, ps_ast_block *block, p
650648
}
651649

652650
/**
653-
* Visit system or user function call:
651+
* Parse system or user function call:
654652
* identifier [ '(' , expression | variable_reference [ ',' , expression | variable_reference ]* ')' ]
655653
*/
656654
bool ps_parse_function_call(ps_compiler *compiler, ps_ast_block *block, ps_ast_node **expression, ps_symbol *function)
@@ -676,7 +674,7 @@ bool ps_parse_function_call(ps_compiler *compiler, ps_ast_block *block, ps_ast_n
676674
}
677675

678676
/**
679-
* Visit constant expression:
677+
* Parse constant expression:
680678
* [ '-' ] INTEGER_VALUE
681679
* | UNSIGNED_VALUE
682680
* | CHAR_VALUE

src/ps_parse_statement.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "ps_ast.h"
1010
#include "ps_functions.h"
1111
#include "ps_parse.h"
12+
#include "ps_parse_executable.h"
1213
#include "ps_parse_expression.h"
1314
#include "ps_procedures.h"
1415
#include "ps_symbol.h"
@@ -385,7 +386,6 @@ bool ps_parse_assignment_or_procedure_call(ps_compiler *compiler, ps_ast_block *
385386
PARSE_BEGIN("STATEMENT", "ASSIGNMENT OR PROCEDURE CALL");
386387
ps_identifier identifier;
387388
ps_symbol *symbol;
388-
ps_identifier result_identifier = "RESULT";
389389
ps_ast_assignment **assignement = NULL;
390390

391391
COPY_IDENTIFIER(identifier)
@@ -418,9 +418,10 @@ bool ps_parse_assignment_or_procedure_call(ps_compiler *compiler, ps_ast_block *
418418
statement = (ps_ast_node **)assignement;
419419
break;
420420
case PS_SYMBOL_KIND_PROCEDURE:
421-
ps_ast_node **expression = NULL;
422-
if (!ps_parse_procedure_or_function_call(compiler, block, expression, symbol))
421+
ps_ast_call **procedure = NULL;
422+
if (!ps_parse_procedure_or_function_call(compiler, block, procedure, symbol))
423423
TRACE_ERROR("PROCEDURE_CALL")
424+
*statement = (ps_ast_node *)(*procedure);
424425
break;
425426
case PS_SYMBOL_KIND_FUNCTION:
426427
// Assignment to function name => assignment to Result
@@ -429,7 +430,7 @@ bool ps_parse_assignment_or_procedure_call(ps_compiler *compiler, ps_ast_block *
429430
ps_compiler_set_message(compiler, "Cannot assign to %s from %s", identifier, block->name);
430431
RETURN_ERROR(PS_ERROR_UNEXPECTED_TOKEN);
431432
}
432-
symbol = ps_compiler_find_symbol(compiler, block, result_identifier, true);
433+
symbol = ps_compiler_find_symbol(compiler, block, "RESULT", true);
433434
if (symbol == NULL)
434435
RETURN_ERROR(PS_ERROR_SYMBOL_NOT_FOUND)
435436
if (!ps_parse_assignment(compiler, block, assignement, symbol))

0 commit comments

Comments
 (0)