Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generate assembler code for higher-order functions #47

Open
LBacchiani opened this issue Jan 29, 2019 · 1 comment
Open

generate assembler code for higher-order functions #47

LBacchiani opened this issue Jan 29, 2019 · 1 comment

Comments

@LBacchiani
Copy link

LBacchiani commented Jan 29, 2019

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.

@pastafood10
Copy link

binary inside the parenthesis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants