Merge branch 'master' of git.xeserv.us:victorvalenca/platypus

This commit is contained in:
Victor Fernandes 2017-04-17 10:48:57 -04:00
commit 5bd748b2e6
2 changed files with 220 additions and 214 deletions

View File

@ -267,7 +267,7 @@ Token malar_next_token(Buffer * sc_buf)
b_retract_to_mark(sc_buf); b_retract_to_mark(sc_buf);
lex_buf = b_create(1, 1, 'a'); lex_buf = b_create(20, 8, 'a');
/* Copy the scanned lexeme into lexical buffer */ /* Copy the scanned lexeme into lexical buffer */
for (; lexstart < lexend; ++lexstart) { for (; lexstart < lexend; ++lexstart) {

432
stable.c
View File

@ -9,13 +9,13 @@
*/ */
#include "stable.h" #include "stable.h"
#define PLSBD_SZ 256 #define PLSBD_SZ 128
#define PLSBD_INC 8 #define PLSBD_INC 64
#define DEBUG #define DEBUG
/*#undef DEBUG*/ #undef DEBUG*/
/* Forward function declarations */ /* Forward function declarations */
static void st_setsize(void); static void st_setsize(void);
static void st_incoffset(void); static void st_incoffset(void);
extern STD sym_table; extern STD sym_table;
@ -24,30 +24,30 @@ extern STD sym_table;
* Author: Victor Fernandes, 040772243 * Author: Victor Fernandes, 040772243
* Version: 0.0.1 * Version: 0.0.1
* Called functions: malloc, b_create, free * Called functions: malloc, b_create, free
* Parameters: * Parameters:
int - size of the symbol table int - size of the symbol table
* Return value: * Return value:
STD - The symbol table STD - The symbol table
* Algorithm: * Algorithm:
*/ */
STD st_create(int st_size){ STD st_create(int st_size) {
STD new_stable; STD new_stable;
new_stable.plsBD = NULL; new_stable.plsBD = NULL;
new_stable.pstvr = (STVR*)malloc((size_t)st_size * sizeof(STVR)); new_stable.pstvr = (STVR*)malloc((size_t)st_size * sizeof(STVR));
if (st_size <= 0 || (new_stable.pstvr == NULL)) { if (st_size <= 0 || (new_stable.pstvr == NULL)) {
new_stable.st_size = 0; new_stable.st_size = 0;
} }
new_stable.plsBD = b_create(PLSBD_SZ, PLSBD_INC, 'a'); new_stable.plsBD = b_create(PLSBD_SZ, PLSBD_INC, 'a');
if (new_stable.plsBD == NULL) { if (new_stable.plsBD == NULL) {
free(new_stable.plsBD); free(new_stable.plsBD);
new_stable.st_size = 0; new_stable.st_size = 0;
} }
new_stable.st_size = st_size; new_stable.st_size = st_size;
new_stable.st_offset = 0; new_stable.st_offset = 0;
return new_stable; return new_stable;
} }
/* Install a new entry in the symbol table /* Install a new entry in the symbol table
@ -55,101 +55,110 @@ STD st_create(int st_size){
* Version: 0.0.1 * Version: 0.0.1
* Called functions: st_lookup, b_setmark, b_size, b_addc, b_rflag, st_incoffset * Called functions: st_lookup, b_setmark, b_size, b_addc, b_rflag, st_incoffset
* Parameters: * Parameters:
STD - The symbol table STD - The symbol table
char - The lexeme to be stored char - The lexeme to be stored
char - the type of the lexeme char - the type of the lexeme
int - the line in the source file where the lexeme was found int - the line in the source file where the lexeme was found
* Return value: * Return value:
int - the element offset of where the symbol table is pointing to int - the element offset of where the symbol table is pointing to
-1 if an internal error occurs -1 if an internal error occurs
* Algorithm: * Algorithm:
*/ */
int st_install(STD s_table, char *lexeme, char type, int line){ int st_install(STD s_table, char *lexeme, char type, int line) {
unsigned int offset, i, j, lex_len; int offset = -1, i, j, lex_len, lex_offset = 0, flag = 0;
short bd_offset, flag;
/* Cannot add new entry, table full */ /* Cannot add new entry, table full */
if (s_table.st_offset >= s_table.st_size) if (s_table.st_offset >= s_table.st_size)
return -1; return -1;
/* Look for an existing entry in the symbol table */
offset = st_lookup(s_table, lexeme);
if (offset > -1)
return offset;
/* Add lexeme to the symbol table's lexeme buffer */ /* Look for an existing entry in the symbol table */
lex_len = strlen(lexeme); if (s_table.st_offset > 0)
for (i = 0; i <= lex_len; ++i){ offset = st_lookup(s_table, lexeme);
if (!b_addc(s_table.plsBD, lexeme[i]))
return -1;
if (b_rflag(s_table.plsBD) == SET_R_FLAG){ /* COPY NEW ADDRESSES TO PLEX ENTRIES */
flag = 1;
}
}
if (flag == 1){
bd_offset = 0;
for (j = 0; j <= s_table.st_offset; ++j){
s_table.pstvr[j].plex = b_setmark(s_table.plsBD, bd_offset + s_table.pstvr[j].i_value.str_offset);
if (j < s_table.st_offset)
bd_offset += s_table.pstvr[j+1].i_value.str_offset + 1; /*Add one because the offset doesn't include '\0' */
}
}
/* Set proper pointer values on symbol table */ if (offset > -1)
s_table.pstvr[s_table.st_offset].plex = b_setmark(s_table.plsBD, b_size(s_table.plsBD)); return offset;
s_table.pstvr[s_table.st_offset].o_line = line;
/* Add lexeme to the symbol table's lexeme buffer */
lex_len = strlen(lexeme);
for (i = 0; i <= lex_len; ++i) {
if (!b_addc(s_table.plsBD, lexeme[i]))
return -1;
if (b_rflag(s_table.plsBD) == SET_R_FLAG) { /* Trigger reassignment loop once lexeme is stored */
flag = 1;
}
}
/* If reallocation happened...*/
if (flag == 1) {
for (j = 0; j < s_table.st_offset; ++j) {
s_table.pstvr[j].plex = b_setmark(s_table.plsBD, (short) s_table.pstvr[j].i_value.str_offset);
}
}
/* Set the default mask before setting the rest of the masks */ /* Set proper pointer values on symbol table */
s_table.pstvr[s_table.st_offset].status_field = DFT_MASK; /* Get buffer offset location of the lexeme stored */
lex_offset = b_size(s_table.plsBD) - (strlen(lexeme) + 1);
switch (type){ s_table.pstvr[s_table.st_offset].plex = b_setmark(s_table.plsBD, (short) lex_offset);
case 'I': /* Integer type */ s_table.pstvr[s_table.st_offset].o_line = line;
s_table.pstvr[s_table.st_offset].status_field |= INT_MASK; s_table.pstvr[s_table.st_offset].i_value.str_offset = lex_offset;
s_table.pstvr[s_table.st_offset].i_value.int_val = 0;
break;
case 'F': /* Floating point type */
s_table.pstvr[s_table.st_offset].status_field |= FLT_MASK;
s_table.pstvr[s_table.st_offset].i_value.fpl_val = 0.0f;
break;
case 'S': /* String type */
s_table.pstvr[s_table.st_offset].status_field |= STR_MASK;
s_table.pstvr[s_table.st_offset].i_value.str_offset = -1;
break;
default:
return -1; /* Not supposed to fall into here */
}
/* Set the default mask before setting the rest of the masks */
s_table.pstvr[s_table.st_offset].status_field = DFT_MASK;
/* Increment the symbol table offset */ switch (type) {
st_incoffset(); case 'I': /* Integer type */
return s_table.st_offset; s_table.pstvr[s_table.st_offset].status_field |= INT_MASK;
s_table.pstvr[s_table.st_offset].i_value.int_val = 0;
break;
case 'F': /* Floating point type */
s_table.pstvr[s_table.st_offset].status_field |= FLT_MASK;
s_table.pstvr[s_table.st_offset].i_value.fpl_val = 0.0f;
break;
case 'S': /* String type */
s_table.pstvr[s_table.st_offset].status_field |= STR_MASK;
s_table.pstvr[s_table.st_offset].i_value.int_val = -1;
s_table.pstvr[s_table.st_offset].i_value.fpl_val = -1.0f;
break;
default:
return -1; /* Not supposed to fall into here */
}
/* Increment the symbol table offset */
st_incoffset();
return s_table.st_offset;
} }
/* Look up the lexeme string in the symbol table's buffer /* Look up the lexeme string in the symbol table's buffer
* Author: Victor Fernandes * Author: Victor Fernandes
* Version: 0.1 * Version: 0.1
* Called functions: b_setmark, strcmp, strlen * Called functions: b_setmark, strcmp, strlen
* Parameters: * Parameters:
STD - The symbol table STD - The symbol table
char - The lexeme to be searched char - The lexeme to be searched
* Return value: * Return value:
int - the element offset index in the symbol table int - the element offset index in the symbol table
-1 if no element was found -1 if no element was found
*/ */
int st_lookup(STD s_table, char *lexeme){ int st_lookup(STD s_table, char *lexeme) {
int i; /* idx: index location for symbol table, i: increment counter*/ int i; /* idx: index location for symbol table, i: increment counter*/
for (i = s_table.st_offset; i >= 0; --i) {
if (strcmp(lexeme, s_table.pstvr[i].plex) == 0)
return i;
}
#ifdef DEBUG #ifdef DEBUG
printf("found nothing\n"); printf("Looking up %s...", lexeme);
#endif #endif
return -1; /* Found nothing */ for (i = s_table.st_offset - 1; i >= 0; --i) {
if (strcmp(lexeme, s_table.pstvr[i].plex) == 0) {
#ifdef DEBUG
printf("YES\n");
#endif
return i;
}
}
#ifdef DEBUG
printf("NO\n");
#endif
return -1; /* Found nothing */
} }
/* Change the data type indicator of the variable entry located in vid_offset. /* Change the data type indicator of the variable entry located in vid_offset.
@ -157,40 +166,37 @@ int st_lookup(STD s_table, char *lexeme){
* Version: 0.1 * Version: 0.1
* Called functions: N/A * Called functions: N/A
* Parameters: * Parameters:
STD - The symbol table STD - The symbol table
int - the offset location of the VID int - the offset location of the VID
char - the new type of the VID char - the new type of the VID
* Return value: * Return value:
1 if change successful, -1 if no change was made or internal error 1 if change successful, -1 if no change was made or internal error
*/ */
int st_change_type(STD s_table, int vid_offset, char v_type) { int st_change_type(STD s_table, int vid_offset, char v_type) {
/* Do nothing if update flag has already been set */ /* Do nothing if update flag has already been set */
if ((s_table.pstvr[vid_offset].status_field & U_MASK)) return -1; if ((s_table.pstvr[vid_offset].status_field & U_MASK)) return -1;
/* Reset to new type with default mask and update flag /* Reset to new type with default mask and update flag
Note: Can separate the statements to set the update flag at the Note: Can separate the statements to set the update flag at the
end, but this resets AND updates at once end, but this resets AND updates at once
*/ */
/*sym_table.pstvr[vid_offset].status_field = sym_table.pstvr[vid_offset].status_field & DFT_U_MASK;*/ /*sym_table.pstvr[vid_offset].status_field = sym_table.pstvr[vid_offset].status_field & DFT_U_MASK;*/
s_table.pstvr[vid_offset].status_field &= DFT_U_MASK; s_table.pstvr[vid_offset].status_field &= DFT_U_MASK;
/*TODO: Ask if re-setting flags and "bailing out" is spec breaking, and switch (v_type) {
if flags should only be set if v_type is valid */ case 'I': /* Integer type */
s_table.pstvr[vid_offset].status_field |= INT_MASK;
switch (v_type){ break;
case 'I': /* Integer type */ case 'F': /* Floating point type */
s_table.pstvr[s_table.st_offset].status_field |= INT_MASK; s_table.pstvr[vid_offset].status_field |= FLT_MASK;
break; break;
case 'F': /* Floating point type */ case 'S': /* String type, do nothing as it cannot be changed */
s_table.pstvr[s_table.st_offset].status_field |= FLT_MASK; break;
break; default:
case 'S': /* String type, do nothing as it cannot be changed */ return -1; /* Not supposed to fall into here */
break; }
default: return 1;
return -1; /* Not supposed to fall into here */
}
return 1;
} }
@ -199,14 +205,14 @@ int st_change_type(STD s_table, int vid_offset, char v_type) {
* Version: 0.0.1 * Version: 0.0.1
* Called functions: N/A * Called functions: N/A
* Parameters: * Parameters:
STD - The symbol table STD - The symbol table
int - the offset location of the VID int - the offset location of the VID
Value - the new value of the VID Value - the new value of the VID
* Return value: the offset location of the VID * Return value: the offset location of the VID
*/ */
int st_change_value(STD s_table, int vid_offset, Value value){ int st_change_value(STD s_table, int vid_offset, Value value) {
s_table.pstvr[vid_offset].i_value = value; s_table.pstvr[vid_offset].i_value = value;
return vid_offset; return vid_offset;
} }
/* Get the type of the variable specified by vid_offset /* Get the type of the variable specified by vid_offset
@ -214,25 +220,25 @@ int st_change_value(STD s_table, int vid_offset, Value value){
* Version: 0.0.1 * Version: 0.0.1
* Called functions: N/A * Called functions: N/A
* Parameters: * Parameters:
STD - The symbol table STD - The symbol table
int - the offset of the VID in the table int - the offset of the VID in the table
* Return value: * Return value:
char - the type of the VID ('I','F', or 'S') char - the type of the VID ('I','F', or 'S')
-1 if there is an invalid value set -1 if there is an invalid value set
*/ */
char st_get_type(STD s_table, int vid_offset){ char st_get_type(STD s_table, int vid_offset) {
unsigned short mask; unsigned short mask;
mask = s_table.pstvr[vid_offset].status_field & CHK_MASK; mask = s_table.pstvr[vid_offset].status_field & CHK_MASK;
switch (mask){ switch (mask) {
case INT_MASK: case INT_MASK:
return 'I'; return 'I';
case FLT_MASK: case FLT_MASK:
return 'F'; return 'F';
case STR_MASK: case STR_MASK:
return 'S'; return 'S';
default: default:
return -1; /* Not supposed to fall into here */ return -1; /* Not supposed to fall into here */
} }
} }
/* Return the i_value of the variable specified by vid_offset /* Return the i_value of the variable specified by vid_offset
@ -240,14 +246,14 @@ char st_get_type(STD s_table, int vid_offset){
* Version: 0.0.1 * Version: 0.0.1
* Called functions: * Called functions:
* Parameters: * Parameters:
STD - The symbol table STD - The symbol table
int - the offset of the VID in the table int - the offset of the VID in the table
* Return value: * Return value:
Value - the value of the VID Value - the value of the VID
Incorrect parameters will cause undefined behaviour Incorrect parameters will cause undefined behaviour
*/ */
Value st_get_value(STD s_table, int vid_offset){ Value st_get_value(STD s_table, int vid_offset) {
return s_table.pstvr[vid_offset].i_value; return s_table.pstvr[vid_offset].i_value;
} }
/* Free memory used by the symbol table /* Free memory used by the symbol table
@ -255,14 +261,14 @@ Value st_get_value(STD s_table, int vid_offset){
* Version: 0.0.1 * Version: 0.0.1
* Called functions: free, b_free * Called functions: free, b_free
* Parameters: * Parameters:
STD - The symbol table STD - The symbol table
*/ */
void st_destroy(STD s_table){ void st_destroy(STD s_table) {
if (s_table.pstvr != NULL){ if (s_table.pstvr != NULL) {
free(s_table.pstvr); free(s_table.pstvr);
s_table.pstvr = NULL; s_table.pstvr = NULL;
} }
b_free(s_table.plsBD); b_free(s_table.plsBD);
} }
/* Print the contents of the symbol table to standard output /* Print the contents of the symbol table to standard output
@ -270,70 +276,70 @@ void st_destroy(STD s_table){
* Version: 0.0.1 * Version: 0.0.1
* Called functions: printf * Called functions: printf
* Parameters: * Parameters:
STD - The symbol table STD - The symbol table
* Return value: * Return value:
int - the number of items printed to stdout int - the number of items printed to stdout
*/ */
int st_print(STD s_table){ int st_print(STD s_table) {
int i; int i;
if (s_table.st_size <=0) return -1;
printf("Symbol Table\n____________\nLine Number\tVariable Identifier\n");
for(i = 0; i < s_table.st_offset; ++i)
printf("%2d\t\t%s\n", s_table.pstvr[i].o_line, s_table.pstvr[i].plex);
return i;
}
/* Store the symbol table to a file named $stable.ste. if (s_table.st_size <= 0) return -1;
printf("Symbol Table\n____________\nLine Number\tVariable Identifier\n");
for (i = 0; i <= s_table.st_offset - 1 ; ++i)
printf("%2d\t\t%s\n", s_table.pstvr[i].o_line, s_table.pstvr[i].plex);
return i;
}
/* Store the symbol table to a file named $stable.ste.
It overwrites any existing file named $stable.ste. It overwrites any existing file named $stable.ste.
* Author: Victor Fernandes, 040772243 * Author: Victor Fernandes, 040772243
* Version: 0.0.1 * Version: 0.0.1
* Called functions: fopen, fprintf, st_get_type, fclose, printf * Called functions: fopen, fprintf, st_get_type, fclose, printf
* Parameters: * Parameters:
STD - The symbol table STD - The symbol table
* Return value: * Return value:
int - the number of items stored int - the number of items stored
-1 if the file stream cannot be opened -1 if the file stream cannot be opened
*/ */
int st_store(STD s_table){ int st_store(STD s_table) {
FILE *out; /* The target file*/ FILE *out; /* The target file*/
int i; int i;
/* Windows does not like fopen, and fopen_s is Windows-only. This will ensure the /* Windows does not like fopen, and fopen_s is Windows-only. This will ensure the
* use of the proper function call if PLATYPUS is being built on a non-windows system. * use of the proper function call if PLATYPUS is being built on a non-windows system.
* Best approach is to add _CRT_SECURE_NO_WARNINGS to the preprocessor definitions, but * Best approach is to add _CRT_SECURE_NO_WARNINGS to the preprocessor definitions, but
* this works, too. * this works, too.
*/ */
#ifdef _WIN32 #ifdef _WIN32
if (fopen_s(&out, ST_FILE_NAME, "w+") != 0 || out == NULL) if (fopen_s(&out, ST_FILE_NAME, "w+") != 0 || out == NULL)
#else #else
if ((out = fopen(ST_FILE_NAME, "w+")) == NULL) if ((out = fopen(ST_FILE_NAME, "w+")) == NULL)
#endif #endif
return -1; /* Can't open file, stop. */ return -1; /* Can't open file, stop. */
fprintf(out, "%d", s_table.st_size); fprintf(out, "%d", s_table.st_size);
for(i = 0; i < s_table.st_size; ++i){ for (i = 0; i < s_table.st_offset; ++i) {
fprintf(out, " %4X %d %s %d", fprintf(out, " %4X %d %s %d",
s_table.pstvr[i].status_field, /* Status flag */ s_table.pstvr[i].status_field, /* Status flag */
(int)strlen(s_table.pstvr[i].plex), /* Length of lexeme */ (int)strlen(s_table.pstvr[i].plex), /* Length of lexeme */
s_table.pstvr[i].plex, /* The lexeme itself */ s_table.pstvr[i].plex, /* The lexeme itself */
s_table.pstvr[i].o_line); /* Line number */ s_table.pstvr[i].o_line); /* Line number */
/* Initial value */ /* Initial value */
char type = st_get_type(s_table, i); char type = st_get_type(s_table, i);
switch (type){ switch (type) {
case 'I': case 'I':
case 'F': case 'F':
case 'S': case 'S':
fprintf(out, " %c", type); fprintf(out, " %c", type);
} }
} }
fclose(out); fclose(out);
printf("Symbol Table stored\n"); printf("Symbol Table stored\n");
return i; return i;
} }
@ -344,10 +350,10 @@ int st_store(STD s_table){
* Parameters: N/A * Parameters: N/A
* Return value: N/A * Return value: N/A
*/ */
static void st_setsize(void){ static void st_setsize(void) {
sym_table.st_size = 0; sym_table.st_size = 0;
} }
/* Internal function to increment st_offset by 1. /* Internal function to increment st_offset by 1.
* Author: Victor Fernandes, 040772243 * Author: Victor Fernandes, 040772243
* Version: 0.0.1 * Version: 0.0.1
@ -355,8 +361,8 @@ static void st_setsize(void){
* Parameters: N/A * Parameters: N/A
* Return value: N/A * Return value: N/A
*/ */
static void st_incoffset(void){ static void st_incoffset(void) {
++sym_table.st_offset; ++sym_table.st_offset;
} }
@ -364,13 +370,13 @@ static void st_incoffset(void){
* Author: Victor Fernandes, 040772243 * Author: Victor Fernandes, 040772243
* Version: 0.0.1 * Version: 0.0.1
* Called functions: * Called functions:
* Parameters: * Parameters:
* Return value: * Return value:
* Algorithm: * Algorithm:
*/ */
int st_sort(STD s_table, char s_order){ int st_sort(STD s_table, char s_order) {
/* Compiler warning about unused parameter, /* Compiler warning about unused parameters,
* this is fine for this "future" implementation * this is fine for this dummy method
*/ */
return 0; /* SYKE! */ return 0; /* SYKE! */
} }