|
|
|
@ -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 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
|
|
|
|
|
````````````````````````````````
|
|
|
|
@ -216,12 +216,16 @@ int main(int argc, char *argv[]) {
|
|
|
|
|
char temp_string[strlen((char *)current_file->data)+strlen(code_dir)+1];
|
|
|
|
|
sprintf(temp_string, "%s%s", code_dir, (char *)current_file->data);
|
|
|
|
|
printf("-> precompiling %s\n", temp_string);
|
|
|
|
|
switch(vm_precompileFile(temp_string)) {
|
|
|
|
|
int errors = 0;
|
|
|
|
|
switch(errors = vm_precompileFile(temp_string)) {
|
|
|
|
|
case 0:
|
|
|
|
|
printf("-> OK: successfully read %s\n", temp_string);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
printf("-> ERR: could not open file for reading\n");
|
|
|
|
|
case -1:
|
|
|
|
|
printf("ERROR, could not open file for reading\n");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
printf("%d ERRORS encountered while compiling %s\n", errors, temp_string);
|
|
|
|
|
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) {
|
|
|
|
|
FILE *file = fopen(file_name, "r");
|
|
|
|
|
if (file == NULL) {
|
|
|
|
|
return 1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
char c; // current char!
|
|
|
|
|
int cpos = 1; // char position
|
|
|
|
@ -264,6 +268,7 @@ int vm_precompileFile(const char *file_name) {
|
|
|
|
|
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 errors = 0; // error count returned by precompileCode
|
|
|
|
|
int total_errors = 0; // total error count, used in return
|
|
|
|
|
while(( c = fgetc(file)) != EOF) {
|
|
|
|
|
if (isdigit(c)) {
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
total_errors += errors;
|
|
|
|
|
}
|
|
|
|
|
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) {
|
|
|
|
|
struct vm_pc_Scope *group_scope = getTablePairValue(vm_pc_group_scopes, first);
|
|
|
|
|
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);
|
|
|
|
|
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);
|
|
|
|
|
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(" * dumping precompiled variables\n");
|
|
|
|
|
//vm_pc_dumpScope(group_scope);
|
|
|
|
|
fpos = 0;
|
|
|
|
|
first[fpos] = '\0';
|
|
|
|
|
} 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);
|
|
|
|
|
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);
|
|
|
|
|
total_errors += errors;
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
first[fpos] = '\0';
|
|
|
|
|
spos = -1;
|
|
|
|
@ -346,7 +367,7 @@ int vm_precompileFile(const char *file_name) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fclose(file);
|
|
|
|
|
return 0; // success, baby
|
|
|
|
|
return total_errors; // success, baby
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#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 wcpos = 0; // word character position, i.e., Y
|
|
|
|
|
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);
|
|
|
|
|
char c; // current char!
|
|
|
|
|
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;
|
|
|
|
|
}*/
|
|
|
|
|
// 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') {
|
|
|
|
|
if (pdepth > 0) {
|
|
|
|
|
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 == ';') {
|
|
|
|
|
int wwpos = 0;
|
|
|
|
|
int wtypes[wpos];
|
|
|
|
|
// BEGIN VARIABLE PARSING
|
|
|
|
|
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_"
|
|
|
|
|
int wtype = vm_isReserved(words[wwpos]);
|
|
|
|
|
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) {
|
|
|
|
|
// now we check if the first word's type is "1" - a built-in data type.
|
|
|
|
|
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]);
|
|
|
|
|
// TODO: check if variable name is valid (alpha-only)
|
|
|
|
|
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 {
|
|
|
|
|
printf("[%d,%d]: ERROR, bad variable name, \"%s\" is reserved\n", lpos, cpos, words[wwpos]);
|
|
|
|
|
error++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// END VARIABLE DECLARATION
|
|
|
|
|
// now we parse for assignment operations, if available
|
|
|
|
|
// BEGIN VARIABLE SETTING
|
|
|
|
|
} else if (wwpos == 2) {
|
|
|
|
|
wtypes[wwpos] = vm_isReserved(words[wwpos]);
|
|
|
|
|
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++;
|
|
|
|
|
break;
|
|
|
|
|
} 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 {
|
|
|
|
|
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 {
|
|
|
|
|
wtypes[wwpos] = vm_isReserved(words[wwpos]);
|
|
|
|
|
if (wtypes[wwpos] == 4) { // "="
|
|
|
|
@ -460,7 +550,20 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
|
|
|
|
|
error++;
|
|
|
|
|
break;
|
|
|
|
|
} 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 {
|
|
|
|
|
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++) {
|
|
|
|
|
printf("%s ", words[wwpos]);
|
|
|
|
|
}
|
|
|
|
|
printf("\n");
|
|
|
|
|
printf("\n");*/
|
|
|
|
|
// RESET
|
|
|
|
|
wpos = 0;
|
|
|
|
|
wcpos = 0;
|
|
|
|
|
memset(&words, '\0', 31*128);
|
|
|
|
|
// when a '{' is encountered, what follows should be a function.
|
|
|
|
|
// BEGIN FUNCTION PARSING
|
|
|
|
|
} else if (c == '{') {
|
|
|
|
|
// 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
|
|
|
|
|
printf("func, while, etc. baby\n");
|
|
|
|
|
int wwpos = 0;
|
|
|
|
|
// TODO: run a check for function-style adherence
|
|
|
|
|
// TODO: call vm_precompileFunction
|
|
|
|
|
/*int wwpos = 0;
|
|
|
|
|
for(wwpos = 0;wwpos <= wpos;wwpos++) {
|
|
|
|
|
printf("%d: %s\n", wwpos, words[wwpos]);
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
// RESET
|
|
|
|
|
wpos = 0;
|
|
|
|
|
wcpos = 0;
|
|
|
|
|
memset(&words, '\0', 31*128);
|
|
|
|
|
} else if (c == '}') {
|
|
|
|
|
// 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++) {
|
|
|
|
|
printf("%d: %s\n", wwpos, words[wwpos]);
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
// RESET
|
|
|
|
|
wpos = 0;
|
|
|
|
|
wcpos = 0;
|
|
|
|
|
memset(&words, '\0', 31*128);
|
|
|
|
|
// END FUNCTION PARSING
|
|
|
|
|
} else {
|
|
|
|
|
words[wpos][wcpos++] = c;
|
|
|
|
|
}
|
|
|
|
@ -512,6 +618,68 @@ int vm_precompileCode(FILE *file, int *lpos_, int *cpos_, struct vm_pc_Scope *gl
|
|
|
|
|
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 checkpos;
|
|
|
|
|
for (checkpos = 0;checkpos <= MAX_TYPES;checkpos++) {
|
|
|
|
@ -536,3 +704,78 @@ int vm_isReserved(char *word) {
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|