/******************************************************************************* * * Copyright (C) 2008 Fujitsu Services Ltd. * * Author: Nick Battle * * This file is part of VDMJ. * * VDMJ is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VDMJ is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VDMJ. If not, see <http://www.gnu.org/licenses/>. * ******************************************************************************/ package org.overture.pog.contexts; import java.util.ListIterator; import java.util.Map; import java.util.Stack; import org.overture.ast.expressions.AVariableExp; import org.overture.ast.expressions.PExp; import org.overture.ast.intf.lex.ILexNameToken; import org.overture.ast.types.PType; import org.overture.pog.pub.IPOContext; import org.overture.pog.pub.IPOContextStack; import org.overture.pog.utility.UniqueNameGenerator; @SuppressWarnings("serial") public class POContextStack extends Stack<IPOContext> implements IPOContextStack { private UniqueNameGenerator gen; @Override public void setGenerator(UniqueNameGenerator gen) { this.gen = gen; } @Override public UniqueNameGenerator getGenerator() { return gen; } /** * Pop a non-stateful context from the Stack. Stateful contexts can be removed with {@link #clearStateContexts()} */ @Override public synchronized IPOContext pop() { IPOContext obj = peek(); int len = size(); for (int i = len - 1; i >= 0; i--) { if (!this.get(i).isStateful()) { removeElementAt(i); return obj; } } return obj; } public PExp getPredWithContext(PExp initialPredicate) { return getContextNode(initialPredicate); } private PExp getContextNode(PExp stitchPoint) { for (int i = this.size() - 1; i >= 0; i--) { IPOContext ctxt = this.get(i); if (!(ctxt instanceof PONameContext)) { stitchPoint = ctxt.getContextNode(stitchPoint); } } return stitchPoint; } /* * (non-Javadoc) * @see org.overture.pog.IPOContextStack#getName() */ @Override public String getName() { StringBuilder result = new StringBuilder(); String prefix = ""; for (IPOContext ctxt : this) { String name = ctxt.getName(); if (name.length() > 0) { result.append(prefix); result.append(name); prefix = ", "; } } return result.toString(); } /* * (non-Javadoc) * @see org.overture.pog.IPOContextStack#getObligation(java.lang.String) */ @Override public String getObligation(String root) { StringBuilder result = new StringBuilder(); String spacing = " "; String indent = ""; StringBuilder tail = new StringBuilder(); for (IPOContext ctxt : this) { String po = ctxt.getContext(); if (po.length() > 0) { result.append(indent); result.append("("); result.append(indentNewLines(po, indent)); result.append("\n"); indent = indent + spacing; tail.append(")"); } } result.append(indent); result.append(indentNewLines(root, indent)); result.append(tail); result.append("\n"); return result.toString(); } private String indentNewLines(String line, String indent) { StringBuilder sb = new StringBuilder(); String[] parts = line.split("\n"); String prefix = ""; for (int i = 0; i < parts.length; i++) { sb.append(prefix); sb.append(parts[i]); prefix = "\n" + indent; } return sb.toString(); } public void noteType(PExp exp, PType PType) { this.peek().noteType(exp, PType); } public PType checkType(PExp exp, PType expected) { ListIterator<IPOContext> p = this.listIterator(size()); while (p.hasPrevious()) { IPOContext c = p.previous(); if (c.isScopeBoundary()) { break; // Change of name scope for expressions. } PType t = c.checkType(exp); if (t != null) { return t; } } return expected; } @Override public void clearStateContexts() { int len = size(); for (int i = len - 1; i > 0; i--) { if (this.get(i).isStateful()) { removeElementAt(i); } } } @Override public Map<ILexNameToken, AVariableExp> getLast_Vars() { ListIterator<IPOContext> p = this.listIterator(size()); while (p.hasPrevious()) { IPOContext c = p.previous(); if (c instanceof StatefulContext) { return ((StatefulContext) c).getLast_vars(); } } return null; } }