diff --git a/grammar.y b/grammar.y index bfd7e8b..9bf2930 100644 --- a/grammar.y +++ b/grammar.y @@ -98,76 +98,23 @@ program : statements { $$ = program_statements($1); } ; statements - : { - syntax_store *s = Syntax.push(); - s->type = ast_statements; - s->size = 0; - $$ = s; } - + : { $$ = statements_root(); } | statements statementz { - syntax_store *statements = (syntax_store *) $1; - syntax_store *statementz = (syntax_store *) $2; - size_t oldsize = statements->size; - statements->size += statementz->size; - size_t bytes = statements->size * sizeof(syntax_store *); - statements->content = (syntax_store **) realloc( - statements->content, bytes); - for (size_t i = oldsize; i < statements->size; ++i) { - statements->content[i] = statementz->content[i - oldsize]; - statements->content[i]->topic = statements; - } - statementz->prune = true; - $$ = statements; } - + $$ = statements_statements_statementz($1, $2); } | statements statementz PERIOD { - syntax_store *statements = (syntax_store *) $1; - syntax_store *statementz = (syntax_store *) $2; - size_t oldsize = statements->size; - statements->size += statementz->size; - size_t bytes = statements->size * sizeof(syntax_store *); - statements->content = (syntax_store **) realloc( - statements->content, bytes); - for (size_t i = oldsize; i < statements->size; ++i) { - statements->content[i] = statementz->content[i - oldsize]; - statements->content[i]->topic = statements; - } - statementz->prune = true; - $$ = statements; } + $$ = statements_statements_statementz_PERIOD($1, $2); } | statements import { } | statements scope { - syntax_store *statements = (syntax_store *) $1; - syntax_store *scope = (syntax_store *) $2; - statements->size += 1; - size_t bytes = statements->size * sizeof(syntax_store *); - statements->content = (syntax_store **) realloc( - statements->content, bytes); - statements->content[statements->size - 1] = scope; - scope->topic = statements; - $$ = statements; } + $$ = statements_statements_scope($1, $2); } ; import : EN_IMPORT EN_MODULE IDENTIFIER {} ; scope : scope_export scope_module scope_name LCURL statements RCURL { - syntax_store *s = Syntax.push(); - s->type = ast_scope; - s->size = 2; - s->content = malloc(sizeof(syntax_store *) * s->size); - s->content[0] = (syntax_store *) $5; - s->content[1] = (syntax_store *) $3; - s->content[0]->topic = s; - $$ = s; } - + $$ = scope_scope($5, $3); } | scope_context scope_name LCURL statements RCURL { - syntax_store *s = Syntax.push(); - s->type = ast_scope; - s->size = 2; - s->content = malloc(sizeof(syntax_store *) * s->size); - s->content[0] = (syntax_store *) $4; - s->content[1] = (syntax_store *) $2; - s->content[0]->topic = s; - $$ = s; } + $$ = scope_scope($4, $2); } ; scope_export : EN_EXPORT {} diff --git a/include/grammar.h b/include/grammar.h index c56fc89..ffc99b5 100644 --- a/include/grammar.h +++ b/include/grammar.h @@ -1,2 +1,4 @@ #pragma once -#include "grammar/program.h" \ No newline at end of file +#include "grammar/program.h" +#include "grammar/statements.h" +#include "grammar/scope.h" \ No newline at end of file diff --git a/include/grammar/scope.h b/include/grammar/scope.h new file mode 100644 index 0000000..7d7721d --- /dev/null +++ b/include/grammar/scope.h @@ -0,0 +1,6 @@ +#pragma once +#include "syntax.h" + +syntax_store *scope_scope( + syntax_store *statements, + syntax_store *scope_name); diff --git a/include/grammar/statements.h b/include/grammar/statements.h new file mode 100644 index 0000000..53b10c0 --- /dev/null +++ b/include/grammar/statements.h @@ -0,0 +1,16 @@ +#pragma once +#include "syntax.h" + +syntax_store *statements_root(void); + +syntax_store *statements_statements_statementz( + syntax_store *statements, + syntax_store *statementz); + +syntax_store *statements_statements_statementz_PERIOD( + syntax_store *statements, + syntax_store *statementz); + +syntax_store *statements_statements_scope( + syntax_store *statements, + syntax_store *scope); \ No newline at end of file diff --git a/include/syntax.h b/include/syntax.h index d694e83..158b9f9 100644 --- a/include/syntax.h +++ b/include/syntax.h @@ -34,19 +34,26 @@ typedef struct sstore { syntax_store_type type; size_t token_index; size_t size; + size_t capacity; struct sstore *topic; struct sstore **content; bool prune; } syntax_store; +syntax_store **syntax_realloc( + syntax_store **stores, + size_t *count, + size_t *capacity); + struct syntax { - syntax_store *( *tree) (void); /* NOTE: to get around const. */ - syntax_info * info; - int ( *parse) (void); - syntax_store *( *push) (void); - void ( *check) (syntax_store *); - void ( *print) (void); - void ( *free) (void); + syntax_store *( *tree) (void); /* NOTE: to get around const. */ + syntax_info * info; + int ( *parse) (void); + syntax_store *( *push) (void); + void ( *check) (syntax_store *); + void ( *print) (void); + void ( *free) (void); + size_t ( *errors) (void); }; extern const struct syntax Syntax; diff --git a/source/algorithm/memory_compare.c b/source/algorithm/memory_compare.c index 6f07db8..5b4070d 100644 --- a/source/algorithm/memory_compare.c +++ b/source/algorithm/memory_compare.c @@ -25,6 +25,8 @@ max_shared_vlaues(uint8_t *a, size_t as, uint8_t *b, size_t bs) { j += tmp - bp; bp = tmp; + length = 0; + for (size_t k = 0; i + k < as && j + k < bs; ++k) { spa = ap + k; diff --git a/source/grammar/scope.c b/source/grammar/scope.c new file mode 100644 index 0000000..6510d2d --- /dev/null +++ b/source/grammar/scope.c @@ -0,0 +1,17 @@ +#include "grammar/scope.h" + +syntax_store *scope_scope( + syntax_store *statements, + syntax_store *scope_name) { + + syntax_store *scope = Syntax.push(); + scope->type = ast_scope; + scope->size = 2; + scope->content = malloc(sizeof(syntax_store *) * scope->size); + scope->content[0] = statements; + scope->content[1] = scope_name; + scope->content[0]->topic = scope; + return scope; +} + + \ No newline at end of file diff --git a/source/grammar/statements.c b/source/grammar/statements.c new file mode 100644 index 0000000..04d4bb1 --- /dev/null +++ b/source/grammar/statements.c @@ -0,0 +1,86 @@ +#include "grammar/statements.h" + +syntax_store *statements_root(void) { + + /* Create and setup the program node */ + syntax_store *statements = Syntax.push(); + statements->type = ast_statements; + statements->size = 0; + + return statements; +} + +syntax_store *statements_statements_statementz( + syntax_store *statements, + syntax_store *statementz) { + + /* Store the current statements size. */ + size_t oldsize = statements->size; + + /* Add the size of the statement groups together. */ + statements->size += statementz->size; + + /* Recallocate space for both statement groups. */ + size_t bytes = statements->size * sizeof(syntax_store *); + statements->content = (syntax_store **) realloc( + statements->content, bytes); + + /* Set all of the topic/content pointers. */ + for (size_t i = oldsize; i < statements->size; ++i) { + statements->content[i] = statementz->content[i - oldsize]; + statements->content[i]->topic = statements; + } + + /* Set the prune flag of the statementz node. */ + statementz->prune = true; + + return statements; +} + +syntax_store *statements_statements_statementz_PERIOD( + syntax_store *statements, + syntax_store *statementz) { + + /* Store the current statements size. */ + size_t oldsize = statements->size; + + /* Add the size of the statement groups together. */ + statements->size += statementz->size; + + /* Recallocate space for both statement groups. */ + size_t bytes = statements->size * sizeof(syntax_store *); + statements->content = (syntax_store **) realloc( + statements->content, bytes); + + /* Set all of the topic/content pointers. */ + for (size_t i = oldsize; i < statements->size; ++i) { + statements->content[i] = statementz->content[i - oldsize]; + statements->content[i]->topic = statements; + } + + /* Set the prune flag of the statementz node. */ + statementz->prune = true; + + return statements; +} + + + +syntax_store *statements_statements_scope( + syntax_store *statements, + syntax_store *scope) { + + /* Add the size of the statement groups together. */ + statements->size += 1; + + /* Recallocate space for both statement groups. */ + size_t bytes = statements->size * sizeof(syntax_store *); + statements->content = (syntax_store **) realloc( + statements->content, bytes); + + /* Set all the topic/content pointers. */ + statements->content[statements->size - 1] = scope; + scope->topic = statements; + + return statements; +} diff --git a/source/main.c b/source/main.c index b96d527..2f33d52 100644 --- a/source/main.c +++ b/source/main.c @@ -14,11 +14,18 @@ int main(int argc, char **argv) { /* Lex the file into tokens. */ Lex.analyze(); - Lex.print(); + // Lex.print(); /* Parse the tokens into an AST. */ Syntax.parse(); + if (Syntax.errors()) { + Syntax.free(); + Lex.free(); + return 1; + } + + Syntax.print(); Context.validate(); diff --git a/source/syntax.c b/source/syntax.c index a8e1f44..4ce05f5 100644 --- a/source/syntax.c +++ b/source/syntax.c @@ -6,6 +6,7 @@ extern int yyparse (void); static syntax_info TheInfo = {0}; static syntax_store *TheTree; +static size_t TheErrors = 0; /* Invoke bison LALR1 parser. */ int syntax_parse(void) { @@ -29,6 +30,22 @@ syntax_store *syntax_push(void) { return TheTree + TheInfo.count; } +syntax_store **syntax_realloc( + syntax_store **stores, + size_t *count, + size_t *capacity) { + + size_t bytes; + if (*count == *capacity) { + *capacity += NODES_SIZE; + bytes = sizeof(syntax_store) * (*capacity); + TheTree = (syntax_store *) realloc(stores, bytes); + } + + TheInfo.count += 1; + return stores + (*count); +} + bool _letters_identical( uint8_t **letters, size_t *lengths, @@ -68,7 +85,7 @@ bool _letters_ambiguous( for (size_t j = i + 1; j < store->size; ++j) { max = max_shared_vlaues(letters[i], lengths[i], letters[j], lengths[j]); - size_t m = max & 0xFF; + size_t m = max & 0x00F; if (m >= lengths[i]) { lstore = Lex.store(store->content[j]->token_index); printf("%s:%u:%u: error: alphabet definition is " @@ -118,6 +135,7 @@ void _typecheck_alphabet_body_letters(syntax_store *store) { goto pass; fail: + TheErrors += 1; free(lengths); free(letters); return; @@ -191,6 +209,10 @@ void syntax_print(void) { } void syntax_free(void) { + for (size_t i = 0; i < TheInfo.capacity; ++i) { + if (TheTree[i].size > 0) + free(TheTree[i].content); + } free(TheTree); } @@ -198,12 +220,19 @@ syntax_store *get_tree(void) { return &TheTree[TheInfo.count]; } + +size_t syntax_errors(void) { + return TheErrors; +} + + const struct syntax Syntax = { - .tree = get_tree, - .info = &TheInfo, - .parse = syntax_parse, - .push = syntax_push, - .check = syntax_check, - .print = syntax_print, - .free = syntax_free + .tree = get_tree, + .info = &TheInfo, + .parse = syntax_parse, + .push = syntax_push, + .check = syntax_check, + .print = syntax_print, + .free = syntax_free, + .errors = syntax_errors };