feature/char-support #3
@@ -71,7 +71,7 @@ public class GenASM implements Visitor<Void> {
|
|||||||
private int lCount = 0;
|
private int lCount = 0;
|
||||||
private int currentFunctionStartLabel = 0;
|
private int currentFunctionStartLabel = 0;
|
||||||
private long bytesToClearFromTheStack = 0;
|
private long bytesToClearFromTheStack = 0;
|
||||||
private Parameter[] currentFunctionParams;
|
private FunctionDefinition currentFunctionDef;
|
||||||
|
|
||||||
public GenASM(String mainName, Map<String, StructDefinition> structs) {
|
public GenASM(String mainName, Map<String, StructDefinition> structs) {
|
||||||
this.mainName = mainName;
|
this.mainName = mainName;
|
||||||
@@ -543,9 +543,23 @@ public class GenASM implements Visitor<Void> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(Block e) {
|
public Void visit(Block e) {
|
||||||
for (var statement : e.statementsOrFunctionCalls) {
|
for (var statementOrFunctionCall : e.statementsOrFunctionCalls) {
|
||||||
statement.welcome(this);
|
statementOrFunctionCall.welcome(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It's possible (and allowed -> void functions) that there is no return statement
|
||||||
|
// in the outermost block of a function body. In this case, no
|
||||||
|
// direct descendant of Block will be a return statement.
|
||||||
|
// This means we have to generate an implicit return, otherwise
|
||||||
|
// the code would fall through to the next function below :D
|
||||||
|
// We also have to clean up the stack which is the ReturnStatement's job.
|
||||||
|
|
||||||
|
// Check if we have to generate an implicit return
|
||||||
|
var lastStatementOrFunctionCall = e.statementsOrFunctionCalls[e.statementsOrFunctionCalls.length - 1];
|
||||||
|
if (currentFunctionDef.block == e && !(lastStatementOrFunctionCall instanceof ReturnStatement)) {
|
||||||
|
visit(new ReturnStatement());
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -558,9 +572,11 @@ public class GenASM implements Visitor<Void> {
|
|||||||
e.name = "main_by_user";
|
e.name = "main_by_user";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remember the current function definition so everyone below us knows where they belong to.
|
||||||
|
currentFunctionDef = e;
|
||||||
|
|
||||||
var lblStart = ++lCount;
|
var lblStart = ++lCount;
|
||||||
currentFunctionStartLabel = lblStart;
|
currentFunctionStartLabel = lblStart;
|
||||||
currentFunctionParams = e.parameters;
|
|
||||||
asm.functionHead(e.name);
|
asm.functionHead(e.name);
|
||||||
asm.push("q", "%rbp");
|
asm.push("q", "%rbp");
|
||||||
asm.mov("q", "%rsp", "%rbp");
|
asm.mov("q", "%rsp", "%rbp");
|
||||||
@@ -675,10 +691,10 @@ public class GenASM implements Visitor<Void> {
|
|||||||
|
|
||||||
// push args into local var locations, last arg is on top of the stack
|
// push args into local var locations, last arg is on top of the stack
|
||||||
for (int i = e.arguments.length - 1; i >= 0; i--) {
|
for (int i = e.arguments.length - 1; i >= 0; i--) {
|
||||||
asm.pop("q", this.env.get(this.currentFunctionParams[i].name) + "(%rbp)");
|
asm.pop("q", env.get(currentFunctionDef.parameters[i].name) + "(%rbp)");
|
||||||
}
|
}
|
||||||
|
|
||||||
asm.jmp(this.currentFunctionStartLabel);
|
asm.jmp(currentFunctionStartLabel);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user