generate assembler code for higher-order functions
Opened this issue · 1 comments
I have to create a compilare for a fool Language where functions can be passed as parameters. I have these instructions to create assembler code:
`grammar SVM;
@Header {
import java.util.HashMap;
}
@lexer::members {
int lexicalErrors=0;
}
@parser::members {
int[] code = new int[ExecuteVM.CODESIZE];
private int i = 0;
private HashMap<String,Integer> labelAdd = new HashMap<String,Integer>();
private HashMap<Integer,String> labelRef = new HashMap<Integer,String>();
}
/*------------------------------------------------------------------
- PARSER RULES
------------------------------------------------------------------/
assembly:
( PUSH n=NUMBER {code[i++] = PUSH;
code[i++] = Integer.parseInt($n.text);}
| PUSH l=LABEL {code[i++] = PUSH; //
labelRef.put(i++,$l.text);}
| POP {code[i++] = POP;}
| ADD {code[i++] = ADD;}
| SUB {code[i++] = SUB;}
| MULT {code[i++] = MULT;}
| DIV {code[i++] = DIV;}
| STOREW {code[i++] = STOREW;} //
| LOADW {code[i++] = LOADW;} //
| l=LABEL COL {labelAdd.put($l.text,i);}
| BRANCH l=LABEL {code[i++] = BRANCH;
labelRef.put(i++,$l.text);}
| BRANCHEQ l=LABEL {code[i++] = BRANCHEQ; //
labelRef.put(i++,$l.text);}
| BRANCHLESSEQ l=LABEL {code[i++] = BRANCHLESSEQ;
labelRef.put(i++,$l.text);}
| JS {code[i++] = JS;} //
| LOADRA {code[i++] = LOADRA;} //
| STORERA {code[i++] = STORERA;} //
| LOADRV {code[i++] = LOADRV;} //
| STORERV {code[i++] = STORERV;} //
| LOADFP {code[i++] = LOADFP;} //
| STOREFP {code[i++] = STOREFP;} //
| COPYFP {code[i++] = COPYFP;} //
| LOADHP {code[i++] = LOADHP;} //
| STOREHP {code[i++] = STOREHP;} //
| PRINT {code[i++] = PRINT;}
| HALT {code[i++] = HALT;}
)* { for (Integer refAdd: labelRef.keySet()) {
code[refAdd]=labelAdd.get(labelRef.get(refAdd));
}
} ;
/*------------------------------------------------------------------
- LEXER RULES
------------------------------------------------------------------/
PUSH : 'push' ;
POP : 'pop' ;
ADD : 'add' ;
SUB : 'sub' ;
MULT : 'mult' ;
DIV : 'div' ;
STOREW : 'sw' ;
LOADW : 'lw' ;
BRANCH : 'b' ;
BRANCHEQ : 'beq' ;
BRANCHLESSEQ:'bleq' ;
JS : 'js' ;
LOADRA : 'lra' ;
STORERA : 'sra' ;
LOADRV : 'lrv' ;
STORERV : 'srv' ;
LOADFP : 'lfp' ;
STOREFP : 'sfp' ;
COPYFP : 'cfp' ;
LOADHP : 'lhp' ;
STOREHP : 'shp' ;
PRINT : 'print' ;
HALT : 'halt' ;
COL : ':' ;
LABEL : ('a'..'z'|'A'..'Z')('a'..'z' | 'A'..'Z' | '0'..'9')* ;
NUMBER : '0' | ('-')?(('1'..'9')('0'..'9')*) ;
WHITESP : (' '|'\t'|'\n'|'\r')+ -> channel(HIDDEN) ;
ERR : . { System.out.println("Invalid char: "+ getText()); lexicalErrors++; } -> channel(HIDDEN); `
I have to generate the code for this small program:
`
let
fun g:int(x:(int,int)->int)
x(5,7);
fun f:int(c:int)
let
fun linsum:int(a:int,b:int)
(a+b)*c;
in
g(linsum);
in
print(f(5));
`
I have generated this code but the result isn'correct:
`push 0
push function0
push function2
lfp
push 5
lfp
push -3
lfp
add
lw
js
print
halt
function0:
cfp
lra
lfp
push 7
push 5
lfp
push 2
lfp
add
lw
js
srv
sra
pop
pop
pop
sfp
lrv
lra
js
function1:
cfp
lra
push 1
lfp
add
lw
push 2
lfp
add
lw
add
push 1
lfp
lw
add
lw
mult
srv
sra
pop
pop
pop
sfp
lrv
lra
js
function2:
cfp
lra
push function1
lfp
push -2
lfp
add
lw
push -4
lfp
add
lw
lfp
lw
push -2
lfp
lw
add
lw
js
srv
pop
sra
pop
pop
sfp
lrv
lra
js
`
but the result is 420 and i have to get 60. I have found the error into three nodes: funNode's code generation, callNode's code generation and idNode's code generation:
funNode:
` public String codeGeneration() {
String declCode="";
for (Node dec:declist) declCode+=dec.codeGeneration();
String popDecl="";
for (DecNode dec:declist.stream().map(x->(DecNode)x).collect(Collectors.toList())) {
if (dec.getSymType() instanceof ArrowTypeNode) {
popDecl+="pop\n";
}
popDecl+="pop\n";
}
String popParl="";
for (DecNode par:parlist.stream().map(x->(DecNode)x).collect(Collectors.toList()))
{
if (par.getSymType() instanceof ArrowTypeNode) {
popParl+="pop\n";
}
popParl+="pop\n";
}
String funl=FOOLlib.freshFunLabel();
FOOLlib.putCode(funl+":\n"+
"cfp\n"+
"lra\n"+
declCode+
exp.codeGeneration()+
"srv\n"+
popDecl+
"sra\n"+
"pop\n"+
popParl+
"sfp\n"+
"lrv\n"+
"lra\n"+
"js\n"
);
return
"push "+ funl + "\n";
}`
CallNode:
return "lfp \n"+ parCode+ "lfp\n"+getAR+ "push "+entry.getOffset()+"\n"+ "lfp\n"+getAR+ "add\n"+ "lw\n"+ "js\n";
id Node:
`
return
"push "+(entry.getOffset())+"\n"+
"lfp\n"+getAR+
"add\n"+
"lw\n";
`
but I don't know how to fix them.
binary inside the parenthesis