Package compiler.lincode

Source Code of compiler.lincode.Interpreter

package compiler.lincode;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;

import compiler.frames.Frame;
import compiler.frames.Label;
import compiler.frames.Temp;
import compiler.imcode.ImcBINOP;
import compiler.imcode.ImcCALL;
import compiler.imcode.ImcCJUMP;
import compiler.imcode.ImcCONST;
import compiler.imcode.ImcChunk;
import compiler.imcode.ImcCodeChunk;
import compiler.imcode.ImcConstChunk;
import compiler.imcode.ImcDataChunk;
import compiler.imcode.ImcEXP;
import compiler.imcode.ImcExpr;
import compiler.imcode.ImcJUMP;
import compiler.imcode.ImcLABEL;
import compiler.imcode.ImcMEM;
import compiler.imcode.ImcMOVE;
import compiler.imcode.ImcNAME;
import compiler.imcode.ImcSEQ;
import compiler.imcode.ImcStmt;
import compiler.imcode.ImcTEMP;
import compiler.report.Report;

public class Interpreter {

  int debug = 0;

  /** Pomnilnik.  */
  public HashMap<Integer,Integer> memory = new HashMap<Integer,Integer>();

  /** Preslikava label globalnih spremenljivk in konstant v naslove.  */
  public HashMap<String,Integer> labels = new HashMap<String,Integer>();

  /** Preslikava label funkcij v kodo.  */
  public HashMap<String,ImcCodeChunk> chunks = new HashMap<String,ImcCodeChunk>();

  /** Lokalne spremenljivke.  */
  public HashMap<String,Integer> temps = new HashMap<String,Integer>();

  /** Kazalec na sklad.  */
  public Integer SP;

  /** Kazalec na klicni zapis.  */
  public Integer FP;

  /** Kazalec na kopico.  */
  public Integer HP;

  public Interpreter(LinkedList<ImcChunk> progChunks) {
    SP = 65536;
    FP = 65536;
    HP = 1024;

    Iterator<ImcChunk> chunks = progChunks.iterator();
    while (chunks.hasNext()) {
      ImcChunk chunk = chunks.next();
      if (chunk instanceof ImcCodeChunk) {
        ImcCodeChunk codeChunk = (ImcCodeChunk)chunk;
        this.chunks.put(codeChunk.frame.label.name(), codeChunk);
      }
      if (chunk instanceof ImcDataChunk) {
        ImcDataChunk dataChunk = (ImcDataChunk)chunk;
        this.labels.put(dataChunk.label.name(), HP);
        HP = HP + dataChunk.size;
      }
      if (chunk instanceof ImcConstChunk) {
        ImcConstChunk constChunk = (ImcConstChunk)chunk;
        this.labels.put(constChunk.label.name(), HP);
        for (int i = 0; i < constChunk.value.length(); i++) {
          ST(HP + i * 4, new Integer(constChunk.value.charAt(i)));
        }
        ST(HP + constChunk.size, 0);
        HP = HP + constChunk.size + 4;
      }
    }

    execFun("_main");
  }

  public static String prefix = "";

  public Integer execFun(String label) {
    if (label.equals("_new")) {
      Integer addr = HP;
      HP = HP + LD(SP + 4);
      return addr;
    }
    if (label.equals("_free")) {
      return 0;
    }
    if (label.equals("_read_int")) {
      return (new Scanner(System.in)).nextInt();
    }
    if (label.equals("_print_char")) {
      System.out.print((char)(LD(SP + 4)).byteValue());
      return 0;
    }
    if (label.equals("_print_int")) {
      System.out.print(LD(SP + 4));
      return 0;
    }

    if (debug == 1) System.err.println(prefix + "=> " + label + " SP:" + SP + " FP:" + FP);

    ImcCodeChunk chunk = chunks.get(label);
    Frame frame = chunk.frame;
    HashMap<String,Integer> outerTemps = temps;
    temps = new HashMap<String,Integer>();

    // Prolog:
    ST(SP - frame.sizeLocs - 4, FP);
    FP = SP;
    SP = SP - frame.size();
    ST(frame.FP, FP);
    if (debug == 1) System.err.println(prefix + "in " + label + " SP:" + SP + " FP:" + FP);

    // jedro:
    LinkedList<ImcStmt> stmts = ((ImcSEQ)(chunk.lincode)).stmts;
    int PC = 0;
    while (PC < stmts.size()) {
      Label newLabel = execStmt(stmts.get(PC));
      if (newLabel != null) {
        // Razveljavimo cevovod:
        PC = stmts.indexOf(new ImcLABEL(newLabel));
      }
      else PC++;
    }

    // Epilog:
    SP = SP + frame.size();
    FP = LD(SP - frame.sizeLocs - 4);
    Integer retValue = LD(frame.RV);
    if (debug == 1) System.err.println(prefix + "<= " + label + " SP:" + SP + " FP:" + FP);

    temps = outerTemps;
    return retValue;
  }

  public Label execStmt(ImcStmt stmt) {
    if (debug == 1) System.err.println(prefix + stmt);

    if (stmt instanceof ImcCJUMP) {
      ImcCJUMP cjump = (ImcCJUMP)stmt;
      Integer cond = execExpr(cjump.cond);
      return cond != 0 ? cjump.trueLabel : cjump.falseLabel;
    }
    if (stmt instanceof ImcEXP) {
      ImcEXP expr = (ImcEXP)stmt;
      execExpr(expr.expr);
      return null;
    }
    if (stmt instanceof ImcJUMP) {
      return ((ImcJUMP)stmt).label;
    }
    if (stmt instanceof ImcLABEL) {
      return null;
    }
    if (stmt instanceof ImcMOVE) {
      ImcMOVE move = (ImcMOVE)stmt;
      if (move.dst instanceof ImcTEMP) {
        ImcTEMP dst = (ImcTEMP)move.dst;
        Integer src = execExpr(move.src);
        ST(dst.temp, src);
        return null;
      }
      if (move.dst instanceof ImcMEM) {
        Integer dst = execExpr(((ImcMEM)move.dst).expr);
        Integer src = execExpr(move.src);
        ST(dst, src);
        return null;
      }
      Report.error("Illegal MOVE statement.", 0);
    }
    Report.error("Unknown statement: " + stmt, 0);
    return null;
  }

  public Integer execExpr(ImcExpr expr) {
    // if (debug == 1) System.err.println(prefix + expr);

    if (expr instanceof ImcBINOP) {
      ImcBINOP binop = (ImcBINOP)expr;
      Integer lval = execExpr(binop.limc);
      Integer rval = execExpr(binop.rimc);
      switch (binop.op) {
      case ImcBINOP.ADD: return lval + rval;
      case ImcBINOP.SUB: return lval - rval;
      case ImcBINOP.MUL: return lval * rval;
      case ImcBINOP.DIV: return lval / rval;
      case ImcBINOP.EQU: return (lval == rval ? 1 : 0);
      case ImcBINOP.NEQ: return (lval != rval ? 1 : 0);
      case ImcBINOP.LTH: return (lval < rval ? 1 : 0);
      case ImcBINOP.GTH: return (lval > rval ? 1 : 0);
      case ImcBINOP.LEQ: return (lval <= rval ? 1 : 0);
      case ImcBINOP.GEQ: return (lval >= rval ? 1 : 0);
      case ImcBINOP.AND: return lval * rval;
      case ImcBINOP.OR : return (lval + rval) % 2;
      }
    }
    if (expr instanceof ImcCALL) {
      ImcCALL call = (ImcCALL)expr;
      for (int a = 0; a < call.args.size(); a++) {
        Integer v = execExpr(call.args.get(a));
        ST(SP + 4 * a, v);
      }
      prefix = prefix + "  ";
      Integer result = execFun(call.label.name());
      prefix = prefix.substring(2);
      return result;
    }
    if (expr instanceof ImcCONST) {
      return ((ImcCONST)expr).value;
    }
    if (expr instanceof ImcMEM) {
      return LD(execExpr(((ImcMEM)expr).expr));
    }
    if (expr instanceof ImcNAME) {
      return labels.get(((ImcNAME)expr).label.name());
    }
    if (expr instanceof ImcTEMP) {
      return LD(((ImcTEMP)expr).temp);
    }
    Report.error("Unknown expression: " + expr, 0);
    return null;
  }

  public Integer LD(Integer addr) {
    Integer data = memory.get(addr / 4);
    if (debug == 1) System.err.println(prefix + "[" + addr + "]" + "->" + (data == null ? 0 : data));
    if (data == null) return 0; else return data;
  }

  public Integer LD(Temp temp) {
    Integer value = temps.get(temp.name());
    if (debug == 1) System.err.println(prefix + temp.name() + "->" + (value == null ? 0 : value));
    if (value == null) return 0; else return value;
  }

  public void ST(Integer addr, Integer data) {
    if (debug == 1) System.err.println(prefix + "[" + addr + "]" + "<-" + data);
    memory.put(addr / 4, data);
  }

  public void ST(Temp temp, Integer value) {
    if (debug == 1) System.err.println(prefix + temp.name() + "<-" + value);
    temps.put(temp.name(), value);
  }

}
TOP

Related Classes of compiler.lincode.Interpreter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.