Package org.rascalmpl.semantics.dynamic

Source Code of org.rascalmpl.semantics.dynamic.Tree$Cycle

/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*   * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
*******************************************************************************/
package org.rascalmpl.semantics.dynamic;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

import org.eclipse.imp.pdb.facts.IConstructor;
import org.eclipse.imp.pdb.facts.IList;
import org.eclipse.imp.pdb.facts.IListWriter;
import org.eclipse.imp.pdb.facts.ISetWriter;
import org.eclipse.imp.pdb.facts.ISourceLocation;
import org.eclipse.imp.pdb.facts.IValue;
import org.eclipse.imp.pdb.facts.type.Type;
import org.rascalmpl.interpreter.IEvaluator;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.env.Environment;
import org.rascalmpl.interpreter.matching.BasicBooleanResult;
import org.rascalmpl.interpreter.matching.ConcreteApplicationPattern;
import org.rascalmpl.interpreter.matching.ConcreteListPattern;
import org.rascalmpl.interpreter.matching.ConcreteListVariablePattern;
import org.rascalmpl.interpreter.matching.ConcreteOptPattern;
import org.rascalmpl.interpreter.matching.IBooleanResult;
import org.rascalmpl.interpreter.matching.IMatchingResult;
import org.rascalmpl.interpreter.matching.LiteralPattern;
import org.rascalmpl.interpreter.matching.NodePattern;
import org.rascalmpl.interpreter.matching.SetPattern;
import org.rascalmpl.interpreter.matching.TypedVariablePattern;
import org.rascalmpl.interpreter.result.Result;
import org.rascalmpl.interpreter.staticErrors.UndeclaredVariable;
import org.rascalmpl.interpreter.staticErrors.UninitializedVariable;
import org.rascalmpl.interpreter.types.NonTerminalType;
import org.rascalmpl.interpreter.types.RascalTypeFactory;
import org.rascalmpl.values.uptr.Factory;
import org.rascalmpl.values.uptr.ProductionAdapter;
import org.rascalmpl.values.uptr.SymbolAdapter;
import org.rascalmpl.values.uptr.TreeAdapter;

/**
* These classes special case Expression.CallOrTree for concrete syntax patterns
*/
public abstract class Tree {
  static public class MetaVariable extends org.rascalmpl.ast.Expression {
  private final String name;
  private final Type type;

  public MetaVariable(IConstructor node, IConstructor symbol, String name) {
    super(node);
    this.name = name;
    this.type = RTF.nonTerminalType(symbol);
  }
 
  @Override
  public Type typeOf(Environment env, boolean instantiateTypeParameters, IEvaluator<Result<IValue>> eval) {
    return type;
  }
 
  public boolean equals(Object o) {
    if (!(o instanceof MetaVariable)) {
      return false;
    }
    MetaVariable other = (MetaVariable) o;

    return name.equals(other.name) && type.equals(other.type);
  }

  public int hashCode() {
    return 13333331 + 37 * name.hashCode() + 61 * type.hashCode();
  }
 
  @Override
  public Result<IValue> interpret(IEvaluator<Result<IValue>> eval) {
    Result<IValue> variable = eval.getCurrentEnvt().getVariable(name);

    if (variable == null) {
      throw new UndeclaredVariable(name, this);
    }

    if (variable.getValue() == null) {
      throw new UninitializedVariable(name, this);
    }
   
    return variable;
  }
 
  @Override
  public IMatchingResult buildMatcher(IEvaluatorContext ctx) {
    IConstructor symbol = ((NonTerminalType) type).getSymbol();
    if (SymbolAdapter.isStarList(symbol) || SymbolAdapter.isPlusList(symbol)) {
      return new ConcreteListVariablePattern(ctx, this, type, name);
    }
    else {
      return new TypedVariablePattern(ctx, this, type, name);
    }
  }
   
  }
 
  static public class Appl extends org.rascalmpl.ast.Expression {
  protected final IConstructor production;
  protected final java.util.List<org.rascalmpl.ast.Expression> args;
  protected final Type type;
  protected final boolean constant;
  protected final IConstructor node;

  public Appl(IConstructor node, java.util.List<org.rascalmpl.ast.Expression> args) {
    super(node);
    this.production = TreeAdapter.getProduction(node);
    this.type = RascalTypeFactory.getInstance().nonTerminalType(production);
    this.args = args;
    this.constant = false; // TODO! isConstant(args);
    this.node = this.constant ? node : null;
    ISourceLocation src = TreeAdapter.getLocation(node);
   
    if (src != null) {
      this.setSourceLocation(src);
    }
  }

  public boolean equals(Object o) {
    if (!(o instanceof Appl)) {
      return false;
    }
    Appl other = (Appl) o;
   
    return production.equals(other.production) && args.equals(other.args);
  }
 
  public int hashCode() {
    return 101 + 23 * production.hashCode() + 131 * args.hashCode();
  }
 
  public IConstructor getProduction() {
    return production;
  }
 
  @Override
  public Type _getType() {
    return type;
  }
 
  @Override
  public Type typeOf(Environment env, boolean instantiateTypeParameters, IEvaluator<Result<IValue>> eval) {
    return type;
  }
 
  @Override
  public Result<IValue> interpret(IEvaluator<Result<IValue>> eval) {
    if (constant) {
      return makeResult(type, node, eval);
    }
   
    // TODO add function calling
    IListWriter w = eval.getValueFactory().listWriter(Factory.Tree);
    for (org.rascalmpl.ast.Expression arg : args) {
      w.append(arg.interpret(eval).getValue());
    }
   
    ISourceLocation location = getLocation();
   
    if (location != null) {
      java.util.Map<String,IValue> annos = new HashMap<String,IValue>();
      annos.put("loc", location);
      return makeResult(type, eval.getValueFactory().constructor(Factory.Tree_Appl, annos, production, w.done()), eval);
    }
    else {
      return makeResult(type, eval.getValueFactory().constructor(Factory.Tree_Appl, production, w.done()), eval);
    }
  }
 
  @Override
  public IBooleanResult buildBacktracker(IEvaluatorContext eval) {
    return new BasicBooleanResult(eval, this);
  }
 
  @Override
  public IMatchingResult buildMatcher(IEvaluatorContext eval) {
    if (constant) {
      return new LiteralPattern(eval, this,  node);
    }
   
    java.util.List<IMatchingResult> kids = new java.util.ArrayList<IMatchingResult>(args.size());
    for (int i = 0; i < args.size(); i+=2) { // skip layout elements for efficiency
      kids.add(args.get(i).buildMatcher(eval));
    }
    return new ConcreteApplicationPattern(eval, this,  kids);
  }
  }
 
  static public class Lexical extends Appl {
  public Lexical(IConstructor node, java.util.List<org.rascalmpl.ast.Expression> args) {
    super(node, args);
  }
 
  @Override
  public IMatchingResult buildMatcher(IEvaluatorContext eval) {
    if (constant) {
      return new LiteralPattern(eval, this,  node);
    }
   
    java.util.List<IMatchingResult> kids = new java.util.ArrayList<IMatchingResult>(args.size());
    for (org.rascalmpl.ast.Expression arg : args) {
      kids.add(arg.buildMatcher(eval));
    }
    return new ConcreteApplicationPattern(eval, this,  kids);
  }
  }
 
  static public class Optional extends Appl {
  public Optional(IConstructor node, java.util.List<org.rascalmpl.ast.Expression> args) {
    super(node, args);
  }
 

  @Override
  public IMatchingResult buildMatcher(IEvaluatorContext eval) {
    java.util.List<IMatchingResult> kids = new ArrayList<IMatchingResult>(args.size());
    if (args.size() == 1) {
      kids.add(args.get(0).buildMatcher(eval));
    }
    return new ConcreteOptPattern(eval, this,  kids);
  }
  }
 
  static public class List extends Appl {
  private final int delta;

  public List(IConstructor node, java.util.List<org.rascalmpl.ast.Expression> args) {
    super(node, args);
    this.delta = getDelta(production);
  }
 
  @Override
  public IMatchingResult buildMatcher(IEvaluatorContext eval) {
    if (constant) {
      return new LiteralPattern(eval, this,  node);
    }
   
    java.util.List<IMatchingResult> kids = new java.util.ArrayList<IMatchingResult>(args.size());
    for (org.rascalmpl.ast.Expression arg : args) {
      kids.add(arg.buildMatcher(eval));
    }
    return new ConcreteListPattern(eval, this,  kids);
  }
 
  public Result<IValue> interpret(IEvaluator<Result<IValue>> eval) {
    if (constant) {
      return makeResult(type, node, eval);
    }
   
    // TODO add function calling
    IListWriter w = eval.getValueFactory().listWriter(Factory.Tree);
    for (org.rascalmpl.ast.Expression arg : args) {
      w.append(arg.interpret(eval).getValue());
    }
   
    ISourceLocation location = getLocation();
   
    if (location != null) {
      java.util.Map<String,IValue> annos = new HashMap<String,IValue>();
      annos.put("loc", location);
      return makeResult(type, eval.getValueFactory().constructor(Factory.Tree_Appl, annos, production, flatten(w.done())), eval);
    }
    else {
      return makeResult(type, eval.getValueFactory().constructor(Factory.Tree_Appl, production, flatten(w.done())), eval);
    }
  }

  private void appendPreviousSeparators(IList args, IListWriter result, int delta, int i, boolean previousWasEmpty) {
    if (!previousWasEmpty) {
      for (int j = i - delta; j > 0 && j < i; j++) {
        result.append(args.get(j));
      }
    }
  }

  private IList flatten(IList args) {
    IListWriter result = VF.listWriter(Factory.Args.getElementType());
    boolean previousWasEmpty = false;
   
    for (int i = 0; i < args.length(); i+=(delta+1)) {
      IConstructor tree = (IConstructor) args.get(i);
     
      if (TreeAdapter.isList(tree) && ProductionAdapter.shouldFlatten(production, TreeAdapter.getProduction(tree))) {
        IList nestedArgs = TreeAdapter.getArgs(tree);
        if (nestedArgs.length() > 0) {
          appendPreviousSeparators(args, result, delta, i, previousWasEmpty);
          result.appendAll(nestedArgs);
        }
        else {
          previousWasEmpty = true;
        }
      }
      else {
        appendPreviousSeparators(args, result, delta, i, previousWasEmpty);
        result.append(tree);
        previousWasEmpty = false;
      }
    }
   
    return result.done();
  }

  private int getDelta(IConstructor prod) {
    IConstructor rhs = ProductionAdapter.getType(prod);
   
    if (SymbolAdapter.isIterPlusSeps(rhs) || SymbolAdapter.isIterStarSeps(rhs)) {
      return SymbolAdapter.getSeparators(rhs).length();
    }
   
    return 0;
  }
  }
 
  static public class Amb extends  org.rascalmpl.ast.Expression {
  private final Type type;
  private final java.util.List<org.rascalmpl.ast.Expression> alts;
  private final boolean constant;
  protected final IConstructor node;

  public Amb(IConstructor node, java.util.List<org.rascalmpl.ast.Expression> alternatives) {
    super(node);
    this.type = RascalTypeFactory.getInstance().nonTerminalType(node);
    this.alts = alternatives;
    this.constant = false; // TODO! isConstant(alternatives);
    this.node = this.constant ? node : null;
  }
 
  public boolean equals(Object o) {
    if (!(o instanceof Amb)) {
      return false;
    }
    Amb other = (Amb) o;
   
    return node.equals(other.node);
  }
 
  public int hashCode() {
    return node.hashCode();
  }
 
  @Override
  public Result<IValue> interpret(IEvaluator<Result<IValue>> eval) {
    if (constant) {
      return makeResult(type, node, eval);
    }
   
    // TODO: add filtering semantics, function calling
    ISetWriter w = eval.getValueFactory().setWriter(Factory.Tree);
    for (org.rascalmpl.ast.Expression a : alts) {
      w.insert(a.interpret(eval).getValue());
    }
    return makeResult(type, eval.getValueFactory().constructor(Factory.Tree_Amb, (IValue) w.done()), eval);
  }
 
  @Override
  public Type typeOf(Environment env, boolean instantiateTypeParameters, IEvaluator<Result<IValue>> eval) {
    return type;
  }
 
  @Override
  public IBooleanResult buildBacktracker(IEvaluatorContext eval) {
    return new BasicBooleanResult(eval, this);
  }
 
  @Override
  public IMatchingResult buildMatcher(IEvaluatorContext eval) {
    if (constant) {
      return new LiteralPattern(eval, this,  node);
    }

    java.util.List<IMatchingResult> kids = new java.util.ArrayList<IMatchingResult>(alts.size());
    for (org.rascalmpl.ast.Expression arg : alts) {
      kids.add(arg.buildMatcher(eval));
    }

    IMatchingResult setMatcher = new SetPattern(eval, this,  kids);
    java.util.List<IMatchingResult> wrap = new ArrayList<IMatchingResult>(1);
    wrap.add(setMatcher);

    Result<IValue> ambCons = eval.getCurrentEnvt().getVariable("amb");
    return new NodePattern(eval, this, new LiteralPattern(eval, this,  ambCons.getValue()), null, Factory.Tree_Amb, wrap, Collections.<String,IMatchingResult>emptyMap());
  }
  }
 
  static public class Char extends  org.rascalmpl.ast.Expression {
    private final IConstructor node;

    public Char(IConstructor node) {
      super(node);
      this.node = node;
    }

    public boolean equals(Object o) {
      if (!(o instanceof Char)) {
        return false;
      }
      Char other = (Char) o;
     
      return node.equals(other.node);
    }
   
    public int hashCode() {
      return 17 + 37 * node.hashCode();
    }
   
    @Override
    public Result<IValue> interpret(IEvaluator<Result<IValue>> eval) {
      // TODO allow override
      return makeResult(Factory.Tree, node, eval);
    }

    @Override
    public IMatchingResult buildMatcher(IEvaluatorContext eval) {
      return new LiteralPattern(eval, this,  node);
    }

    @Override
    public Type typeOf(Environment env, boolean instantiateTypeParameters, IEvaluator<Result<IValue>> eval) {
      return Factory.Tree;
    }
  }
 
  static public class Cycle extends  org.rascalmpl.ast.Expression {
    private final int length;
    private final IConstructor node;

    public Cycle(IConstructor node, int length) {
      super(node);
      this.length = length;
      this.node = node;
    }

    public boolean equals(Object o) {
      if (!(o instanceof Cycle)) {
        return false;
      }
      Cycle other = (Cycle) o;

      return node.equals(other.node);
    }

    public int hashCode() {
      return node.hashCode();
    }
   
    @Override
    public Result<IValue> interpret(IEvaluator<Result<IValue>> eval) {
      return makeResult(Factory.Tree, VF.constructor(Factory.Tree_Cycle, node, VF.integer(length)), eval);
    }

    @Override
    public IMatchingResult buildMatcher(IEvaluatorContext eval) {
      return new LiteralPattern(eval, this, VF.constructor(Factory.Tree_Cycle, node, VF.integer(length)));
    }

    @Override
    public Type typeOf(Environment env, boolean instantiateTypeParameters, IEvaluator<Result<IValue>> eval) {
      return Factory.Tree;
    }
  }
}
TOP

Related Classes of org.rascalmpl.semantics.dynamic.Tree$Cycle

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.