Skip to content

generate assembler code for higher-order functions  #47

@LBacchiani

Description

@LBacchiani

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions