/** * <copyright> * * This program and the accompanying materials are made available under the * terms of the BSD 3-clause license which accompanies this distribution. * * </copyright> */ package siple; import java.util.*; import siple.ast.*; /** * Instances of this class represent <i>SiPLE</i> interpreter states. The * interpretation of a <i>SiPLE</i> program starts with the empty state * consisting of a single frame and finishes either, with a state consisting * of a single frame that contains the program's results or an {@link * InterpretationException interpretation exception}, iff the program is * erroneous. Since <i>SiPLE</i> is Turing complete, the interpretation might * also not terminate at all. * @author C. Bürger */ public final class State { /** * The procedure currently in execution. */ public Frame currentFrame = new Frame(); /** * The standard output buffer. */ public final StringBuilder stdOut = new StringBuilder(); /** * Allocate memory for the given entity in the current frame and * initialize its value. * @param decl The entity to allocate and initialize. * @param value The entities' initialization value; To specify, that the * entity is not initialized during its allocation the parameter has to be * <tt>null</tt>. */ public void allocate(Declaration decl, Object value) { MemoryLocation loc = new MemoryLocation(); loc.value = value; currentFrame.environment.put(decl, loc); } /** * Access an entity, i.e., return its {@link MemoryLocation memory * location}. * @param decl The entity to access. * @return The entities' address. * @throws InterpretationException Thrown, iff the given entity is not * allocated. */ public MemoryLocation access(Declaration decl) throws InterpretationException { for (Frame cf = currentFrame; cf != null; cf = cf.closure) { MemoryLocation loc = cf.environment.get(decl); if (loc != null) return loc; } throw new InterpretationException( "Access to unallocated variable ["+ decl.getName() +"]."); } /** * Each frame represents the execution environment of a procedure, i.e., * the current state of a procedure in execution. It consists of:<ul> * <li>(1) The procedure's {@link #implementation} (AST procedure * declaration)</li> * <li>(2) The procedure's {@link #closure} (the frame within which this * frame is instantiated; required for accesses to non local entities)</li> * <li>(3) The procedure's local {@link #environment} (local variable * bindings)</li> * <li>(4) The procedure's {@link #returnValue return value} (given, iff * the procedure's execution finished)</li></ul> * @author C. Bürger */ public static final class Frame { /** See {@link Frame}. */ public ProcedureDeclaration implementation = null; /** See {@link Frame}. */ public Frame closure = null; /** See {@link Frame}. */ public Map<Declaration, MemoryLocation> environment = new TreeMap<Declaration, MemoryLocation>(); /** See {@link Frame}. */ public Object returnValue = null; } /** * Simple wrapper class to represent addressable memory locations. * @author C. Bürger */ public static final class MemoryLocation { /** * The value stored under the address this memory location represents. */ public Object value; } }