Precompiler now adds Variables to a pc_Variable Table. Additional precompilation error checking implemented. TablePair now uses a T_POINTER type. If this data type is used, the memory pointed to is _not_ freed when the TablePair or its parent Table is freed. The developer must remember to free this data type manually when it is used.

master
kts 2014-04-15 11:18:52 -07:00
parent 5eb6cf5db2
commit 30472bf0ca
5 changed files with 300 additions and 34 deletions

View File

@ -401,6 +401,9 @@ void freeTablePair(struct TablePair *table_pair) {
struct TablePair *sub_pair = pair->next; struct TablePair *sub_pair = pair->next;
free(pair->key); free(pair->key);
switch (pair->type) { switch (pair->type) {
case T_POINTER:
// we do nothing with pointers - remember to free yoself!
break;
case T_PROTO_INVENTORY: case T_PROTO_INVENTORY:
freeInventoryData(pair->value); freeInventoryData(pair->value);
break; break;

View File

@ -14,6 +14,7 @@
#define T_DOUBLE 8 #define T_DOUBLE 8
#define T_LONG_DOUBLE 9 #define T_LONG_DOUBLE 9
#define T_STRING 20 #define T_STRING 20
#define T_POINTER 30
#define T_TABLE 50 #define T_TABLE 50

View File

@ -1,17 +1,20 @@
{ {
return; int global_x = 0;
int x = 2; string str = "test string";
int x y; float fl = 0.1f;
int x = y = z; char ch = 'a';
int test = 2;
string hate;
int globalFunction(int param_1) { int globalFunction(int param_1) {
return (param_1 - 1); int i = param_1 - 1;
return i;
} }
} }
0:0 { 0 {
int x; int group_x;
int y = 2; int 2;
int = =; }
0:0 {
int local_x = 2;
int y = 2;
} }

View File

@ -33,7 +33,7 @@ Categorization of functions into global, group, and individual is accomplished t
Once the scope is found, the Parser begins to search for variable and function declarations. During reading a line, if the line does not end with a ';', then it is checked as a possible function declaration - otherwise, it is checked as a variable declaration. During this stage, spaces, tabs and return characters are eaten, allowing for multiple function declaration styles. Once the scope is found, the Parser begins to search for variable and function declarations. During reading a line, if the line does not end with a ';', then it is checked as a possible function declaration - otherwise, it is checked as a variable declaration. During this stage, spaces, tabs and return characters are eaten, allowing for multiple function declaration styles.
Once a function section is identified, a mid-level function struct is created and populated with the function name, return data type, and variable structs for the parameters and added to the apropriate scope function Table. When a variable is encountered, it is converted into a mid-level variable struct and added into the appropriate scope variable Table. Once a function section is identified, a mid-level function struct is created and populated with the function name, return data type, and variable structs for the parameters and added to the appropriate scope function Table. When a variable is encountered, it is converted into a mid-level variable struct and added into the appropriate scope variable Table.
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Program Structure - function parsing and pre-compilation Program Structure - function parsing and pre-compilation
```````````````````````````````` ````````````````````````````````
@ -216,12 +216,16 @@ int main(int argc, char *argv[]) {
char temp_string[strlen((char *)current_file->data)+strlen(code_dir)+1]; char temp_string[strlen((char *)current_file->data)+strlen(code_dir)+1];
sprintf(temp_string, "%s%s", code_dir, (char *)current_file->data); sprintf(temp_string, "%s%s", code_dir, (char *)current_file->data);
printf("-> precompiling %s\n", temp_string); printf("-> precompiling %s\n", temp_string);
switch(vm_precompileFile(temp_string)) { int errors = 0;
switch(errors = vm_precompileFile(temp_string)) {
case 0: case 0:
printf("-> OK: successfully read %s\n", temp_string); printf("-> OK: successfully read %s\n", temp_string);
break; break;
case 1: case -1:
printf("-> ERR: could not open file for reading\n"); printf("ERROR, could not open file for reading\n");
break;
default:
printf("%d ERRORS encountered while compiling %s\n", errors, temp_string);
break; break;
} }
} }
@ -254,7 +258,7 @@ The appropriate scopes are created and passed to vm_precompileCode for actual pr
int vm_precompileFile(const char *file_name) { int vm_precompileFile(const char *file_name) {
FILE *file = fopen(file_name, "r"); FILE *file = fopen(file_name, "r");
if (file == NULL) { if (file == NULL) {
return 1; return -1;
} }
char c; // current char! char c; // current char!
int cpos = 1; // char position int cpos = 1; // char position
@ -264,6 +268,7 @@ int vm_precompileFile(const char *file_name) {
char second[128]; // max 128 for id string char second[128]; // max 128 for id string
int spos = -1; // char pos for ^, we cheat by using -1 as a way to use spos and fpos for our mode (e.g., group scope == -1, local scope >= 0) int spos = -1; // char pos for ^, we cheat by using -1 as a way to use spos and fpos for our mode (e.g., group scope == -1, local scope >= 0)
int errors = 0; // error count returned by precompileCode int errors = 0; // error count returned by precompileCode
int total_errors = 0; // total error count, used in return
while(( c = fgetc(file)) != EOF) { while(( c = fgetc(file)) != EOF) {
if (isdigit(c)) { if (isdigit(c)) {
if (spos >= 0) { if (spos >= 0) {
@ -286,8 +291,11 @@ int vm_precompileFile(const char *file_name) {
printf("[%d,%d]: starting precompile for global code block\n", lpos, cpos); printf("[%d,%d]: starting precompile for global code block\n", lpos, cpos);
if ((errors = vm_precompileCode(file, &lpos, &cpos, &vm_pc_global_scope, NULL, NULL)) != 0) { if ((errors = vm_precompileCode(file, &lpos, &cpos, &vm_pc_global_scope, NULL, NULL)) != 0) {
printf("%d ERRORS encountered while compiling global code block!\n", errors); printf("%d ERRORS encountered while compiling global code block!\n", errors);
total_errors += errors;
} }
printf("[%d,%d]: finished precompile for global code block\n", lpos, cpos); printf("[%d,%d]: finished precompile for global code block\n", lpos, cpos);
//printf(" * dumping precompiled global variables\n");
//vm_pc_dumpScope(&vm_pc_global_scope);
} else if (spos == -1) { } else if (spos == -1) {
struct vm_pc_Scope *group_scope = getTablePairValue(vm_pc_group_scopes, first); struct vm_pc_Scope *group_scope = getTablePairValue(vm_pc_group_scopes, first);
if (group_scope == NULL) { // create if does not exist if (group_scope == NULL) { // create if does not exist
@ -299,8 +307,14 @@ int vm_precompileFile(const char *file_name) {
printf("[%d,%d]: starting precompile for group code block %s\n", lpos, cpos, first); printf("[%d,%d]: starting precompile for group code block %s\n", lpos, cpos, first);
if ((errors = vm_precompileCode(file, &lpos, &cpos, &vm_pc_global_scope, group_scope, NULL)) != 0) { if ((errors = vm_precompileCode(file, &lpos, &cpos, &vm_pc_global_scope, group_scope, NULL)) != 0) {
printf("%d ERRORS encountered while compiling group code block %s!\n", errors, first); printf("%d ERRORS encountered while compiling group code block %s!\n", errors, first);
total_errors += errors;
// TODO: perhaps allow potentially broken code?
// TODO: return 1 on failure
vm_pc_freeVariables(group_scope->variables);
} }
printf("[%d,%d]: finished precompile for group code block %s\n", lpos, cpos, first); printf("[%d,%d]: finished precompile for group code block %s\n", lpos, cpos, first);
//printf(" * dumping precompiled variables\n");
//vm_pc_dumpScope(group_scope);
fpos = 0; fpos = 0;
first[fpos] = '\0'; first[fpos] = '\0';
} else { } else {
@ -330,8 +344,15 @@ int vm_precompileFile(const char *file_name) {
printf("[%d,%d]: starting precompile for local code block %s:%s\n", lpos, cpos, first, second); printf("[%d,%d]: starting precompile for local code block %s:%s\n", lpos, cpos, first, second);
if ((errors = vm_precompileCode(file, &lpos, &cpos, &vm_pc_global_scope, group_scope, local_scope)) != 0) { if ((errors = vm_precompileCode(file, &lpos, &cpos, &vm_pc_global_scope, group_scope, local_scope)) != 0) {
printf("%d ERRORS encountered while compiling local code block %s:%s!\n", errors, first, second); printf("%d ERRORS encountered while compiling local code block %s:%s!\n", errors, first, second);
total_errors += errors;
} }
printf("[%d,%d]: finished precompile for local code block %s:%s\n", lpos, cpos, first, second); printf("[%d,%d]: finished precompile for local code block %s:%s\n", lpos, cpos, first, second);
/*printf(" * dumping precompiled global variables\n");
vm_pc_dumpScope(&vm_pc_global_scope);
printf(" * dumping precompiled group variables\n");
vm_pc_dumpScope(group_scope);
printf(" * dumping precompiled local variables\n");
vm_pc_dumpScope(local_scope);*/
fpos = 0; fpos = 0;
first[fpos] = '\0'; first[fpos] = '\0';
spos = -1; spos = -1;
@ -346,7 +367,7 @@ int vm_precompileFile(const char *file_name) {
} }
} }
fclose(file); fclose(file);
return 0; // success, baby return total_errors; // success, baby
} }
#define DISCOVER 0 #define DISCOVER 0
@ -359,7 +380,21 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
int wpos = 0; // word position, i.e., X int wpos = 0; // word position, i.e., X
int wcpos = 0; // word character position, i.e., Y int wcpos = 0; // word character position, i.e., Y
int error = 0; int error = 0;
struct vm_pc_Scope *current_scope = local; // default scope is local int ret = 0;
struct vm_pc_Scope *current_scope; // default scope is local
// if local is NULL, that means we are in group scope. If group is NULL, we are in global
if (local == NULL) {
if (group == NULL) {
//printf(" * Precompiling global\n");
current_scope = global;
} else {
//printf(" * Precompiling group\n");
current_scope = group;
}
} else {
//printf(" * Precompiling local\n");
current_scope = local;
}
memset(&words, '\0', 31*128); memset(&words, '\0', 31*128);
char c; // current char! char c; // current char!
while(( c = fgetc(file)) != EOF) { while(( c = fgetc(file)) != EOF) {
@ -396,6 +431,7 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
wcpos = 0; wcpos = 0;
}*/ }*/
// if parenthesis depth is greater than zero, then add spaces or tabs to the current word. If not, end current word and start new word. // if parenthesis depth is greater than zero, then add spaces or tabs to the current word. If not, end current word and start new word.
// TODO: quotations should enable skipping of the following
} else if (c == ' ' || c == '\t') { } else if (c == ' ' || c == '\t') {
if (pdepth > 0) { if (pdepth > 0) {
words[wpos][wcpos++] = c; words[wpos][wcpos++] = c;
@ -413,22 +449,62 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
} else if (c == ';') { } else if (c == ';') {
int wwpos = 0; int wwpos = 0;
int wtypes[wpos]; int wtypes[wpos];
// BEGIN VARIABLE PARSING
for (wwpos=0;wwpos <= wpos;wwpos++) { for (wwpos=0;wwpos <= wpos;wwpos++) {
// BEGIN VARIABLE DECLARATION
// first we set the first word's type by checking against reserved words.
if (wwpos == 0) { // "_int_" if (wwpos == 0) { // "_int_"
int wtype = vm_isReserved(words[wwpos]); int wtype = vm_isReserved(words[wwpos]);
wtypes[wwpos] = wtype; wtypes[wwpos] = wtype;
if (wpos == 0) {
printf("[%d,%d]: ERROR, floating statement \"%s\".\n", lpos, cpos, words[wwpos]);
error++;
}
if (wtype != 1) {
printf("[%d,%d]: ERROR, \"%s\" is not a valid data type.\n", lpos, cpos, words[wwpos]);
error++;
}
} else if (wwpos == 1) { } else if (wwpos == 1) {
// now we check if the first word's type is "1" - a built-in data type.
if (wtypes[wwpos-1] == 1) { // "int _x_ . . ." if (wtypes[wwpos-1] == 1) { // "int _x_ . . ."
// check against dbl datatype declaration, i.e., int int // we check against a second datatype declaration, such as "int int" - this is invalid
wtypes[wwpos] = vm_isReserved(words[wwpos]); wtypes[wwpos] = vm_isReserved(words[wwpos]);
// TODO: check if variable name is valid (alpha-only)
if (wtypes[wwpos] == 0) { if (wtypes[wwpos] == 0) {
printf("ADDING %s %s\n", words[wwpos-1], words[wwpos]); // now add to our current scope's variable Table
if ((ret = vm_pc_addVariableToScope(current_scope, words[wwpos-1], words[wwpos])) != 0) {
switch(ret) {
case 1:
printf("[%d,%d]: ERROR, could not add \"%s\", as \"%s\" was already defined.\n", lpos, cpos, words[wwpos], words[wwpos]);
error++;
break;
case 2:
printf("[%d,%d]: ERROR, could not add \"%s\", as type \"%s\" is undefined.\n", lpos, cpos, words[wwpos], words[wwpos-1]);
error++;
break;
case 3:
printf("[%d,%d]: ERROR, could not add \"%s\", as type \"%s\" is undefined in translation function.\n", lpos, cpos, words[wwpos], words[wwpos-1]);
error++;
break;
case -1:
printf("[%d,%d]: ERROR, could not add \"%s\", as scope is NULL\n", lpos, cpos, words[wwpos]);
error++;
break;
default:
printf("[%d,%d]: ERROR, unhandled error while adding variable!\n", lpos, cpos);
error++;
break;
}
}
} else { } else {
printf("[%d,%d]: ERROR, bad variable name, \"%s\" is reserved\n", lpos, cpos, words[wwpos]); printf("[%d,%d]: ERROR, bad variable name, \"%s\" is reserved\n", lpos, cpos, words[wwpos]);
error++; error++;
break; break;
} }
} }
// END VARIABLE DECLARATION
// now we parse for assignment operations, if available
// BEGIN VARIABLE SETTING
} else if (wwpos == 2) { } else if (wwpos == 2) {
wtypes[wwpos] = vm_isReserved(words[wwpos]); wtypes[wwpos] = vm_isReserved(words[wwpos]);
if (wtypes[wwpos-1] == 0) { // variable name if (wtypes[wwpos-1] == 0) { // variable name
@ -443,7 +519,20 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
error++; error++;
break; break;
} else { } else {
printf("SETTING %s %s %s\n", words[wwpos-1], words[wwpos], words[wwpos+1]); // TODO: check if is a value or variable. if right-hand of assignment is a variable and does not exist, complain.
if ((ret = vm_pc_setVariable((struct vm_pc_Variable*)getTablePairValue(current_scope->variables, words[wwpos-1]), words[wwpos+1])) != 0) {
switch(ret) {
case -1:
printf("[%d,%d]: ERROR, variable \"%s\" undeclared!\n", lpos, cpos, words[wwpos-1]);
error++;
break;
default:
printf("[%d,%d]: ERROR, unhandled error while setting variable \"%s\"!\n", lpos, cpos, words[wwpos-1]);
error++;
break;
}
}
//printf(" SET (%s)%s=>%s\n", ((struct vm_pc_Variable *)getTablePairValue(current_scope->variables, words[wwpos-1]))->type, words[wwpos-1], ((struct vm_pc_Variable *)getTablePairValue(current_scope->variables, words[wwpos-1]))->data);
} }
} else { } else {
printf("[%d,%d]: ERROR, \"%s\" after \"%s\" is invalid!\n", lpos, cpos, words[wwpos], words[wwpos-1]); printf("[%d,%d]: ERROR, \"%s\" after \"%s\" is invalid!\n", lpos, cpos, words[wwpos], words[wwpos-1]);
@ -451,6 +540,7 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
} }
} }
} }
// VARIABLE SETTING cont'd
} else { } else {
wtypes[wwpos] = vm_isReserved(words[wwpos]); wtypes[wwpos] = vm_isReserved(words[wwpos]);
if (wtypes[wwpos] == 4) { // "=" if (wtypes[wwpos] == 4) { // "="
@ -460,7 +550,20 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
error++; error++;
break; break;
} else { } else {
printf("SETTING %s %s %s\n", words[wwpos-1], words[wwpos], words[wwpos+1]); // TODO: check if is a value or variable. if right-hand of assignment is a variable and does not exist, complain.
if ((ret = vm_pc_setVariable((struct vm_pc_Variable*)getTablePairValue(current_scope->variables, words[wwpos-1]), words[wwpos+1])) != 0) {
switch(ret) {
case -1:
printf("[%d,%d]: ERROR, variable \"%s\" undeclared!\n", lpos, cpos, words[wwpos-1]);
error++;
break;
default:
printf("[%d,%d]: ERROR, unhandled error while setting variable!\n", lpos, cpos);
error++;
break;
}
}
printf(" SET (%s)%s=>%s\n", ((struct vm_pc_Variable *)getTablePairValue(current_scope->variables, words[wwpos-1]))->type, words[wwpos-1], ((struct vm_pc_Variable *)getTablePairValue(current_scope->variables, words[wwpos-1]))->data);
} }
} else { } else {
printf("[%d,%d]: ERROR, \"%s\" after \"%s\" is invalid!\n", lpos, cpos, words[wwpos], words[wwpos-1]); printf("[%d,%d]: ERROR, \"%s\" after \"%s\" is invalid!\n", lpos, cpos, words[wwpos], words[wwpos-1]);
@ -468,41 +571,44 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
} }
} }
} }
// END VARIABLE SETTING
} }
printf("\t\t"); // END VARIABLE PARSING
/*printf("\t\t");
for(wwpos = 0;wwpos <= wpos;wwpos++) { for(wwpos = 0;wwpos <= wpos;wwpos++) {
printf("%s ", words[wwpos]); printf("%s ", words[wwpos]);
} }
printf("\n"); printf("\n");*/
// RESET // RESET
wpos = 0; wpos = 0;
wcpos = 0; wcpos = 0;
memset(&words, '\0', 31*128); memset(&words, '\0', 31*128);
// when a '{' is encountered, what follows should be a function. // when a '{' is encountered, what follows should be a function.
// BEGIN FUNCTION PARSING
} else if (c == '{') { } else if (c == '{') {
// TODO: create vm_pc_Function and set some current scope up for statements. // TODO: create vm_pc_Function and set some current scope up for statements.
// TODO: also check for conditional thing and convert to ops, of course // TODO: also check for conditional thing and convert to ops, of course
printf("func, while, etc. baby\n"); // TODO: run a check for function-style adherence
int wwpos = 0; // TODO: call vm_precompileFunction
/*int wwpos = 0;
for(wwpos = 0;wwpos <= wpos;wwpos++) { for(wwpos = 0;wwpos <= wpos;wwpos++) {
printf("%d: %s\n", wwpos, words[wwpos]); printf("%d: %s\n", wwpos, words[wwpos]);
} }*/
// RESET // RESET
wpos = 0; wpos = 0;
wcpos = 0; wcpos = 0;
memset(&words, '\0', 31*128); memset(&words, '\0', 31*128);
} else if (c == '}') { } else if (c == '}') {
// I guess leave current vm_pc_Function scope here if depth == 0? // I guess leave current vm_pc_Function scope here if depth == 0?
printf("function body\n"); /*int wwpos = 0;
int wwpos = 0;
for(wwpos = 0;wwpos <= wpos;wwpos++) { for(wwpos = 0;wwpos <= wpos;wwpos++) {
printf("%d: %s\n", wwpos, words[wwpos]); printf("%d: %s\n", wwpos, words[wwpos]);
} }*/
// RESET // RESET
wpos = 0; wpos = 0;
wcpos = 0; wcpos = 0;
memset(&words, '\0', 31*128); memset(&words, '\0', 31*128);
// END FUNCTION PARSING
} else { } else {
words[wpos][wcpos++] = c; words[wpos][wcpos++] = c;
} }
@ -512,6 +618,68 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
return error; return error;
} }
/*
Returns:
0 on success
1 if the variable is already defined
2 if the data type does not exist
*/
int vm_pc_addVariableToScope(struct vm_pc_Scope *scope, const char *data_type, const char *data_name) {
if (scope == NULL) {
return -1; // FIXME
}
if (getTablePair(scope->variables, data_name) != NULL) {
return 1;
}
int type;
for (type = 0;type <= MAX_TYPES;type++) {
if (strcmp(data_type, vm_datatypes[type]) == 0) {
struct vm_pc_Variable *new_var = vm_pc_newVariable(data_type, "undef");
addTablePairPointer(scope->variables, data_name, new_var, T_POINTER);
//printf(" ADDED (%s)%s=>%s\n", ((struct vm_pc_Variable *)getTablePairValue(scope->variables, data_name))->type, data_name, ((struct vm_pc_Variable *)getTablePairValue(scope->variables, data_name))->data);
return 0;
}
}
return 2;
}
struct vm_pc_Variable *vm_pc_newVariable(const char *type, const char *value) {
struct vm_pc_Variable *var = malloc(sizeof(struct vm_pc_Variable));
if (var == NULL) {
printf("!!! PC_CRIT_ERR, could not malloc memory for variable\n");
return NULL;
}
int type_size = strlen(type)+1;
if ((var->type = malloc(type_size)) == NULL) {
printf("!!! PC_CRIT_ERR, could not malloc memory for variable type\n");
return NULL;
} else {
memcpy(var->type, type, type_size);
}
int value_size = strlen(value)+1;
if ((var->data = malloc(value_size)) == NULL) {
printf("!!! PC_CRIT_ERR, could not malloc memory for variable data\n");
free(var->type);
return NULL;
} else {
memcpy(var->data, value, value_size);
}
return var;
}
int vm_pc_setVariable(struct vm_pc_Variable *var, const char *data) {
// TODO: check for var types - do not set strings to ints, etc.
if (var == NULL) {
return -1;
}
int data_size = strlen(data)+1;
var->data = realloc(var->data, data_size);
memcpy(var->data, data, data_size);
return 0;
}
int vm_isReserved(char *word) { int vm_isReserved(char *word) {
int checkpos; int checkpos;
for (checkpos = 0;checkpos <= MAX_TYPES;checkpos++) { for (checkpos = 0;checkpos <= MAX_TYPES;checkpos++) {
@ -536,3 +704,78 @@ int vm_isReserved(char *word) {
} }
return 0; return 0;
} }
int vm_pc_dumpScope(struct vm_pc_Scope *scope) {
int i = 0;
while (i < scope->variables->size) {
struct TablePair *entry = scope->variables->pair[i];
while (entry != NULL) {
struct vm_pc_Variable *var = entry->value;
printf(" %s %s = %s\n", var->type, entry->key, var->data);
entry = entry->next;
}
i++;
}
return 0;
}
int vm_pc_freeScope(struct vm_pc_Scope *scope) {
if (scope == NULL) return 1;
vm_pc_freeVariables(scope->variables);
vm_pc_freeFunctions(scope->functions);
return 0;
}
int vm_pc_freeVariables(struct Table *variables) {
if (variables == NULL) return 1;
int i = 0;
while (i < variables->size) {
struct TablePair *entry = variables->pair[i];
struct TablePair *next_entry = NULL;
while (entry != NULL) {
next_entry = entry->next;
struct vm_pc_Variable *var = entry->value;
vm_pc_freeVariable(var);
freeTablePair(entry);
variables->count--;
entry = next_entry;
}
variables->pair[i] = NULL;
i++;
}
return 0;
}
int vm_pc_freeVariable(struct vm_pc_Variable *variable) {
if (variable == NULL) return 1;
if (variable->type != NULL) free(variable->type);
if (variable->data != NULL) free(variable->data);
free(variable);
return 0;
}
int vm_pc_freeFunctions(struct Table *functions) {
int i =0;
while (i < functions->size) {
struct TablePair *entry = functions->pair[i];
struct TablePair *next_entry = NULL;
while (entry != NULL) {
next_entry = entry->next;
struct vm_pc_Function *func = entry->value;
vm_pc_freeFunction(func);
freeTablePair(entry);
functions->count--;
entry = next_entry;
}
i++;
}
return 0;
}
int vm_pc_freeFunction(struct vm_pc_Function *function) {
if (function == NULL) return 1;
if (function->variables) vm_pc_freeVariables(function->variables);
// TODO: free ops
free(function);
return 0;
}

View File

@ -19,7 +19,8 @@ struct Table *vm_pc_groupVariables;
struct Table *vm_pc_localVariables; struct Table *vm_pc_localVariables;
struct vm_pc_Variable { struct vm_pc_Variable {
// ?? char *type; // data type as string, malloc'd and memcpy'd
char *data; // data as string, malloc'd and memcpy'd
}; };
struct vm_pc_Operation { struct vm_pc_Operation {
@ -31,8 +32,10 @@ struct vm_pc_Operation {
}; };
struct vm_pc_Function { struct vm_pc_Function {
struct Table *variables; struct vm_pc_Variable ret; // return variable
struct Table *operations; struct Table *parameters; // input params
struct Table *variables; // function local variables
struct Table *operations; // operations! :)
}; };
struct vm_pc_Scope { struct vm_pc_Scope {
@ -46,6 +49,19 @@ struct Table *vm_pc_local_scopes;
int vm_precompileFile(const char *file_name); int vm_precompileFile(const char *file_name);
int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *global, struct vm_pc_Scope *group, struct vm_pc_Scope *local); int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *global, struct vm_pc_Scope *group, struct vm_pc_Scope *local);
int vm_pc_addVariableToScope(struct vm_pc_Scope *scope, const char *data_type, const char *data_name);
int vm_isReserved(char *word); int vm_isReserved(char *word);
int vm_pc_freeScope(struct vm_pc_Scope *scope);
struct vm_pc_Variable *vm_pc_newVariable(const char *type, const char *value);
int vm_pc_freeVariable(struct vm_pc_Variable *variable);
int vm_pc_freeVariables(struct Table *variables);
int vm_pc_setVariable(struct vm_pc_Variable *variable, const char *value);
int vm_pc_freeFunction(struct vm_pc_Function *function);
int vm_pc_freeFunctions(struct Table *functions);
int vm_pc_dumpScope(struct vm_pc_Scope *scope);
#endif #endif