Skip to content

Commit c7cb153

Browse files
committed
AST WIP
1 parent 643a9f2 commit c7cb153

9 files changed

Lines changed: 77 additions & 52 deletions

File tree

include/ps_ast.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ extern "C"
100100
ps_ast_statement_list *then_branch; /** @brief Statements to execute if condition is true, can be empty */
101101
ps_ast_statement_list *else_branch; /** @brief Statements to execute if condition is false, can be empty */
102102
} ps_ast_if;
103-
#define PS_AST_IF_SIZE sizeof(ps_ast_if)
103+
#define PS_AST_IF_SIZE sizeof(ps_ast_if)
104104

105105
/** @brief WHILE statement */
106106
typedef struct s_ps_ast_while
@@ -123,16 +123,16 @@ extern "C"
123123
typedef struct s_ps_ast_variable_simple
124124
{
125125
PS_AST_NODE_COMMON
126-
ps_symbol *variable; /** @brief Symbol being referenced */
126+
ps_symbol *variable; /** @brief Variable being referenced */
127127
} ps_ast_variable_simple;
128128

129129
/** @brief Lvalue: array value, like A[I], A[I, J, K], ... */
130130
typedef struct s_ps_ast_variable_array
131131
{
132132
PS_AST_NODE_COMMON
133-
ps_symbol *variable; /** @brief Array being referenced */
134-
size_t n_indexes; /** @brief Number of dimensions */
135-
ps_ast_node **indexes; /** @brief Values for each dimension */
133+
ps_symbol *variable; /** @brief Array being referenced */
134+
size_t n_indexes; /** @brief Number of dimensions */
135+
ps_ast_node **indexes; /** @brief Expressions for each dimension */
136136
} ps_ast_variable_array;
137137

138138
/** @brief FOR statement */

include/ps_config.h

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ extern "C"
2222
// #define PS_BITNESS 64
2323

2424
/*
25-
NB: 32 bits by default, as our far target is RP2040 and RP2350 which have either ARM M0+ or M33 cores
25+
NB: 32 bits by default, as our far target is RP2040 and RP2350 which have either 32bit ARM M0+ or M33 cores
2626
16 bits if someone tries to port PascalScript to an older architecture
2727
64 bits on actual computers
2828
cf. <https://en.wiktionary.org/wiki/bitness>
@@ -162,12 +162,8 @@ extern "C"
162162
*/
163163
#endif
164164

165-
#ifndef PS_STRING_REF_TYPE
166-
#define PS_STRING_REF_TYPE uint16_t
167-
#endif
168-
169-
#if !defined(PS_STRING_LEN_TYPE) || !defined(PS_STRING_MAX_LEN) || !defined(PS_STRING_REF_TYPE)
170-
#error PS_STRING_LEN_TYPE / PS_STRING_MAX_LEN / PS_STRING_REF_TYPE must be defined.
165+
#if !defined(PS_STRING_LEN_TYPE) || !defined(PS_STRING_MAX_LEN)
166+
#error PS_STRING_LEN_TYPE and PS_STRING_MAX_LEN must be defined.
171167
#endif
172168

173169
#ifndef PS_IDENTIFIER_LEN
@@ -176,6 +172,24 @@ extern "C"
176172

177173
#define PS_IDENTIFIER_SIZE ((size_t)(PS_IDENTIFIER_LEN + 1u))
178174

175+
#if PS_BITNESS == 16
176+
#define PS_HANDLE uint16_t
177+
#define PS_HANDLE_FMT_10 PRIu16
178+
#define PS_HANDLE_FMT_16 PRIx16
179+
#endif
180+
181+
#if PS_BITNESS == 32
182+
#define PS_HANDLE uint32_t
183+
#define PS_HANDLE_FMT_10 PRIu32
184+
#define PS_HANDLE_FMT_16 PRIx32
185+
#endif
186+
187+
#if PS_BITNESS == 64
188+
#define PS_HANDLE uint64_t
189+
#define PS_HANDLE_FMT_10 PRIu64
190+
#define PS_HANDLE_FMT_16 PRIx64
191+
#endif
192+
179193
typedef char ps_identifier[PS_IDENTIFIER_SIZE];
180194

181195
void ps_config_report(FILE *output);

include/ps_system_types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ extern "C"
4646

4747
typedef uint32_t ps_set[8]; /** @brief Set of 256 bits */
4848

49-
/** @brief */
49+
typedef PS_HANDLE ps_handle; /** @brief Handle: variable index in stack */
50+
51+
/** @brief pointer *FUTURE* */
5052
typedef void *ps_pointer;
5153

5254
// clang-format off

include/ps_value_data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ extern "C"
2626
/** @brief Value union */
2727
typedef union u_ps_value_data {
2828
// clang-format off
29+
ps_handle h; /** @brief "h" is for "_h_andle" */
2930
ps_real r; /** @brief "r" is for "_r_eal" */
3031
ps_integer i; /** @brief "i" is for "_i_nteger" */
3132
ps_unsigned u; /** @brief "u" is for "_u_nsigned" */

src/ps_lexer.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,6 @@ char *ps_lexer_get_debug_value(ps_lexer *lexer)
593593
{
594594
static char value[128] = {0};
595595
static char string[96] = {0};
596-
size_t len;
597596

598597
switch (lexer->current_token.type)
599598
{
@@ -617,17 +616,9 @@ char *ps_lexer_get_debug_value(ps_lexer *lexer)
617616
break;
618617
case PS_TOKEN_STRING_VALUE:
619618
// s t r l c p y(string, lexer->current_token.value.s, sizeof(string));
620-
len = strlen(lexer->current_token.value.s);
621-
if (len < sizeof(string))
622-
{
623-
snprintf(value, sizeof(value) - 1, "STRING \"%s\"", lexer->current_token.value.s);
624-
}
625-
else
626-
{
627-
strncpy(string, lexer->current_token.value.s, sizeof(string) - 1);
628-
string[sizeof(string) - 1] = '\0';
629-
snprintf(value, sizeof(value) - 1, "STRING \"%s\"", string);
630-
}
619+
strncpy(string, lexer->current_token.value.s, sizeof(string) - 1);
620+
string[sizeof(string) - 1] = '\0';
621+
snprintf(value, sizeof(value) - 1, "STRING \"%s\"", string);
631622
break;
632623
case PS_TOKEN_IDENTIFIER:
633624
snprintf(value, sizeof(value) - 1, "IDENTIFIER \"%s\"", lexer->current_token.value.identifier);

src/ps_parse_executable.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "ps_parse_declaration.h"
1616
#include "ps_parse_executable.h"
1717
#include "ps_parse_expression.h"
18+
#include "ps_parse_statement.h"
1819
#include "ps_parse_type.h"
1920
#include "ps_procedures.h"
2021
#include "ps_signature.h"
@@ -459,20 +460,25 @@ bool ps_parse_procedure_or_function_declaration(ps_compiler *compiler, ps_ast_bl
459460
}
460461

461462
bool ps_parse_procedure_or_function_call_user(ps_compiler *compiler, ps_ast_block *block, ps_ast_call **call,
462-
ps_symbol *executable, ps_value *result_value)
463+
ps_symbol *executable)
463464
{
464465
PARSE_BEGIN("PROCEDURE_OR_FUNCTION_CALL", "")
466+
(void)start_line;
467+
(void)start_column;
465468

466469
uint16_t line = 0;
467470
uint16_t column = 0;
468-
bool has_environment = false;
469471
ps_symbol *result_symbol = NULL;
470472
ps_identifier result_identifier = "RESULT";
473+
ps_value *result_value = NULL;
474+
475+
if (executable->kind != PS_SYMBOL_KIND_PROCEDURE && executable->kind != PS_SYMBOL_KIND_FUNCTION)
476+
RETURN_ERROR(PS_ERROR_UNEXPECTED_TOKEN)
471477

472478
// Enter environment for procedure or function
473-
has_environment = ps_compiler_enter_environment(compiler, executable->name);
474-
if (!has_environment)
475-
TRACE_ERROR("ENTER_ENVIRONMENT")
479+
// has_environment = ps_compiler_enter_environment(compiler, executable->name);
480+
// if (!has_environment)
481+
// TRACE_ERROR("ENTER_ENVIRONMENT")
476482
// Parse actual parameters
477483
if (lexer->current_token.type == PS_TOKEN_LEFT_PARENTHESIS)
478484
{
@@ -502,16 +508,14 @@ bool ps_parse_procedure_or_function_call_user(ps_compiler *compiler, ps_ast_bloc
502508
else if (executable->kind == PS_SYMBOL_KIND_FUNCTION)
503509
{
504510
// Function have a return value
505-
result_value->type = executable->value->data.x->block->signature->result_type;
506-
result_value->data.v = NULL;
507-
result_value->allocated = false;
511+
result_value =
512+
ps_value_alloc(executable->value->data.x->block->signature->result_type, (ps_value_data){.h = 0});
513+
if (result_value == NULL)
514+
GOTO_CLEANUP(PS_ERROR_OUT_OF_MEMORY)
508515
result_symbol = ps_symbol_alloc(PS_SYMBOL_KIND_VARIABLE, result_identifier, result_value);
509516
if (result_symbol == NULL)
510-
{
511-
compiler->error = PS_ERROR_OUT_OF_MEMORY;
512-
goto cleanup;
513-
}
514-
if (!ps_environment_add_symbol(ps_compiler_get_environment(compiler), result_symbol))
517+
GOTO_CLEANUP(PS_ERROR_OUT_OF_MEMORY)
518+
if (!ps_compiler_add_symbol(compiler, block, result_symbol))
515519
{
516520
ps_symbol_free(result_symbol);
517521
compiler->error = PS_ERROR_OUT_OF_MEMORY;
@@ -520,6 +524,9 @@ bool ps_parse_procedure_or_function_call_user(ps_compiler *compiler, ps_ast_bloc
520524
}
521525

522526
// TODO build AST node for CALL
527+
*call = ps_ast_create_call(line, column,
528+
executable->kind == PS_SYMBOL_KIND_PROCEDURE ? PS_AST_PROCEDURE : PS_AST_FUNCTION,
529+
executable, 0, NULL, NULL, NULL);
523530

524531
cleanup:
525532
if (compiler->error != PS_ERROR_NONE)
@@ -537,24 +544,26 @@ bool ps_parse_procedure_or_function_call(ps_compiler *compiler, ps_ast_block *bl
537544
ps_symbol *executable)
538545
{
539546
PARSE_BEGIN("PROCEDURE_OR_FUNCTION_CALL", "")
547+
(void)start_line;
548+
(void)start_column;
540549

541550
if (executable == &ps_system_procedure_write || executable == &ps_system_procedure_writeln)
542551
{
543552
// Write or WriteLn
544-
if (!ps_parse_write_or_writeln(compiler, block, executable == &ps_system_procedure_writeln))
553+
if (!ps_parse_write_or_writeln(compiler, block, call, executable == &ps_system_procedure_writeln))
545554
TRACE_ERROR("WRITE[LN]");
546555
}
547556
else if (executable == &ps_system_procedure_read || executable == &ps_system_procedure_readln)
548557
{
549558
compiler->error = PS_ERROR_NOT_IMPLEMENTED;
550-
if (!ps_parse_read_or_readln(compiler, block, executable == &ps_system_procedure_readln))
559+
if (!ps_parse_read_or_readln(compiler, block, call, executable == &ps_system_procedure_readln))
551560
TRACE_ERROR("READ[LN]");
552561
}
553562
else if (executable == &ps_system_procedure_randomize)
554563
{
555564
// Randomize
556-
if (!ps_procedure_randomize(compiler, NULL))
557-
TRACE_ERROR("RANDOMIZE");
565+
ps_compiler_set_message(compiler, "TODO: call RANDOMIZE", executable->name);
566+
RETURN_ERROR(PS_ERROR_NOT_IMPLEMENTED)
558567
}
559568
else if (executable->system)
560569
{
@@ -563,7 +572,7 @@ bool ps_parse_procedure_or_function_call(ps_compiler *compiler, ps_ast_block *bl
563572
RETURN_ERROR(PS_ERROR_NOT_IMPLEMENTED)
564573
}
565574
// User defined procedure or function call
566-
else if (!ps_parse_procedure_or_function_call_user(compiler, block, call, executable, result_value))
575+
else if (!ps_parse_procedure_or_function_call_user(compiler, block, call, executable))
567576
TRACE_ERROR("USER");
568577

569578
PARSE_END("OK")

src/ps_parse_expression.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,8 @@ bool ps_parse_function_call_low_high(ps_compiler *compiler, ps_ast_block *block,
538538
*symbol = ps_compiler_find_symbol(compiler, block, identifier, false);
539539
if (*symbol == NULL)
540540
RETURN_ERROR(PS_ERROR_SYMBOL_NOT_FOUND)
541+
if (!ps_value_is_ordinal((*symbol)->value) && !ps_value_is_array((*symbol)->value))
542+
RETURN_ERROR(PS_ERROR_UNEXPECTED_TYPE)
541543
READ_NEXT_TOKEN
542544
EXPECT_TOKEN(PS_TOKEN_RIGHT_PARENTHESIS)
543545
READ_NEXT_TOKEN
@@ -605,7 +607,9 @@ bool ps_parse_function_call_system(ps_compiler *compiler, ps_ast_block *block, p
605607
n_args = -1;
606608
if (!ps_parse_function_call_low_high(compiler, block, &symbol))
607609
TRACE_ERROR("LOW_HIGH")
608-
args[0] = symbol;
610+
ps_ast_variable_simple *symbol_node =
611+
ps_ast_create_variable_simple(start_line, start_column, PS_AST_LVALUE_SIMPLE, symbol);
612+
args[0] = (ps_ast_node *)symbol_node;
609613
}
610614
else if (function == &ps_system_function_power)
611615
{
@@ -693,8 +697,10 @@ bool ps_parse_function_call(ps_compiler *compiler, ps_ast_block *block, ps_ast_c
693697
bool ps_parse_constant_expression(ps_compiler *compiler, ps_ast_block *block, ps_value *constant)
694698
{
695699
PARSE_BEGIN("CONSTANT_EXPRESSION", "");
696-
bool negate = false;
700+
(void)start_line;
701+
(void)start_column;
697702

703+
bool negate = false;
698704
ps_identifier identifier = {0};
699705
ps_symbol *symbol = NULL;
700706

src/ps_parse_statement.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,6 @@ bool ps_parse_for_do(ps_compiler *compiler, ps_ast_block *block, ps_ast_for **fo
616616
bool downto = false;
617617
ps_ast_statement_list *body = NULL;
618618
ps_identifier identifier = {0};
619-
uint16_t line = 0;
620-
uint16_t column = 0;
621619

622620
// FOR
623621
EXPECT_TOKEN(PS_TOKEN_FOR)
@@ -665,7 +663,11 @@ bool ps_parse_for_do(ps_compiler *compiler, ps_ast_block *block, ps_ast_for **fo
665663
if (!ps_parse_statement_or_compound_statement(compiler, block, &body))
666664
TRACE_ERROR("STATEMENT_OR_COMPOUND")
667665

668-
*for_statement = ps_ast_create_for(start_line, start_column, variable, start, finish, downto ? -1 : 1, body);
666+
ps_ast_variable_simple *variable_node =
667+
ps_ast_create_variable_simple(start_line, start_column, PS_AST_LVALUE_SIMPLE, variable);
668+
if (variable_node == NULL)
669+
RETURN_ERROR(PS_ERROR_OUT_OF_MEMORY)
670+
*for_statement = ps_ast_create_for(start_line, start_column, variable_node, start, finish, downto ? -1 : 1, body);
669671
if (*for_statement == NULL)
670672
RETURN_ERROR(PS_ERROR_OUT_OF_MEMORY)
671673

@@ -691,7 +693,7 @@ bool ps_parse_statement_list(ps_compiler *compiler, ps_ast_block *block, ps_ast_
691693
else
692694
{
693695
// Let's go!
694-
ps_ast_node *statement = NULL;
696+
ps_ast_node **statement = NULL;
695697
// Up to 256 statements for now
696698
size_t count = 0;
697699
ps_ast_node *statements[256];
@@ -703,7 +705,7 @@ bool ps_parse_statement_list(ps_compiler *compiler, ps_ast_block *block, ps_ast_
703705
count += 1;
704706
if (count > 255)
705707
RETURN_ERROR(PS_ERROR_TOO_MANY_ARGUMENTS) // should be PS_ERROR_TOO_MANY_STATEMENTS
706-
statements[count - 1] = statement;
708+
statements[count - 1] = (ps_ast_node *)(*statement);
707709
// NB: semi-colon at statement list end is optional
708710
if (lexer->current_token.type == PS_TOKEN_SEMI_COLON)
709711
{
@@ -749,7 +751,7 @@ bool ps_parse_statement_or_compound_statement(ps_compiler *compiler, ps_ast_bloc
749751
*statement_list = ps_ast_create_statement_list(start_line, start_column, 1);
750752
if (*statement_list == NULL)
751753
RETURN_ERROR(PS_ERROR_OUT_OF_MEMORY)
752-
(*statement_list)->statements[0] = statement;
754+
(*statement_list)->statements[0] = *statement;
753755
}
754756

755757
PARSE_END("OK")

src/ps_system.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ bool ps_system_init(ps_symbol_table *system)
193193

194194
void ps_system_done(ps_symbol_table *system)
195195
{
196-
ps_symbol_table_done(system->symbols);
196+
ps_symbol_table_free(system);
197197
}
198198

199199
bool ps_system_add_symbol(ps_symbol_table *system, ps_symbol *symbol)

0 commit comments

Comments
 (0)