diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 4e7a66a..4f823f9 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -1,6 +1,11 @@
 <component name="InspectionProjectProfileManager">
   <profile version="1.0">
     <option name="myName" value="Project Default" />
+    <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
+      <Languages>
+        <language minSize="51" name="Java" />
+      </Languages>
+    </inspection_tool>
     <inspection_tool class="GrazieInspection" enabled="false" level="GRAMMAR_ERROR" enabled_by_default="false" />
     <inspection_tool class="LanguageDetectionInspection" enabled="false" level="WARNING" enabled_by_default="false" />
     <inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
diff --git a/src/pins25/phase/CodeGen.java b/src/pins25/phase/CodeGen.java
index 9e61b0f..7a83297 100644
--- a/src/pins25/phase/CodeGen.java
+++ b/src/pins25/phase/CodeGen.java
@@ -50,8 +50,7 @@ public class CodeGen {
          * @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<AST.Node, List<PDM.CodeInstr>> attrCode,
-                       final Map<AST.Node, List<PDM.DataInstr>> attrData) {
+        public AttrAST(final Memory.AttrAST attrAST, final Map<AST.Node, List<PDM.CodeInstr>> attrCode, final Map<AST.Node, List<PDM.DataInstr>> attrData) {
             super(attrAST);
             this.attrCode = attrCode;
             this.attrData = attrData;
@@ -83,12 +82,10 @@ public class CodeGen {
             if (attrCode.get(node) != null) {
                 List<PDM.CodeInstr> instrs = attrCode.get(node);
                 if (instrs != null) {
-                    if (indent > 0)
-                        System.out.printf("%" + indent + "c", ' ');
+                    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", ' ');
+                        if (indent > 0) System.out.printf("%" + indent + "c", ' ');
                         System.out.println((instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
                     }
                 }
@@ -96,12 +93,10 @@ public class CodeGen {
             if (attrData.get(node) != null) {
                 List<PDM.DataInstr> instrs = attrData.get(node);
                 if (instrs != null) {
-                    if (indent > 0)
-                        System.out.printf("%" + indent + "c", ' ');
+                    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", ' ');
+                        if (indent > 0) System.out.printf("%" + indent + "c", ' ');
                         System.out.println((instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
                     }
                 }
@@ -121,8 +116,7 @@ public class CodeGen {
      * predstavitve.
      */
     public static AttrAST generate(final Memory.AttrAST memoryAttrAST) {
-        AttrAST attrAST = new AttrAST(memoryAttrAST, new HashMap<AST.Node, List<PDM.CodeInstr>>(),
-                new HashMap<AST.Node, List<PDM.DataInstr>>());
+        AttrAST attrAST = new AttrAST(memoryAttrAST, new HashMap<AST.Node, List<PDM.CodeInstr>>(), new HashMap<AST.Node, List<PDM.DataInstr>>());
         (new CodeGenerator(attrAST)).generate();
         return attrAST;
     }
@@ -161,8 +155,7 @@ public class CodeGen {
          */
         public AttrAST generate() {
             attrAST.ast.accept(new Generator(), null);
-            return new AttrAST(attrAST, Collections.unmodifiableMap(attrAST.attrCode),
-                    Collections.unmodifiableMap(attrAST.attrData));
+            return new AttrAST(attrAST, Collections.unmodifiableMap(attrAST.attrCode), Collections.unmodifiableMap(attrAST.attrData));
         }
 
         /**
@@ -179,6 +172,8 @@ public class CodeGen {
                 Report.Locatable loc = attrAST.attrLoc.get(funDef);
                 List<PDM.CodeInstr> code = new ArrayList<>();
 
+                frame = attrAST.attrFrame.get(funDef);
+
                 code.add(new PDM.LABEL(funDef.name, loc));
 
                 code.addAll(funDef.stmts.accept(this, frame));
@@ -190,6 +185,11 @@ public class CodeGen {
                 return code;
             }
 
+            @Override
+            public List<PDM.CodeInstr> visit(AST.ParDef parDef, Mem.Frame frame) {
+                return new ArrayList<>();
+            }
+
             @Override
             public List<PDM.CodeInstr> visit(AST.AtomExpr atomExpr, Mem.Frame frame) {
                 Report.Locatable loc = attrAST.attrLoc.get(atomExpr);
@@ -210,7 +210,7 @@ public class CodeGen {
                         }
                         attrAST.attrData.put(atomExpr, data);
                         code.add(new PDM.NAME(label, loc));
-                        code.add(new PDM.LOAD(loc));
+//                        code.add(new PDM.LOAD(loc));
                         break;
                 }
 
@@ -224,7 +224,6 @@ public class CodeGen {
 
                 List<PDM.CodeInstr> code = new ArrayList<>();
 
-                // TODO: invert
                 code.addAll(binExpr.fstExpr.accept(this, frame));
                 code.addAll(binExpr.sndExpr.accept(this, frame));
 
@@ -265,27 +264,60 @@ public class CodeGen {
                 return exprStmt.expr.accept(this, frame);
             }
 
+            private List<PDM.CodeInstr> resolveAddr(AST.Expr expr, Mem.Frame frame) {
+                Report.Locatable loc = attrAST.attrLoc.get(expr);
+                List<PDM.CodeInstr> code = new ArrayList<>();
+
+                switch (expr) {
+                    case AST.UnExpr unExpr:
+                        if (unExpr.oper != AST.UnExpr.Oper.VALUEAT) {
+                            return code;
+                        }
+
+                        code.addAll(unExpr.expr.accept(this, frame));
+                        break;
+
+                    case AST.VarExpr varExpr:
+                        AST.Def def = attrAST.attrDef.get(varExpr);
+
+                        Mem.Access access = switch (def) {
+                            case AST.VarDef varDef -> attrAST.attrVarAccess.get(varDef);
+                            case AST.ParDef parDef -> attrAST.attrParAccess.get(parDef);
+                            default -> null;
+                        };
+                        if (access == null) {
+                            return code;
+                        }
+
+                        switch (access) {
+                            case Mem.AbsAccess absAccess:
+                                code.add(new PDM.NAME(absAccess.name, loc));
+                                break;
+                            case Mem.RelAccess relAccess:
+                                code.add(new PDM.REGN(PDM.REGN.Reg.FP, loc));
+                                for (int i = 0; i < frame.depth - relAccess.depth; i++) {
+                                    code.add(new PDM.LOAD(loc));
+                                }
+                                code.add(new PDM.PUSH(relAccess.offset, loc));
+                                code.add(new PDM.OPER(PDM.OPER.Oper.ADD, loc));
+                                break;
+                            default:
+                        }
+                        break;
+
+                    default:
+                        break;
+                }
+
+                return code;
+            }
+
             @Override
             public List<PDM.CodeInstr> visit(AST.VarExpr varExpr, Mem.Frame frame) {
                 Report.Locatable loc = attrAST.attrLoc.get(varExpr);
-                List<PDM.CodeInstr> 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:
-                }
+                List<PDM.CodeInstr> code = resolveAddr(varExpr, frame);
+                code.add(new PDM.LOAD(loc));
 
                 attrAST.attrCode.put(varExpr, code);
                 return code;
@@ -295,15 +327,26 @@ public class CodeGen {
             public List<PDM.CodeInstr> visit(AST.UnExpr unExpr, Mem.Frame frame) {
                 Report.Locatable loc = attrAST.attrLoc.get(unExpr);
 
-                List<PDM.CodeInstr> code = new ArrayList<>(unExpr.expr.accept(this, frame));
+                List<PDM.CodeInstr> code = new ArrayList<>();
 
-                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);
-                });
+                if (unExpr.oper != AST.UnExpr.Oper.MEMADDR) {
+                    code.addAll(unExpr.expr.accept(this, frame));
+                }
+
+                switch (unExpr.oper) {
+                    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 VALUEAT -> code.add(new PDM.LOAD(loc));
+                    case MEMADDR -> {
+                        if (unExpr.expr instanceof AST.VarExpr varExpr) {
+                            code.addAll(resolveAddr(varExpr, frame));
+                        } else {
+                            // TODO: are non variable expressions allowed?
+                            throw new Report.Error(loc, "Expression not a variable");
+                        }
+                    }
+                }
 
                 attrAST.attrCode.put(unExpr, code);
                 return code;
@@ -314,24 +357,156 @@ public class CodeGen {
                 Report.Locatable loc = attrAST.attrLoc.get(callExpr);
                 List<PDM.CodeInstr> code = new ArrayList<>();
 
-                for (int i = 0; i < callExpr.args.size(); i++) {
+                for (int i = callExpr.args.size() - 1; i >= 0; 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;
             }
+
+            @Override
+            public List<PDM.CodeInstr> visit(AST.VarDef varDef, Mem.Frame frame) {
+                Report.Locatable loc = attrAST.attrLoc.get(varDef);
+                List<PDM.CodeInstr> code = new ArrayList<>();
+                List<PDM.DataInstr> data = new ArrayList<>();
+
+                Mem.Access access = attrAST.attrVarAccess.get(varDef);
+
+                switch (access) {
+                    case Mem.AbsAccess absAccess:
+                        data.add(new PDM.LABEL(absAccess.name, loc));
+                        for (int i = 0; i < absAccess.size / 4; i++) {
+                            data.add(new PDM.DATA(0, loc));
+                        }
+
+                        data.add(new PDM.LABEL(absAccess.name + ".init", loc));
+                        for (Integer init : absAccess.inits) {
+                            data.add(new PDM.DATA(init, loc));
+                        }
+
+                        code.add(new PDM.NAME(absAccess.name, loc));
+                        code.add(new PDM.NAME(absAccess.name + ".init", loc));
+                        code.add(new PDM.INIT(loc));
+                        break;
+
+                    case Mem.RelAccess relAccess:
+                        String initLabel = String.valueOf(labelCounter++);
+                        data.add(new PDM.LABEL(initLabel, 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.POPN(loc));
+
+                        code.add(new PDM.REGN(PDM.REGN.Reg.SP, loc));
+                        code.add(new PDM.NAME(initLabel, loc));
+                        code.add(new PDM.INIT(loc));
+                        break;
+
+                    default:
+                        break;
+                }
+
+                attrAST.attrCode.put(varDef, code);
+                attrAST.attrData.put(varDef, data);
+                return code;
+            }
+
+            @Override
+            public List<PDM.CodeInstr> visit(AST.Init init, Mem.Frame frame) {
+                return new ArrayList<>();
+            }
+
+            @Override
+            public List<PDM.CodeInstr> visit(AST.AssignStmt assignStmt, Mem.Frame frame) {
+                Report.Locatable loc = attrAST.attrLoc.get(assignStmt);
+                List<PDM.CodeInstr> code = new ArrayList<>();
+
+                code.addAll(assignStmt.srcExpr.accept(this, frame));
+                code.addAll(resolveAddr(assignStmt.dstExpr, frame));
+                code.add(new PDM.SAVE(loc));
+
+                attrAST.attrCode.put(assignStmt, code);
+                return code;
+            }
+
+            @Override
+            public List<PDM.CodeInstr> visit(AST.LetStmt letStmt, Mem.Frame frame) {
+                List<PDM.CodeInstr> code = new ArrayList<>();
+
+                for (AST.MainDef def : letStmt.defs) {
+                    code.addAll(def.accept(this, frame));
+                }
+
+                for (AST.Stmt stmt : letStmt.stmts) {
+                    code.addAll(stmt.accept(this, frame));
+                }
+
+                attrAST.attrCode.put(letStmt, code);
+                return code;
+            }
+
+            @Override
+            public List<PDM.CodeInstr> visit(AST.IfStmt ifStmt, Mem.Frame frame) {
+                Report.Locatable loc = attrAST.attrLoc.get(ifStmt);
+
+                String thenLabel = String.valueOf(labelCounter++);
+                String elseLabel = String.valueOf(labelCounter++);
+                String endLabel = String.valueOf(labelCounter++);
+
+                List<PDM.CodeInstr> code = ifStmt.cond.accept(this, frame);
+                code.add(new PDM.NAME(thenLabel, loc));
+                code.add(new PDM.NAME(elseLabel, loc));
+                code.add(new PDM.CJMP(loc));
+
+                code.add(new PDM.LABEL(thenLabel, loc));
+                code.addAll(ifStmt.thenStmts.accept(this, frame));
+                code.add(new PDM.NAME(endLabel, loc));
+                code.add(new PDM.UJMP(loc));
+
+                code.add(new PDM.LABEL(elseLabel, loc));
+                code.addAll(ifStmt.elseStmts.accept(this, frame));
+
+                code.add(new PDM.LABEL(endLabel, loc));
+
+                attrAST.attrCode.put(ifStmt, code);
+                return code;
+            }
+
+            @Override
+            public List<PDM.CodeInstr> visit(AST.WhileStmt whileStmt, Mem.Frame frame) {
+                Report.Locatable loc = attrAST.attrLoc.get(whileStmt);
+                List<PDM.CodeInstr> code = new ArrayList<>();
+
+                String condLabel = String.valueOf(labelCounter++);
+                String startLabel = String.valueOf(labelCounter++);
+                String endLabel = String.valueOf(labelCounter++);
+
+                code.add(new PDM.LABEL(condLabel, loc));
+                code.addAll(whileStmt.cond.accept(this, frame));
+                code.add(new PDM.NAME(startLabel, loc));
+                code.add(new PDM.NAME(endLabel, loc));
+                code.add(new PDM.CJMP(loc));
+
+                code.add(new PDM.LABEL(startLabel, loc));
+                code.addAll(whileStmt.stmts.accept(this, frame));
+
+                code.add(new PDM.NAME(condLabel, loc));
+                code.add(new PDM.UJMP(loc));
+
+                code.add(new PDM.LABEL(endLabel, loc));
+
+                attrAST.attrCode.put(whileStmt, code);
+                return code;
+            }
         }
     }
 
@@ -401,8 +576,7 @@ public class CodeGen {
 
             @Override
             public Object visit(final AST.FunDef funDef, final Object arg) {
-                if (funDef.stmts.size() == 0)
-                    return null;
+                if (funDef.stmts.size() == 0) return null;
                 List<PDM.CodeInstr> code = attrAST.attrCode.get(funDef);
                 codeFunsSegment.addAll(code);
                 funDef.pars.accept(this, arg);
@@ -429,9 +603,7 @@ public class CodeGen {
                 }
                 return null;
             }
-
         }
-
     }
 
     /**
@@ -482,8 +654,7 @@ public class CodeGen {
             @Override
             public Object visit(final AST.VarDef varDef, final Object arg) {
                 List<PDM.DataInstr> data = attrAST.attrData.get(varDef);
-                if (data != null)
-                    dataSegment.addAll(data);
+                if (data != null) dataSegment.addAll(data);
                 varDef.inits.accept(this, arg);
                 return null;
             }
@@ -491,8 +662,7 @@ public class CodeGen {
             @Override
             public Object visit(final AST.AtomExpr atomExpr, final Object arg) {
                 List<PDM.DataInstr> data = attrAST.attrData.get(atomExpr);
-                if (data != null)
-                    dataSegment.addAll(data);
+                if (data != null) dataSegment.addAll(data);
                 return null;
             }
 
@@ -511,10 +681,8 @@ public class CodeGen {
         System.out.println("This is PINS'25 compiler (code generation):");
 
         try {
-            if (cmdLineArgs.length == 0)
-                throw new Report.Error("No source file specified in the command line.");
-            if (cmdLineArgs.length > 1)
-                Report.warning("Unused arguments in the command line.");
+            if (cmdLineArgs.length == 0) throw new Report.Error("No source file specified in the command line.");
+            if (cmdLineArgs.length > 1) Report.warning("Unused arguments in the command line.");
 
             try (SynAn synAn = new SynAn(cmdLineArgs[0])) {
                 // abstraktna sintaksa:
@@ -533,8 +701,7 @@ public class CodeGen {
                     {
                         System.out.println("\n\033[1mCODE SEGMENT:\033[0m");
                         for (final PDM.CodeInstr instr : codeSegment) {
-                            System.out.printf("%8d [%s] %s\n", addr, instr.size(),
-                                    (instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
+                            System.out.printf("%8d [%s] %s\n", addr, instr.size(), (instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
                             addr += instr.size();
                         }
                     }
@@ -542,8 +709,7 @@ public class CodeGen {
                     {
                         System.out.println("\n\033[1mDATA SEGMENT:\033[0m");
                         for (final PDM.DataInstr instr : dataSegment) {
-                            System.out.printf("%8d [%s] %s\n", addr, (instr instanceof PDM.SIZE) ? " " : instr.size(),
-                                    (instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
+                            System.out.printf("%8d [%s] %s\n", addr, (instr instanceof PDM.SIZE) ? " " : instr.size(), (instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
                             addr += instr.size();
                         }
                     }
diff --git a/src/pins25/phase/Machine.java b/src/pins25/phase/Machine.java
index 2f43723..f6d834e 100644
--- a/src/pins25/phase/Machine.java
+++ b/src/pins25/phase/Machine.java
@@ -6,7 +6,7 @@ import pins25.common.*;
 
 /**
  * Skladovni stroj.
- * 
+ * <p>
  * Naslovi 'sistemskih' funkcij:
  * <ol>
  * <li>{@code -1}: {@code fun exit(exitcode)}</li>
@@ -20,605 +20,636 @@ import pins25.common.*;
  */
 public class Machine {
 
-	@SuppressWarnings({ "doclint:missing" })
-	public Machine() {
-		throw new Report.InternalError();
-	}
+    @SuppressWarnings({"doclint:missing"})
+    public Machine() {
+        throw new Report.InternalError();
+    }
 
-	/** Ali se opravi testni izpis ukazov. */
-	public static boolean debugInstrsList = false;
+    /**
+     * Ali se opravi testni izpis ukazov.
+     */
+    public static boolean debugInstrsList = true;
 
-	/** Ali se opravi testni izpis vrednost oznak. */
-	public static boolean debugLabelsList = false;
+    /**
+     * Ali se opravi testni izpis vrednost oznak.
+     */
+    public static boolean debugLabelsList = false;
 
-	/** Ali se opravi testni izpis dogajanja na skladu. */
-	public static boolean debugStack = false;
+    /**
+     * Ali se opravi testni izpis dogajanja na skladu.
+     */
+    public static boolean debugStack = false;
 
-	/**
-	 * Izvajanje skladovnega stroja.
-	 */
-	public static class Executor {
+    /**
+     * Izvajanje skladovnega stroja.
+     */
+    public static class Executor {
 
-		/** Seznam ukazov kode programa. */
-		private final HashMap<Integer, PDM.CodeInstr> program = new HashMap<Integer, PDM.CodeInstr>();
+        /**
+         * Seznam ukazov kode programa.
+         */
+        private final HashMap<Integer, PDM.CodeInstr> program = new HashMap<Integer, PDM.CodeInstr>();
 
-		/** Pomnilnik (brez predstavitve ukazov. */
-		private final HashMap<Integer, Byte> memory = new HashMap<Integer, Byte>();
+        /**
+         * Pomnilnik (brez predstavitve ukazov.
+         */
+        private final HashMap<Integer, Byte> memory = new HashMap<Integer, Byte>();
 
-		/** Preslikava imen oznak v fizicne naslove. */
-		private final HashMap<String, Integer> labelToAddr = new HashMap<String, Integer>();
+        /**
+         * Preslikava imen oznak v fizicne naslove.
+         */
+        private final HashMap<String, Integer> labelToAddr = new HashMap<String, Integer>();
 
-		/** Preslikava fizicnih naslovov v imena oznak. */
-		private final HashMap<Integer, String> addrToLabel = new HashMap<Integer, String>();
+        /**
+         * Preslikava fizicnih naslovov v imena oznak.
+         */
+        private final HashMap<Integer, String> addrToLabel = new HashMap<Integer, String>();
 
-		/** Velikost segmenta z ukazi kode programa. */
-		private final int codeSegmentSize;
+        /**
+         * Velikost segmenta z ukazi kode programa.
+         */
+        private final int codeSegmentSize;
 
-		/** Velikost segmenta s staticnimi spremenljivkami. */
-		private final int dataSegmentSize;
+        /**
+         * Velikost segmenta s staticnimi spremenljivkami.
+         */
+        private final int dataSegmentSize;
 
-		/** Preslikava naslova v lokacijo kode, ki je izvor vrednosti na naslovu. */
-		final HashMap<Integer, String> debugLocs = new HashMap<Integer, String>();
+        /**
+         * Preslikava naslova v lokacijo kode, ki je izvor vrednosti na naslovu.
+         */
+        final HashMap<Integer, String> debugLocs = new HashMap<Integer, String>();
 
-		/** Preslikava naslova v pomen podatka, ki je shranjen na naslovu. */
-		final HashMap<Integer, String> debugDscs = new HashMap<Integer, String>();
+        /**
+         * Preslikava naslova v pomen podatka, ki je shranjen na naslovu.
+         */
+        final HashMap<Integer, String> debugDscs = new HashMap<Integer, String>();
 
-		{
-			labelToAddr.put("exit", -1);
-			addrToLabel.put(-1, "exit");
-			labelToAddr.put("getint", -2);
-			addrToLabel.put(-2, "getint");
-			labelToAddr.put("putint", -3);
-			addrToLabel.put(-3, "putint");
-			labelToAddr.put("getstr", -4);
-			addrToLabel.put(-4, "getstr");
-			labelToAddr.put("putstr", -5);
-			addrToLabel.put(-5, "putstr");
-			labelToAddr.put("new", -6);
-			addrToLabel.put(-6, "new");
-			labelToAddr.put("del", -7);
-			addrToLabel.put(-7, "del");
-		}
+        {
+            labelToAddr.put("exit", -1);
+            addrToLabel.put(-1, "exit");
+            labelToAddr.put("getint", -2);
+            addrToLabel.put(-2, "getint");
+            labelToAddr.put("putint", -3);
+            addrToLabel.put(-3, "putint");
+            labelToAddr.put("getstr", -4);
+            addrToLabel.put(-4, "getstr");
+            labelToAddr.put("putstr", -5);
+            addrToLabel.put(-5, "putstr");
+            labelToAddr.put("new", -6);
+            addrToLabel.put(-6, "new");
+            labelToAddr.put("del", -7);
+            addrToLabel.put(-7, "del");
+        }
 
-		/** Programski stevec. */
-		private int PC;
+        /**
+         * Programski stevec.
+         */
+        private int PC;
 
-		/** Klicni kazalec. */
-		private int FP;
+        /**
+         * Klicni kazalec.
+         */
+        private int FP;
 
-		/** Skladovni kazalec. */
-		private int SP;
+        /**
+         * Skladovni kazalec.
+         */
+        private int SP;
 
-		/** Kazalec na prvi prosti naslov na kopici. */
-		private int HP;
+        /**
+         * Kazalec na prvi prosti naslov na kopici.
+         */
+        private int HP;
 
-		/**
-		 * Shrani vrednost v pomnilnik.
-		 * 
-		 * @param addr       Pomnilniski naslov.
-		 * @param value      Vrednost.
-		 * @param debugInstr Lokacija dela izvorne kode, ki zahteva shranjevanje.
-		 */
-		private void memSAVE(int addr, int value, final PDM.INSTR debugInstr) {
-			if (addr < codeSegmentSize)
-				throw new Report.InternalError();
-			if (debugStack && (debugInstr != null) && (debugInstr.debugLocation != null))
-				debugLocs.put(addr, debugInstr.debugLocation.toString());
-			for (int b = 0; b < 4; b++) {
-				int val = ((value >> (b * 8)) & 0xFF);
-				memory.put(addr, (byte) val);
-				addr += 1;
-			}
-		}
+        /**
+         * Shrani vrednost v pomnilnik.
+         *
+         * @param addr       Pomnilniski naslov.
+         * @param value      Vrednost.
+         * @param debugInstr Lokacija dela izvorne kode, ki zahteva shranjevanje.
+         */
+        private void memSAVE(int addr, int value, final PDM.INSTR debugInstr) {
+            if (addr < codeSegmentSize)
+                throw new Report.InternalError();
+            if (debugStack && (debugInstr != null) && (debugInstr.debugLocation != null))
+                debugLocs.put(addr, debugInstr.debugLocation.toString());
+            for (int b = 0; b < 4; b++) {
+                int val = ((value >> (b * 8)) & 0xFF);
+                memory.put(addr, (byte) val);
+                addr += 1;
+            }
+        }
 
-		/**
-		 * Prebere vrednost iz pomnilnika.
-		 * 
-		 * @param addr Pomnilniski naslov.
-		 * @return Vrednost.
-		 */
-		private int memLOAD(int addr) {
-			if (addr < codeSegmentSize)
-				throw new Report.InternalError();
-			int value = 0;
-			for (int b = 0; b < 4; b++) {
-				Byte val = memory.get(addr);
-				addr += 1;
-				if (val == null)
-					val = 0;
-				value = value | (((val < 0) ? ((int) val) + 256 : ((int) val)) << (b * 8));
-			}
-			return value;
-		}
+        /**
+         * Prebere vrednost iz pomnilnika.
+         *
+         * @param addr Pomnilniski naslov.
+         * @return Vrednost.
+         */
+        private int memLOAD(int addr) {
+            if (addr < codeSegmentSize)
+                throw new Report.InternalError();
+            int value = 0;
+            for (int b = 0; b < 4; b++) {
+                Byte val = memory.get(addr);
+                addr += 1;
+                if (val == null)
+                    val = 0;
+                value = value | (((val < 0) ? ((int) val) + 256 : ((int) val)) << (b * 8));
+            }
+            return value;
+        }
 
-		/**
-		 * Prenos nove vrednosti na sklad.
-		 * 
-		 * @param value      Vrednost.
-		 * @param debugInstr Lokacija dela izvorne kode, ki prenos nove vrednosti na
-		 *                   sklad.
-		 */
-		private void push(final int value, final PDM.INSTR debugInstr) {
-			SP -= 4;
-			memSAVE(SP, value, debugInstr);
-		}
+        /**
+         * Prenos nove vrednosti na sklad.
+         *
+         * @param value      Vrednost.
+         * @param debugInstr Lokacija dela izvorne kode, ki prenos nove vrednosti na
+         *                   sklad.
+         */
+        private void push(final int value, final PDM.INSTR debugInstr) {
+            SP -= 4;
+            memSAVE(SP, value, debugInstr);
+        }
 
-		/**
-		 * Prevzem vrednost z vrha sklada.
-		 * 
-		 * @return Vrednost.
-		 */
-		private int pop() {
-			if (debugStack)
-				debugLocs.put(SP, null);
-			final int value = memLOAD(SP);
-			SP += 4;
-			return value;
-		}
+        /**
+         * Prevzem vrednost z vrha sklada.
+         *
+         * @return Vrednost.
+         */
+        private int pop() {
+            if (debugStack)
+                debugLocs.put(SP, null);
+            final int value = memLOAD(SP);
+            SP += 4;
+            return value;
+        }
 
-		/**
-		 * Ustvari nov skladovni stroj za podan program in ta program izvede.
-		 * 
-		 * @param codeSegment Seznam ukazov, ki predstavljajo kodo programa.
-		 * @param dataSegment Seznam ukazov, ki predstavljajo podatke programa.
-		 */
-		public Executor(final List<PDM.CodeInstr> codeSegment, final List<PDM.DataInstr> dataSegment) {
+        /**
+         * Ustvari nov skladovni stroj za podan program in ta program izvede.
+         *
+         * @param codeSegment Seznam ukazov, ki predstavljajo kodo programa.
+         * @param dataSegment Seznam ukazov, ki predstavljajo podatke programa.
+         */
+        public Executor(final List<PDM.CodeInstr> codeSegment, final List<PDM.DataInstr> dataSegment) {
 
-			Scanner scanner = new Scanner(System.in);
+            Scanner scanner = new Scanner(System.in);
 
-			int memPtr = 0;
+            int memPtr = 0;
 
-			if (debugLabelsList)
-				System.out.println("\n\033[1mCODE LABELS:\033[0m");
-			for (final PDM.CodeInstr instr : codeSegment) {
-				switch (instr) {
-				case PDM.LABEL i -> {
-					labelToAddr.put(i.name, memPtr);
-					addrToLabel.put(memPtr, i.name);
-					if (debugLabelsList)
-						System.out.printf("LABEL %s = %d\n", i.name, memPtr);
-					memPtr -= 1;
-				}
-				case PDM.INIT i -> program.put(memPtr, i);
-				case PDM.LOAD i -> program.put(memPtr, i);
-				case PDM.SAVE i -> program.put(memPtr, i);
-				case PDM.POPN i -> program.put(memPtr, i);
-				case PDM.PUSH i -> {
-					program.put(memPtr, i);
-					memPtr += 4;
-				}
-				case PDM.NAME i -> {
-					program.put(memPtr, i);
-					memPtr += 4;
-				}
-				case PDM.REGN i -> program.put(memPtr, i);
-				case PDM.OPER i -> program.put(memPtr, i);
-				case PDM.UJMP i -> program.put(memPtr, i);
-				case PDM.CJMP i -> program.put(memPtr, i);
-				case PDM.CALL i -> program.put(memPtr, i);
-				case PDM.RETN i -> program.put(memPtr, i);
-				default -> throw new Report.InternalError();
-				}
-				memPtr += 1;
-			}
-			codeSegmentSize = memPtr;
+            if (debugLabelsList)
+                System.out.println("\n\033[1mCODE LABELS:\033[0m");
+            for (final PDM.CodeInstr instr : codeSegment) {
+                switch (instr) {
+                    case PDM.LABEL i -> {
+                        labelToAddr.put(i.name, memPtr);
+                        addrToLabel.put(memPtr, i.name);
+                        if (debugLabelsList)
+                            System.out.printf("LABEL %s = %d\n", i.name, memPtr);
+                        memPtr -= 1;
+                    }
+                    case PDM.INIT i -> program.put(memPtr, i);
+                    case PDM.LOAD i -> program.put(memPtr, i);
+                    case PDM.SAVE i -> program.put(memPtr, i);
+                    case PDM.POPN i -> program.put(memPtr, i);
+                    case PDM.PUSH i -> {
+                        program.put(memPtr, i);
+                        memPtr += 4;
+                    }
+                    case PDM.NAME i -> {
+                        program.put(memPtr, i);
+                        memPtr += 4;
+                    }
+                    case PDM.REGN i -> program.put(memPtr, i);
+                    case PDM.OPER i -> program.put(memPtr, i);
+                    case PDM.UJMP i -> program.put(memPtr, i);
+                    case PDM.CJMP i -> program.put(memPtr, i);
+                    case PDM.CALL i -> program.put(memPtr, i);
+                    case PDM.RETN i -> program.put(memPtr, i);
+                    default -> throw new Report.InternalError();
+                }
+                memPtr += 1;
+            }
+            codeSegmentSize = memPtr;
 
-			if (debugLabelsList)
-				System.out.println("\n\033[1mDATA LABELS:\033[0m");
-			for (final PDM.DataInstr instr : dataSegment) {
-				switch (instr) {
-				case PDM.LABEL i -> {
-					labelToAddr.put(i.name, memPtr);
-					addrToLabel.put(memPtr, i.name);
-					if (debugLabelsList)
-						System.out.printf("LABEL %s = %d\n", i.name, memPtr);
-				}
-				case PDM.SIZE i -> {
-					memPtr += i.size;
-				}
-				case PDM.DATA i -> {
-					memSAVE(memPtr, i.intc, i);
-					memPtr += 4;
-				}
-				default -> throw new Report.InternalError();
-				}
-			}
-			dataSegmentSize = memPtr - codeSegmentSize;
+            if (debugLabelsList)
+                System.out.println("\n\033[1mDATA LABELS:\033[0m");
+            for (final PDM.DataInstr instr : dataSegment) {
+                switch (instr) {
+                    case PDM.LABEL i -> {
+                        labelToAddr.put(i.name, memPtr);
+                        addrToLabel.put(memPtr, i.name);
+                        if (debugLabelsList)
+                            System.out.printf("LABEL %s = %d\n", i.name, memPtr);
+                    }
+                    case PDM.SIZE i -> {
+                        memPtr += i.size;
+                    }
+                    case PDM.DATA i -> {
+                        memSAVE(memPtr, i.intc, i);
+                        memPtr += 4;
+                    }
+                    default -> throw new Report.InternalError();
+                }
+            }
+            dataSegmentSize = memPtr - codeSegmentSize;
 
-			PC = 0;
-			FP = 0x10000;
-			SP = 0x10000;
-			HP = codeSegmentSize + dataSegmentSize;
+            PC = 0;
+            FP = 0x10000;
+            SP = 0x10000;
+            HP = codeSegmentSize + dataSegmentSize;
 
-			push(-1, null);
-			FP = SP + 0;
-			push(-1, null);
-			SP = SP + 0;
+            push(-1, null);
+            FP = SP + 0;
+            push(-1, null);
+            SP = SP + 0;
 
-			System.out.printf("\n");
-			loop: while (true) {
+            System.out.printf("\n");
+            loop:
+            while (true) {
 
-				if (debugStack) {
-					for (int stackAddr = 0x10000 - 4; stackAddr >= SP; stackAddr -= 4) {
-						final String debugLoc = debugLocs.get(stackAddr);
-						System.out.printf("%15s ", debugLoc == null ? "" : debugLoc);
-						if (stackAddr == FP)
-							System.out.printf("FP => ");
-						else if (stackAddr == SP)
-							System.out.printf("SP => ");
-						else
-							System.out.printf("      ");
-						System.out.printf("%6d: %12d", stackAddr, memLOAD(stackAddr));
-						final String debugDsc = debugDscs.get(stackAddr);
-						System.out.printf(" %s", debugDsc == null ? "" : debugDsc);
-						System.out.printf("\n");
-					}
-					System.out.printf("\n");
-				}
+                if (debugStack) {
+                    for (int stackAddr = 0x10000 - 4; stackAddr >= SP; stackAddr -= 4) {
+                        final String debugLoc = debugLocs.get(stackAddr);
+                        System.out.printf("%15s ", debugLoc == null ? "" : debugLoc);
+                        if (stackAddr == FP)
+                            System.out.printf("FP => ");
+                        else if (stackAddr == SP)
+                            System.out.printf("SP => ");
+                        else
+                            System.out.printf("      ");
+                        System.out.printf("%6d: %12d", stackAddr, memLOAD(stackAddr));
+                        final String debugDsc = debugDscs.get(stackAddr);
+                        System.out.printf(" %s", debugDsc == null ? "" : debugDsc);
+                        System.out.printf("\n");
+                    }
+                    System.out.printf("\n");
+                }
 
-				final PDM.CodeInstr instr = program.get(PC);
-				if (debugStack) {
-					System.out.printf("\033[1m%15s %5d: %s\033[0m\n\n",
-							((PDM.INSTR) instr).debugLocation == null ? "" : ((PDM.INSTR) instr).debugLocation, PC,
-							instr.toString());
-				}
+                final PDM.CodeInstr instr = program.get(PC);
+                if (debugStack) {
+                    System.out.printf("\033[1m%15s %5d: %s\033[0m\n\n",
+                            ((PDM.INSTR) instr).debugLocation == null ? "" : ((PDM.INSTR) instr).debugLocation, PC,
+                            instr.toString());
+                }
 
-				switch (instr) {
-				case PDM.INIT i: {
-					int initAddr = pop();
-					int dstAddr = pop();
-					final int numInits = memLOAD(initAddr);
-					initAddr += 4;
-					for (int nInit = 0; nInit < numInits; nInit++) {
-						int num = memLOAD(initAddr);
-						initAddr += 4;
-						int len = memLOAD(initAddr);
-						initAddr += 4;
-						for (int n = 0; n < num; n++) {
-							for (int l = 0; l < len; l++) {
-								memSAVE(dstAddr, memLOAD(initAddr + 4 * l), i);
-								dstAddr += 4;
-							}
-						}
-						initAddr += 4 * len;
-					}
-					PC += i.size();
-					break;
-				}
-				case PDM.LOAD i: {
-					int addr = pop();
-					int value = memLOAD(addr);
-					push(value, i);
-					PC += i.size();
-					break;
-				}
-				case PDM.SAVE i: {
-					final int addr = pop();
-					final int value = pop();
-					memSAVE(addr, value, i);
-					PC += i.size();
-					break;
-				}
-				case PDM.POPN i: {
-					int n = pop();
-					if (n < 0) {
-						while (n < 0) {
-							push(0, i);
-							n += 4;
-						}
-					} else {
-						while (n > 0) {
-							pop();
-							n -= 4;
-						}
-					}
-					PC += i.size();
-					break;
-				}
-				case PDM.PUSH i: {
-					push(i.intc, i);
-					PC += i.size();
-					break;
-				}
-				case PDM.NAME i: {
-					push(labelToAddr.get(i.name), i);
-					PC += i.size();
-					break;
-				}
-				case PDM.REGN i: {
-					final int value = switch (i.regn) {
-					case PC -> PC;
-					case FP -> FP;
-					case SP -> SP;
-					default -> throw new Report.InternalError();
-					};
-					push(value, i);
-					PC += i.size();
-					break;
-				}
-				case PDM.OPER i: {
-					switch (i.oper) {
-					case NOT:
-					case NEG: {
-						final int expr = pop();
-						final int result = switch (i.oper) {
-						case NOT -> (expr == 0) ? 1 : 0;
-						case NEG -> -expr;
-						default -> throw new Report.InternalError();
-						};
-						push(result, i);
-						break;
-					}
-					case OR:
-					case AND:
-					case EQU:
-					case NEQ:
-					case GTH:
-					case LTH:
-					case GEQ:
-					case LEQ:
-					case ADD:
-					case SUB:
-					case MUL:
-					case DIV:
-					case MOD: {
-						final int snd = pop();
-						final int fst = pop();
-						int result = switch (i.oper) {
-						case OR -> (fst != 0) || (snd != 0) ? 1 : 0;
-						case AND -> (fst != 0) && (snd != 0) ? 1 : 0;
-						case EQU -> fst == snd ? 1 : 0;
-						case NEQ -> fst != snd ? 1 : 0;
-						case GTH -> fst > snd ? 1 : 0;
-						case LTH -> fst < snd ? 1 : 0;
-						case GEQ -> fst >= snd ? 1 : 0;
-						case LEQ -> fst <= snd ? 1 : 0;
-						case ADD -> fst + snd;
-						case SUB -> fst - snd;
-						case MUL -> fst * snd;
-						case DIV -> fst / snd;
-						case MOD -> fst % snd;
-						default -> throw new Report.InternalError();
-						};
-						push(result, i);
-						break;
-					}
-					default:
-						throw new Report.InternalError();
-					}
-					PC += i.size();
-					break;
-				}
-				case PDM.UJMP i: {
-					PC = pop();
-					break;
-				}
-				case PDM.CJMP i: {
-					final int elsePC = pop();
-					final int thenPC = pop();
-					final int cond = pop();
-					PC = (cond != 0) ? thenPC : elsePC;
-					break;
-				}
-				case PDM.CALL i: {
-					final int newPC = pop();
-					if (newPC < 0) {
-						switch (newPC) {
-						case -1: { // exit(exitcode)
-							pop(); // SL
-							final int exitCode = pop();
-							pop();
-							pop();
-							System.out.printf("EXIT CODE (SP=%d): %d\n", SP, exitCode);
-							break loop;
-						}
-						case -2: { // getint()
-							pop(); // SL
-							final int intValue = scanner.nextInt();
-							push(intValue, null); // result
-							PC += i.size();
-							break;
-						}
-						case -3: { // putint(intvalue)
-							pop(); // SL
-							final int intValue = pop();
-							System.out.printf("%d", intValue);
-							push(1, null); // result
-							PC += i.size();
-							break;
-						}
-						case -4: { // getstr(straddr)
-							pop(); // SL
-							int strAddr = pop();
-							final String strValue = scanner.nextLine();
-							for (int c = 0; c < strValue.length(); c++) {
-								memSAVE(strAddr, strValue.charAt(c), null);
-								strAddr += 4;
-							}
-							memSAVE(strAddr, 0, null);
-							push(1, null); // result
-							PC += i.size();
-							break;
-						}
-						case -5: { // putstr(straddr)
-							pop(); // SL
-							int strAddr = pop();
-							while (true) {
-								int c = memLOAD(strAddr);
-								if (c == 0)
-									break;
-								System.out.printf("%c", c);
-								strAddr += 4;
-							}
-							push(1, null); // result
-							PC += i.size();
-							break;
-						}
-						case -6: { // new(size)
-							pop(); // SL
-							final int size = pop();
-							final int addr = HP;
-							for (int a = addr; a < addr + size; a++)
-								memory.put(a, (byte) 0);
-							HP += size;
-							push(addr, null); // result
-							PC += i.size();
-							break;
-						}
-						case -7: { // del(addr)
-							pop(); // SL
-							pop(); // addr
-							push(1, null); // result
-							PC += i.size();
-							break;
-						}
-						default:
-							throw new Report.InternalError();
-						}
-					} else {
-						if (debugStack) {
-							debugDscs.put(SP, "... SL");
-							debugDscs.put(SP - 4,
-									"... FP *** " + (i.debugFrame == null ? "" : i.debugFrame.name) + " ***");
-							debugDscs.put(SP - 8, "... RA ");
-							if (i.debugFrame != null) {
-								if (i.debugFrame.debugPars != null)
-									for (final Mem.RelAccess relAccess : i.debugFrame.debugPars)
-										if (relAccess.debugName != null)
-											debugDscs.put(SP + relAccess.offset, "... par: " + relAccess.debugName);
-								if (i.debugFrame.debugVars != null)
-									for (final Mem.RelAccess relAccess : i.debugFrame.debugVars)
-										if (relAccess.debugName != null) {
-											if (relAccess.size == 4)
-												debugDscs.put(SP + relAccess.offset, "... var: " + relAccess.debugName);
-											else {
-												for (int s = 0; s < relAccess.size; s += 4)
-													debugDscs.put(SP + relAccess.offset + s,
-															"... var: " + relAccess.debugName + "[" + (s / 4) + "]");
-											}
-										}
-							}
-						}
-						push(FP, i);
-						push(PC + i.size(), i);
-						FP = SP + 8;
-						PC = newPC;
-					}
-					break;
-				}
-				case PDM.RETN i: {
-					if (debugStack) {
-						debugDscs.put(FP, null);
-						debugDscs.put(FP - 4, null);
-						debugDscs.put(FP - 8, null);
-						if (i.debugFrame != null) {
-							if (i.debugFrame.debugPars != null)
-								for (final Mem.RelAccess relAccess : i.debugFrame.debugPars)
-									if (relAccess.debugName != null)
-										debugDscs.put(FP + relAccess.offset, null);
-							if (i.debugFrame.debugVars != null)
-								for (final Mem.RelAccess relAccess : i.debugFrame.debugVars)
-									if (relAccess.debugName != null) {
-										if (relAccess.size == 4)
-											debugDscs.put(FP + relAccess.offset, null);
-										else {
-											for (int s = 0; s < relAccess.size; s += 4)
-												debugDscs.put(FP + relAccess.offset + s, null);
-										}
-									}
-						}
-					}
-					int parsSize = pop();
-					final int result = pop();
-					PC = memLOAD(FP - 8);
-					while (SP != FP) {
-						pop();
-					}
-					// SP = FP;
-					FP = memLOAD(FP - 4);
-					parsSize += 4;
-					while (parsSize > 0) {
-						pop();
-						parsSize -= 4;
-					}
-					push(result, i);
-					break;
-				}
-				default:
-					throw new Report.InternalError();
-				}
-			}
+                switch (instr) {
+                    case PDM.INIT i: {
+                        int initAddr = pop();
+                        int dstAddr = pop();
+                        final int numInits = memLOAD(initAddr);
+                        initAddr += 4;
+                        for (int nInit = 0; nInit < numInits; nInit++) {
+                            int num = memLOAD(initAddr);
+                            initAddr += 4;
+                            int len = memLOAD(initAddr);
+                            initAddr += 4;
+                            for (int n = 0; n < num; n++) {
+                                for (int l = 0; l < len; l++) {
+                                    memSAVE(dstAddr, memLOAD(initAddr + 4 * l), i);
+                                    dstAddr += 4;
+                                }
+                            }
+                            initAddr += 4 * len;
+                        }
+                        PC += i.size();
+                        break;
+                    }
+                    case PDM.LOAD i: {
+                        int addr = pop();
+                        int value = memLOAD(addr);
+                        push(value, i);
+                        PC += i.size();
+                        break;
+                    }
+                    case PDM.SAVE i: {
+                        final int addr = pop();
+                        final int value = pop();
+                        memSAVE(addr, value, i);
+                        PC += i.size();
+                        break;
+                    }
+                    case PDM.POPN i: {
+                        int n = pop();
+                        if (n < 0) {
+                            while (n < 0) {
+                                push(0, i);
+                                n += 4;
+                            }
+                        } else {
+                            while (n > 0) {
+                                pop();
+                                n -= 4;
+                            }
+                        }
+                        PC += i.size();
+                        break;
+                    }
+                    case PDM.PUSH i: {
+                        push(i.intc, i);
+                        PC += i.size();
+                        break;
+                    }
+                    case PDM.NAME i: {
+                        push(labelToAddr.get(i.name), i);
+                        PC += i.size();
+                        break;
+                    }
+                    case PDM.REGN i: {
+                        final int value = switch (i.regn) {
+                            case PC -> PC;
+                            case FP -> FP;
+                            case SP -> SP;
+                            default -> throw new Report.InternalError();
+                        };
+                        push(value, i);
+                        PC += i.size();
+                        break;
+                    }
+                    case PDM.OPER i: {
+                        switch (i.oper) {
+                            case NOT:
+                            case NEG: {
+                                final int expr = pop();
+                                final int result = switch (i.oper) {
+                                    case NOT -> (expr == 0) ? 1 : 0;
+                                    case NEG -> -expr;
+                                    default -> throw new Report.InternalError();
+                                };
+                                push(result, i);
+                                break;
+                            }
+                            case OR:
+                            case AND:
+                            case EQU:
+                            case NEQ:
+                            case GTH:
+                            case LTH:
+                            case GEQ:
+                            case LEQ:
+                            case ADD:
+                            case SUB:
+                            case MUL:
+                            case DIV:
+                            case MOD: {
+                                final int snd = pop();
+                                final int fst = pop();
+                                int result = switch (i.oper) {
+                                    case OR -> (fst != 0) || (snd != 0) ? 1 : 0;
+                                    case AND -> (fst != 0) && (snd != 0) ? 1 : 0;
+                                    case EQU -> fst == snd ? 1 : 0;
+                                    case NEQ -> fst != snd ? 1 : 0;
+                                    case GTH -> fst > snd ? 1 : 0;
+                                    case LTH -> fst < snd ? 1 : 0;
+                                    case GEQ -> fst >= snd ? 1 : 0;
+                                    case LEQ -> fst <= snd ? 1 : 0;
+                                    case ADD -> fst + snd;
+                                    case SUB -> fst - snd;
+                                    case MUL -> fst * snd;
+                                    case DIV -> fst / snd;
+                                    case MOD -> fst % snd;
+                                    default -> throw new Report.InternalError();
+                                };
+                                push(result, i);
+                                break;
+                            }
+                            default:
+                                throw new Report.InternalError();
+                        }
+                        PC += i.size();
+                        break;
+                    }
+                    case PDM.UJMP i: {
+                        PC = pop();
+                        break;
+                    }
+                    case PDM.CJMP i: {
+                        final int elsePC = pop();
+                        final int thenPC = pop();
+                        final int cond = pop();
+                        PC = (cond != 0) ? thenPC : elsePC;
+                        break;
+                    }
+                    case PDM.CALL i: {
+                        final int newPC = pop();
+                        if (newPC < 0) {
+                            switch (newPC) {
+                                case -1: { // exit(exitcode)
+                                    pop(); // SL
+                                    final int exitCode = pop();
+                                    pop();
+                                    pop();
+                                    System.out.printf("EXIT CODE (SP=%d): %d\n", SP, exitCode);
+                                    break loop;
+                                }
+                                case -2: { // getint()
+                                    pop(); // SL
+                                    final int intValue = scanner.nextInt();
+                                    push(intValue, null); // result
+                                    PC += i.size();
+                                    break;
+                                }
+                                case -3: { // putint(intvalue)
+                                    pop(); // SL
+                                    final int intValue = pop();
+                                    System.out.printf("%d", intValue);
+                                    push(1, null); // result
+                                    PC += i.size();
+                                    break;
+                                }
+                                case -4: { // getstr(straddr)
+                                    pop(); // SL
+                                    int strAddr = pop();
+                                    final String strValue = scanner.nextLine();
+                                    for (int c = 0; c < strValue.length(); c++) {
+                                        memSAVE(strAddr, strValue.charAt(c), null);
+                                        strAddr += 4;
+                                    }
+                                    memSAVE(strAddr, 0, null);
+                                    push(1, null); // result
+                                    PC += i.size();
+                                    break;
+                                }
+                                case -5: { // putstr(straddr)
+                                    pop(); // SL
+                                    int strAddr = pop();
+                                    while (true) {
+                                        int c = memLOAD(strAddr);
+                                        if (c == 0)
+                                            break;
+                                        System.out.printf("%c", c);
+                                        strAddr += 4;
+                                    }
+                                    push(1, null); // result
+                                    PC += i.size();
+                                    break;
+                                }
+                                case -6: { // new(size)
+                                    pop(); // SL
+                                    final int size = pop();
+                                    final int addr = HP;
+                                    for (int a = addr; a < addr + size; a++)
+                                        memory.put(a, (byte) 0);
+                                    HP += size;
+                                    push(addr, null); // result
+                                    PC += i.size();
+                                    break;
+                                }
+                                case -7: { // del(addr)
+                                    pop(); // SL
+                                    pop(); // addr
+                                    push(1, null); // result
+                                    PC += i.size();
+                                    break;
+                                }
+                                default:
+                                    throw new Report.InternalError();
+                            }
+                        } else {
+                            if (debugStack) {
+                                debugDscs.put(SP, "... SL");
+                                debugDscs.put(SP - 4,
+                                        "... FP *** " + (i.debugFrame == null ? "" : i.debugFrame.name) + " ***");
+                                debugDscs.put(SP - 8, "... RA ");
+                                if (i.debugFrame != null) {
+                                    if (i.debugFrame.debugPars != null)
+                                        for (final Mem.RelAccess relAccess : i.debugFrame.debugPars)
+                                            if (relAccess.debugName != null)
+                                                debugDscs.put(SP + relAccess.offset, "... par: " + relAccess.debugName);
+                                    if (i.debugFrame.debugVars != null)
+                                        for (final Mem.RelAccess relAccess : i.debugFrame.debugVars)
+                                            if (relAccess.debugName != null) {
+                                                if (relAccess.size == 4)
+                                                    debugDscs.put(SP + relAccess.offset, "... var: " + relAccess.debugName);
+                                                else {
+                                                    for (int s = 0; s < relAccess.size; s += 4)
+                                                        debugDscs.put(SP + relAccess.offset + s,
+                                                                "... var: " + relAccess.debugName + "[" + (s / 4) + "]");
+                                                }
+                                            }
+                                }
+                            }
+                            push(FP, i);
+                            push(PC + i.size(), i);
+                            FP = SP + 8;
+                            PC = newPC;
+                        }
+                        break;
+                    }
+                    case PDM.RETN i: {
+                        if (debugStack) {
+                            debugDscs.put(FP, null);
+                            debugDscs.put(FP - 4, null);
+                            debugDscs.put(FP - 8, null);
+                            if (i.debugFrame != null) {
+                                if (i.debugFrame.debugPars != null)
+                                    for (final Mem.RelAccess relAccess : i.debugFrame.debugPars)
+                                        if (relAccess.debugName != null)
+                                            debugDscs.put(FP + relAccess.offset, null);
+                                if (i.debugFrame.debugVars != null)
+                                    for (final Mem.RelAccess relAccess : i.debugFrame.debugVars)
+                                        if (relAccess.debugName != null) {
+                                            if (relAccess.size == 4)
+                                                debugDscs.put(FP + relAccess.offset, null);
+                                            else {
+                                                for (int s = 0; s < relAccess.size; s += 4)
+                                                    debugDscs.put(FP + relAccess.offset + s, null);
+                                            }
+                                        }
+                            }
+                        }
+                        int parsSize = pop();
+                        final int result = pop();
+                        PC = memLOAD(FP - 8);
+                        while (SP != FP) {
+                            pop();
+                        }
+                        // SP = FP;
+                        FP = memLOAD(FP - 4);
+                        parsSize += 4;
+                        while (parsSize > 0) {
+                            pop();
+                            parsSize -= 4;
+                        }
+                        push(result, i);
+                        break;
+                    }
+                    default:
+                        throw new Report.InternalError();
+                }
+            }
 
-			scanner.close();
-		}
+            scanner.close();
+        }
 
-	}
+    }
 
-	// --- ZAGON ---
+    // --- ZAGON ---
 
-	/**
-	 * Zagon izracuna pomnilniske predstavitve kot samostojnega programa.
-	 * 
-	 * @param cmdLineArgs Argumenti v ukazni vrstici.
-	 */
-	public static void main(final String[] cmdLineArgs) {
-		System.out.println("This is PINS'25 compiler (pushdown machine):");
+    /**
+     * Zagon izracuna pomnilniske predstavitve kot samostojnega programa.
+     *
+     * @param cmdLineArgs Argumenti v ukazni vrstici.
+     */
+    public static void main(final String[] cmdLineArgs) {
+        System.out.println("This is PINS'25 compiler (pushdown machine):");
 
-		try {
-			if (cmdLineArgs.length == 0)
-				throw new Report.Error("No source file specified in the command line.");
-			if (cmdLineArgs.length > 1)
-				Report.warning("Unused arguments in the command line.");
+        try {
+            if (cmdLineArgs.length == 0)
+                throw new Report.Error("No source file specified in the command line.");
+            if (cmdLineArgs.length > 1)
+                Report.warning("Unused arguments in the command line.");
 
-			try (SynAn synAn = new SynAn(cmdLineArgs[0])) {
-				// abstraktna sintaksa:
-				final Abstr.AttrAST abstrAttrAST = Abstr.constructAST(synAn);
-				// semanticna analiza:
-				final SemAn.AttrAST semanAttrAST = SemAn.analyze(abstrAttrAST);
-				// pomnilniska predstavitev:
-				final Memory.AttrAST memoryAttrAST = Memory.organize(semanAttrAST);
-				// generiranje kode:
-				final CodeGen.AttrAST codegenAttrAST = CodeGen.generate(memoryAttrAST);
+            try (SynAn synAn = new SynAn(cmdLineArgs[0])) {
+                // abstraktna sintaksa:
+                final Abstr.AttrAST abstrAttrAST = Abstr.constructAST(synAn);
+                // semanticna analiza:
+                final SemAn.AttrAST semanAttrAST = SemAn.analyze(abstrAttrAST);
+                // pomnilniska predstavitev:
+                final Memory.AttrAST memoryAttrAST = Memory.organize(semanAttrAST);
+                // generiranje kode:
+                final CodeGen.AttrAST codegenAttrAST = CodeGen.generate(memoryAttrAST);
 
-				final List<PDM.CodeInstr> codeSegment = (new CodeGen.CodeSegmentGenerator(codegenAttrAST))
-						.codeSegment();
-				final List<PDM.DataInstr> dataSegment = (new CodeGen.DataSegmentGenerator(codegenAttrAST))
-						.dataSegment();
+                final List<PDM.CodeInstr> codeSegment = (new CodeGen.CodeSegmentGenerator(codegenAttrAST))
+                        .codeSegment();
+                final List<PDM.DataInstr> dataSegment = (new CodeGen.DataSegmentGenerator(codegenAttrAST))
+                        .dataSegment();
 
-				if (debugInstrsList) {
-					int addr = 0;
-					{
-						System.out.println("\n\033[1mCODE SEGMENT:\033[0m");
-						for (final PDM.CodeInstr instr : codeSegment) {
-							System.out.printf("%8d [%s] %s\n", addr, instr.size(),
-									(instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
-							addr += instr.size();
-						}
-					}
-					{
-						System.out.println("\n\033[1mDATA SEGMENT:\033[0m");
-						for (final PDM.DataInstr instr : dataSegment) {
-							System.out.printf("%8d [%s] %s\n", addr, (instr instanceof PDM.SIZE) ? " " : instr.size(),
-									(instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
-							addr += instr.size();
-						}
-					}
-				}
+                if (debugInstrsList) {
+                    int addr = 0;
+                    {
+                        System.out.println("\n\033[1mCODE SEGMENT:\033[0m");
+                        for (final PDM.CodeInstr instr : codeSegment) {
+                            System.out.printf("%8d [%s] %s\n", addr, instr.size(),
+                                    (instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
+                            addr += instr.size();
+                        }
+                    }
+                    {
+                        System.out.println("\n\033[1mDATA SEGMENT:\033[0m");
+                        for (final PDM.DataInstr instr : dataSegment) {
+                            System.out.printf("%8d [%s] %s\n", addr, (instr instanceof PDM.SIZE) ? " " : instr.size(),
+                                    (instr instanceof PDM.LABEL ? "" : "  ") + instr.toString());
+                            addr += instr.size();
+                        }
+                    }
+                }
 
-				// ustvari nov stroj in izvede program:
-				new Executor(codeSegment, dataSegment);
-			}
+                // ustvari nov stroj in izvede program:
+                new Executor(codeSegment, dataSegment);
+            }
 
-			// Upajmo, da kdaj pridemo to te tocke.
-			// A zavedajmo se sledecega:
-			// 1. Prevod je zaradi napak v programu lahko napacen :-o
-			// 2. Izvorni program se zdalec ni tisto, kar je programer hotel, da bi bil ;-)
-			Report.info("Done.");
-		} catch (Report.Error error) {
-			// Izpis opisa napake.
-			System.err.println(error.getMessage());
-			System.exit(1);
-		}
-	}
+            // Upajmo, da kdaj pridemo to te tocke.
+            // A zavedajmo se sledecega:
+            // 1. Prevod je zaradi napak v programu lahko napacen :-o
+            // 2. Izvorni program se zdalec ni tisto, kar je programer hotel, da bi bil ;-)
+            Report.info("Done.");
+        } catch (Report.Error error) {
+            // Izpis opisa napake.
+            System.err.println(error.getMessage());
+            System.exit(1);
+        }
+    }
 
 }
\ No newline at end of file
diff --git a/src/pins25/phase/Memory.java b/src/pins25/phase/Memory.java
index 3e7234d..ce65e47 100644
--- a/src/pins25/phase/Memory.java
+++ b/src/pins25/phase/Memory.java
@@ -241,7 +241,7 @@ public class Memory {
                 Mem.Frame frame = new Mem.Frame(
                         funDef.name,
                         frameBuilder.depth,
-                        parOffset,
+                        parOffset - 4,
                         -frameBuilder.varOffset,
                         debugPars,
                         frameBuilder.debugVars