Code Gen
This commit is contained in:
parent
c7b835dd1a
commit
a59eca0e8a
@ -167,6 +167,16 @@ public class CodeGen {
|
|||||||
public Generator() {
|
public Generator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Stack<AST.FunDef> staticLinks = new Stack<>();
|
||||||
|
|
||||||
|
private String funLabel(AST.FunDef funDef) {
|
||||||
|
if (funDef.name.equals("main") || funDef.stmts.size() == 0) {
|
||||||
|
return funDef.name;
|
||||||
|
}
|
||||||
|
Report.Location loc = attrAST.attrLoc.get(funDef).location();
|
||||||
|
return "$fun:" + funDef.name + "@" + loc.begLine() + ":" + loc.begColumn();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PDM.CodeInstr> visit(AST.FunDef funDef, Mem.Frame frame) {
|
public List<PDM.CodeInstr> visit(AST.FunDef funDef, Mem.Frame frame) {
|
||||||
Report.Locatable loc = attrAST.attrLoc.get(funDef);
|
Report.Locatable loc = attrAST.attrLoc.get(funDef);
|
||||||
@ -174,15 +184,17 @@ public class CodeGen {
|
|||||||
|
|
||||||
frame = attrAST.attrFrame.get(funDef);
|
frame = attrAST.attrFrame.get(funDef);
|
||||||
|
|
||||||
code.add(new PDM.LABEL(funDef.name, loc));
|
code.add(new PDM.LABEL(funLabel(funDef), loc));
|
||||||
|
|
||||||
|
staticLinks.push(funDef);
|
||||||
code.addAll(funDef.stmts.accept(this, frame));
|
code.addAll(funDef.stmts.accept(this, frame));
|
||||||
|
staticLinks.pop();
|
||||||
|
|
||||||
code.add(new PDM.PUSH(attrAST.attrFrame.get(funDef).parsSize, loc));
|
code.add(new PDM.PUSH(attrAST.attrFrame.get(funDef).parsSize, loc));
|
||||||
code.add(new PDM.RETN(attrAST.attrFrame.get(funDef), loc));
|
code.add(new PDM.RETN(attrAST.attrFrame.get(funDef), loc));
|
||||||
|
|
||||||
attrAST.attrCode.put(funDef, code);
|
attrAST.attrCode.put(funDef, code);
|
||||||
return code;
|
return new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -203,14 +215,13 @@ public class CodeGen {
|
|||||||
break;
|
break;
|
||||||
case STRCONST:
|
case STRCONST:
|
||||||
List<PDM.DataInstr> data = new ArrayList<>();
|
List<PDM.DataInstr> data = new ArrayList<>();
|
||||||
String label = String.valueOf(labelCounter++);
|
String label = "$str@" + loc.location().begLine() + ":" + loc.location().begColumn();
|
||||||
data.add(new PDM.LABEL(label, loc));
|
data.add(new PDM.LABEL(label, loc));
|
||||||
for (Integer value : Memory.decodeStrConst(atomExpr, loc)) {
|
for (Integer value : Memory.decodeStrConst(atomExpr, loc)) {
|
||||||
data.add(new PDM.DATA(value, loc));
|
data.add(new PDM.DATA(value, loc));
|
||||||
}
|
}
|
||||||
attrAST.attrData.put(atomExpr, data);
|
attrAST.attrData.put(atomExpr, data);
|
||||||
code.add(new PDM.NAME(label, loc));
|
code.add(new PDM.NAME(label, loc));
|
||||||
// code.add(new PDM.LOAD(loc));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +302,7 @@ public class CodeGen {
|
|||||||
|
|
||||||
switch (access) {
|
switch (access) {
|
||||||
case Mem.AbsAccess absAccess:
|
case Mem.AbsAccess absAccess:
|
||||||
code.add(new PDM.NAME(absAccess.name, loc));
|
code.add(new PDM.NAME("$var:" + absAccess.name, loc));
|
||||||
break;
|
break;
|
||||||
case Mem.RelAccess relAccess:
|
case Mem.RelAccess relAccess:
|
||||||
code.add(new PDM.REGN(PDM.REGN.Reg.FP, loc));
|
code.add(new PDM.REGN(PDM.REGN.Reg.FP, loc));
|
||||||
@ -335,17 +346,17 @@ public class CodeGen {
|
|||||||
|
|
||||||
switch (unExpr.oper) {
|
switch (unExpr.oper) {
|
||||||
case NOT -> code.add(new PDM.OPER(PDM.OPER.Oper.NOT, loc));
|
case NOT -> code.add(new PDM.OPER(PDM.OPER.Oper.NOT, loc));
|
||||||
case ADD -> code.add(new PDM.OPER(PDM.OPER.Oper.ADD, loc)); // TODO
|
|
||||||
case SUB -> code.add(new PDM.OPER(PDM.OPER.Oper.NEG, loc));
|
case SUB -> code.add(new PDM.OPER(PDM.OPER.Oper.NEG, loc));
|
||||||
case VALUEAT -> code.add(new PDM.LOAD(loc));
|
case VALUEAT -> code.add(new PDM.LOAD(loc));
|
||||||
case MEMADDR -> {
|
case MEMADDR -> {
|
||||||
if (unExpr.expr instanceof AST.VarExpr varExpr) {
|
if (unExpr.expr instanceof AST.VarExpr varExpr) {
|
||||||
code.addAll(resolveAddr(varExpr, frame));
|
code.addAll(resolveAddr(varExpr, frame));
|
||||||
} else {
|
} else {
|
||||||
// TODO: are non variable expressions allowed?
|
|
||||||
throw new Report.Error(loc, "Expression not a variable");
|
throw new Report.Error(loc, "Expression not a variable");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case ADD -> {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attrAST.attrCode.put(unExpr, code);
|
attrAST.attrCode.put(unExpr, code);
|
||||||
@ -357,14 +368,20 @@ public class CodeGen {
|
|||||||
Report.Locatable loc = attrAST.attrLoc.get(callExpr);
|
Report.Locatable loc = attrAST.attrLoc.get(callExpr);
|
||||||
List<PDM.CodeInstr> code = new ArrayList<>();
|
List<PDM.CodeInstr> code = new ArrayList<>();
|
||||||
|
|
||||||
|
AST.FunDef funDef = (AST.FunDef) attrAST.attrDef.get(callExpr);
|
||||||
|
|
||||||
for (int i = callExpr.args.size() - 1; i >= 0; i--) {
|
for (int i = callExpr.args.size() - 1; i >= 0; i--) {
|
||||||
AST.Expr expr = (AST.Expr) callExpr.args.get(i);
|
AST.Expr expr = (AST.Expr) callExpr.args.get(i);
|
||||||
code.addAll(expr.accept(this, frame));
|
code.addAll(expr.accept(this, frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
code.add(new PDM.REGN(PDM.REGN.Reg.FP, loc)); // SL
|
// SL
|
||||||
|
code.add(new PDM.REGN(PDM.REGN.Reg.FP, loc));
|
||||||
|
if (attrAST.attrFrame.get(funDef).depth.equals(frame.depth)) {
|
||||||
|
code.add(new PDM.LOAD(loc));
|
||||||
|
}
|
||||||
|
|
||||||
code.add(new PDM.NAME(callExpr.name, loc));
|
code.add(new PDM.NAME(funLabel(funDef), loc));
|
||||||
code.add(new PDM.CALL(frame, loc));
|
code.add(new PDM.CALL(frame, loc));
|
||||||
|
|
||||||
attrAST.attrCode.put(callExpr, code);
|
attrAST.attrCode.put(callExpr, code);
|
||||||
@ -380,27 +397,31 @@ public class CodeGen {
|
|||||||
Mem.Access access = attrAST.attrVarAccess.get(varDef);
|
Mem.Access access = attrAST.attrVarAccess.get(varDef);
|
||||||
|
|
||||||
switch (access) {
|
switch (access) {
|
||||||
case Mem.AbsAccess absAccess:
|
case Mem.AbsAccess absAccess -> {
|
||||||
data.add(new PDM.LABEL(absAccess.name, loc));
|
String varLabel = "$var:" + absAccess.name;
|
||||||
|
data.add(new PDM.LABEL(varLabel, loc));
|
||||||
for (int i = 0; i < absAccess.size / 4; i++) {
|
for (int i = 0; i < absAccess.size / 4; i++) {
|
||||||
data.add(new PDM.DATA(0, loc));
|
data.add(new PDM.DATA(0, loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
data.add(new PDM.LABEL(absAccess.name + ".init", loc));
|
String initLabel = "$init:" + absAccess.name;
|
||||||
|
data.add(new PDM.LABEL(initLabel, loc));
|
||||||
for (Integer init : absAccess.inits) {
|
for (Integer init : absAccess.inits) {
|
||||||
data.add(new PDM.DATA(init, loc));
|
data.add(new PDM.DATA(init, loc));
|
||||||
}
|
}
|
||||||
|
|
||||||
code.add(new PDM.NAME(absAccess.name, loc));
|
code.add(new PDM.NAME(varLabel, loc));
|
||||||
code.add(new PDM.NAME(absAccess.name + ".init", loc));
|
code.add(new PDM.NAME(initLabel, loc));
|
||||||
code.add(new PDM.INIT(loc));
|
code.add(new PDM.INIT(loc));
|
||||||
break;
|
}
|
||||||
|
|
||||||
case Mem.RelAccess relAccess:
|
case Mem.RelAccess relAccess -> {
|
||||||
String initLabel = String.valueOf(labelCounter++);
|
String initLabel = "$init:" + varDef.name + "@" + loc.location().begLine() + ":" + loc.location().begColumn();
|
||||||
data.add(new PDM.LABEL(initLabel, loc));
|
data.add(new PDM.LABEL(initLabel, loc));
|
||||||
for (Integer init : relAccess.inits) {
|
if (relAccess.inits != null) {
|
||||||
data.add(new PDM.DATA(init, loc));
|
for (Integer init : relAccess.inits) {
|
||||||
|
data.add(new PDM.DATA(init, loc));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code.add(new PDM.PUSH(-relAccess.size, loc));
|
code.add(new PDM.PUSH(-relAccess.size, loc));
|
||||||
@ -409,10 +430,10 @@ public class CodeGen {
|
|||||||
code.add(new PDM.REGN(PDM.REGN.Reg.SP, loc));
|
code.add(new PDM.REGN(PDM.REGN.Reg.SP, loc));
|
||||||
code.add(new PDM.NAME(initLabel, loc));
|
code.add(new PDM.NAME(initLabel, loc));
|
||||||
code.add(new PDM.INIT(loc));
|
code.add(new PDM.INIT(loc));
|
||||||
break;
|
}
|
||||||
|
|
||||||
default:
|
default -> {
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attrAST.attrCode.put(varDef, code);
|
attrAST.attrCode.put(varDef, code);
|
||||||
@ -456,11 +477,12 @@ public class CodeGen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PDM.CodeInstr> visit(AST.IfStmt ifStmt, Mem.Frame frame) {
|
public List<PDM.CodeInstr> visit(AST.IfStmt ifStmt, Mem.Frame frame) {
|
||||||
Report.Locatable loc = attrAST.attrLoc.get(ifStmt);
|
Report.Location loc = attrAST.attrLoc.get(ifStmt).location();
|
||||||
|
|
||||||
String thenLabel = String.valueOf(labelCounter++);
|
String locStr = loc.begLine() + ":" + loc.begColumn();
|
||||||
String elseLabel = String.valueOf(labelCounter++);
|
String thenLabel = "$if:then@" + locStr;
|
||||||
String endLabel = String.valueOf(labelCounter++);
|
String elseLabel = "$if:else@" + locStr;
|
||||||
|
String endLabel = "$if:end@" + locStr;
|
||||||
|
|
||||||
List<PDM.CodeInstr> code = ifStmt.cond.accept(this, frame);
|
List<PDM.CodeInstr> code = ifStmt.cond.accept(this, frame);
|
||||||
code.add(new PDM.NAME(thenLabel, loc));
|
code.add(new PDM.NAME(thenLabel, loc));
|
||||||
@ -483,20 +505,21 @@ public class CodeGen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<PDM.CodeInstr> visit(AST.WhileStmt whileStmt, Mem.Frame frame) {
|
public List<PDM.CodeInstr> visit(AST.WhileStmt whileStmt, Mem.Frame frame) {
|
||||||
Report.Locatable loc = attrAST.attrLoc.get(whileStmt);
|
Report.Location loc = attrAST.attrLoc.get(whileStmt).location();
|
||||||
List<PDM.CodeInstr> code = new ArrayList<>();
|
List<PDM.CodeInstr> code = new ArrayList<>();
|
||||||
|
|
||||||
String condLabel = String.valueOf(labelCounter++);
|
String locStr = loc.begLine() + ":" + loc.begColumn();
|
||||||
String startLabel = String.valueOf(labelCounter++);
|
String condLabel = "$while:cond@" + locStr;
|
||||||
String endLabel = String.valueOf(labelCounter++);
|
String begLabel = "$while:beg@" + locStr;
|
||||||
|
String endLabel = "$while:end@" + locStr;
|
||||||
|
|
||||||
code.add(new PDM.LABEL(condLabel, loc));
|
code.add(new PDM.LABEL(condLabel, loc));
|
||||||
code.addAll(whileStmt.cond.accept(this, frame));
|
code.addAll(whileStmt.cond.accept(this, frame));
|
||||||
code.add(new PDM.NAME(startLabel, loc));
|
code.add(new PDM.NAME(begLabel, loc));
|
||||||
code.add(new PDM.NAME(endLabel, loc));
|
code.add(new PDM.NAME(endLabel, loc));
|
||||||
code.add(new PDM.CJMP(loc));
|
code.add(new PDM.CJMP(loc));
|
||||||
|
|
||||||
code.add(new PDM.LABEL(startLabel, loc));
|
code.add(new PDM.LABEL(begLabel, loc));
|
||||||
code.addAll(whileStmt.stmts.accept(this, frame));
|
code.addAll(whileStmt.stmts.accept(this, frame));
|
||||||
|
|
||||||
code.add(new PDM.NAME(condLabel, loc));
|
code.add(new PDM.NAME(condLabel, loc));
|
||||||
|
@ -33,7 +33,7 @@ public class Machine {
|
|||||||
/**
|
/**
|
||||||
* Ali se opravi testni izpis vrednost oznak.
|
* Ali se opravi testni izpis vrednost oznak.
|
||||||
*/
|
*/
|
||||||
public static boolean debugLabelsList = false;
|
public static boolean debugLabelsList = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ali se opravi testni izpis dogajanja na skladu.
|
* Ali se opravi testni izpis dogajanja na skladu.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user