diff --git a/src/grammar.y b/src/grammar.y index 064e56b..5e9ed19 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -752,6 +752,11 @@ ablock: argument_list: expression{ 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 // 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); + 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)); $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); @@ -1094,10 +1104,21 @@ expression: emit_reserve(node, tn_or_const(INTEGER, &v)); $$ = 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 { - cur = CreateScope(cur, -1,-1); - } L_PAREN argument_list R_PAREN { + cur = CreateScope(cur, -2,-1); + } ablock { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); int a = S_Size(S_Peek(stack)) + 1; @@ -1105,6 +1126,81 @@ expression: 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 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(traverseadditionalinfo->RecAdInfo->numofelements; } -// This gets the array. Needs to up be updated to get the scope instead + SymbolTable *getRecList(TableNode *definition) { if (definition == NULL) { printdebug( @@ -462,6 +462,76 @@ int getRecSize(SymbolTable *tn) { } 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 ; // 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) { print_symbol_table(getFirstChild(node), file_ptr); } else { - if (getLine(getFirstChild(node)) == -1) { + if (getLine(getFirstChild(node)) < 0) { continue; } else { print_symbol_table(getFirstChild(node), file_ptr); diff --git a/tests/sprint4/test/sp4_tc_arrays.alpha b/tests/sprint4/test/sp4_tc_arrays.alpha new file mode 100644 index 0000000..19a31de --- /dev/null +++ b/tests/sprint4/test/sp4_tc_arrays.alpha @@ -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; +} \ No newline at end of file