Skip to content

Commit 5fa842c

Browse files
committed
AST WIP
1 parent fb26554 commit 5fa842c

13 files changed

Lines changed: 360 additions & 197 deletions

include/ps_ast.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,13 +83,13 @@ extern "C"
8383
/** @details Units may be separated as they are special cases with interface and implementation */
8484
typedef struct s_ps_ast_block
8585
{
86-
PS_AST_NODE_COMMON ps_identifier name; /** @brief Every block has a name */
86+
PS_AST_NODE_COMMON ps_identifier name; /** @brief Every block has a name */
8787
size_t n_vars; /** @brief Number of variables to allocate at startup */
8888
ps_symbol_table *symbols; /** @brief Constants, types, variables, procedures and functions */
8989
size_t n_executables; /** @brief exactly 1 for procedure and function, 0 or more otherwise */
9090
ps_ast_node **executables; /** @brief declarations of procedures and functions */
91-
ps_ast_statement_list *statement_list; /** @brief Statements in this block */
92-
ps_formal_signature *signature; /** @brief Only for procedures and functions, empty otherwise */
91+
ps_ast_statement_list *statement_list; /** @brief Statements for this block */
92+
ps_formal_signature *signature; /** @brief Only for procedures and functions, NULL otherwise */
9393
ps_symbol *result_type; /** @brief Only for functions, NULL otherwise */
9494
} ps_ast_block;
9595

@@ -212,12 +212,17 @@ extern "C"
212212
#define PS_AST_NODE_VARIABLE_ARRAY_SIZE sizeof(ps_ast_variable_array)
213213
// clang-format on
214214

215+
/** @brief Check if an AST node belongs to a specific group */
216+
bool ps_ast_node_check_group(const ps_ast_node *node, ps_ast_node_group expected_group);
217+
/** @brief Check if an AST node has a specific kind */
218+
bool ps_ast_node_check_kind(const ps_ast_node *node, ps_ast_node_kind expected_kind);
219+
215220
/** @brief Create a new AST node of the given group & kind */
216221
ps_ast_node *ps_ast_create_node(ps_ast_node_group group, ps_ast_node_kind kind, uint16_t line, uint16_t column,
217222
size_t size);
218223

219224
// clang-format off
220-
ps_ast_block *ps_ast_create_block (uint16_t line, uint16_t column, ps_ast_node_kind kind, char *name );
225+
ps_ast_block *ps_ast_create_block (uint16_t line, uint16_t column, ps_ast_node_kind kind, const char *name );
221226
ps_ast_statement_list *ps_ast_create_statement_list (uint16_t line, uint16_t column, size_t count );
222227
ps_ast_assignment *ps_ast_create_assignment (uint16_t line, uint16_t column, ps_ast_node *lvalue,ps_ast_node *expression );
223228
ps_ast_if *ps_ast_create_if (uint16_t line, uint16_t column, ps_ast_node *condition, ps_ast_statement_list *then_branch, ps_ast_statement_list *else_branch );

include/ps_ast_execute.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,6 @@ extern "C"
1414
{
1515
#endif
1616

17-
/** @brief Check if an AST node belongs to a specific group */
18-
bool ps_ast_check_group(const ps_ast_node *node, ps_ast_node_group expected_group);
19-
/** @brief Check if an AST node has a specific kind */
20-
bool ps_ast_check_kind(const ps_ast_node *node, ps_ast_node_kind expected_kind);
2117
/** @brief Run a Pascal program */
2218
bool ps_ast_run_program(ps_interpreter *interpreter, ps_ast_block *program);
2319
/** @brief Run a Pascal procedure */

include/ps_ast_test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ extern "C"
1313
#endif
1414

1515
bool ps_ast_test_minimal();
16+
bool ps_ast_test_assignment();
1617
bool ps_ast_test_hello();
1718

1819
#ifdef __cplusplus
File renamed without changes.

src/pascalscript.c

Lines changed: 73 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,21 @@
66

77
#include <stdio.h>
88

9+
#include "ps_ast_debug.h"
910
#include "ps_ast_test.h"
1011

1112
int main(int argc, char *argv[])
1213
{
1314
(void)argc; // silence unused variable warning
1415
(void)argv; // silence unused variable warning
1516

16-
ps_ast_test_minimal();
17+
// ps_ast_debug_line("****************************************************************");
18+
// ps_ast_test_minimal();
19+
ps_ast_debug_line("****************************************************************");
20+
ps_ast_test_assignment();
21+
ps_ast_debug_line("****************************************************************");
22+
// ps_ast_test_hello();
23+
// ps_ast_debug_line("****************************************************************");
1724

1825
return 0;
1926
}
@@ -163,8 +170,8 @@ int main(int argc, char *argv[])
163170
// if (!ps_interpreter_load_file(interpreter, source_file))
164171
// {
165172
// fprintf(stderr, "File %s not loaded!\n", source_file);
166-
// fprintf(stderr, "Error %d %s\n", interpreter->error, ps_error_get_message(interpreter->error)); // NOSONAR false positive
167-
// return false;
173+
// fprintf(stderr, "Error %d %s\n", interpreter->error, ps_error_get_message(interpreter->error)); // NOSONAR
174+
// false positive return false;
168175
// }
169176
// if (verbose)
170177
// fprintf(stderr, "Loaded %s!\n", source_file);
@@ -194,69 +201,69 @@ int main(int argc, char *argv[])
194201

195202
// int main(int argc, char *argv[])
196203
// {
197-
// // Paths & file names
198-
// char *current_path = NULL;
199-
// char *program_file = NULL;
200-
// char source_file[256] = {0};
201-
202-
// int arg = get_options(argc, argv);
203-
204-
// // Force when debugging as I didn't find how to pass command line options
205-
// // trace = true;
206-
// // debug = true;
207-
208-
// current_path = getcwd(NULL, 0);
209-
// if (arg + 1 < argc)
210-
// {
211-
// program_file = argv[argc - 1];
212-
// snprintf(source_file, sizeof(source_file) - 1, "%s/%s", current_path, program_file);
213-
// }
214-
// else
215-
// {
216-
// program_file = DEBUGGER_SOURCE;
217-
// if (program_file != NULL)
218-
// snprintf(source_file, sizeof(source_file) - 1, "%s/../%s", current_path, program_file);
219-
// else
220-
// source_file[0] = '\0';
221-
// }
222-
// if (strlen(source_file) == 0)
223-
// {
224-
// fprintf(stderr, "No file to run!\n");
225-
// usage(argv[0]);
226-
// return EXIT_FAILURE;
227-
// }
228-
229-
// /* Display banner, intepreter runtime options, current path & source file, ... */
230-
// if (verbose)
231-
// {
232-
// banner(stdout);
233-
// fprintf(stdout, "Runtime options:\n");
234-
// fprintf(stdout, " - boolean evaluation: $B%c (*FUTURE*)\n", bool_eval ? '+' : '-');
235-
// fprintf(stdout, " - IO check : $I%c (*FUTURE*)\n", io_check ? '+' : '-');
236-
// fprintf(stdout, " - Range check : $R%c\n", range_check ? '+' : '-');
237-
// fprintf(stdout, "Current working directory: %s\n", current_path);
238-
// fprintf(stdout, "Source file: %s\n", source_file);
239-
// }
240-
// free(current_path);
241-
// current_path = NULL;
242-
243-
// /* Initialize interpreter */
244-
// interpreter = ps_interpreter_alloc(range_check, bool_eval, io_check);
245-
// if (interpreter == NULL)
246-
// {
247-
// fprintf(stderr, "Could not initialize interpreter!\n");
248-
// return EXIT_FAILURE;
249-
// }
250-
251-
// bool ok = run(source_file);
252-
253-
// /* Terminate interpreter */
254-
// interpreter = ps_interpreter_free(interpreter);
255-
256-
// if (memory)
257-
// ps_memory_debug(stderr);
258-
259-
// return ok ? EXIT_SUCCESS : EXIT_FAILURE;
204+
// // Paths & file names
205+
// char *current_path = NULL;
206+
// char *program_file = NULL;
207+
// char source_file[256] = {0};
208+
209+
// int arg = get_options(argc, argv);
210+
211+
// // Force when debugging as I didn't find how to pass command line options
212+
// // trace = true;
213+
// // debug = true;
214+
215+
// current_path = getcwd(NULL, 0);
216+
// if (arg + 1 < argc)
217+
// {
218+
// program_file = argv[argc - 1];
219+
// snprintf(source_file, sizeof(source_file) - 1, "%s/%s", current_path, program_file);
220+
// }
221+
// else
222+
// {
223+
// program_file = DEBUGGER_SOURCE;
224+
// if (program_file != NULL)
225+
// snprintf(source_file, sizeof(source_file) - 1, "%s/../%s", current_path, program_file);
226+
// else
227+
// source_file[0] = '\0';
228+
// }
229+
// if (strlen(source_file) == 0)
230+
// {
231+
// fprintf(stderr, "No file to run!\n");
232+
// usage(argv[0]);
233+
// return EXIT_FAILURE;
234+
// }
235+
236+
// /* Display banner, intepreter runtime options, current path & source file, ... */
237+
// if (verbose)
238+
// {
239+
// banner(stdout);
240+
// fprintf(stdout, "Runtime options:\n");
241+
// fprintf(stdout, " - boolean evaluation: $B%c (*FUTURE*)\n", bool_eval ? '+' : '-');
242+
// fprintf(stdout, " - IO check : $I%c (*FUTURE*)\n", io_check ? '+' : '-');
243+
// fprintf(stdout, " - Range check : $R%c\n", range_check ? '+' : '-');
244+
// fprintf(stdout, "Current working directory: %s\n", current_path);
245+
// fprintf(stdout, "Source file: %s\n", source_file);
246+
// }
247+
// free(current_path);
248+
// current_path = NULL;
249+
250+
// /* Initialize interpreter */
251+
// interpreter = ps_interpreter_alloc(range_check, bool_eval, io_check);
252+
// if (interpreter == NULL)
253+
// {
254+
// fprintf(stderr, "Could not initialize interpreter!\n");
255+
// return EXIT_FAILURE;
256+
// }
257+
258+
// bool ok = run(source_file);
259+
260+
// /* Terminate interpreter */
261+
// interpreter = ps_interpreter_free(interpreter);
262+
263+
// if (memory)
264+
// ps_memory_debug(stderr);
265+
266+
// return ok ? EXIT_SUCCESS : EXIT_FAILURE;
260267
// }
261268

262269
/* EOF */

src/ps_ast.c

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,28 @@
1818
// ps_ast_node
1919
// =============================================================================
2020

21+
bool ps_ast_node_check_group(const ps_ast_node *node, ps_ast_node_group expected_group)
22+
{
23+
if (node->group != expected_group)
24+
{
25+
ps_ast_debug_line("Error: expected AST node group %s but got %s\n", ps_ast_node_get_group_name(expected_group),
26+
ps_ast_node_get_group_name(node->group));
27+
return false;
28+
}
29+
return true;
30+
}
31+
32+
bool ps_ast_node_check_kind(const ps_ast_node *node, ps_ast_node_kind expected_kind)
33+
{
34+
if (node->kind != expected_kind)
35+
{
36+
ps_ast_debug_line("Error: expected AST node kind %s but got %s\n", ps_ast_node_get_kind_name(expected_kind),
37+
ps_ast_node_get_kind_name(node->kind));
38+
return false;
39+
}
40+
return true;
41+
}
42+
2143
ps_ast_node *ps_ast_create_node(ps_ast_node_group group, ps_ast_node_kind kind, uint16_t line, uint16_t column,
2244
size_t size)
2345
{
@@ -86,7 +108,7 @@ ps_ast_node *ps_ast_free_node(ps_ast_node *node)
86108
// PS_AST_BLOCK
87109
// =============================================================================
88110

89-
ps_ast_block *ps_ast_create_block(uint16_t line, uint16_t column, ps_ast_node_kind kind, char *name)
111+
ps_ast_block *ps_ast_create_block(uint16_t line, uint16_t column, ps_ast_node_kind kind, const char *name)
90112
{
91113
assert(kind == PS_AST_PROGRAM || kind == PS_AST_PROCEDURE || kind == PS_AST_FUNCTION || kind == PS_AST_UNIT);
92114
ps_ast_block *block = (ps_ast_block *)ps_ast_create_node(PS_AST_BLOCK, kind, line, column, sizeof(ps_ast_block));
@@ -162,8 +184,8 @@ ps_ast_node *ps_ast_free_statement_list(ps_ast_statement_list *statement_list)
162184
ps_ast_assignment *ps_ast_create_assignment(uint16_t line, uint16_t column, ps_ast_node *lvalue,
163185
ps_ast_node *expression)
164186
{
165-
assert(lvalue != NULL && ps_ast_check_group(lvalue, PS_AST_LVALUE));
166-
assert(expression != NULL && ps_ast_check_group(expression, PS_AST_EXPRESSION));
187+
assert(lvalue != NULL && ps_ast_node_check_group(lvalue, PS_AST_LVALUE));
188+
assert(expression != NULL && ps_ast_node_check_group(expression, PS_AST_EXPRESSION));
167189
ps_ast_assignment *assignment = (ps_ast_assignment *)ps_ast_create_node(PS_AST_STATEMENT, PS_AST_ASSIGNMENT, line,
168190
column, sizeof(ps_ast_assignment));
169191
if (assignment == NULL)
@@ -190,9 +212,9 @@ ps_ast_node *ps_ast_free_assignment(ps_ast_assignment *assignment)
190212
ps_ast_if *ps_ast_create_if(uint16_t line, uint16_t column, ps_ast_node *condition, ps_ast_statement_list *then_branch,
191213
ps_ast_statement_list *else_branch)
192214
{
193-
assert(condition != NULL && ps_ast_check_group(condition, PS_AST_EXPRESSION));
194-
assert(then_branch != NULL && ps_ast_check_group(then_branch, PS_AST_STATEMENT));
195-
assert(else_branch == NULL || ps_ast_check_group(else_branch, PS_AST_STATEMENT));
215+
assert(condition != NULL && ps_ast_node_check_group(condition, PS_AST_EXPRESSION));
216+
assert(then_branch != NULL && ps_ast_node_check_group((ps_ast_node *)then_branch, PS_AST_STATEMENT));
217+
assert(else_branch == NULL || ps_ast_node_check_group((ps_ast_node *)else_branch, PS_AST_STATEMENT));
196218
ps_ast_if *if_statement =
197219
(ps_ast_if *)ps_ast_create_node(PS_AST_STATEMENT, PS_AST_IF, line, column, sizeof(ps_ast_if));
198220
if (if_statement == NULL)
@@ -220,8 +242,8 @@ ps_ast_node *ps_ast_free_if(ps_ast_if *if_statement)
220242

221243
ps_ast_while *ps_ast_create_while(uint16_t line, uint16_t column, ps_ast_node *condition, ps_ast_statement_list *body)
222244
{
223-
assert(condition != NULL && ps_ast_check_group(condition, PS_AST_EXPRESSION));
224-
assert(body != NULL && ps_ast_check_group(body, PS_AST_STATEMENT));
245+
assert(condition != NULL && ps_ast_node_check_group(condition, PS_AST_EXPRESSION));
246+
assert(body != NULL && ps_ast_node_check_group((ps_ast_node *)body, PS_AST_STATEMENT));
225247
ps_ast_while *while_statement =
226248
(ps_ast_while *)ps_ast_create_node(PS_AST_STATEMENT, PS_AST_WHILE, line, column, sizeof(ps_ast_while));
227249
if (while_statement == NULL)
@@ -247,8 +269,8 @@ ps_ast_node *ps_ast_free_while(ps_ast_while *while_statement)
247269

248270
ps_ast_repeat *ps_ast_create_repeat(uint16_t line, uint16_t column, ps_ast_statement_list *body, ps_ast_node *condition)
249271
{
250-
assert(body != NULL && ps_ast_check_group(body, PS_AST_STATEMENT));
251-
assert(condition != NULL && ps_ast_check_group(condition, PS_AST_EXPRESSION));
272+
assert(body != NULL && ps_ast_node_check_group((ps_ast_node *)body, PS_AST_STATEMENT));
273+
assert(condition != NULL && ps_ast_node_check_group(condition, PS_AST_EXPRESSION));
252274
ps_ast_repeat *repeat_statement =
253275
(ps_ast_repeat *)ps_ast_create_node(PS_AST_STATEMENT, PS_AST_REPEAT, line, column, sizeof(ps_ast_repeat));
254276
if (repeat_statement == NULL)
@@ -276,10 +298,10 @@ ps_ast_for *ps_ast_create_for(uint16_t line, uint16_t column, ps_ast_variable_si
276298
ps_ast_node *end, int step, ps_ast_statement_list *body)
277299
{
278300
assert(variable != NULL);
279-
assert(ps_ast_check_kind(variable, PS_AST_LVALUE_SIMPLE));
280-
assert(start != NULL && ps_ast_check_group(start, PS_AST_EXPRESSION));
281-
assert(end != NULL && ps_ast_check_group(end, PS_AST_EXPRESSION));
282-
assert(body != NULL && ps_ast_check_group(body, PS_AST_STATEMENT));
301+
assert(ps_ast_node_check_kind((ps_ast_node *)variable, PS_AST_LVALUE_SIMPLE));
302+
assert(start != NULL && ps_ast_node_check_group((ps_ast_node *)start, PS_AST_EXPRESSION));
303+
assert(end != NULL && ps_ast_node_check_group((ps_ast_node *)end, PS_AST_EXPRESSION));
304+
assert(body != NULL && ps_ast_node_check_group((ps_ast_node *)body, PS_AST_STATEMENT));
283305
assert(step == 1 || step == -1);
284306
ps_ast_for *for_statement =
285307
(ps_ast_for *)ps_ast_create_node(PS_AST_STATEMENT, PS_AST_FOR, line, column, sizeof(ps_ast_for));
@@ -370,7 +392,7 @@ ps_ast_unary_operation *ps_ast_create_unary_operation(uint16_t line, uint16_t co
370392
ps_ast_node *operand)
371393
{
372394
assert(operator == PS_OP_NEG || operator == PS_OP_NOT);
373-
assert(operand != NULL && ps_ast_check_group(operand, PS_AST_EXPRESSION));
395+
assert(operand != NULL && ps_ast_node_check_group(operand, PS_AST_EXPRESSION));
374396
ps_ast_unary_operation *unary_operation = (ps_ast_unary_operation *)ps_ast_create_node(
375397
PS_AST_EXPRESSION, PS_AST_UNARY_OPERATION, line, column, sizeof(ps_ast_unary_operation));
376398
if (unary_operation == NULL)
@@ -399,8 +421,8 @@ ps_ast_binary_operation *ps_ast_create_binary_operation(uint16_t line, uint16_t
399421
operator == PS_OP_AND || operator == PS_OP_SHL || operator == PS_OP_SHR || operator == PS_OP_EQ ||
400422
operator == PS_OP_GE || operator == PS_OP_GT || operator == PS_OP_LE || operator == PS_OP_LT ||
401423
operator == PS_OP_NE);
402-
assert(left != NULL && ps_ast_check_group(left, PS_AST_EXPRESSION));
403-
assert(right != NULL && ps_ast_check_group(right, PS_AST_EXPRESSION));
424+
assert(left != NULL && ps_ast_node_check_group((ps_ast_node *)left, PS_AST_EXPRESSION));
425+
assert(right != NULL && ps_ast_node_check_group((ps_ast_node *)right, PS_AST_EXPRESSION));
404426
ps_ast_binary_operation *binary_operation = (ps_ast_binary_operation *)ps_ast_create_node(
405427
PS_AST_EXPRESSION, PS_AST_BINARY_OPERATION, line, column, sizeof(ps_ast_binary_operation));
406428
if (binary_operation == NULL)

0 commit comments

Comments
 (0)