diff --git a/src/grammar.y b/src/grammar.y index b10933b..ab9e3a2 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -32,12 +32,17 @@ %locations + %type idlist %type assignable %type expression %type constant %type id_or_types %type types +%type sblock +%type compound_statement +%type simple_statement +%type statement_list %type argument_list %type ablock %token 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 { + $$ = $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); + $$ = $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) { diff --git a/tests/sprint2/test/sp2_sp2_arrayargs.alpha b/tests/sprint2/test/sp2_sp2_arrayargs.alpha new file mode 100644 index 0000000..dfb0332 --- /dev/null +++ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha @@ -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; +} \ No newline at end of file diff --git a/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ new file mode 100644 index 0000000..ce1673d --- /dev/null +++ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ @@ -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; +} \ No newline at end of file diff --git a/tests/sprint3/test/sp3_multiple_args.alpha b/tests/sprint3/test/sp3_multiple_args.alpha new file mode 100644 index 0000000..e59c4b6 --- /dev/null +++ b/tests/sprint3/test/sp3_multiple_args.alpha @@ -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; +} \ No newline at end of file diff --git a/tests/sprint3/test/sp3_multiple_args.alpha~ b/tests/sprint3/test/sp3_multiple_args.alpha~ new file mode 100644 index 0000000..641c654 --- /dev/null +++ b/tests/sprint3/test/sp3_multiple_args.alpha~ @@ -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; +} \ No newline at end of file