org.overturetool.cgisa.IsaTranslations Maven / Gradle / Ivy
/*
* #%~
* VDM to Isabelle Translation
* %%
* Copyright (C) 2008 - 2015 Overture
* %%
* This program 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.
*
* This program 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 this program. If not, see
* .
* #~%
*/
package org.overturetool.cgisa;
import java.io.StringWriter;
import java.util.Iterator;
import java.util.List;
import org.overture.ast.definitions.AImplicitFunctionDefinition;
import org.overture.codegen.ir.INode;
import org.overture.codegen.ir.SExpIR;
import org.overture.codegen.ir.SMultipleBindIR;
import org.overture.codegen.ir.STypeIR;
import org.overture.codegen.ir.analysis.AnalysisException;
import org.overture.codegen.ir.declarations.AFieldDeclIR;
import org.overture.codegen.ir.declarations.AFormalParamLocalParamIR;
import org.overture.codegen.ir.declarations.AFuncDeclIR;
import org.overture.codegen.ir.declarations.ANamedTypeDeclIR;
import org.overture.codegen.ir.declarations.ARecordDeclIR;
import org.overture.codegen.ir.declarations.ATypeDeclIR;
import org.overture.codegen.ir.expressions.AApplyExpIR;
import org.overture.codegen.ir.types.AMethodTypeIR;
import org.overture.codegen.ir.types.AVoidTypeIR;
import org.overture.codegen.ir.SourceNode;
import org.overture.codegen.merging.MergeVisitor;
import org.overture.codegen.merging.TemplateCallable;
import org.overture.codegen.merging.TemplateManager;
import org.overturetool.cgisa.utils.IsMethodTypeVisitor;
import org.overturetool.cgisa.utils.IsSeqOfCharTypeVisitor;
public class IsaTranslations {
private static final String TEMPLATE_CALLABLE_NAME = "Isa";
private static final String TYPE_PARAM_SEP = " and ";
private static final String LIST_SEP = ", ";
private static final String TUPLE_TYPE_SEPARATOR = "*";
private static final String ISA_TEMPLATE_ROOT = "IsaTemplates";
private MergeVisitor mergeVisitor;
protected IsaChecks isaUtils;
public IsaTranslations() {
TemplateCallable[] templateCallables = new TemplateCallable[]{new TemplateCallable(TEMPLATE_CALLABLE_NAME, this)};
this.mergeVisitor = new MergeVisitor(new TemplateManager(ISA_TEMPLATE_ROOT, this.getClass()),templateCallables);
this.isaUtils = new IsaChecks();
}
public MergeVisitor getMergeVisitor() {
return mergeVisitor;
}
// Translations
public String trans(INode node) throws AnalysisException {
StringWriter writer = new StringWriter();
node.apply(mergeVisitor, writer);
return writer.toString();
}
public String transApplyParams(List params)
throws AnalysisException {
return transNodeList(params, LIST_SEP);
}
public String transTypeParams(List params)
throws AnalysisException {
return transNodeList(params, TYPE_PARAM_SEP);
}
public String transBinds(List extends SMultipleBindIR> binds)
throws AnalysisException {
return transNodeList(binds, LIST_SEP);
}
public String transNodeList(List extends INode> params, String sep)
throws AnalysisException {
StringBuilder sb = new StringBuilder();
Iterator extends INode> it = params.iterator();
while (it.hasNext()) {
StringWriter writer = new StringWriter();
it.next().apply(mergeVisitor, writer);
sb.append(writer.toString());
if (it.hasNext()) {
sb.append(sep);
}
}
return sb.toString();
}
public String transString(List args) throws AnalysisException {
StringBuilder sb = new StringBuilder();
sb.append("''");
for (SExpIR arg : args) {
sb.append(trans(arg));
}
sb.append("''");
return sb.toString();
}
public String transSeq(List args) throws AnalysisException {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append(transNodeList(args, LIST_SEP));
sb.append("]");
return sb.toString();
}
public String rec2Tuple(ARecordDeclIR record) throws AnalysisException {
StringBuilder sb = new StringBuilder();
Iterator it = record.getFields().iterator();
while (it.hasNext()) {
AFieldDeclIR n = it.next();
sb.append(trans(n.getType()));
if (it.hasNext()) {
sb.append(TUPLE_TYPE_SEPARATOR);
}
}
return sb.toString();
}
// Hacks - translations that manipulate the tree in grostesque way due to
// issues with the IR
// FIXME Unhack result name extraction for implicit functions
public String hackResultName(AFuncDeclIR func) throws AnalysisException {
SourceNode x = func.getSourceNode();
if (x.getVdmNode() instanceof AImplicitFunctionDefinition) {
AImplicitFunctionDefinition iFunc = (AImplicitFunctionDefinition) x.getVdmNode();
return iFunc.getResult().getPattern().toString();
}
throw new AnalysisException("Expected AFuncDeclIR in implicit function source. Got: "
+ x.getVdmNode().getClass().toString());
}
// FIXME Unhack invariant extraction for named types
public String hackInv(ANamedTypeDeclIR type) {
ATypeDeclIR tDecl = (ATypeDeclIR) type.parent();
if (tDecl.getInv() != null) {
AFuncDeclIR invFunc = (AFuncDeclIR) tDecl.getInv();
StringBuilder sb = new StringBuilder();
sb.append("inv ");
sb.append(invFunc.getFormalParams().get(0).getPattern().toString());
sb.append(" == ");
sb.append(invFunc.getName());
sb.append("(");
sb.append("&");
sb.append(invFunc.getFormalParams().get(0).getPattern().toString());
sb.append(")");
return sb.toString();
}
return "";
}
// FIXME Unhack invariant extraction for namedt ypes
public String hackInv(ARecordDeclIR type) {
if (type.getInvariant() != null) {
AFuncDeclIR invFunc = (AFuncDeclIR) type.getInvariant();
StringBuilder sb = new StringBuilder();
sb.append("inv ");
sb.append(invFunc.getFormalParams().get(0).getPattern().toString());
sb.append(" == ");
sb.append(invFunc.getName());
sb.append("(");
sb.append("&");
sb.append(invFunc.getFormalParams().get(0).getPattern().toString());
sb.append(")");
return sb.toString();
}
return "";
}
public String hackInvDecl(ARecordDeclIR type) throws AnalysisException {
if (type.getInvariant() != null) {
return trans(type.getInvariant());
}
return "";
}
// Renamings
public String norm(String name) {
return name.replaceAll("-", "_");
}
public String varWrap(String v) {
StringBuilder sb = new StringBuilder();
sb.append('<');
sb.append(v);
sb.append('>');
return sb.toString();
}
// Control flow
public String filter(AFieldDeclIR field) throws AnalysisException {
if (field.getFinal() && field.getStatic()) {
return trans(field);
}
return "";
}
// Checks
public boolean hasReturn(AMethodTypeIR node) {
return !(node.getResult() instanceof AVoidTypeIR);
}
public boolean isRoot(INode node) {
return isaUtils.isRoot(node);
}
public boolean isRootRec(AApplyExpIR node) {
return isaUtils.isRootRec(node);
}
public boolean isString(STypeIR node) throws AnalysisException {
return node.apply(new IsSeqOfCharTypeVisitor());
}
public boolean isFunc(STypeIR node) throws AnalysisException {
return node.apply(new IsMethodTypeVisitor());
}
public boolean isRecordDecl(ATypeDeclIR node) {
return (node.getDecl() instanceof ARecordDeclIR);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy