Skip to content

Commit 8dc1a23

Browse files
committed
AST WIP (compiles! :-))
1 parent c7cb153 commit 8dc1a23

2 files changed

Lines changed: 61 additions & 17 deletions

File tree

src/ps_parse_declaration.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ static bool ps_parse_var_identifier_list(ps_compiler *compiler, ps_ast_block *bl
361361

362362
/**
363363
* Parse variable declaration:
364-
* 'VAR' [ IDENTIFIER [ ',' IDENTIFIER ]* ':' TYPE ';' ]+
364+
* 'VAR' [ IDENTIFIER [ ',' IDENTIFIER ]* ':' TYPE_REFERENCE ';' ]+
365365
* (allow up to 8 identifiers with commas)
366366
* Examples:
367367
* Var a, b, c: Integer;
@@ -374,25 +374,32 @@ bool ps_parse_var(ps_compiler *compiler, ps_ast_block *block)
374374
(void)start_line;
375375
(void)start_column;
376376

377-
ps_identifier identifier[8];
377+
ps_identifier identifiers[8];
378378
int var_count;
379379
ps_symbol *type_symbol = NULL;
380380

381+
// VAR
381382
EXPECT_TOKEN(PS_TOKEN_VAR)
382383
READ_NEXT_TOKEN
383384
do
384385
{
385-
if (!ps_parse_var_identifier_list(compiler, block, identifier, &var_count))
386+
// IDENTIFIER [ ',' IDENTIFIER ]*
387+
if (!ps_parse_var_identifier_list(compiler, block, identifiers, &var_count))
386388
TRACE_ERROR("VARIABLE IDENTIFIER LIST")
389+
// ':'
390+
EXPECT_TOKEN(PS_TOKEN_COLON)
387391
READ_NEXT_TOKEN
392+
// TYPE_REFERENCE
388393
if (!ps_parse_type_reference(compiler, block, &type_symbol, NULL))
389394
TRACE_ERROR("TYPE REFERENCE")
395+
// ';'
390396
EXPECT_TOKEN(PS_TOKEN_SEMI_COLON)
397+
// Add variable(s) to symbol table of current block
391398
for (int i = 0; i < var_count; i++)
392399
{
393-
if (!ps_compiler_add_variable(compiler, block, identifier[i], type_symbol))
400+
if (!ps_compiler_add_variable(compiler, block, identifiers[i], type_symbol))
394401
{
395-
ps_compiler_set_message(compiler, "Cannot add variable %s", identifier[i]);
402+
ps_compiler_set_message(compiler, "Cannot add variable %s", identifiers[i]);
396403
TRACE_ERROR("ADD VARIABLE")
397404
}
398405
}
Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66

77
#include <assert.h>
88

9+
#include "ps_enum.h"
910
#include "ps_executable.h"
1011
#include "ps_memory.h"
1112
#include "ps_parse.h"
1213
#include "ps_parse_expression.h"
14+
#include "ps_parse_type.h"
15+
#include "ps_subrange.h"
1316
#include "ps_symbol.h"
1417
#include "ps_symbol_list.h"
1518
#include "ps_system.h"
@@ -25,6 +28,8 @@
2528
bool ps_parse_type_definition(ps_compiler *compiler, ps_ast_block *block)
2629
{
2730
PARSE_BEGIN("TYPE_DEFINITION", "");
31+
(void)start_line;
32+
(void)start_column;
2833

2934
ps_symbol *type_reference = NULL;
3035
ps_identifier type_name = {0};
@@ -36,7 +41,7 @@ bool ps_parse_type_definition(ps_compiler *compiler, ps_ast_block *block)
3641
RETURN_ERROR(PS_ERROR_UNEXPECTED_TOKEN)
3742
COPY_IDENTIFIER(type_name)
3843
// Check that type name does not already exist in local symbol table
39-
if (ps_interpreter_find_symbol(compiler, type_name, true) != NULL)
44+
if (ps_compiler_find_symbol(compiler, block, type_name, true) != NULL)
4045
RETURN_ERROR(PS_ERROR_SYMBOL_EXISTS)
4146
READ_NEXT_TOKEN
4247
// '='
@@ -46,7 +51,7 @@ bool ps_parse_type_definition(ps_compiler *compiler, ps_ast_block *block)
4651
if (!ps_parse_type_reference(compiler, block, &type_reference, type_name))
4752
TRACE_ERROR("TYPE REFERENCE")
4853

49-
ps_value_data data = {.t = type_reference};
54+
ps_value_data data = {.t = type_reference->value->data.t};
5055
type_value = ps_value_alloc(&ps_system_type_def, data);
5156
type_definition = ps_symbol_alloc(PS_SYMBOL_KIND_TYPE_DEFINITION, type_name, type_value);
5257

@@ -67,6 +72,8 @@ static bool ps_type_definition_register(ps_compiler *compiler, ps_ast_block *blo
6772
ps_type_definition *type_def, ps_symbol **symbol)
6873
{
6974
PARSE_BEGIN("REGISTER", "")
75+
(void)start_line;
76+
(void)start_column;
7077

7178
// Allocate value for type definition
7279
ps_value *value = ps_value_alloc(&ps_system_type_def, (ps_value_data){.t = type_def});
@@ -84,7 +91,7 @@ static bool ps_type_definition_register(ps_compiler *compiler, ps_ast_block *blo
8491
RETURN_ERROR(PS_ERROR_OUT_OF_MEMORY)
8592
}
8693
// Register type symbol in symbol table
87-
if (!ps_interpreter_add_symbol(compiler, *symbol))
94+
if (!ps_compiler_add_symbol(compiler, block, *symbol))
8895
{
8996
ps_symbol_free(*symbol);
9097
ps_value_free(value);
@@ -103,6 +110,9 @@ bool ps_parse_type_reference_string(ps_compiler *compiler, ps_ast_block *block,
103110
const char *type_name)
104111
{
105112
PARSE_BEGIN("TYPE_REFERENCE_STRING", "")
113+
(void)start_line;
114+
(void)start_column;
115+
106116
ssize_t len = 0;
107117

108118
if (lexer->current_token.type != PS_TOKEN_STRING)
@@ -212,8 +222,11 @@ bool ps_parse_type_reference_string(ps_compiler *compiler, ps_ast_block *block,
212222
bool ps_parse_type_reference(ps_compiler *compiler, ps_ast_block *block, ps_symbol **type_symbol, const char *type_name)
213223
{
214224
PARSE_BEGIN("TYPE_REFERENCE", "");
225+
(void)start_line;
226+
(void)start_column;
215227

216228
ps_symbol *symbol = NULL;
229+
217230
// By default, we advance to next token after processing type reference,
218231
// but some cases (like copy of existing type) may already have advanced it,
219232
// so we won't advance in those cases
@@ -274,7 +287,7 @@ bool ps_parse_type_reference(ps_compiler *compiler, ps_ast_block *block, ps_symb
274287
// - a copy of an existing type
275288
// - a subrange definition from an enumeration
276289
// - a subrange definition beginning with a constant expression
277-
symbol = ps_interpreter_find_symbol(compiler, lexer->current_token.value.identifier, false);
290+
symbol = ps_compiler_find_symbol(compiler, block, lexer->current_token.value.identifier, false);
278291
if (symbol == NULL)
279292
RETURN_ERROR(PS_ERROR_UNKOWN_IDENTIFIER);
280293
if (symbol->kind == PS_SYMBOL_KIND_CONSTANT)
@@ -313,6 +326,8 @@ bool ps_parse_type_reference_enum(ps_compiler *compiler, ps_ast_block *block, ps
313326
const char *type_name)
314327
{
315328
PARSE_BEGIN("TYPE_REFERENCE_ENUM", "");
329+
(void)start_line;
330+
(void)start_column;
316331

317332
// Up to 256 values in an enumeration, re-allocate 16 more if exhausted
318333
ps_symbol_list *list = ps_symbol_list_alloc(16, 16);
@@ -323,6 +338,7 @@ bool ps_parse_type_reference_enum(ps_compiler *compiler, ps_ast_block *block, ps
323338
if (lexer->current_token.type != PS_TOKEN_LEFT_PARENTHESIS)
324339
GOTO_CLEANUP(PS_ERROR_UNEXPECTED_TOKEN)
325340
READ_NEXT_TOKEN_OR_CLEANUP
341+
326342
// Empty enumeration not allowed
327343
if (lexer->current_token.type == PS_TOKEN_RIGHT_PARENTHESIS)
328344
GOTO_CLEANUP(PS_ERROR_UNEXPECTED_TOKEN)
@@ -331,9 +347,11 @@ bool ps_parse_type_reference_enum(ps_compiler *compiler, ps_ast_block *block, ps
331347
ps_type_definition *type_def = ps_enum_create();
332348
if (type_def == NULL)
333349
GOTO_CLEANUP(PS_ERROR_OUT_OF_MEMORY)
350+
334351
// Register it
335352
if (!ps_type_definition_register(compiler, block, type_name, type_def, type_symbol))
336353
GOTO_CLEANUP(compiler->error)
354+
337355
// Parse enumeration values
338356
do // NOSONAR
339357
{
@@ -345,19 +363,21 @@ bool ps_parse_type_reference_enum(ps_compiler *compiler, ps_ast_block *block, ps
345363
// - locally in the same enumeration
346364
// - or globally in the symbol table
347365
if (ps_symbol_list_find(list, lexer->current_token.value.identifier) ||
348-
(ps_interpreter_find_symbol(compiler, lexer->current_token.value.identifier, true) != NULL))
366+
(ps_compiler_find_symbol(compiler, block, lexer->current_token.value.identifier, true) != NULL))
349367
GOTO_CLEANUP(PS_ERROR_SYMBOL_EXISTS)
350368
ps_symbol *value_symbol = ps_symbol_list_add(list, *type_symbol, lexer->current_token.value.identifier);
351369
if (value_symbol == NULL)
352370
GOTO_CLEANUP(PS_ERROR_OUT_OF_MEMORY)
353-
if (!ps_interpreter_add_symbol(compiler, value_symbol))
371+
if (!ps_compiler_add_symbol(compiler, block, value_symbol))
354372
GOTO_CLEANUP(PS_ERROR_SYMBOL_NOT_ADDED)
355373
READ_NEXT_TOKEN_OR_CLEANUP
374+
// If next token is ',' continue with next enumeration value
356375
if (lexer->current_token.type == PS_TOKEN_COMMA)
357376
{
358377
READ_NEXT_TOKEN_OR_CLEANUP
359378
continue;
360379
}
380+
// If next token is ')' end of enumeration definition
361381
if (lexer->current_token.type == PS_TOKEN_RIGHT_PARENTHESIS)
362382
break;
363383
} while (true);
@@ -377,6 +397,8 @@ bool ps_parse_type_reference_subrange_min(ps_compiler *compiler, ps_ast_block *b
377397
ps_value_type *min_base, ps_type_definition_subrange *subrange)
378398
{
379399
PARSE_BEGIN("TYPE_REFERENCE_SUBRANGE", "")
400+
(void)start_line;
401+
(void)start_column;
380402

381403
if (!ps_parse_constant_expression(compiler, block, min_value))
382404
TRACE_ERROR("MIN")
@@ -414,6 +436,8 @@ bool ps_parse_type_reference_subrange_max(ps_compiler *compiler, ps_ast_block *b
414436
ps_value_type *max_base, ps_type_definition_subrange *subrange)
415437
{
416438
PARSE_BEGIN("TYPE_REFERENCE_SUBRANGE", "")
439+
(void)start_line;
440+
(void)start_column;
417441

418442
if (!ps_parse_constant_expression(compiler, block, max_value))
419443
TRACE_ERROR("MAX")
@@ -452,6 +476,8 @@ bool ps_parse_type_reference_subrange_register_type_def(ps_compiler *compiler, p
452476
const ps_type_definition_subrange *subrange)
453477
{
454478
PARSE_BEGIN("TYPE_REFERENCE_SUBRANGE", "")
479+
(void)start_line;
480+
(void)start_column;
455481

456482
ps_type_definition *type_def = NULL;
457483
ps_identifier name = {0};
@@ -503,6 +529,8 @@ bool ps_parse_type_reference_subrange(ps_compiler *compiler, ps_ast_block *block
503529
const char *type_name)
504530
{
505531
PARSE_BEGIN("TYPE_REFERENCE_SUBRANGE", "")
532+
(void)start_line;
533+
(void)start_column;
506534

507535
ps_type_definition_subrange subrange = {0};
508536
ps_value min_value = {0};
@@ -522,10 +550,10 @@ bool ps_parse_type_reference_subrange(ps_compiler *compiler, ps_ast_block *block
522550
TRACE_ERROR("MAX")
523551
// *** Copy value to max with same type as min
524552
max_value.type = min_value.type;
525-
if (!ps_interpreter_copy_value(compiler, &tmp_value, &max_value))
553+
if (!ps_compiler_copy_value(compiler, &tmp_value, &max_value))
526554
{
527-
ps_interpreter_set_message(compiler, "Min and max value of subrange type mismatch: %s %s", min_value.type->name,
528-
max_value.type->name);
555+
ps_compiler_set_message(compiler, "Min and max value of subrange type mismatch: %s %s", min_value.type->name,
556+
max_value.type->name);
529557
TRACE_ERROR("COPY_MAX")
530558
}
531559
// *** Check that subrange min is less than max
@@ -557,7 +585,9 @@ bool ps_parse_type_reference_subrange(ps_compiler *compiler, ps_ast_block *block
557585
bool ps_parse_type_reference_array(ps_compiler *compiler, ps_ast_block *block, ps_symbol **type_symbol,
558586
const char *type_name)
559587
{
560-
PARSE_BEGIN("TYPE_REFERENCE_ARRAY", "");
588+
PARSE_BEGIN("TYPE_REFERENCE_ARRAY", "")
589+
(void)start_line;
590+
(void)start_column;
561591

562592
ps_symbol *subranges[8] = {0};
563593
uint8_t dimensions = 0;
@@ -598,25 +628,30 @@ bool ps_parse_type_reference_array(ps_compiler *compiler, ps_ast_block *block, p
598628
}
599629
RETURN_ERROR(PS_ERROR_UNEXPECTED_TOKEN)
600630
} while (true);
631+
601632
// For now, only accept one dimension
602633
// We should define and register an array type definition for each dimension
603634
// and "chain" them, exactly as if array[dim1, dim2] of item would have been
604635
// written as array[dim1] of array[dim2] of item
605636
if (dimensions > 1)
606637
{
607-
ps_interpreter_set_message(compiler, "%d dimensions for an array is TODO/WIP", dimensions);
638+
ps_compiler_set_message(compiler, "%d dimensions for an array is TODO/WIP", dimensions);
608639
RETURN_ERROR(PS_ERROR_NOT_IMPLEMENTED)
609640
}
641+
610642
// Expect 'OF'
611643
if (lexer->current_token.type != PS_TOKEN_OF)
612644
RETURN_ERROR(PS_ERROR_UNEXPECTED_TOKEN)
613645
READ_NEXT_TOKEN
646+
614647
// Item type (may be another array definition)
615648
if (!ps_parse_type_reference(compiler, block, &item_type, NULL))
616649
TRACE_ERROR("ITEM_TYPE")
650+
617651
// Item type can be any type, even another array
618652
if (item_type->kind != PS_SYMBOL_KIND_TYPE_DEFINITION)
619653
RETURN_ERROR(PS_ERROR_EXPECTED_TYPE)
654+
620655
// Create type definition for array
621656
ps_type_definition *type_def = NULL;
622657
ps_identifier name = {0};
@@ -629,9 +664,11 @@ bool ps_parse_type_reference_array(ps_compiler *compiler, ps_ast_block *block, p
629664
RETURN_ERROR(PS_ERROR_OUT_OF_MEMORY)
630665
type_def->def.a.item_type = item_type;
631666
type_def->def.a.dimensions = dimensions;
667+
type_def->def.a.subrange = subranges[0];
668+
632669
// Register new type definition in symbol table
633670
if (!ps_type_definition_register(compiler, block, name, type_def, type_symbol))
634-
RETURN_ERROR(compiler->error)
671+
TRACE_ERROR("REGISTER")
635672

636673
PARSE_END("OK")
637674
}

0 commit comments

Comments
 (0)