working on making sure arrays and reserve/release are working properly
This commit is contained in:
140
src/grammar.y
140
src/grammar.y
@ -752,6 +752,11 @@ ablock:
|
|||||||
argument_list:
|
argument_list:
|
||||||
expression{
|
expression{
|
||||||
TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL);
|
TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL);
|
||||||
|
if(getLine(cur)==-2){
|
||||||
|
if(getTypeEntry(arg) != integ){
|
||||||
|
throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// this is emitting the param withthe wrong TableNode
|
// this is emitting the param withthe wrong TableNode
|
||||||
// We need to fiture out how to get the right one.
|
// We need to fiture out how to get the right one.
|
||||||
@ -772,6 +777,11 @@ argument_list:
|
|||||||
|
|
||||||
{
|
{
|
||||||
TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL);
|
TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL);
|
||||||
|
if(getLine(cur)==-2){
|
||||||
|
if(getTypeEntry(arg) != integ){
|
||||||
|
throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
emit_parameter(tn_or_const(NODE,$1));
|
emit_parameter(tn_or_const(NODE,$1));
|
||||||
$$ = 1;
|
$$ = 1;
|
||||||
printdebug("[ARGUMENT_LIST] argument list is %d", $$);
|
printdebug("[ARGUMENT_LIST] argument list is %d", $$);
|
||||||
@ -1094,10 +1104,21 @@ expression:
|
|||||||
emit_reserve(node, tn_or_const(INTEGER, &v));
|
emit_reserve(node, tn_or_const(INTEGER, &v));
|
||||||
$$ = node;
|
$$ = node;
|
||||||
}
|
}
|
||||||
| RELEASE ID {$$ = undefined; }
|
| RELEASE ID {
|
||||||
|
TableNode * n = look_up(cur, $2);
|
||||||
|
if(getAdInfoType(n) != TYPE_RECORD){
|
||||||
|
throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.",
|
||||||
|
getName((TableNode*)n), getType((TableNode*)n));
|
||||||
|
$$=undefined;
|
||||||
|
}
|
||||||
|
char* temp = temp_var_gen();
|
||||||
|
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
|
||||||
|
//emit release needed here
|
||||||
|
$$ = node;
|
||||||
|
}
|
||||||
| RESERVE ID {
|
| RESERVE ID {
|
||||||
cur = CreateScope(cur, -1,-1);
|
cur = CreateScope(cur, -2,-1);
|
||||||
} L_PAREN argument_list R_PAREN {
|
} ablock {
|
||||||
char* temp = temp_var_gen();
|
char* temp = temp_var_gen();
|
||||||
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL);
|
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL);
|
||||||
int a = S_Size(S_Peek(stack)) + 1;
|
int a = S_Size(S_Peek(stack)) + 1;
|
||||||
@ -1105,6 +1126,81 @@ expression:
|
|||||||
S_Pop(stack);
|
S_Pop(stack);
|
||||||
emit_function_call(node, a, tn_or_const(NODE, $2));
|
emit_function_call(node, a, tn_or_const(NODE, $2));
|
||||||
$$ = node;
|
$$ = node;
|
||||||
|
TableNode * n = look_up(cur, $2);
|
||||||
|
if(getAdInfoType(n) != TYPE_ARRAY){
|
||||||
|
throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.",
|
||||||
|
getName(n), getType(n));
|
||||||
|
$$=undefined;
|
||||||
|
}
|
||||||
|
//doing more complicated type checking in a block
|
||||||
|
if(getNumArrDim(getTypeEntry(n)) != $4){
|
||||||
|
throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", getNumArrDim(getTypeEntry(n)), $4);
|
||||||
|
$$=undefined;
|
||||||
|
}
|
||||||
|
cur = getParent(cur);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*TableNode * t = getFirstEntry(cur);
|
||||||
|
TableNode * n = look_up(cur, $2);
|
||||||
|
if(getAdInfoType(n) == TYPE_ARRAY){
|
||||||
|
int array_dims = getNumArrDim(getTypeEntry(n));
|
||||||
|
if ($5 != array_dims) {
|
||||||
|
throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5);
|
||||||
|
}else{
|
||||||
|
int traverse = 0;
|
||||||
|
while(t != NULL && t != undefined && getName(t)[0] != '&'){
|
||||||
|
t = getNextEntry(t);
|
||||||
|
}
|
||||||
|
if(getTypeEntry(t) != integ){
|
||||||
|
throw_error(ERROR_TYPE, "Arg for an array is not of type integer");
|
||||||
|
$$= undefined;
|
||||||
|
}else{
|
||||||
|
//seen first number
|
||||||
|
traverse++;
|
||||||
|
t = getNextEntry(t);
|
||||||
|
while(traverse<array_dims){
|
||||||
|
while(t !=NULL && t!=undefined && getName(t)[0]!='&'){
|
||||||
|
t = getNextEntry(t);
|
||||||
|
}
|
||||||
|
if(getTypeEntry(t) != integ){
|
||||||
|
throw_error(ERROR_TYPE, "Arg for an array is not of type integer");
|
||||||
|
$$= undefined;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
traverse++;
|
||||||
|
t = getNextEntry(t);
|
||||||
|
}
|
||||||
|
if(traverse != array_dims){
|
||||||
|
throw_error(ERROR_TYPE, "Invalid number of arguments for array %s. Expected %d but got %d", getName(n), array_dims, traverse);
|
||||||
|
$$= undefined;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
| RELEASE ID {
|
||||||
|
cur = CreateScope(cur, -2,-1);
|
||||||
|
} ablock {
|
||||||
|
char* temp = temp_var_gen();
|
||||||
|
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL);
|
||||||
|
int a = S_Size(S_Peek(stack)) + 1;
|
||||||
|
emit_push_all(S_Peek(stack));
|
||||||
|
S_Pop(stack);
|
||||||
|
emit_function_call(node, a, tn_or_const(NODE, $2));
|
||||||
|
$$ = node;
|
||||||
|
TableNode * n = look_up(cur, $2);
|
||||||
|
if(getAdInfoType(n) != TYPE_ARRAY){
|
||||||
|
throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.",
|
||||||
|
getName(n), getType(n));
|
||||||
|
$$=undefined;
|
||||||
|
}
|
||||||
|
//doing more complicated type checking in a block
|
||||||
|
if(getNumArrDim(getTypeEntry(n)) != $4){
|
||||||
|
throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", getNumArrDim(getTypeEntry(n)), $4);
|
||||||
|
$$=undefined;
|
||||||
|
}
|
||||||
|
cur = getParent(cur);
|
||||||
/*
|
/*
|
||||||
TableNode * t = getFirstEntry(cur);
|
TableNode * t = getFirstEntry(cur);
|
||||||
TableNode * n = look_up(cur, $2);
|
TableNode * n = look_up(cur, $2);
|
||||||
@ -1113,41 +1209,37 @@ expression:
|
|||||||
if ($5 != array_dims) {
|
if ($5 != array_dims) {
|
||||||
throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5);
|
throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", array_dims, $5);
|
||||||
}else{
|
}else{
|
||||||
|
int traverse = 0;
|
||||||
while(t != NULL && t != undefined && getName(t)[0] != '&'){
|
while(t != NULL && t != undefined && getName(t)[0] != '&'){
|
||||||
t = getNextEntry(t);
|
t = getNextEntry(t);
|
||||||
}
|
}
|
||||||
if(getTypeEntry(t) != integ){
|
if(getTypeEntry(t) != integ){
|
||||||
throw_error(ERROR_TYPE, "Arg for an array is not of type integer");
|
throw_error(ERROR_TYPE, "Arg for an array is not of type integer");
|
||||||
}
|
$$= undefined;
|
||||||
|
}else{
|
||||||
|
//seen first number
|
||||||
|
traverse++;
|
||||||
t = getNextEntry(t);
|
t = getNextEntry(t);
|
||||||
|
while(traverse<array_dims){
|
||||||
while(t !=NULL && t!=undefined && getName(t)[0]!='&'){
|
while(t !=NULL && t!=undefined && getName(t)[0]!='&'){
|
||||||
while(getTypeEntry(t) != integ)(arg_given != NULL && getName(arg_given)[0]!='&'){
|
t = getNextEntry(t);
|
||||||
arg_given = getNextEntry(arg_given);
|
|
||||||
}
|
}
|
||||||
if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){
|
if(getTypeEntry(t) != integ){
|
||||||
throw_error(ERROR_TYPE, "expected type %s expression as argument of a record in function call but got type %s", getType(param_arg_type), getType(arg_given));
|
throw_error(ERROR_TYPE, "Arg for an array is not of type integer");
|
||||||
|
$$= undefined;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
arg_given = getNextEntry(arg_given);
|
traverse++;
|
||||||
param_arg_type = getNextEntry(param_arg_type);
|
t = getNextEntry(t);
|
||||||
|
}
|
||||||
|
if(traverse != array_dims){
|
||||||
|
throw_error(ERROR_TYPE, "Invalid number of arguments for array %s. Expected %d but got %d", getName(n), array_dims, traverse);
|
||||||
|
$$= undefined;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
| RELEASE ID L_PAREN argument_list R_PAREN
|
|
||||||
{
|
|
||||||
int d = getAdInfoType((TableNode*)$2);
|
|
||||||
//commenting out type checks for now since assignable is being resolved to something before reserve is being applied which is tricky
|
|
||||||
//if(d == TYPE_ARRAY ||d == TYPE_RECORD) {
|
|
||||||
char* temp = temp_var_gen();
|
|
||||||
TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL);
|
|
||||||
//NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK)
|
|
||||||
$$ = node;
|
|
||||||
// } else {
|
|
||||||
// throw_error(ERROR_TYPE, "Invalid memOp expression with object %s of type %s.", getName((TableNode*)$2), getType((TableNode*)$2));
|
|
||||||
// $$=undefined;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
| RELEASE assignable
|
| RELEASE assignable
|
||||||
{
|
{
|
||||||
|
@ -408,7 +408,7 @@ int getRecLength(TableNode *definition) {
|
|||||||
}
|
}
|
||||||
return definition->additionalinfo->RecAdInfo->numofelements;
|
return definition->additionalinfo->RecAdInfo->numofelements;
|
||||||
}
|
}
|
||||||
// This gets the array. Needs to up be updated to get the scope instead
|
|
||||||
SymbolTable *getRecList(TableNode *definition) {
|
SymbolTable *getRecList(TableNode *definition) {
|
||||||
if (definition == NULL) {
|
if (definition == NULL) {
|
||||||
printdebug(
|
printdebug(
|
||||||
@ -462,6 +462,76 @@ int getRecSize(SymbolTable *tn) {
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
int getRecPosition(TableNode* rec, char* id){
|
||||||
|
if (rec == NULL) {
|
||||||
|
printdebug(
|
||||||
|
"passed a NULL entry to getRecPosition. Invalid.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (rec == undefined) {
|
||||||
|
printdebug(
|
||||||
|
"passed an undefined entry to getRecPosition. Invalid.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (getAdInfoType(rec) != TYPE_RECORD_TYPE) {
|
||||||
|
printdebug(
|
||||||
|
"not checking the position of a record -- invalid op");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
TableNode* cur = getFirstEntry(getRecList(rec));
|
||||||
|
int i = 1;
|
||||||
|
while(cur != NULL){
|
||||||
|
if(strcmp(getName(cur), id) == 0){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
cur = getNextEntry(cur);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (cur == NULL){
|
||||||
|
printdebug(
|
||||||
|
"passed an invalid entry to getRecPosition. Invalid.");
|
||||||
|
return -1;
|
||||||
|
}else{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getElementOffset(TableNode *rec, char* id) {
|
||||||
|
if (rec == NULL) {
|
||||||
|
printdebug(
|
||||||
|
"passed a NULL entry to getElementOffset. Invalid.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (rec == undefined) {
|
||||||
|
printdebug(
|
||||||
|
"passed an undefined entry to getElementOffset. Invalid.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (getAdInfoType(rec) != TYPE_RECORD_TYPE) {
|
||||||
|
printdebug(
|
||||||
|
"not checking the offset of a record -- invalid op");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int* offsets = getRecOffsets(rec);
|
||||||
|
int position = getRecPosition(rec, id);
|
||||||
|
if (position == -1) {
|
||||||
|
printdebug(
|
||||||
|
"passed an invalid entry to getElementOffset. Invalid.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
position = position - 1;
|
||||||
|
int total_offset = 0;
|
||||||
|
int current_position = 1;
|
||||||
|
while(current_position < position+1){
|
||||||
|
//adding current element in struct
|
||||||
|
total_offset += offsets[2*current_position];
|
||||||
|
//adding padding between elements
|
||||||
|
total_offset += offsets[2*current_position+1];
|
||||||
|
current_position++;
|
||||||
|
}
|
||||||
|
//returning the offset of the start of the element
|
||||||
|
return total_offset;
|
||||||
|
}
|
||||||
|
|
||||||
// below function takes a bool to see if parameter should be decomposed or not
|
// below function takes a bool to see if parameter should be decomposed or not
|
||||||
; // note that functions only take one input and have one output
|
; // note that functions only take one input and have one output
|
||||||
@ -1419,7 +1489,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) {
|
|||||||
if ((getFirstChild(node)) == NULL) {
|
if ((getFirstChild(node)) == NULL) {
|
||||||
print_symbol_table(getFirstChild(node), file_ptr);
|
print_symbol_table(getFirstChild(node), file_ptr);
|
||||||
} else {
|
} else {
|
||||||
if (getLine(getFirstChild(node)) == -1) {
|
if (getLine(getFirstChild(node)) < 0) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
print_symbol_table(getFirstChild(node), file_ptr);
|
print_symbol_table(getFirstChild(node), file_ptr);
|
||||||
|
27
tests/sprint4/test/sp4_tc_arrays.alpha
Normal file
27
tests/sprint4/test/sp4_tc_arrays.alpha
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
type string: 1 -> character
|
||||||
|
type a_of_s: 1 -> string
|
||||||
|
type main: integer -> integer
|
||||||
|
function entry: main
|
||||||
|
|
||||||
|
(* maybe some other type definitions *)
|
||||||
|
|
||||||
|
entry(arg) := {
|
||||||
|
[ string: one_name; string: another_name; a_of_s: many_names ]
|
||||||
|
one_name := "a string literal";
|
||||||
|
another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *)
|
||||||
|
another_name(0) := 'C';
|
||||||
|
another_name(1) := 'a';
|
||||||
|
another_name(2) := 'r';
|
||||||
|
another_name(3) := 'l';
|
||||||
|
many_names := reserve many_names(3);
|
||||||
|
many_names(0) := one_name;
|
||||||
|
many_names(1) := another_name;
|
||||||
|
many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *)
|
||||||
|
many_names(2)(0) := 'P';
|
||||||
|
many_names(2)(1) := 'a';
|
||||||
|
many_names(2)(2) := 'r';
|
||||||
|
many_names(2)(3) := 't';
|
||||||
|
many_names(2)(4) := 'h';
|
||||||
|
many_names(2)(5) := 'o';
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user