Skip to content

Commit

Permalink
recursive function works
Browse files Browse the repository at this point in the history
  • Loading branch information
geno authored and gabrielegenovese committed Jul 9, 2024
1 parent 64500ab commit 34ab5b9
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 69 deletions.
18 changes: 13 additions & 5 deletions src/ast/nodes/AtomNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ public class AtomNode implements Node {

protected String val;
protected TestlistCompNode exprlist;

// very scatchy
protected int ns;
protected int offset;

public AtomNode(String val, Node exprlist) {
Expand All @@ -40,7 +41,9 @@ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
errors.add(new SemanticError("name '" + getId() + "' is not defined."));
} else {
// System.out.println("exist " + getId());
if ((typeCheck() instanceof AtomType)){
if ((typeCheck() instanceof AtomType)) {
int varNs = ST.lookup(getId()).getNesting();
ns = _nesting - varNs;
offset = ST.lookup(getId()).getOffset();
}
}
Expand Down Expand Up @@ -98,9 +101,9 @@ public Type typeCheck() {
@Override
public String codeGeneration() {
String baseData = "storei A0 ";
String baseAccess = "load A0 ";
// String baseAccess = "load A0 ";

if(exprlist != null) {
if (exprlist != null) {
return exprlist.codeGeneration();
}
if (typeCheck() instanceof IntType) {
Expand All @@ -110,7 +113,12 @@ public String codeGeneration() {
return baseData + boolValue(getId()) + "\n";
}
if (typeCheck() instanceof AtomType) {
return baseAccess + String.valueOf(offset) + "(FP)\n" ;
String str = "move AL T1\n";
for (int i = 0; i < ns; i++) {
str += "store T1 0(T1)\n";
}
str += "subi T1 " + (offset - 1) + "\nstore A0 0(T1)\n";
return str;
}
return "Error: could not parse an atom\n";
}
Expand Down
188 changes: 147 additions & 41 deletions src/ast/nodes/ExprNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {

// check if the atom is a function
if (atom != null && !trailers.isEmpty()) {


System.out.println("EVAL ATOM " + atom.getId());
// check if the atom is not a built-in function
if (!Arrays.asList(bif).contains(atom.getId())) {

Expand All @@ -84,19 +85,22 @@ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {
FunctionType ft = (FunctionType) fun.getType();
paramNumber = ft.getParamNumber();
funL = ft.getLabel();
System.out.println("FUN " + funL);
int argNumber = trailer.getArgumentNumber();

if (paramNumber != argNumber) {
errors.add(new SemanticError(funName + "() takes " + String.valueOf(paramNumber)
+ " positional arguments but " + String.valueOf(argNumber) + " were given."));
}
for (var t : trailers) {
errors.addAll(t.checkSemantics(ST, _nesting));
}
}
}
} else {
for (var trailer : trailers) {
errors.addAll(trailer.checkSemantics(ST, _nesting));
}

}
} else if (atom != null) {
errors.addAll(atom.checkSemantics(ST, _nesting));
Expand Down Expand Up @@ -126,18 +130,29 @@ public Type typeCheck() {
@Override
public String codeGeneration() {
// check function call

if (atom != null && !trailers.isEmpty()) {
TrailerNode trailer = (TrailerNode) trailers.get(0);
String trailerS = trailer.codeGeneration();
// check if the atom is a built-in function
if (Arrays.asList(bif).contains(atom.getId())) {
// TODO: AGGIUNGERE COMMENTI PER SPIEGARE GESTIONE PRINT
return trailerS;
}
// if (Arrays.asList(bif).contains(atom.getId())) {
// // TODO: AGGIUNGERE COMMENTI PER SPIEGARE GESTIONE PRINT
// return trailerS;
// }

// taken from slide 56 of CodeGeneration.pdf
String parNum = String.valueOf(paramNumber + 1);
return "pushr FP\n" + trailerS + "move SP FP\naddi FP " + parNum + "\njsub " + funL + "\n";
// String parNum = String.valueOf(paramNumber + 1);
System.out.println("LABEL " + funL);
return "pushr FP\n" +
"move SP FP\n" +
"addi FP 1\n" +
"move AL T1\n" +
"pushr T1\n" + // slide 62, non implementiamo il for loop perché non supportiamo funzioni
// annidate
trailerS +
"move FP AL\n" +
"subi AL 1\n" +
"jsub " + funL + "\n";
}

// check operation
Expand All @@ -159,14 +174,28 @@ public String codeGeneration() {
default:
return "Error: operation " + op + " not supported\n";
}

}

// check comp operation
if (compOp != null) {
CompOpNode cmpOp = (CompOpNode) compOp;
String op = cmpOp.getOp();
return boolOpCodeGen(exprs.get(0), exprs.get(1), op);
switch (op) {
case "==":
return eqCodeGen(exprs.get(0), exprs.get(1));
case "!=":
return neqCodeGen(exprs.get(0), exprs.get(1));
case "<":
return lsCodeGen(exprs.get(0), exprs.get(1));
case "<=":
return leqCodeGen(exprs.get(0), exprs.get(1));
case ">":
return gtCodeGen(exprs.get(0), exprs.get(1));
case ">=":
return gteCodeGen(exprs.get(0), exprs.get(1));
default:
return "Error: operation " + op + " not supported\n";
}
}

if (atom != null) {
Expand Down Expand Up @@ -275,41 +304,118 @@ public String notCodeGen(Node expr) {
return exprs + "storei T1 1\nsub T1 A0\npopr A0\n";
}

public String boolOpCodeGen(Node leftE, Node rightE, String op) {
public String eqCodeGen(Node leftE, Node rightE) {
String truel = Label.newBasic("true");
String endl = Label.newBasic("end");
String ls = leftE.codeGeneration();
String rs = rightE.codeGeneration();
String ops;
switch (op) {
case ">":
ops = "bgt";
break;
case "<":
ops = "blt";
break;
case ">=":
ops = "bge";
break;
case "<=":
ops = "ble";
break;
case "==":
ops = "beq";
break;
case "!=":
// inverse of ==
return ls + "pushr A0\n" +
rs + "popr T1\n" +
"beq T1 A0 " + truel + "\nstorei A0 1\nb " + endl + "\n" + // storei A0 1 instead of storei A0 0
truel + ":\nstorei A0 0\n" + endl + ":\n"; // storei A0 0 instead of storei A0 1
default:
return "Error: operation " + op + " not supported\n";
}
return ls + "pushr A0\n" +
rs + "popr T1\n" +
ops + " T1 A0 " + truel + "\nstorei A0 0\nb " + endl + "\n" +
truel + ":\nstorei A0 1\n" + endl + ":\n";
return ls +
"pushr A0\n" +
rs +
"popr T1\n" +
"beq T1 A0 " + truel + "\n" +
"storei A0 0\n" +
"b " + endl + "\n" +
truel + ":\n" +
"storei A0 1\n" +
endl + ":\n";
}

public String neqCodeGen(Node leftE, Node rightE) {
String truel = Label.newBasic("true");
String endl = Label.newBasic("end");
String ls = leftE.codeGeneration();
String rs = rightE.codeGeneration();
return ls +
"pushr A0\n" +
rs +
"popr T1\n" +
"beq T1 A0 " + truel + "\n" +
"storei A0 1\n" +
"b " + endl + "\n" + // storei A0 1 instead of storei A0 0
truel + ":\n" +
"storei A0 0\n" + // storei A0 0 instead of storei A0 1
endl + ":\n";
}

public String lsCodeGen(Node leftE, Node rightE) {
String truel = Label.newBasic("true");
String truel2 = Label.newBasic("true");
String endl = Label.newBasic("end");
String ls = leftE.codeGeneration();
String rs = rightE.codeGeneration();
return ls +
"pushr A0\n" +
rs +
"popr T1\n" +
"bleq T1 A0 " + truel + "\n" +
"storei A0 0\n" +
"b " + endl + "\n" +
truel + ":\n" +
"beq T1 A0 " + truel2 + "\n" +
"storei A0 1\n" +
"b " + endl + "\n" +
truel2 + ":\n" +
"storei A0 0\n" +
"b " + endl + "\n" +
endl + ":\n";
}

public String leqCodeGen(Node leftE, Node rightE) {
String truel = Label.newBasic("true");
String endl = Label.newBasic("end");
String ls = leftE.codeGeneration();
String rs = rightE.codeGeneration();
return ls +
"pushr A0\n" +
rs +
"popr T1\n" +
"bleq T1 A0 " + truel + "\n" +
"storei A0 0\n" +
"b " + endl + "\n" +
truel + ":\n" +
"storei A0 1\n" +
endl + ":\n";
}

public String gtCodeGen(Node leftE, Node rightE) {
String truel = Label.newBasic("true");
String endl = Label.newBasic("end");
String ls = leftE.codeGeneration();
String rs = rightE.codeGeneration();
return ls +
"pushr A0\n" +
rs +
"popr T1\n" +
"bleq A0 T1 " + truel + "\n" + // inverto A0 e T1 rispetto a leq
"storei A0 0\n" +
"b " + endl + "\n" +
truel + ":\n" +
"storei A0 1\n" +
endl + ":\n";
}

public String gteCodeGen(Node leftE, Node rightE) {
String truel = Label.newBasic("true");
String truel2 = Label.newBasic("true");
String endl = Label.newBasic("end");
String ls = leftE.codeGeneration();
String rs = rightE.codeGeneration();
return ls +
"pushr A0\n" +
rs +
"popr T1\n" +
"bleq T1 A0 " + truel + "\n" +
"storei A0 1\n" +
"b " + endl + "\n" +
truel + ":\n" +
"beq T1 A0 " + truel2 + "\n" +
"storei A0 0\n" +
"b " + endl + "\n" +
truel2 + ":\n" +
"storei A0 1\n" +
"b " + endl + "\n" +
endl + ":\n";
}

}
13 changes: 8 additions & 5 deletions src/ast/nodes/FuncdefNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,11 @@ public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting) {

ST.insert(funName, ft, _nesting + 1, "");

// Offset is increased for the possible return value
if (paramlist != null) {
errors.addAll(paramlist.checkSemantics(ST, _nesting + 1));
}

// TODO: think to the offset
// Offset is increased for the possible return value
ST.increaseoffset();

errors.addAll(block.checkSemantics(ST, _nesting + 1));
Expand All @@ -67,14 +66,18 @@ public Type typeCheck() {
return new VoidType();
}

// taken from slide 56 of CodeGeneration.pdf
// taken from slide 56 of CodeGeneration.pdf
@Override
public String codeGeneration() {
Label.setFuntrace(this.name.toString());
String blockS = block.codeGeneration();
String skipL = Label.newBasic("skip");
// nel block c'è il return che mette a posto l'RA
return "b " + skipL + "\n" + funLabel + ":\npushr RA\n" + blockS + skipL + ":\n";

String funS = funLabel + ":\n" +
"pushr RA\n" +
blockS;
Label.addFunDef(funS);
return "";
}

@Override
Expand Down
24 changes: 17 additions & 7 deletions src/ast/nodes/IfNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public Type typeCheck() {
Type thenexp = thenBranch.typeCheck();
Type elseexp = elseBranch.typeCheck();
if (thenexp.getClass().equals(elseexp.getClass())) {
return thenexp;
}else {
return thenexp;
} else {
System.out.println("Type Error: incompatible types in then and else branches.");
return new ErrorType();
}
Expand All @@ -59,12 +59,22 @@ public String codeGeneration() {

String guardS = guard.codeGeneration();
String thenS = thenBranch.codeGeneration();
String elseS = elseBranch.codeGeneration();
String elseS = "";
if (elseBranch != null) {
elseS = elseBranch.codeGeneration();
}

// Assumo che la guardia sia un dato booleano o una operazione booleana che mette in A0 il valore true (1) o false (0)
return guardS + "storei T1 1\nbeq A0 T1 " + thenLabel + "\n" + // Controllo che A0 sia true (1). Se vero faccio jump alla
elseS + "b " + endLabel + "\n" + // thenBranch, altrimenti eseguo la elseBranch e jumpo alla fine
thenLabel + ":\n" + thenS + endLabel + ":\n";
// Assumo che la guardia sia un dato booleano o una operazione booleana che
// mette in A0 il valore true (1) o false (0)
return guardS +
"storei T1 1\n" +
"beq A0 T1 " + thenLabel + "\n" + // Controllo che A0 sia true (1). Se vero faccio jump alla
// thenBranch, altrimenti eseguo la elseBranch e jumpo alla fine
elseS +
"b " + endLabel + "\n" +
thenLabel + ":\n" +
thenS +
endLabel + ":\n";
}

@Override
Expand Down
Loading

0 comments on commit 34ab5b9

Please sign in to comment.