worked on function call return type check and started checking return type

This commit is contained in:
Annie
2025-04-15 00:53:03 -04:00
parent 06db190428
commit 2b1557b52c
5 changed files with 150 additions and 17 deletions

View File

@ -32,12 +32,17 @@
%locations
%type <integ> idlist
%type <tn> assignable
%type <tn> expression
%type <tn> constant
%type <tn> id_or_types
%type <tn> types
%type <tn> sblock
%type <tn> compound_statement
%type <tn> simple_statement
%type <tn> statement_list
%type <integ> argument_list
%type <integ> ablock
%token <words> ID 101
@ -100,6 +105,7 @@
%precedence DOT
%precedence RESERVE RELEASE
%%
program:
@ -247,7 +253,16 @@ definition:
}
//counter = 0;
printdebug("Created a new scope after seeing a function definition");
} idlist R_PAREN ASSIGN sblock //check sblock type
} idlist R_PAREN ASSIGN sblock {
TableNode *expected = getReturn(getTypeEntry(look_up(cur, $1)));
if ($8 == undefined) {
printdebug("sblock return type is undefined");
} else if ($8 != expected) {
printdebug("expected %s as return type but got %s", getName(expected), getName($8));
} else {
printdebug("CORRECT RETURN TYPE!!!");
}
}
;
@ -350,6 +365,7 @@ sblock:
}
statement_list
{
$<tn>$ = $3;
printdebug("Moving up a scope after seeing sblock");
cur = getParent(cur);
}
@ -374,6 +390,7 @@ sblock:
{
printdebug("Moving up a scope after seeing sblock with dblock");
cur = getParent(cur);
$<tn>$ = $5;
}
R_BRACE
;
@ -458,18 +475,59 @@ id_or_types:
statement_list:
compound_statement statement_list
| compound_statement
| simple_statement SEMI_COLON statement_list
| simple_statement SEMI_COLON
compound_statement statement_list {
if ($1 == undefined && $2 != undefined) {
$$ = $2;
} else if ($1 != undefined && $2 == undefined) {
$$ = $1;
} else if ($1 == $2) {
$$ = $1;
} else {
printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column);
$$ = undefined;
}
}
| compound_statement {
$$ = $1;
}
| simple_statement SEMI_COLON statement_list{
if ($1 == undefined && $3 != undefined) {
$$ = $3;
} else if ($1 != undefined && $3 == undefined) {
$$ = $1;
} else if ($1 == $3) {
$$ = $1;
} else {
printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column);
$$ = undefined;
}
}
| simple_statement SEMI_COLON {
$$ = $1;
}
;
compound_statement:
WHILE L_PAREN expression R_PAREN sblock
| IF L_PAREN expression R_PAREN THEN sblock ELSE sblock
| sblock
WHILE L_PAREN expression R_PAREN sblock {
$$ = $5;
}
| IF L_PAREN expression R_PAREN THEN sblock ELSE sblock {
if ($6 == undefined && $8 != undefined) {
$$ = $8;
} else if ($6 != undefined && $8 == undefined) {
$$ = $6;
} else if ($6 == $8) {
$$ = $6;
} else {
printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column);
$$ = undefined;
}
}
| sblock {
$$ = $1;
}
;
@ -517,9 +575,11 @@ simple_statement:
printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, getType(left), getType(right), COLOR_WHITE);
printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(left));
}
$$ = undefined;
}
| RETURN expression
| RETURN expression {$$ = $2;}
;
@ -697,6 +757,7 @@ expression:
else if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE||
getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE||
getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_TYPE||
getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE_TYPE ||
getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){
printdebug("assignable passing up to expression is array type, record type, function type, or function declaration");
$$= ((TableNode*)$1);
@ -751,20 +812,20 @@ assignable:
printdebug("%stype is %d", COLOR_PURPLE, type);
printdebug("%s", getName((TableNode*)$1));
if (type == TYPE_FUNCTION_DECLARATION) {
if (type == TYPE_FUNCTION_TYPE) {
printdebug("%sEntering function call", COLOR_LIGHTGREEN);
if (look_up(getParent(cur), getName((TableNode*)$1))->additionalinfo->FunDecAdInfo->regularoras) {
printdebug("as function");
//char *funtype = getType(look_up(cur, $1));
printdebug("%s", getType(look_up(cur, getName((TableNode*)$1))));
// printdebug("%s", getType(look_up(cur, getName((TableNode*)$1))));
TableNode * typeNode = table_lookup(getAncestor(cur), getType((TableNode*)$1));
TableNode * typeNode = $1;
TableNode *param = getParameter(typeNode);
printTableNode(param);
if (getAdInfoType(param) == TYPE_RECORD) {
if (getAdInfoType(param) == TYPE_RECORD_TYPE) {
SymbolTable *recList = getRecList(param);
TableNode *lastCheckedRef = getFirstEntry(recList);
TableNode *lastCheckedAct = getFirstEntry(cur);
@ -772,12 +833,14 @@ assignable:
lastCheckedRef = getNextEntry(lastCheckedRef);
}
if ($3 != getRecLength(param)) {
printdebug("expected %d arguments but got %d", getRecLength(param), $3);
}
//this isn't very efficient, but will hopefully work
while (lastCheckedAct != NULL && lastCheckedRef != NULL) {
if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) {
if (getTypeEntry(lastCheckedRef) != getTypeEntry(lastCheckedAct)) {
printdebug("expected %s. expression in function call got %s. at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column);
printdebug("%d", strcmp(getName(lastCheckedAct), getName(lastCheckedRef)));
}
lastCheckedAct = getNextEntry(lastCheckedAct);
TableNode *tn = getFirstEntry(recList);
@ -804,8 +867,12 @@ assignable:
if (strcmp(expected, actual) != 0) {
printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column);
}
if ($3 != 1) {
printdebug("expected 1 argument but got %d", $3);
}
}
$$ = getReturn((table_lookup(getAncestor(cur), getType((TableNode*)$1))));
printTableNode(getReturn($1));
$$ = getReturn($1);
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName((TableNode*)$$), getName((TableNode*)$1));
} else if (type == TYPE_ARRAY_TYPE) {

View File

@ -0,0 +1,16 @@
type string: 1 -> character
type a_of_s: 1 -> string
(* maybe some other type definitions *)
entry(arg) := {
[ string: one_name; string: another_name; a_of_s: many_names ]
another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *)
many_names := reserve a_of_s(many_names);
many_names(0) := one_name;
many_names(1) := another_name;
many_names(2) := reserve a_of_s(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";
return 0;
}

View File

@ -0,0 +1,16 @@
type string: 1 -> character
type a_of_s: 1 -> string
(* maybe some other type definitions *)
entry(arg) := {
[ string: one_name; string: another_name; a_of_s: many_names ]
another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *)
many_names := reserve a_of_s(3);
many_names(0) := one_name;
many_names(1) := another_name;
many_names(2) := reserve a_of_s(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";
return 0;
}

View File

@ -0,0 +1,17 @@
type rec: [character: x; integer: y]
type T2: rec -> integer
type main: string -> integer
function entry: main
function bar: T2
bar2 (r,s) := {
return r;
}
entry (arg) := {
[ integer: result ; rec: w]
result := bar('c', 7);
return 0;
}

View File

@ -0,0 +1,17 @@
type rec: [character: x; integer: y]
type T2: rec -> integer
type main: string -> integer
function entry: main
function bar: T2
bar2 (r,s) := {
return s;
}
entry (arg) := {
[ integer: result ; rec: w]
result := bar('c', 7);
return 0;
}