All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.overturetool.cgisa.IsaTranslations Maven / Gradle / Ivy

There is a newer version: 3.0.2
Show newest version
/*
 * #%~
 * 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 binds)
            throws AnalysisException {
        return transNodeList(binds, LIST_SEP);
    }

    public String transNodeList(List params, String sep)
            throws AnalysisException {
        StringBuilder sb = new StringBuilder();

        Iterator 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