Parameter Passing Jason Fullowan, Mariusz G. Kedziora, George Blank.
Parameter Passing
description
Transcript of Parameter Passing
Parameter Passing
COP 3402 Software SystemsSpring 2014
Parameter Passing
• Passing parameter to procedures (instead of using variables) simplifies some types of programs, i.e., recursive procedures.
int a, b;procedure sum;int c;begin
c := a + b;write c;
end;begin
a = 2;b = 3;call sum;
end.
procedure sum(a,b);int c;begin
c := a + b;write c;
end;begin
call sum(2,3);end.
Parameter Passing
• To implement parameter passing we must modify:– Grammar– Activation Record– Parsing– Code generation
GRAMMAR CHANGES
Grammar Changesprogram ::= block "." . block ::= const-declaration var-declaration procedure-declaration statement.const-declaration ::= ["const" ident "=" number {"," ident "=" number} ";"].var-declaration ::= [ "int "ident {"," ident} “;"].procedure-declaration ::= { "procedure" ident ";" block ";" }statement ::= [ ident ":=" expression
| "call" ident| "begin" statement { ";" statement } "end" | "if" condition "then" statement ["else" statement]| "while" condition "do" statement| "read" ident| "write" expression| e ] .
...
Grammar Changesprogram ::= block "." . block ::= const-declaration var-declaration procedure-declaration statement.const-declaration ::= ["const" ident "=" number {"," ident "=" number} ";"].var-declaration ::= [ "int "ident {"," ident} “;"].procedure-declaration ::= { "procedure" ident param-block ";" block ";" }.param-block ::= "(" [ ident { "," ident} ] ")".param-list ::= "(" [ expression { "," expression} ] ")".statement ::= [ ident ":=" expression
| "call" ident param-list| "begin" statement { ";" statement } "end" | "if" condition "then" statement ["else" statement]| "while" condition "do" statement| "read" ident| "write" expression| e ] .
...
Activation Record Changes
• The AR must be expanded to include the Parameter Slots.
Return Value
Static Link
Dynamic Link
Return Address
Int Slots
…
Return Value
Static Link
Dynamic Link
Return Address
Param Slots
…
Int Slots
…
PARSING CHANGES
PROC-DECL Procedure
procedure PROC-DECL (level);begin while TOKEN = "procedure" do begin GET_TOKEN();
if TOKEN <> IDENT then ERROR (missing procedure declaration);ENTER(procedure, ident);GET_TOKEN();if TOKEN <> ";" then ERROR (procedure declaration must end with ;);GET_TOKEN();BLOCK(level+1);if TOKEN <> ";" then ERROR (no ; at the end of block);GET_TOKEN();
end;end;
procedure-declaration ::= { "procedure" ident ";" block ";" }.
PROC-DECL Procedure
procedure PROC-DECL (level);begin while TOKEN = "procedure" do begin GET_TOKEN();
if TOKEN <> IDENT then ERROR (missing procedure declaration);GET_TOKEN();num_params = PARAM-BLOCK(level);ENTER(procedure, ident, num_params);if TOKEN <> ";" then ERROR (procedure declaration must end with ;);GET_TOKEN();BLOCK(level+1, num_params);if TOKEN <> ";" then ERROR (no ; at the end of block);GET_TOKEN();
end;end;
procedure-declaration ::= { "procedure" ident param-block ";" block ";" }.
PARAM-BLOCK Procedureprocedure PARAM-BLOCK(level);begin
int params = 0;if TOKEN <> "(" then ERROR();GET_TOKEN();if TOKEN == IDENT then begin
params++;param_addr = 4 + params;ENTER(int, ident, param_addr);GET_TOKEN();while TOKEN == "," do begin
GET_TOKEN(); if TOKEN <> IDENT then ERROR();params++;param_addr = 4 + params;ENTER(int, ident, param_addr);GET_TOKEN();
endendif TOKEN <> ")" then ERROR();GET_TOKEN();
return params;end
param-block ::= "(" [ ident { "," ident} ] ")".
STATEMENT Procedureprocedure STATEMENT(level);…
else if TOKEN == "call" then beginGET_TOKEN();IF TOKEN <> IDENT then ERROR();GET_TOKEN();
end…
statement ::= … | "call" ident | …
STATEMENT Procedureprocedure STATEMENT(level, ar_size);…
else if TOKEN == "call" then beginGET_TOKEN();IF TOKEN <> IDENT then ERROR();GET_TOKEN();PARAM-LIST(level, ar_size);
end…
statement ::= … | "call" ident param-list | …
PARAM-LIST Procedureprocedure PARAM-LIST(level, ar_size);begin
if TOKEN <> "(" then ERROR();GET_TOKEN();if TOKEN <> ")" then begin
EXPRESSION();while TOKEN == "," do begin
GET_TOKEN(); EXPRESSION();
endendif TOKEN <> ")" then ERROR();GET_TOKEN();
end
param-list ::= "(" [ expression { "," expression} ] ")".
CODE GENERATION CHANGES
BLOCK Procedure
procedure BLOCK(level, num_params);begin
ar_size = 4 + num_params;jmpaddr = gen(JMP, 0, 0); if TOKEN = “const” then CONST-DECL(level);if TOKEN = “var” then VAR-DECL(level, &ar_size);if TOKEN = “procedure” then PROC-DECL(level);code[jmpaddr].addr = NEXT_CODE_ADDR;gen(INC, 0, ar_size);STATEMENT(level, ar_size);gen(OPR, 0, 0);
end;
PARAM-LIST Procedureprocedure PARAM-LIST(level, ar_size);Begin
int param_count = 0;if TOKEN <> "(" then ERROR();GET_TOKEN();if TOKEN <> ")" then begin
EXPRESSION();param_count++;gen(STO, curreg, 0, ar_size+4+param_count);curreg--;while TOKEN == "," do begin
GET_TOKEN(); EXPRESSION();param_count++;gen(STO, curreg, 0, ar_size+4+param_count);curreg--;
endendif TOKEN <> ")" then ERROR();GET_TOKEN();return param_count;
end
PARAM-LIST must initialize the parameters before we call the procedure.
EXPRESSION() gets the value for the parameter…
…and here we store the value in the parameter.
PARAM-LIST Procedure
Why???
procedure PARAM-LIST(level, ar_size);Begin
int param_count = 0;if TOKEN <> "(" then ERROR();GET_TOKEN();if TOKEN <> ")" then begin
EXPRESSION();param_count++;gen(STO, curreg, 0, ar_size+4+param_count);curreg--;while TOKEN == "," do begin
GET_TOKEN(); EXPRESSION();param_count++;gen(STO, curreg, 0, ar_size+4+param_count);curreg--;
endendif TOKEN <> ")" then ERROR();GET_TOKEN();return param_count;
end
PARAM-LIST Procedure
Return ValueStatic Link
Dynamic LinkReturn Address
Param Slots…
Int Slots…
Return ValueStatic Link
Dynamic LinkReturn Address
Param Slots…
Int Slots…
Current AR
Next AR(not created yet!)
procedure PARAM-LIST(level, ar_size);Begin
int param_count = 0;if TOKEN <> "(" then ERROR();GET_TOKEN();if TOKEN <> ")" then begin
EXPRESSION();param_count++;gen(STO, curreg, 0, ar_size+4+param_count);curreg--;while TOKEN == "," do begin
GET_TOKEN(); EXPRESSION();param_count++;gen(STO, curreg, 0, ar_size+4+param_count);curreg--;
endendif TOKEN <> ")" then ERROR();GET_TOKEN();return param_count;
end
Call Code Generation
procedure STATEMENT(level, ar_size);begin
…else if TOKEN = "call" then begin
GET_TOKEN();if TOKEN <> IDENT then ERROR (missing identifier);i = find(TOKEN);
if i == 0 then ERROR (); if symboltype(i) <> PROCEDURE then ERROR();
param_count = PARAM-LIST(level, ar_size);if param_count <> symbolparams(i) then ERROR();gen(CAL, 0, 0, symboladdr(i));
GET_TOKEN();end
…
Call Code Generation
procedure STATEMENT(level, ar_size);begin
…else if TOKEN = "call" then begin
GET_TOKEN();if TOKEN <> IDENT then ERROR (missing identifier);i = find(TOKEN);
if i == 0 then ERROR (); if symboltype(i) <> PROCEDURE then ERROR();
param_count = PARAM-LIST(level, ar_size);if param_count <> symbolparams(i) then ERROR();gen(CAL, 0, 0, symboladdr(i));
GET_TOKEN();end
…
We must verify that the amount of parameters is exactly the same amount that the procedure declared.