Skip to content

Commit

Permalink
Add variable storage in type checking
Browse files Browse the repository at this point in the history
  • Loading branch information
josephmcl committed Aug 18, 2024
1 parent 54871f4 commit cc96dc4
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 11 deletions.
1 change: 1 addition & 0 deletions include/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "context/definitions.h"
#include "context/letter.h"
#include "context/variable.h"

struct context {
void ( *validate) (void);
Expand Down
4 changes: 4 additions & 0 deletions include/context/definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ typedef struct pcontext {
size_t letters_count;
size_t letters_capacity;
lexical_store **letters;

size_t variables_count;
size_t variables_capacity;
lexical_store **variables;
} program_context;

typedef struct {
Expand Down
14 changes: 14 additions & 0 deletions include/context/variable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include "string.h"

#include "definitions.h"

syntax_store *_update_context_variable(
syntax_store *store,
program_context_info *info,
program_context *context);

syntax_store *_update_known_context_variable(
lexical_store *variable,
program_context *context);
36 changes: 25 additions & 11 deletions source/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ syntax_store *update_program_context(syntax_store *store) {
return _update_context_letter(store, &TheInfo, TheContext);
case ast_alphabet_body:
return _update_context_alphabet_body(store);
case ast_variable:
return _update_context_variable(store, &TheInfo, TheContext);
default:
return NULL; }
}
Expand All @@ -211,29 +213,29 @@ void validate_program_context (void) {
}

// TODO: Remove.
printf("\n\n");
printf("\nContext report.\n");

for (size_t i = 0; i < TheInfo.count; ++i) {
printf("Context address (%p) ", (void *) TheContext[i].syntax);
printf("Context %lu\n| address (%p)\n", i, (void *) TheContext[i].syntax);
topic = TheContext[i].topic;
if (topic == NULL) {
printf("(root context).");
printf("| parent NULL (root context) \n");
}
else {
printf("parent (%p) ", (void *) topic->syntax);
else {
printf("| parent (%p)\n", (void *) topic->syntax);
current = TheContext[i].syntax->content[1];
if (current == NULL) {
printf("anonymous");
printf("| name (anonymous)\n");
}
else {
lstore = Lex.store(current->token_index);
int size = (int) (lstore->end - lstore->begin);
printf("name (%.*s)", size, lstore->begin);
int size = (int) (lstore->end - lstore->begin);
printf("| name (%.*s)\n", size, lstore->begin);
}
}

printf(" vars (%lu)\n", TheContext[i].letters_count);
printf("| letters (%lu)\n", TheContext[i].letters_count);
for (size_t j = 0; j < TheContext[i].letters_count; ++j) {
printf("size (%d) ",
printf("| | size (%d) ",
TheContext[i].letters[j]->end -
TheContext[i].letters[j]->begin);
printf("value (%.*s) ",
Expand All @@ -243,6 +245,18 @@ void validate_program_context (void) {
printf("address (%p) \n",
TheContext[i].letters[j]->begin);
}
printf("| variables (%lu)\n", TheContext[i].variables_count);
for (size_t j = 0; j < TheContext[i].variables_count; ++j) {
printf("| | size (%d) ",
TheContext[i].variables[j]->end -
TheContext[i].variables[j]->begin);
printf("value (%.*s) ",
TheContext[i].variables[j]->end -
TheContext[i].variables[j]->begin,
TheContext[i].variables[j]->begin);
printf("address (%p) \n",
TheContext[i].variables[j]->begin);
}
printf("\n");
}
return;
Expand Down
132 changes: 132 additions & 0 deletions source/context/variable.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#include "context.h"

#define CONTEXT_VARIABLES_SIZE 64

lexical_store *_context_push_variable(
program_context *context,
lexical_store *variable);

bool _context_has_variable(
program_context *context,
lexical_store *variable);

syntax_store *_update_context_variable(
syntax_store *store,
program_context_info *info,
program_context *context) {

syntax_store *topic = store;
lexical_store *variable;
size_t index;

/* For the given syntax tree node, nagvigate the topic nodes
until a scope or program node is found. */
while (
topic != NULL /* NOTE: This should not be possible. */
&& topic->type != ast_scope
&& topic->type != ast_program) {

if (topic != NULL) {
topic = topic->topic;
}
else {
printf("Error. Could not determine variables's topic "
"scope.\n");
break; // TODO: Gracefully handle this.
}
}

/* Find the matching syntax tree node associated with existing
contexts. */
index = info->count;
for (size_t i = 0; i < info->count; ++i) {
if (topic == context[i].syntax) {
index = i;
break;
}
}

if (index == info->count)
printf("Error. Could not find matching context for "
"variable.\n");
// TODO: Gracefully handle errors...

/* Add variable to the current context if the context does not
already have that variable. */
variable = Lex.store(store->token_index);
if (!_context_has_variable(&context[index], variable)) {

_context_push_variable(&context[index], variable);

for (size_t i = 0; i < context[index].content_count; ++i) {
_update_known_context_variable(
variable,
context[index].content[i]);
}
}

return NULL;
}

syntax_store *_update_known_context_variable(
lexical_store *variable,
program_context *context) {

if (!_context_has_variable(context, variable)) {
_context_push_variable(context, variable);

for (size_t i = 0; i < context->content_count; ++i) {
_update_known_context_variable(
variable,
context->content[i]);
}
}

return NULL;
}

lexical_store *_context_push_variable(
program_context *context,
lexical_store *variable) {

size_t bytes;
if (context->variables_count == context->variables_capacity) {
context->variables_capacity += CONTEXT_VARIABLES_SIZE;

bytes = sizeof(*context->variables) * context->variables_capacity;
context->variables =
(lexical_store **) realloc(context->variables, bytes);
}

context->variables[context->variables_count] = variable;
context->variables_count += 1;
return *(context->variables + context->variables_count - 1);
}

// TODO: Write a clean up / free function for the abovee. ^^

bool _context_has_variable(
program_context *context,
lexical_store *variable) {

lexical_store *current;
size_t size;
bool match;

size = variable->end - variable->begin;
match = false;
for (size_t i = 0; i < context->variables_count; ++i) {

current = context->variables[i];

if (size != variable->end - variable->begin) continue;


if (memcmp(variable->begin, current->begin, size) == 0) {
match = true;
break;
}
}

return match;
}

0 comments on commit cc96dc4

Please sign in to comment.