Package org.sugarj.common

Source Code of org.sugarj.common.ATermCommands

package org.sugarj.common;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.spoofax.interpreter.terms.IStrategoAppl;
import org.spoofax.interpreter.terms.IStrategoConstructor;
import org.spoofax.interpreter.terms.IStrategoInt;
import org.spoofax.interpreter.terms.IStrategoList;
import org.spoofax.interpreter.terms.IStrategoPlaceholder;
import org.spoofax.interpreter.terms.IStrategoReal;
import org.spoofax.interpreter.terms.IStrategoString;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.spoofax.interpreter.terms.ITermFactory;
import org.spoofax.jsglr.client.InvalidParseTableException;
import org.spoofax.jsglr.client.imploder.IToken;
import org.spoofax.jsglr.client.imploder.ImploderAttachment;
import org.spoofax.jsglr.client.imploder.Token;
import org.spoofax.jsglr.io.ParseTableManager;
import org.spoofax.terms.StrategoListIterator;
import org.spoofax.terms.TermFactory;
import org.spoofax.terms.attachments.ParentAttachment;
import org.spoofax.terms.attachments.ParentTermFactory;
import org.spoofax.terms.io.InlinePrinter;
import org.spoofax.terms.io.TAFTermReader;
import org.strategoxt.HybridInterpreter;
import org.strategoxt.lang.Context;
import org.strategoxt.lang.StrategoExit;
import org.strategoxt.stratego_gpp.ast2abox_0_1;
import org.strategoxt.stratego_gpp.box2text_string_0_1;
import org.strategoxt.stratego_gpp.parse_pptable_file_0_0;
import org.strategoxt.tools.sdf_desugar_0_0;
import org.sugarj.common.path.Path;

/**
* @author Sebastian Erdweg <seba at informatik uni-marburg de>
*/
public class ATermCommands {
 
  public static class MatchError extends Error {
    private static final long serialVersionUID = -3329736288449173760L;
    private final IStrategoTerm scrutinee;
    private final String kind;
    private final String highlevelPattern;
   
    public MatchError(IStrategoTerm scrutinee, String kind, String highlevelPattern) {
      super("Error while matching " + kind + " of " + highlevelPattern);
     
      this.scrutinee = scrutinee;
      this.kind = kind;
      this.highlevelPattern = highlevelPattern;
    }

    public MatchError(IStrategoTerm scrutinee, String kind) {
      super("Error while matching " + kind + " against " + scrutinee.toString());
     
      this.scrutinee = scrutinee;
      this.kind = kind;
      this.highlevelPattern = null;
    }

    public IStrategoTerm getScrutinee() {
      return scrutinee;
    }
   
    public String getKind() {
      return kind;
    }

    public String getHighlevelPattern() {
      return highlevelPattern;
    }
  }
 
  public static class PrettyPrintError extends Error {
    private static final long serialVersionUID = 1435096897087780884L;
    private IStrategoTerm term;
    private String msg;
    public PrettyPrintError(IStrategoTerm term, String msg) {
      this.term = term;
      this.msg = msg;
    }
    public IStrategoTerm getTerm() {
      return term;
    }
    public String getMsg() {
      return msg;
    }
  }
 
  // TODO use origin factory
  public static ITermFactory factory = new ParentTermFactory(new TermFactory().getFactoryWithStorageType(IStrategoTerm.MUTABLE));
  public static ParseTableManager parseTableManager = new ParseTableManager(factory, false);

  public static IStrategoTerm atermFromFile(String filename) throws IOException {
    IStrategoTerm term = Environment.terms.get(filename);
   
    if (term != null)
      return term;
   
    return new TAFTermReader(factory).parseFromFile(filename);
  }
 
  public static IStrategoTerm atermFromString(String s) throws IOException {
    return new TAFTermReader(factory).parseFromString(s);
  }

  public static Path atermToFile(IStrategoTerm aterm) throws IOException {
    Path file = FileCommands.newTempFile("ast");
    atermToFile(aterm, file);
    return file;
  }
 
  public static void atermToFile(IStrategoTerm aterm, Path filename)
      throws IOException {
    Environment.terms.put(filename, aterm);
    FileCommands.writeToFile(filename, atermToString(aterm));
  }
 
  public static String atermToString(IStrategoTerm aterm) {
    InlinePrinter printer = new InlinePrinter();
    aterm.prettyPrint(printer);
    return printer.getString();
  }

  public static boolean isApplication(IStrategoTerm term, String cons) {
    return term.getTermType() == IStrategoTerm.APPL &&
           ((IStrategoAppl) term).getConstructor().getName().equals(cons);
  }
 
  public static IStrategoTerm getApplicationSubterm(IStrategoTerm term, String cons, int index) {
    if (cons == null || isApplication(term, cons))
      return term.getSubterm(index);
   
    throw new MatchError(term, "application", cons);
  }
 
  public static String getString(IStrategoTerm term) {
    if (term.getTermType() == IStrategoTerm.STRING)
      return ((IStrategoString) term).stringValue();
   
    throw new MatchError(term, "string");
  }

  public static boolean isList(IStrategoTerm term) {
    return term.getTermType() == IStrategoTerm.LIST;
  }
 
  public static boolean isString(IStrategoTerm term) {
    return term.getTermType() == IStrategoTerm.STRING;
  }

 
  public static List<IStrategoTerm> getList(IStrategoTerm term) {
   
    if (term.getTermType() == IStrategoTerm.LIST)
    {
      List<IStrategoTerm> l = new ArrayList<IStrategoTerm>();
     
      for (Iterator<IStrategoTerm> it = new StrategoListIterator((IStrategoList) term);
           it.hasNext(); )
        l.add(it.next());
     
      return l;
    }
   
    throw new MatchError(term, "list");
  }
 
  public static IStrategoTerm makeTuple(IStrategoTerm... ts) {
    return makeTuple(null, ts);
  }
 
  public static IStrategoTerm makeTuple(IToken tok, IStrategoTerm... ts) {
    IStrategoTerm t = factory.makeTuple(ts);
    setAttachment(t, "Tuple", tok, ts);
    return t;
  }
 
  public static IStrategoTerm makeSome(IStrategoTerm term, IToken noneToken) {
    if (term != null)
      return makeAppl("Some", "Some", 1, noneToken, term);
   
    return makeAppl("None", "Some", 0, noneToken);
  }

  public static IStrategoTerm makeString(String s) {
    IStrategoTerm t = factory.makeString(s);
    setAttachment(t, "String", null);
    return t;
  }

  public static IStrategoTerm makeString(String s, IToken token) {
    IStrategoTerm t = factory.makeString(s);
    setAttachment(t, "String", token);
    return t;
  }
 
  public static IStrategoList makeList(String sort, IStrategoTerm... ts) {
    assert ts.length > 0;
    return makeList(sort, null, ts);
  }
 
  public static IStrategoList makeList(String sort, IToken emptyListToken, IStrategoTerm... ts) {
    IStrategoList term = factory.makeList(ts);
   
    setAttachment(term, sort, emptyListToken, ts);
    return term;
  }

  public static IStrategoList makeList(String sort, Collection<IStrategoTerm> ts) {
    return makeList(sort, ts.toArray(new IStrategoTerm[ts.size()]));
  }
 
  public static IStrategoList makeList(String sort, IToken emptyListToken, Collection<IStrategoTerm> ts) {
    return makeList(sort, emptyListToken, ts.toArray(new IStrategoTerm[ts.size()]));
  }
 
  public static IStrategoTerm makeAppl(String cons, String sort, int arity, IStrategoTerm... args) {
    assert args.length > 0;
    return makeAppl(cons, sort, arity, null, args);
  }
 
  public static IStrategoTerm makeAppl(String cons, String sort, int arity, IToken emptyArgsToken, IStrategoTerm... args) {
    assert emptyArgsToken != null || args.length > 0;
   
    IStrategoTerm appl =
      factory.makeAppl(
             factory.makeConstructor(cons, arity),
             args);
   
    setAttachment(appl, sort, emptyArgsToken, args);
   
    return appl;
  }
 
  private static void setAttachment(IStrategoTerm term, String sort, IToken emptyToken, IStrategoTerm... children) {
    IToken left;
    IToken right;
   
    if (children.length == 0) {
      if (emptyToken == null)
        return;
     
      left = emptyToken;
      right = emptyToken;
    }
    else {
      left = ImploderAttachment.getLeftToken(children[0]);
      right = ImploderAttachment.getRightToken(children[children.length - 1]);
    }
   
    if (left != null && right != null)
      ImploderAttachment.putImploderAttachment(
          term,
          term.isList(),
          sort,
          left,
          right);
   
   
    for (IStrategoTerm arg : children)
      ParentAttachment.putParent(arg, term, null);
  }
 

 
  public static IStrategoTerm fixSDF(IStrategoTerm term, HybridInterpreter interp) throws IOException, InvalidParseTableException {
    if (term == null)
      return null;
   
    IStrategoTerm result = null;
    try {
      result = sdf_desugar_0_0.instance.invoke(interp.getCompiledContext(), term);
    }
    catch (StrategoExit e) {
      if (e.getValue() != 0 || result == null)
        throw new RuntimeException("Sdf desugaring failed", e);
    }
   
    return result;
  }
 
  public static List<IStrategoTerm> registerSemanticProvider(Collection<IStrategoTerm> editorServices, Path jarfile) throws IOException {
    List<IStrategoTerm> newServices = new ArrayList<IStrategoTerm>(editorServices);

    if (jarfile == null)
      return newServices;
   
    String jarfilePath = jarfile.getAbsolutePath().replace("\\", "\\\\").replace("\"", "\\\"");
    IStrategoTerm builder = ATermCommands.atermFromString(
        "Builders(\"sugarj checking\", [SemanticObserver(Strategy(\"sugarj-analyze\")), SemanticProvider(\"" + jarfilePath + "\")])");
    newServices.add(builder);

    return newServices;
  }

  public static void setErrorMessage(IStrategoTerm toplevelDecl, String msg) {
    IToken left = ImploderAttachment.getLeftToken(toplevelDecl);
    IToken right = ImploderAttachment.getRightToken(toplevelDecl);
   
//    Path file = null;
//    try {
//      file = atermToFile(toplevelDecl);
//    } catch (IOException e) {
//      e.printStackTrace();
//    }
   
    if (left == null || right == null) {
      new IllegalStateException(msg).printStackTrace();
      return;
    }
   
    HashMap<String, String> cache = new HashMap<String, String>();
   
    for (int i = left.getIndex(), max = right.getIndex(); i <= max; i++) {
      Token tok = ((Token) left.getTokenizer().getTokenAt(i));
      if (tok.getError() == null || tok.getError().isEmpty())
        tok.setError(msg);
      else {
        StringBuilder b = new StringBuilder();
        b.append(tok.getError());
        b.append("<br>");
        b.append(msg);
        String key = b.toString();
        String val = cache.get(key);
        if (val == null) {
          val = key;
          cache.put(key, val);
        }
        tok.setError(val);
      }
     
      if (tok.getTokenizer().getInput().length() <= tok.getStartOffset() || tok.getTokenizer().getInput().charAt(tok.getStartOffset()) == '\n')
        break;
    }
  }

  public static IStrategoTerm makeMutable(IStrategoTerm term) {
    if (term.getStorageType() == IStrategoTerm.MUTABLE)
      return term;
   
    IStrategoTerm[] kids = new IStrategoTerm[term.getSubtermCount()];
   
    for (int i = 0; i < kids.length; i++)
      kids[i] = makeMutable(term.getSubterm(i));
   
    switch (term.getTermType()) {
      case IStrategoTerm.APPL :
        return factory.makeAppl(((IStrategoAppl) term).getConstructor(), kids, term.getAnnotations());
      case IStrategoTerm.LIST :
        return factory.makeList(kids, term.getAnnotations());
      case IStrategoTerm.INT :
        return factory.makeInt(((IStrategoInt) term).intValue());
      case IStrategoTerm.REAL :
        return factory.makeReal(((IStrategoReal) term).realValue());
      case IStrategoTerm.STRING :
        return factory.makeString(((IStrategoString) term).stringValue());
      case IStrategoTerm.CTOR :
        return factory.makeConstructor(((IStrategoConstructor) term).getName(), ((IStrategoConstructor) term).getArity());
      case IStrategoTerm.TUPLE :
        return factory.makeTuple(kids, term.getAnnotations());
      case IStrategoTerm.PLACEHOLDER :
        return factory.makePlaceholder(((IStrategoPlaceholder) term).getTemplate());
      default :
        throw new UnsupportedOperationException();
    }
  }


  public static IStrategoTerm pushAmbiguities(IStrategoTerm term) {
    if (isApplication(term, "amb") && term.getSubterm(0).isList() && term.getSubterm(0).getSubtermCount() == 2) {
      IStrategoTerm left = pushAmbiguities(term.getSubterm(0).getSubterm(0));
      IStrategoTerm right = pushAmbiguities(term.getSubterm(0).getSubterm(1));
     
      if (left.getTermType() == IStrategoTerm.APPL &&
          right.getTermType() == IStrategoTerm.APPL &&
          left.getSubtermCount() == right.getSubtermCount() &&
          ((IStrategoAppl) left).getConstructor().equals(((IStrategoAppl) right).getConstructor())) {
       
        IStrategoTerm[] ambKids = new IStrategoTerm[left.getSubtermCount()];
       
        for (int i = 0; i < left.getSubtermCount(); i++)
          ambKids[i] = makeAppl("amb",
                                ImploderAttachment.getElementSort(left.getSubterm(i)),
                                2,
                                makeList(ImploderAttachment.getElementSort(term.getSubterm(0)),
                                         left.getSubterm(i), right.getSubterm(i)));
       
        return makeAppl(
            ((IStrategoAppl) left).getConstructor().getName(),
            ImploderAttachment.getElementSort(left),
            left.getSubtermCount(),
            ambKids);
      }
     
      return term;
    }
   
    return term;
  }
 
  public static IStrategoTerm readPrettyPrintTable(String p) {
    IStrategoTerm ppTableFile = ATermCommands.makeString(p);
    return parse_pptable_file_0_0.instance.invoke(org.strategoxt.stratego_gpp.stratego_gpp.init(), ppTableFile);
  }

  public static String prettyPrint(IStrategoTerm ppTable, IStrategoTerm term, HybridInterpreter interp) {
    Context ctx = interp.getCompiledContext();
    IStrategoTerm ppt_list = makeList("PPTable", ppTable);
    IStrategoTerm aboxTerm = ast2abox_0_1.instance.invoke(ctx, term, ppt_list);
    if (aboxTerm == null)
      return null;
    IStrategoTerm textTerm = box2text_string_0_1.instance.invoke(ctx, aboxTerm, factory.makeInt(80));
    return ATermCommands.getString(textTerm);

  }

  /**
   * Copies the imploder attachments from one term to the other. The two input terms must be structurally equivalent.
   *
   * @return the term 'to' with the imploder attachments of 'from'.
   */
  public static IStrategoTerm copyTokens(IStrategoTerm from, IStrategoTerm to) {
    if (from == to)
      return to;
   
    IStrategoTerm result = to;
    LinkedList<IStrategoTerm> fromStack = new LinkedList<IStrategoTerm>();
    LinkedList<IStrategoTerm> toStack = new LinkedList<IStrategoTerm>();
    fromStack.push(from);
    toStack.push(to);
   
    while (!fromStack.isEmpty()) {
      from = fromStack.pop();
      to = toStack.pop();
     
      ImploderAttachment attach = ImploderAttachment.get(from);
      if (attach != null)
        ImploderAttachment.putImploderAttachment(
            to,
            attach.isSequenceAttachment(),
            attach.isSequenceAttachment() ? attach.getElementSort() : attach.getSort(),
            attach.getLeftToken(),
            attach.getRightToken());
     
      for (int i = 0; i < from.getSubtermCount(); i++) {
        fromStack.push(from.getSubterm(i));
       
        IStrategoTerm subterm = to.getSubterm(i);
        ParentAttachment.putParent(subterm, to, null);
        toStack.push(subterm);
      }
    }
   
    return result;
  }
}
TOP

Related Classes of org.sugarj.common.ATermCommands

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.