diff --git a/src/pins25/common/PDM.java b/src/pins25/common/PDM.java
new file mode 100644
index 0000000..a1f856b
--- /dev/null
+++ b/src/pins25/common/PDM.java
@@ -0,0 +1,494 @@
+package pins25.common;
+
+/**
+ * Ukazi skladovnega stroja.
+ *
+ * Vse spremenljivke (in parametri, ki so samo posebna vrsta spremenljivke),
+ * katerih ime se zacne z {@code debug}, so lahko nastavljene na {@code null}.
+ * Uporabljajo se samo za izpis sledenja delovanja skladovnega stroja.
+ */
+public class PDM {
+
+ @SuppressWarnings({ "doclint:missing" })
+ public PDM() {
+ throw new Report.InternalError();
+ }
+
+ /**
+ * Vrsta ukazov skladovnega stroja.
+ */
+ public static interface Instruction {
+
+ /**
+ * Vrne dolzino ukaza.
+ *
+ * @return Dolzina ukaza.
+ */
+ Integer size();
+
+ }
+
+ /** Ukazi skladovnega stroja za opis podatkov. */
+ public static interface DataInstr extends Instruction {
+ }
+
+ /** Ukazi skladovnega stroja za opis kode programa. */
+ public static interface CodeInstr extends Instruction {
+ }
+
+ /**
+ * Ukaz skladovnega stroja.
+ */
+ public static abstract class INSTR implements Instruction {
+
+ /** Lokacija dela izvorne kode, ki se prevede v ta ukaz. */
+ public final Report.Location debugLocation;
+
+ /**
+ * Ustvari nov ukaz skladovnega stroja.
+ *
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public INSTR(final Report.Locatable debugLocation) {
+ this.debugLocation = debugLocation == null ? null : debugLocation.location();
+ }
+
+ @Override
+ public Integer size() {
+ return 1;
+ }
+
+ }
+
+ /**
+ * Oznaka.
+ */
+ public static class LABEL extends INSTR implements DataInstr, CodeInstr {
+
+ /** Ime oznake. */
+ public final String name;
+
+ /**
+ * Ustvari nov ukaz {@link LABEL}.
+ *
+ * @param name Ime oznake.
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public LABEL(final String name, final Report.Locatable debugLocation) {
+ super(debugLocation);
+ this.name = name;
+ }
+
+ @Override
+ public Integer size() {
+ return 0;
+ }
+
+ @Override
+ public String toString() {
+ return "LABEL " + name;
+ }
+
+ }
+
+ /**
+ * Dodeljevanje prostora v staticnem pomnilniku.
+ */
+ public static class SIZE extends INSTR implements DataInstr {
+
+ /** Velikost prostora v pomnilniku. */
+ public final Integer size;
+
+ /**
+ * Ustvari nov ukaz {@link SIZE}.
+ *
+ * @param size Velikost prostora v pomnilniku.
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public SIZE(final Integer size, final Report.Locatable debugLocation) {
+ super(debugLocation);
+ this.size = size;
+ }
+
+ @Override
+ public Integer size() {
+ return size;
+ }
+
+ @Override
+ public String toString() {
+ return "SIZE " + size;
+ }
+
+ }
+
+ /**
+ * Konstanta v v staticnem pomnilniku.
+ */
+ public static class DATA extends INSTR implements DataInstr {
+
+ /**
+ * Vrednost konstante.
+ */
+ public final Integer intc;
+
+ /**
+ * Ustvari nov ukaz {@link SIZE}.
+ *
+ * @param intc Vrednost konstante.
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public DATA(final Integer intc, final Report.Locatable debugLocation) {
+ super(debugLocation);
+ this.intc = intc;
+ }
+
+ @Override
+ public Integer size() {
+ return 4;
+ }
+
+ @Override
+ public String toString() {
+ return "DATA " + intc;
+ }
+
+ }
+
+ /**
+ * Inicializacija spremenljivke.
+ */
+ public static class INIT extends INSTR implements CodeInstr {
+
+ /**
+ * Ustvari nok ukaz {@link INIT}.
+ *
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public INIT(final Report.Locatable debugLocation) {
+ super(debugLocation);
+ }
+
+ @Override
+ public String toString() {
+ return "INIT";
+ }
+
+ }
+
+ /**
+ * Prenos vrednosti iz pomnilnika na sklad.
+ */
+ public static class LOAD extends INSTR implements CodeInstr {
+
+ /**
+ * Ustvari nok ukaz {@link LOAD}.
+ *
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public LOAD(final Report.Locatable debugLocation) {
+ super(debugLocation);
+ }
+
+ @Override
+ public String toString() {
+ return "LOAD";
+ }
+
+ }
+
+ /**
+ * Prenos vrednosti s sklada v pomnilnik.
+ */
+ public static class SAVE extends INSTR implements CodeInstr {
+
+ /**
+ * Ustvari nok ukaz {@link SAVE}.
+ *
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public SAVE(final Report.Locatable debugLocation) {
+ super(debugLocation);
+ }
+
+ @Override
+ public String toString() {
+ return "SAVE";
+ }
+
+ }
+
+ /**
+ * Spreminjanje lokacija vrha sklada.
+ */
+ public static class POPN extends INSTR implements CodeInstr {
+
+ /**
+ * Ustvari nok ukaz {@link POPN}.
+ *
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public POPN(final Report.Locatable debugLocation) {
+ super(debugLocation);
+ }
+
+ @Override
+ public String toString() {
+ return "POPN";
+ }
+
+ }
+
+ /**
+ * Prenos konstante na sklad.
+ */
+ public static class PUSH extends INSTR implements CodeInstr {
+
+ /** Konstanta. */
+ public final Integer intc;
+
+ /**
+ * Ustvari nok ukaz {@link PUSH}.
+ *
+ * @param intc Konstanta.
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public PUSH(final Integer intc, final Report.Locatable debugLocation) {
+ super(debugLocation);
+ this.intc = intc;
+ }
+
+ @Override
+ public Integer size() {
+ return super.size() + 4;
+ }
+
+ @Override
+ public String toString() {
+ return "PUSH " + intc;
+ }
+
+ }
+
+ /**
+ * Prenos imena oznake na sklad.
+ */
+ public static class NAME extends INSTR implements CodeInstr {
+
+ /** Ime oznake. */
+ public final String name;
+
+ /**
+ * Ustvari nok ukaz {@link NAME}.
+ *
+ * @param name Ime oznake.
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public NAME(final String name, final Report.Locatable debugLocation) {
+ super(debugLocation);
+ this.name = name;
+ }
+
+ @Override
+ public Integer size() {
+ return super.size() + 4;
+ }
+
+ @Override
+ public String toString() {
+ return "NAME " + name;
+ }
+
+ }
+
+ /**
+ * Prenos vrednosti registra na sklad.
+ */
+ public static class REGN extends INSTR implements CodeInstr {
+
+ /** Imena registrov. */
+ public enum Reg {
+ /** Programski stevec. */
+ PC,
+ /** Klicni kazalec. */
+ FP,
+ /** Skladovni zapis. */
+ SP,
+ }
+
+ /** Ime registra. */
+ public final Reg regn;
+
+ /**
+ * Ustvari nok ukaz {@link REGN}.
+ *
+ * @param regn Ime registra.
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public REGN(Reg regn, final Report.Locatable debugLocation) {
+ super(debugLocation);
+ this.regn = regn;
+ }
+
+ @Override
+ public String toString() {
+ return "REGN." + regn;
+ }
+
+ }
+
+ /**
+ * Izvedba racunske operacije.
+ */
+ public static class OPER extends INSTR implements CodeInstr {
+
+ /** Vrste racunskih operacij. */
+ public enum Oper {
+ /** Negacija. */
+ NOT,
+ /** Sprememba predznaka. */
+ NEG,
+ /** Disjunkcija. */
+ OR,
+ /** Konjunkcija. */
+ AND,
+ /** Enakonst. */
+ EQU,
+ /** Neenakost. */
+ NEQ,
+ /** Vecji kot. */
+ GTH,
+ /** Manjsi kot. */
+ LTH,
+ /** Vecji ali enak. */
+ GEQ,
+ /** Manjsi ali enak. */
+ LEQ,
+ /** Sestevanje. */
+ ADD,
+ /** Odstevanje. */
+ SUB,
+ /** Mnozenje. */
+ MUL,
+ /** Deljenje. */
+ DIV,
+ /** Modulo. */
+ MOD,
+ }
+
+ /** Racunska operacija. */
+ public final Oper oper;
+
+ /**
+ * Ustvari nok ukaz {@link OPER}.
+ *
+ * @param oper Racunska operacija.
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public OPER(final Oper oper, final Report.Locatable debugLocation) {
+ super(debugLocation);
+ this.oper = oper;
+ }
+
+ @Override
+ public String toString() {
+ return "OPER." + oper;
+ }
+
+ }
+
+ /**
+ * Brezpogojni skok.
+ */
+ public static class UJMP extends INSTR implements CodeInstr {
+
+ /**
+ * Ustvari nok ukaz {@link UJMP}.
+ *
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public UJMP(final Report.Locatable debugLocation) {
+ super(debugLocation);
+ }
+
+ @Override
+ public String toString() {
+ return "UJMP";
+ }
+
+ }
+
+ /**
+ * Pogojni skok.
+ */
+ public static class CJMP extends INSTR implements CodeInstr {
+
+ /**
+ * Ustvari nok ukaz {@link CJMP}.
+ *
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public CJMP(final Report.Locatable debugLocation) {
+ super(debugLocation);
+ }
+
+ @Override
+ public String toString() {
+ return "CJMP";
+ }
+
+ }
+
+ /**
+ * Klic podprograma.
+ */
+ public static class CALL extends INSTR implements CodeInstr {
+
+ /** Klicni zapis klicanega podprograma. */
+ public final Mem.Frame debugFrame;
+
+ /**
+ * Ustvari nok ukaz {@link CALL}.
+ *
+ * @param debugFrame Klicni zapis klicanega podprograma.
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public CALL(final Mem.Frame debugFrame, final Report.Locatable debugLocation) {
+ super(debugLocation);
+ this.debugFrame = debugFrame;
+ }
+
+ @Override
+ public String toString() {
+ return "CALL";
+ }
+
+ }
+
+ /**
+ * Vrnitev iz podprograma.
+ */
+ public static class RETN extends INSTR implements CodeInstr {
+
+ /** Klicni zapis vracajocega se podprograma. */
+ public final Mem.Frame debugFrame;
+
+ /**
+ * Ustvari nok ukaz {@link RETN}.
+ *
+ * @param debugFrame Klicni zapis vracajocega se programa.
+ * @param debugLocation Lokacija dela izvorne kode, ki se prevede v ta ukaz.
+ */
+ public RETN(final Mem.Frame debugFrame, final Report.Locatable debugLocation) {
+ super(debugLocation);
+ this.debugFrame = debugFrame;
+ }
+
+ @Override
+ public String toString() {
+ return "RETN";
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/pins25/phase/CodeGen.java b/src/pins25/phase/CodeGen.java
new file mode 100644
index 0000000..9e61b0f
--- /dev/null
+++ b/src/pins25/phase/CodeGen.java
@@ -0,0 +1,566 @@
+package pins25.phase;
+
+import java.util.*;
+
+import pins25.common.*;
+
+/**
+ * Generiranje kode.
+ */
+public class CodeGen {
+
+ @SuppressWarnings({"doclint:missing"})
+ public CodeGen() {
+ throw new Report.InternalError();
+ }
+
+ /**
+ * Abstraktno sintaksno drevo z dodanimi atributi izracuna pomnilniske
+ * predstavitve.
+ *
+ * Atributi:
+ *
+ * - ({@link Abstr}) lokacija kode, ki pripada posameznemu vozliscu;
+ * - ({@link SemAn}) definicija uporabljenega imena;
+ * - ({@link SemAn}) ali je dani izraz levi izraz;
+ * - ({@link Memory}) klicni zapis funkcije;
+ * - ({@link Memory}) dostop do parametra;
+ * - ({@link Memory}) dostop do spremenljivke;
+ * - ({@link CodeGen}) seznam ukazov, ki predstavljajo kodo programa;
+ * - ({@link CodeGen}) seznam ukazov, ki predstavljajo podatke programa.
+ *
+ */
+ public static class AttrAST extends Memory.AttrAST {
+
+ /**
+ * Atribut: seznam ukazov, ki predstavljajo kodo programa.
+ */
+ public final Map> attrCode;
+
+ /**
+ * Atribut: seznam ukazov, ki predstavljajo podatke programa.
+ */
+ public final Map> attrData;
+
+ /**
+ * Ustvari novo abstraktno sintaksno drevo z dodanimi atributi generiranja kode.
+ *
+ * @param attrAST Abstraktno sintaksno drevo z dodanimi atributi pomnilniske
+ * predstavitve.
+ * @param attrCode Attribut: seznam ukazov, ki predstavljajo kodo programa.
+ * @param attrData Attribut: seznam ukazov, ki predstavljajo podatke programa.
+ */
+ public AttrAST(final Memory.AttrAST attrAST, final Map> attrCode,
+ final Map> attrData) {
+ super(attrAST);
+ this.attrCode = attrCode;
+ this.attrData = attrData;
+ }
+
+ /**
+ * Ustvari novo abstraktno sintaksno drevo z dodanimi atributi generiranja kode.
+ *
+ * @param attrAST Abstraktno sintaksno drevo z dodanimi atributi generiranja
+ * kode.
+ */
+ public AttrAST(final AttrAST attrAST) {
+ super(attrAST);
+ this.attrCode = attrAST.attrCode;
+ this.attrData = attrAST.attrData;
+ }
+
+ @Override
+ public String head(final AST.Node node, final boolean highlighted) {
+ final StringBuffer head = new StringBuffer();
+ head.append(super.head(node, false));
+ return head.toString();
+ }
+
+ @Override
+ public void desc(final int indent, final AST.Node node, final boolean highlighted) {
+ super.desc(indent, node, false);
+ System.out.print(highlighted ? "\033[31m" : "");
+ if (attrCode.get(node) != null) {
+ List instrs = attrCode.get(node);
+ if (instrs != null) {
+ if (indent > 0)
+ System.out.printf("%" + indent + "c", ' ');
+ System.out.printf("--- Code: ---\n");
+ for (final PDM.CodeInstr instr : instrs) {
+ if (indent > 0)
+ System.out.printf("%" + indent + "c", ' ');
+ System.out.println((instr instanceof PDM.LABEL ? "" : " ") + instr.toString());
+ }
+ }
+ }
+ if (attrData.get(node) != null) {
+ List instrs = attrData.get(node);
+ if (instrs != null) {
+ if (indent > 0)
+ System.out.printf("%" + indent + "c", ' ');
+ System.out.printf("--- Data: ---\n");
+ for (final PDM.DataInstr instr : instrs) {
+ if (indent > 0)
+ System.out.printf("%" + indent + "c", ' ');
+ System.out.println((instr instanceof PDM.LABEL ? "" : " ") + instr.toString());
+ }
+ }
+ }
+ System.out.print(highlighted ? "\033[30m" : "");
+ return;
+ }
+
+ }
+
+ /**
+ * Izracuna kodo programa
+ *
+ * @param memoryAttrAST Abstraktno sintaksno drevo z dodanimi atributi izracuna
+ * pomnilniske predstavitve.
+ * @return Abstraktno sintaksno drevo z dodanimi atributi izracuna pomnilniske
+ * predstavitve.
+ */
+ public static AttrAST generate(final Memory.AttrAST memoryAttrAST) {
+ AttrAST attrAST = new AttrAST(memoryAttrAST, new HashMap>(),
+ new HashMap>());
+ (new CodeGenerator(attrAST)).generate();
+ return attrAST;
+ }
+
+ /**
+ * Generiranje kode v abstraktnem sintaksnem drevesu.
+ */
+ private static class CodeGenerator {
+
+ /**
+ * Abstraktno sintaksno drevo z dodanimi atributi izracuna pomnilniske
+ * predstavitve.
+ */
+ private final AttrAST attrAST;
+
+ /**
+ * Stevec anonimnih label.
+ */
+ private int labelCounter = 0;
+
+ /**
+ * Ustvari nov generator kode v abstraktnem sintaksnem drevesu.
+ *
+ * @param attrAST Abstraktno sintaksno drevo z dodanimi atributi izracuna
+ * pomnilniske predstavitve.
+ */
+ public CodeGenerator(final AttrAST attrAST) {
+ this.attrAST = attrAST;
+ }
+
+ /**
+ * Sprozi generiranje kode v abstraktnem sintaksnem drevesu.
+ *
+ * @return Abstraktno sintaksno drevo z dodanimi atributi izracuna pomnilniske
+ * predstavitve.
+ */
+ public AttrAST generate() {
+ attrAST.ast.accept(new Generator(), null);
+ return new AttrAST(attrAST, Collections.unmodifiableMap(attrAST.attrCode),
+ Collections.unmodifiableMap(attrAST.attrData));
+ }
+
+ /**
+ * Obiskovalec, ki generira kodo v abstraktnem sintaksnem drevesu.
+ */
+ private class Generator implements AST.FullVisitor, Mem.Frame> {
+
+ @SuppressWarnings({"doclint:missing"})
+ public Generator() {
+ }
+
+ @Override
+ public List visit(AST.FunDef funDef, Mem.Frame frame) {
+ Report.Locatable loc = attrAST.attrLoc.get(funDef);
+ List code = new ArrayList<>();
+
+ code.add(new PDM.LABEL(funDef.name, loc));
+
+ code.addAll(funDef.stmts.accept(this, frame));
+
+ code.add(new PDM.PUSH(attrAST.attrFrame.get(funDef).parsSize, loc));
+ code.add(new PDM.RETN(attrAST.attrFrame.get(funDef), loc));
+
+ attrAST.attrCode.put(funDef, code);
+ return code;
+ }
+
+ @Override
+ public List visit(AST.AtomExpr atomExpr, Mem.Frame frame) {
+ Report.Locatable loc = attrAST.attrLoc.get(atomExpr);
+ List code = new ArrayList<>();
+ switch (atomExpr.type) {
+ case INTCONST:
+ code.add(new PDM.PUSH(Memory.decodeIntConst(atomExpr, loc), loc));
+ break;
+ case CHRCONST:
+ code.add(new PDM.PUSH(Memory.decodeChrConst(atomExpr, loc), loc));
+ break;
+ case STRCONST:
+ List data = new ArrayList<>();
+ String label = String.valueOf(labelCounter++);
+ data.add(new PDM.LABEL(label, loc));
+ for (Integer value : Memory.decodeStrConst(atomExpr, loc)) {
+ data.add(new PDM.DATA(value, loc));
+ }
+ attrAST.attrData.put(atomExpr, data);
+ code.add(new PDM.NAME(label, loc));
+ code.add(new PDM.LOAD(loc));
+ break;
+ }
+
+ attrAST.attrCode.put(atomExpr, code);
+ return code;
+ }
+
+ @Override
+ public List visit(AST.BinExpr binExpr, Mem.Frame frame) {
+ Report.Locatable loc = attrAST.attrLoc.get(binExpr);
+
+ List code = new ArrayList<>();
+
+ // TODO: invert
+ code.addAll(binExpr.fstExpr.accept(this, frame));
+ code.addAll(binExpr.sndExpr.accept(this, frame));
+
+ PDM.OPER.Oper oper = switch (binExpr.oper) {
+ case OR -> PDM.OPER.Oper.OR;
+ case AND -> PDM.OPER.Oper.AND;
+ case EQU -> PDM.OPER.Oper.EQU;
+ case NEQ -> PDM.OPER.Oper.NEQ;
+ case GTH -> PDM.OPER.Oper.GTH;
+ case LTH -> PDM.OPER.Oper.LTH;
+ case GEQ -> PDM.OPER.Oper.GEQ;
+ case LEQ -> PDM.OPER.Oper.LEQ;
+ case ADD -> PDM.OPER.Oper.ADD;
+ case SUB -> PDM.OPER.Oper.SUB;
+ case MUL -> PDM.OPER.Oper.MUL;
+ case DIV -> PDM.OPER.Oper.DIV;
+ case MOD -> PDM.OPER.Oper.MOD;
+ };
+
+ code.add(new PDM.OPER(oper, loc));
+
+ attrAST.attrCode.put(binExpr, code);
+ return code;
+ }
+
+ @Override
+ public List visit(AST.Nodes extends AST.Node> nodes, Mem.Frame frame) {
+ List code = new ArrayList<>();
+ for (AST.Node node : nodes) {
+ code.addAll(node.accept(this, frame));
+ }
+ attrAST.attrCode.put(nodes, code);
+ return code;
+ }
+
+ @Override
+ public List visit(AST.ExprStmt exprStmt, Mem.Frame frame) {
+ return exprStmt.expr.accept(this, frame);
+ }
+
+ @Override
+ public List visit(AST.VarExpr varExpr, Mem.Frame frame) {
+ Report.Locatable loc = attrAST.attrLoc.get(varExpr);
+ List code = new ArrayList<>();
+
+ AST.VarDef def = (AST.VarDef) attrAST.attrDef.get(varExpr);
+ Mem.Access access = attrAST.attrVarAccess.get(def);
+
+ switch (access) {
+ case Mem.AbsAccess absAccess:
+ code.add(new PDM.NAME(absAccess.name, loc));
+ code.add(new PDM.LOAD(loc));
+ break;
+ case Mem.RelAccess relAccess:
+ code.add(new PDM.REGN(PDM.REGN.Reg.FP, loc));
+ code.add(new PDM.PUSH(relAccess.offset, loc));
+ code.add(new PDM.OPER(PDM.OPER.Oper.ADD, loc));
+ code.add(new PDM.LOAD(loc));
+ break;
+ default:
+ }
+
+ attrAST.attrCode.put(varExpr, code);
+ return code;
+ }
+
+ @Override
+ public List visit(AST.UnExpr unExpr, Mem.Frame frame) {
+ Report.Locatable loc = attrAST.attrLoc.get(unExpr);
+
+ List code = new ArrayList<>(unExpr.expr.accept(this, frame));
+
+ code.add(switch (unExpr.oper) {
+ case NOT -> new PDM.OPER(PDM.OPER.Oper.NOT, loc);
+ case ADD -> new PDM.OPER(PDM.OPER.Oper.ADD, loc); // TODO
+ case SUB -> new PDM.OPER(PDM.OPER.Oper.NEG, loc);
+ case MEMADDR -> new PDM.REGN(PDM.REGN.Reg.SP, loc);
+ case VALUEAT -> new PDM.LOAD(loc);
+ });
+
+ attrAST.attrCode.put(unExpr, code);
+ return code;
+ }
+
+ @Override
+ public List visit(AST.CallExpr callExpr, Mem.Frame frame) {
+ Report.Locatable loc = attrAST.attrLoc.get(callExpr);
+ List code = new ArrayList<>();
+
+ for (int i = 0; i < callExpr.args.size(); i++) {
+ AST.Expr expr = (AST.Expr) callExpr.args.get(i);
+ code.addAll(expr.accept(this, frame));
+ code.add(new PDM.REGN(PDM.REGN.Reg.SP, loc));
+
+ code.add(new PDM.PUSH(0, loc));
+ code.add(new PDM.OPER(PDM.OPER.Oper.ADD, loc));
+ }
+
+ code.add(new PDM.REGN(PDM.REGN.Reg.FP, loc)); // SL
+
+ code.add(new PDM.NAME(callExpr.name, loc));
+ code.add(new PDM.LOAD(loc));
+ code.add(new PDM.CALL(frame, loc));
+
+ attrAST.attrCode.put(callExpr, code);
+ return code;
+ }
+ }
+ }
+
+ /**
+ * Generator seznama ukazov, ki predstavljajo kodo programa.
+ */
+ public static class CodeSegmentGenerator {
+
+ /**
+ * Abstraktno sintaksno drevo z dodanimi atributi izracuna pomnilniske
+ * predstavitve.
+ */
+ private final AttrAST attrAST;
+
+ /**
+ * Seznam ukazov za inicializacijo staticnih spremenljivk.
+ */
+ private final Vector codeInitSegment = new Vector();
+
+ /**
+ * Seznam ukazov funkcij.
+ */
+ private final Vector codeFunsSegment = new Vector();
+
+ /**
+ * Klicni zapis funkcije {@code main}.
+ */
+ private Mem.Frame main = null;
+
+ /**
+ * Ustvari nov generator seznama ukazov, ki predstavljajo kodo programa.
+ *
+ * @param attrAST Abstraktno sintaksno drevo z dodanimi atributi izracuna
+ * pomnilniske predstavitve.
+ */
+ public CodeSegmentGenerator(final AttrAST attrAST) {
+ this.attrAST = attrAST;
+ }
+
+ /**
+ * Izracuna seznam ukazov, ki predstavljajo kodo programa.
+ *
+ * @return Seznam ukazov, ki predstavljajo kodo programa.
+ */
+ public List codeSegment() {
+ attrAST.ast.accept(new Generator(), null);
+ codeInitSegment.addLast(new PDM.PUSH(0, null));
+ codeInitSegment.addLast(new PDM.NAME("main", null));
+ codeInitSegment.addLast(new PDM.CALL(main, null));
+ codeInitSegment.addLast(new PDM.PUSH(0, null));
+ codeInitSegment.addLast(new PDM.NAME("exit", null));
+ codeInitSegment.addLast(new PDM.CALL(null, null));
+ final Vector codeSegment = new Vector();
+ codeSegment.addAll(codeInitSegment);
+ codeSegment.addAll(codeFunsSegment);
+ return Collections.unmodifiableList(codeSegment);
+ }
+
+ /**
+ * Obiskovalec, ki izracuna seznam ukazov, ki predstavljajo kodo programa.
+ */
+ private class Generator implements AST.FullVisitor