Package apigen.adt

Source Code of apigen.adt.Type

package apigen.adt;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import aterm.AFun;
import aterm.ATerm;
import aterm.ATermAppl;
import aterm.ATermList;
import aterm.ATermPlaceholder;

public class Type {
  private String moduleName;
    private String id;
    private AlternativeList alts;
    private Map<String, Field> fields;
    private List<Field> field_list;

    public Type(String id, String moduleName) {
        this.id = id;
        this.moduleName = moduleName;
        alts = new AlternativeList();
        fields = new HashMap<String, Field>();
        field_list = new ArrayList<Field>();
    }

    public String getId() {
        return id;
    }
   
    public String getModuleName() {
      return moduleName;
    }

    public void addAlternative(Alternative alt) {
        alts.add(alt);

        extractFields(alt.getPattern(), new Location(alt.getId()));
    }

    private void extractFields(ATerm t, Location loc) {
        AFun fun;
        ATermAppl appl;
        ATermList list;

        switch (t.getType()) {
            case ATerm.APPL :
                //{{{ Call 'extractFields' for every argument

                appl = (ATermAppl) t;
                fun = appl.getAFun();
                for (int i = 0; i < fun.getArity(); i++) {
                    Location newloc = (Location) loc.clone();
                    newloc.addStep(new Step(Step.ARG, i));
                    extractFields(appl.getArgument(i), newloc);
                }

                //}}}
                break;

            case ATerm.LIST :
                //{{{ Call 'extractFields' for every element

                list = (ATermList) t;
                for (int i = 0; !list.isEmpty(); i++) {
                    Location newloc = (Location) loc.clone();
                    newloc.addStep(new Step(Step.ELEM, i));
                    extractFields(list.getFirst(), newloc);
                    list = list.getNext();
                }

                //}}}
                break;

            case ATerm.PLACEHOLDER :
                //{{{ Add a new field based on this placeholder

                ATerm ph = ((ATermPlaceholder) t).getPlaceholder();

                if (ph.getType() == ATerm.LIST) {
                    list = (ATermList) ph;
                    appl = (ATermAppl) list.elementAt(0);
                    String fieldId = appl.getAFun().getName();
                    appl = (ATermAppl) appl.getArgument(0);
                    String fieldType = appl.getAFun().getName();
                    loc.makeTail();
                    addField(fieldId, fieldType, loc);
                } else if (ph.getType() == ATerm.APPL) {
                    appl = (ATermAppl) ph;
                    String fieldId = appl.getAFun().getName();
                    appl = (ATermAppl) appl.getArgument(0);
                    String fieldType = appl.getAFun().getName();
                    addField(fieldId, fieldType, loc);
                } else {
                    throw new RuntimeException("illegal field spec: " + t);
                }

                //}}}
                break;

            default :
                break;
        }
    }

    public boolean hasAlternative(String id) {
        Iterator<Alternative> alts = alternativeIterator();

        while (alts.hasNext()) {
            Alternative alt = alts.next();

            if (alt.getId().equals(id)) {
                return true;
            }
        }

        return false;
    }

    private void addField(String id, String type, Location location) {
        if (id.equals("int")) {
            throw new RuntimeException(
                "Illegal use of reserved name \""
                    + id
                    + "\" as field name in type "
                    + this.id);
        }

        Field field = fields.get(id);

        if (field == null) {
            field = new Field(id, type);
            fields.put(id, field);
            field_list.add(field);
        } else if (field.getLocation(location.getAltId()) != null) {
            throw new RuntimeException(
                "\""
                    + id
                    + "\" occurs more than once in alternative \""
                    + location.getAltId()
                    + "\"");
        } else if (field.getType() != type) {
            throw new RuntimeException(
                "Illegal field name \""
                    + id
                    + "\" is used for different types of fields in type:"
                    + this.id);
        }

        field.addLocation(location);
    }

    public AlternativeList getAlternatives() {
        return (AlternativeList) alts.clone();
    }

    public Iterator<Alternative> alternativeIterator() {
        return alts.iterator();
    }

    public Alternative getAlternative(String altId) {
        Iterator<Alternative> iter = alts.iterator();

        while (iter.hasNext()) {
            Alternative element = iter.next();

            if (element.getId().equals(altId)) {
                return element;
            }
        }

        return null;
    }

    public Field getAltField(String altId, String fieldId) {
        Iterator<Field> iter = altFieldIterator(altId);

        while (iter.hasNext()) {
            Field field = iter.next();

            if (field.getId().equals(fieldId)) {
                return field;
            }
        }

        return null;
    }

    public Iterator<Field> fieldIterator() {
        return field_list.iterator();
    }

    public Iterator<Field> altFieldIterator(final String altId) {
        Comparator<Field> comp = new Comparator<Field>() {
            public int compare(Field o1, Field o2) {
                Field field1 = o1;
                Field field2 = o2;

                Iterator<Step> path1 = field1.getLocation(altId).stepIterator();
                Iterator<Step> path2 = field2.getLocation(altId).stepIterator();

                while (path1.hasNext()) {
                    if (!path2.hasNext()) {
                        throw new RuntimeException(
                            "incompatible paths: " + field1 + "," + field2);
                    }
                    Step step1 = path1.next();
                    Step step2 = path2.next();
                    int type1 = step1.getType();
                    int type2 = step2.getType();

                    if (type1 == Step.TAIL && type2 == Step.ELEM) {
                        return 1;
                    }

                    if (type1 == Step.ELEM && type2 == Step.TAIL) {
                        return -1;
                    }

                    if (type1 != type2) {
                        throw new RuntimeException(
                            "incompatible paths: " + field1 + "," + field2);
                    }

                    if (step1.getIndex() < step2.getIndex()) {
                        return -1;
                    }

                    if (step1.getIndex() > step2.getIndex()) {
                        return 1;
                    }
                }
                if (path2.hasNext()) {
                    throw new RuntimeException(
                        "incompatible paths: " + field1 + "," + field2);
                }
                if (o1 != o2) {
                    throw new RuntimeException("asjemenou?");
                }
                return 0;
            }
        };

        SortedSet<Field> sortedAltFields = new TreeSet<Field>(comp);

        Iterator<Field> iter = fields.values().iterator();
        while (iter.hasNext()) {
            Field field = iter.next();
            if (field.hasAltId(altId)) {
                sortedAltFields.add(field);
            }
        }

        return sortedAltFields.iterator();
    }

    public int getAlternativeCount() {
        return alts.size();
    }

    public String toString() {
        return "type[" + id + ",\n\t" + alts.toString() + ",\n\t" + fields.toString() + "]\n\tfrom module "+moduleName;
    }

    public int getAltArity(Alternative alt) {
        Iterator<Field> fields = altFieldIterator(alt.getId());
        int arity = 0;

        for (arity = 0; fields.hasNext(); fields.next()) {
            arity++;
        }

        return arity;
    }
   
}
TOP

Related Classes of apigen.adt.Type

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.