Package sizzle.compiler

Source Code of sizzle.compiler.TableDescription

package sizzle.compiler;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Vector;

import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;

import sizzle.parser.syntaxtree.ArrayType;
import sizzle.parser.syntaxtree.Assignment;
import sizzle.parser.syntaxtree.Block;
import sizzle.parser.syntaxtree.BreakStatement;
import sizzle.parser.syntaxtree.BytesLiteral;
import sizzle.parser.syntaxtree.Call;
import sizzle.parser.syntaxtree.CharLiteral;
import sizzle.parser.syntaxtree.Comparison;
import sizzle.parser.syntaxtree.Component;
import sizzle.parser.syntaxtree.Composite;
import sizzle.parser.syntaxtree.Conjunction;
import sizzle.parser.syntaxtree.ContinueStatement;
import sizzle.parser.syntaxtree.Declaration;
import sizzle.parser.syntaxtree.DoStatement;
import sizzle.parser.syntaxtree.EmitStatement;
import sizzle.parser.syntaxtree.ExprList;
import sizzle.parser.syntaxtree.ExprStatement;
import sizzle.parser.syntaxtree.Expression;
import sizzle.parser.syntaxtree.Factor;
import sizzle.parser.syntaxtree.FingerprintLiteral;
import sizzle.parser.syntaxtree.FloatingPointLiteral;
import sizzle.parser.syntaxtree.ForExprStatement;
import sizzle.parser.syntaxtree.ForStatement;
import sizzle.parser.syntaxtree.ForVarDecl;
import sizzle.parser.syntaxtree.Function;
import sizzle.parser.syntaxtree.FunctionType;
import sizzle.parser.syntaxtree.Identifier;
import sizzle.parser.syntaxtree.IdentifierList;
import sizzle.parser.syntaxtree.IfStatement;
import sizzle.parser.syntaxtree.Index;
import sizzle.parser.syntaxtree.IntegerLiteral;
import sizzle.parser.syntaxtree.MapType;
import sizzle.parser.syntaxtree.Node;
import sizzle.parser.syntaxtree.NodeChoice;
import sizzle.parser.syntaxtree.NodeSequence;
import sizzle.parser.syntaxtree.NodeToken;
import sizzle.parser.syntaxtree.Operand;
import sizzle.parser.syntaxtree.OutputType;
import sizzle.parser.syntaxtree.Pair;
import sizzle.parser.syntaxtree.PairList;
import sizzle.parser.syntaxtree.Program;
import sizzle.parser.syntaxtree.ProtoFieldDecl;
import sizzle.parser.syntaxtree.ProtoMember;
import sizzle.parser.syntaxtree.ProtoMemberList;
import sizzle.parser.syntaxtree.ProtoTupleType;
import sizzle.parser.syntaxtree.Regexp;
import sizzle.parser.syntaxtree.RegexpList;
import sizzle.parser.syntaxtree.ResultStatement;
import sizzle.parser.syntaxtree.ReturnStatement;
import sizzle.parser.syntaxtree.Selector;
import sizzle.parser.syntaxtree.SimpleExpr;
import sizzle.parser.syntaxtree.SimpleMember;
import sizzle.parser.syntaxtree.SimpleMemberList;
import sizzle.parser.syntaxtree.SimpleTupleType;
import sizzle.parser.syntaxtree.Start;
import sizzle.parser.syntaxtree.Statement;
import sizzle.parser.syntaxtree.StatementExpr;
import sizzle.parser.syntaxtree.StaticVarDecl;
import sizzle.parser.syntaxtree.StringLiteral;
import sizzle.parser.syntaxtree.SwitchStatement;
import sizzle.parser.syntaxtree.Term;
import sizzle.parser.syntaxtree.TimeLiteral;
import sizzle.parser.syntaxtree.TupleType;
import sizzle.parser.syntaxtree.Type;
import sizzle.parser.syntaxtree.TypeDecl;
import sizzle.parser.syntaxtree.VarDecl;
import sizzle.parser.syntaxtree.WhenStatement;
import sizzle.parser.syntaxtree.WhileStatement;
import sizzle.parser.visitor.GJDepthFirst;
import sizzle.types.SizzleArray;
import sizzle.types.SizzleBytes;
import sizzle.types.SizzleFunction;
import sizzle.types.SizzleMap;
import sizzle.types.SizzleString;
import sizzle.types.SizzleTable;
import sizzle.types.SizzleType;

class TableDescription {
  private String aggregator;
  private SizzleType type;
  private List<String> parameters;

  public TableDescription(final String aggregator, final SizzleType type) {
    this(aggregator, type, null);
  }

  public TableDescription(final String aggregator, final SizzleType type, final List<String> parameters) {
    this.aggregator = aggregator;
    this.type = type;
    this.parameters = parameters;
  }

  /**
   * @return the name
   */
  public String getAggregator() {
    return this.aggregator;
  }

  /**
   * @return the parameters
   */
  public List<String> getParameters() {
    return this.parameters;
  }

  /**
   * @param name
   *            the name to set
   */
  public void setAggregator(final String aggregator) {
    this.aggregator = aggregator;
  }

  /**
   * @param parameters
   *            the parameters to set
   */
  public void setParameters(final List<String> parameters) {
    this.parameters = parameters;
  }

  /**
   * @return the types
   */
  public SizzleType getType() {
    return this.type;
  }

  /**
   * @param types
   *            the types to set
   */
  public void setTypes(final SizzleType type) {
    this.type = type;
  }
}

public class CodeGeneratingVisitor extends GJDepthFirst<String, SymbolTable> {
  private final TypeCheckingVisitor typechecker;
  private final NameFindingVisitor namefinder;
  private final StaticDeclarationCodeGeneratingVisitor staticdeclarator;
  private final StaticInitializationCodeGeneratingVisitor staticinitializer;

  private final HashMap<String, TableDescription> tables;

  private final String name;
  private final StringTemplateGroup stg;

  public CodeGeneratingVisitor(final String name, final StringTemplateGroup stg) throws IOException {
    this.typechecker = new TypeCheckingVisitor();
    this.namefinder = new NameFindingVisitor();
    this.staticdeclarator = new StaticDeclarationCodeGeneratingVisitor(this);
    this.staticinitializer = new StaticInitializationCodeGeneratingVisitor(this);

    this.tables = new HashMap<String, TableDescription>();
    this.tables.put("stdout", new TableDescription("stdout", new SizzleString()));
    this.tables.put("stderr", new TableDescription("stderr", new SizzleString()));
    this.tables.put("output", new TableDescription("output", new SizzleBytes()));

    this.name = name;
    this.stg = stg;
  }

  @Override
  public String visit(final Start n, final SymbolTable argu) {
    return n.f0.accept(this, argu);
  }

  @Override
  public String visit(final Program n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Program");

    st.setAttribute("name", this.name);
    if (argu.get("input").equals(new SizzleString())) {
      st.setAttribute("inputFormatClass", "org.apache.hadoop.mapreduce.lib.input.TextInputFormat");
      st.setAttribute("keyClass", "org.apache.hadoop.io.LongWritable");
      st.setAttribute("valueClass", "org.apache.hadoop.io.Text");
    } else if (argu.get("input").equals(new SizzleBytes())) {
      throw new RuntimeException("unimplemented");
    }

    st.setAttribute("staticDeclarations", this.staticdeclarator.visit(n, argu));
    st.setAttribute("staticStatements", this.staticinitializer.visit(n, argu));

    final List<String> statements = new ArrayList<String>();
    for (final Node node : n.f0.nodes) {
      final String statement = node.accept(this, argu);
      if (statement != null)
        statements.add(statement);
    }
    st.setAttribute("statements", statements);

    final List<String> tables = new ArrayList<String>();
    for (final Entry<String, TableDescription> entry : this.tables.entrySet()) {
      final String id = entry.getKey();
      final TableDescription description = entry.getValue();
      final String parameters = description.getParameters() == null ? "" : description.getParameters().get(0);
      final SizzleType type = description.getType();

      final StringBuilder src = new StringBuilder();
      for (final Class<?> c : argu.getAggregators(description.getAggregator(), type))
        src.append(", new " + c.getCanonicalName() + "(" + parameters + ")");

      tables.add("this.tables.put(\"" + id + "\", new sizzle.aggregators.Table(" + src.toString().substring(2) + "));");
    }

    st.setAttribute("tables", tables);

    return st.toString();
  }

  @Override
  public String visit(final Declaration n, final SymbolTable argu) {
    return n.f0.choice.accept(this, argu);
  }

  @Override
  public String visit(final TypeDecl n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final StaticVarDecl n, final SymbolTable argu) {
    // this is handled by the static code generator
    return null;
  }

  @Override
  public String visit(final VarDecl n, final SymbolTable argu) {
    final SizzleType type = argu.get(n.f0.f0.tokenImage);

    if (n.f2.present()) {
      argu.setId(n.f0.f0.tokenImage);
      n.f2.node.accept(this, argu);
      argu.setId(null);
    }

    if (type instanceof SizzleTable)
      return null;

    final StringTemplate st = this.stg.getInstanceOf("VarDecl");

    st.setAttribute("id", n.f0.f0.tokenImage);

    // TODO: make templates for types
    st.setAttribute("type", type.toJavaType());

    if (n.f3.present()) {
      final NodeChoice nodeChoice = (NodeChoice) n.f3.node;

      switch (nodeChoice.which) {
      case 0: // initializer
        SizzleType t;
        try {
          t = this.typechecker.visit((Expression) ((NodeSequence) nodeChoice.choice).elementAt(1), argu.cloneNonLocals());
        } catch (final IOException e) {
          throw new RuntimeException(e.getClass().getSimpleName() + " caught", e);
        }

        String src = ((NodeSequence) nodeChoice.choice).elementAt(1).accept(this, argu);

        if (!type.assigns(t)) {
          final SizzleFunction f = argu.getCast(t, type);

          if (f.hasName()) {
            src = f.getName() + "(" + src + ")";
          } else if (f.hasMacro()) {
            src = CodeGeneratingVisitor.expand("X" + f.getMacro(), src.split(","));
          }
        }

        st.setAttribute("initializer", src);
        break;
      default:
        throw new RuntimeException("unexpected choice " + nodeChoice.which + " is a " + nodeChoice.choice.getClass().getSimpleName().toString());
      }
    }

    return st.toString();
  }

  @Override
  public String visit(final Type n, final SymbolTable argu) {
    return n.f0.choice.accept(this, argu);
  }

  @Override
  public String visit(final Component n, final SymbolTable argu) {
    // intentionally ignoring the identifier
    return n.f1.accept(this, argu);
  }

  @Override
  public String visit(final ArrayType n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("ArrayType");

    st.setAttribute("type", n.f2.accept(this, argu));

    return st.toString();
  }

  @Override
  public String visit(final TupleType n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final SimpleTupleType n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final SimpleMemberList n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final SimpleMember n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final ProtoTupleType n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final ProtoMemberList n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final ProtoMember n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final ProtoFieldDecl n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final MapType n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("MapType");

    st.setAttribute("key", n.f2.accept(this, argu));

    st.setAttribute("value", n.f2.accept(this, argu));

    return st.toString();
  }

  @Override
  public String visit(final OutputType n, final SymbolTable argu) {
    final String id = argu.getId();

    final String aggregator = n.f1.f0.tokenImage;

    final SizzleTable t = (SizzleTable) argu.get(id);

    if (n.f2.present()) {
      final String parameter = ((NodeSequence) n.f2.node).nodes.get(1).accept(this, argu);
      this.tables.put(id, new TableDescription(aggregator, t.getType(), Arrays.asList(parameter)));
    } else {
      this.tables.put(id, new TableDescription(aggregator, t.getType()));
    }

    return null;
  }

  @Override
  public String visit(final ExprList n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("ExprList");

    final List<String> expressions = new ArrayList<String>();

    expressions.add(n.f0.accept(this, argu));

    if (n.f1.present())
      for (final Node node : n.f1.nodes)
        expressions.add(((NodeSequence) node).elementAt(1).accept(this, argu));

    st.setAttribute("expressions", expressions);

    return st.toString();
  }

  @Override
  public String visit(final FunctionType n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final Statement n, final SymbolTable argu) {
    return n.f0.choice.accept(this, argu);
  }

  @Override
  public String visit(final Assignment n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final Block n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Block");

    final List<String> statements = new ArrayList<String>();

    if (n.f1.present())
      for (final Node node : n.f1.nodes)
        statements.add(node.accept(this, argu));

    st.setAttribute("statements", statements);

    return st.toString();
  }

  @Override
  public String visit(final BreakStatement n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final ContinueStatement n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final DoStatement n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final EmitStatement n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("EmitStatement");

    if (n.f2.present()) {
      final List<String> indices = new ArrayList<String>();

      for (final Node node : n.f2.nodes)
        indices.add(((NodeSequence) node).elementAt(1).accept(this, argu));

      st.setAttribute("indices", indices);
    }

    st.setAttribute("id", Character.toString('"') + n.f1.f0.tokenImage + '"');

    st.setAttribute("expression", n.f4.f0.accept(this, argu));

    if (n.f5.present())
      st.setAttribute("weight", ((NodeSequence) n.f5.node).elementAt(1).accept(this, argu));

    return st.toString();
  }

  @Override
  public String visit(final ExprStatement n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("ExprStatement");

    st.setAttribute("expression", n.f0.accept(this, argu));

    if (n.f1.present()) {
      final NodeChoice nodeChoice = (NodeChoice) n.f1.node;
      switch (nodeChoice.which) {
      case 0:
        st.setAttribute("operator", "++");
        break;
      case 1:
        st.setAttribute("operator", "--");
        break;
      default:
        throw new RuntimeException("unexpected choice " + nodeChoice.which + " is a " + nodeChoice.choice.getClass().getSimpleName().toString());
      }
    }

    return st.toString();
  }

  @Override
  public String visit(final ForStatement n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("ForStatement");

    SymbolTable symtab;
    try {
      symtab = argu.cloneNonLocals();
    } catch (final IOException e) {
      throw new RuntimeException(e.getClass().getSimpleName() + " caught", e);
    }

    this.typechecker.visit(n.f2, symtab);

    st.setAttribute("declaration", n.f2.accept(this, symtab));
    st.setAttribute("expression", n.f4.accept(this, symtab));
    st.setAttribute("exprstmt", n.f6.accept(this, symtab));
    st.setAttribute("statement", n.f8.accept(this, symtab));

    return st.toString();
  }

  @Override
  public String visit(final ForVarDecl n, final SymbolTable argu) {
    final VarDecl varDecl = new VarDecl(n.f0, n.f1, n.f2, n.f3, new NodeToken(";"));

    return varDecl.accept(this, argu);
  }

  @Override
  public String visit(final ForExprStatement n, final SymbolTable argu) {
    final ExprStatement exprStatement = new ExprStatement(n.f0, n.f1, new NodeToken(";"));

    return exprStatement.accept(this, argu);
  }

  @Override
  public String visit(final IfStatement n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("IfStatement");

    st.setAttribute("expression", n.f2.f0.accept(this, argu));
    st.setAttribute("statement", n.f4.f0.accept(this, argu));

    if (n.f5.present())
      st.setAttribute("elseStatement", ((NodeSequence) n.f5.node).nodes.elementAt(1).accept(this, argu));

    return st.toString();
  }

  @Override
  public String visit(final ResultStatement n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final ReturnStatement n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final SwitchStatement n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final WhenStatement n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("WhenStatement");

    st.setAttribute("expression", n.f3.accept(this, argu));
    st.setAttribute("statement", n.f5.accept(this, argu));

    return st.toString();
  }

  @Override
  public String visit(final IdentifierList n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final WhileStatement n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final Expression n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Expression");

    st.setAttribute("lhs", n.f0.accept(this, argu));

    if (n.f1.present()) {
      final List<String> operators = new ArrayList<String>();
      final List<String> operands = new ArrayList<String>();

      for (final Node node : n.f1.nodes) {
        operators.add("||");
        operands.add(((NodeSequence) node).elementAt(1).accept(this, argu));
      }

      st.setAttribute("operators", operators);
      st.setAttribute("operands", operands);
    }

    return st.toString();
  }

  @Override
  public String visit(final Conjunction n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Expression");

    st.setAttribute("lhs", n.f0.accept(this, argu));

    if (n.f1.present()) {
      final List<String> operators = new ArrayList<String>();
      final List<String> operands = new ArrayList<String>();

      for (final Node node : n.f1.nodes) {
        operators.add("&&");
        operands.add(((NodeSequence) node).elementAt(1).accept(this, argu));
      }

      st.setAttribute("operators", operators);
      st.setAttribute("operands", operands);
    }

    return st.toString();
  }

  @Override
  public String visit(final Comparison n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Expression");

    st.setAttribute("lhs", n.f0.accept(this, argu));

    if (n.f1.present()) {
      final List<String> operators = new ArrayList<String>();
      final List<String> operands = new ArrayList<String>();

      final Vector<Node> nodes = ((NodeSequence) n.f1.node).nodes;
      final NodeChoice nodeChoice = (NodeChoice) nodes.elementAt(0);
      switch (nodeChoice.which) {
      case 0:
        operators.add(" == ");
        break;
      case 1:
        operators.add(" != ");
        break;
      case 2:
        operators.add(" < ");
        break;
      case 3:
        operators.add(" <= ");
        break;
      case 4:
        operators.add(" > ");
        break;
      case 5:
        operators.add(" >= ");
        break;
      default:
        throw new RuntimeException("unexpected choice " + nodeChoice.which + " is " + nodeChoice.choice.getClass());
      }
      operands.add(nodes.elementAt(1).accept(this, argu));

      st.setAttribute("operators", operators);
      st.setAttribute("operands", operands);
    }

    return st.toString();
  }

  @Override
  public String visit(final SimpleExpr n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Expression");

    st.setAttribute("lhs", n.f0.accept(this, argu));

    if (n.f1.present()) {
      final List<String> operators = new ArrayList<String>();
      final List<String> operands = new ArrayList<String>();

      for (final Node node : n.f1.nodes) {
        final NodeSequence nodeSequence = (NodeSequence) node;
        operators.add(((NodeToken) ((NodeChoice) nodeSequence.elementAt(0)).choice).tokenImage);
        operands.add(nodeSequence.elementAt(1).accept(this, argu));
      }

      st.setAttribute("operators", operators);
      st.setAttribute("operands", operands);
    }

    return st.toString();
  }

  @Override
  public String visit(final Term n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Expression");

    st.setAttribute("lhs", n.f0.accept(this, argu));

    if (n.f1.present()) {
      final List<String> operators = new ArrayList<String>();
      final List<String> operands = new ArrayList<String>();

      for (final Node node : n.f1.nodes) {
        final NodeSequence nodeSequence = (NodeSequence) node;
        operators.add(((NodeToken) ((NodeChoice) nodeSequence.elementAt(0)).choice).tokenImage);
        operands.add(nodeSequence.elementAt(1).accept(this, argu));
      }

      st.setAttribute("operators", operators);
      st.setAttribute("operands", operands);
    }

    return st.toString();
  }

  @Override
  public String visit(final Factor n, final SymbolTable argu) {
    if (n.f1.present()) {
      final NodeChoice nodeChoice = (NodeChoice) n.f1.nodes.get(0);

      switch (nodeChoice.which) {
      case 1: // index
      case 2: // call
        argu.setOperand(n.f0);
        final String accept = n.f1.nodes.elementAt(0).accept(this, argu);
        argu.setOperand(null);
        return accept;
      default:
        throw new RuntimeException("unexpected choice " + nodeChoice.which + " is " + nodeChoice.choice.getClass());
      }
    } else {
      return n.f0.accept(this, argu);
    }
  }

  @Override
  public String visit(final Selector n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final Index n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Index");

    try {
      final SizzleType t = this.typechecker.visit(argu.getOperand(), argu.cloneNonLocals());
      if (t instanceof SizzleMap)
        st.setAttribute("map", true);
      else if (t instanceof SizzleArray)
        st.setAttribute("map", false);
    } catch (final IOException e) {
      throw new RuntimeException(e.getClass().getSimpleName() + " caught", e);
    }

    st.setAttribute("operand", argu.getOperand().accept(this, argu));

    st.setAttribute("index", n.f1.accept(this, argu));

    if (n.f2.present())
      st.setAttribute("slice", ((NodeSequence) n.f2.node).elementAt(1).accept(this, argu));

    return st.toString();
  }

  @Override
  public String visit(final Call n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Call");

    final SizzleFunction f = argu.getFunction(this.namefinder.visit(argu.getOperand()).toArray()[0].toString(), this.typechecker.check(n, argu));

    if (f.hasMacro()) {
      st.setAttribute("call", CodeGeneratingVisitor.expand(f.getMacro(), ((ExprList) n.f1.node).accept(this, argu).split(",")));
    } else if (f.hasName()) {
      st.setAttribute("operand", f.getName());

      if (n.f1.present())
        st.setAttribute("parameters", n.f1.node.accept(this, argu));
    }

    return st.toString();

  }

  @Override
  public String visit(final RegexpList n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final Regexp n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final Operand n, final SymbolTable argu) {
    return n.f0.choice.accept(this, argu);
  }

  @Override
  public String visit(final Composite n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Composite");

    if (n.f1.present()) {
      final NodeChoice nodeChoice = (NodeChoice) n.f1.node;
      switch (nodeChoice.which) {
      case 0: // pair list
        st.setAttribute("pairlist", nodeChoice.choice.accept(this, argu));
        break;
      case 1: // expression list
        final SizzleType t;
        try {
          t = this.typechecker.visit((ExprList) nodeChoice.choice, argu.cloneNonLocals());
        } catch (final IOException e) {
          throw new RuntimeException(e.getClass().getSimpleName() + " caught", e);
        }

        st.setAttribute("type", t.toJavaType());
        st.setAttribute("exprlist", nodeChoice.choice.accept(this, argu));
        break;
      default:
        throw new RuntimeException("unexpected choice " + nodeChoice.which + " is " + nodeChoice.choice.getClass());
      }
    }

    return st.toString();
  }

  @Override
  public String visit(final PairList n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("PairList");

    final List<String> pairs = new ArrayList<String>();

    pairs.add(n.f0.accept(this, argu));

    if (n.f1.present())
      for (final Node node : n.f1.nodes)
        pairs.add(((NodeSequence) node).elementAt(1).accept(this, argu));

    st.setAttribute("pairs", pairs);

    return st.toString();
  }

  @Override
  public String visit(final Pair n, final SymbolTable argu) {
    final StringTemplate st = this.stg.getInstanceOf("Pair");

    st.setAttribute("map", argu.getId());
    st.setAttribute("key", n.f0.accept(this, argu));
    st.setAttribute("value", n.f2.accept(this, argu));

    return st.toString();
  }

  @Override
  public String visit(final Function n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final StatementExpr n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final Identifier n, final SymbolTable argu) {
    // TODO: support protobufs/sequence files/avro here
    final String id = n.f0.tokenImage;

    if (argu.hasType(id))
      return argu.getType(id).toString();

    // otherwise return the identifier template
    final StringTemplate st = this.stg.getInstanceOf("Identifier");

    st.setAttribute("id", id);

    return st.toString();
  }

  @Override
  public String visit(final IntegerLiteral n, final SymbolTable argu) {
    return n.f0.tokenImage + 'l';
  }

  @Override
  public String visit(final FingerprintLiteral n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final FloatingPointLiteral n, final SymbolTable argu) {
    return n.f0.tokenImage + "d";
  }

  @Override
  public String visit(final CharLiteral n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final StringLiteral n, final SymbolTable argu) {
    return n.f0.tokenImage;
  }

  @Override
  public String visit(final BytesLiteral n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  @Override
  public String visit(final TimeLiteral n, final SymbolTable argu) {
    throw new RuntimeException("unimplemented");
  }

  private static String expand(final String template, final String... parameters) {
    String replaced = template;

    for (int i = 0; i < parameters.length; i++)
      replaced = replaced.replace("${" + i + "}", parameters[i]);

    return replaced;
  }

  // private static String expand(final String template, final String[]
  // parameters) {
  // String replaced = template;
  //
  // for (int i = 0; i < parameters.length; i++)
  // replaced = replaced.replace("${" + i + "}", parameters[i]);
  //
  // return replaced;
  // }

  // private String name;
  //
  // private final NameFindingVisitor namefinder;
  // private final TypeCheckingVisitor typefinder;
  // private final IndexeeFindingVisitor indexeefinder;
  // private StaticDeclarationCodeGeneratingVisitor staticfinder;
  // private String staticDeclarations;
  //
  // private final Map<String, AggregatorDescription> aggregators;
  // private final Map<String, String> codeMap;
  //
  //
  // public CodeGeneratingVisitor(final String name) {
  // this();
  //
  // this.staticfinder = new
  // StaticDeclarationCodeGeneratingVisitor(this.namefinder);
  //
  // this.name = name;
  // }
  //
  // // TODO: really support implicit cast on assignment?
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final Assignment n, final SymbolTable argu) {
  // final String id = n.f0.f0.tokenImage;
  //
  // argu.setInitializerType(argu.get(id));
  // final String source = n.f0.accept(this, argu) + " = " + n.f2.accept(this,
  // argu);
  // argu.setInitializerType(null);
  //
  // return source;
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final AssignmentList n, final SymbolTable argu) {
  // final StringBuilder source = new StringBuilder(n.f0.accept(this, argu));
  //
  // if (n.f1.present())
  // for (final Node node : n.f1.nodes)
  // source.append(((AssignmentRest) node).accept(this, argu));
  //
  // return source.toString();
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final AssignmentRest n, final SymbolTable argu) {
  // return n.f1.accept(this, argu);
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final AssignmentStatement n, final SymbolTable argu)
  // {
  // throw new RuntimeException("unimplemented");
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final Atom n, final SymbolTable argu) {
  // switch (n.f0.which) {
  // case 0: // identifier
  // return ((Identifier) n.f0.choice).accept(this, argu);
  // case 1: // string
  // return ((StringLiteral) n.f0.choice).accept(this, argu);
  // case 2: // integer
  // return ((IntegerLiteral) n.f0.choice).accept(this, argu);
  // case 3: // float
  // return ((FloatingPointLiteral) n.f0.choice).accept(this, argu);
  // default:
  // throw new RuntimeException("unexpected choice " + n.f0.which + " is " +
  // n.f0.choice.getClass());
  // }
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final Block n, final SymbolTable argu) {
  // final StringBuilder source = new StringBuilder("{\n");
  //
  // if (n.f1.present()) {
  // final List<Node> arrayList = n.f1.nodes;
  // for (final Node i : arrayList)
  // source.append(((Statement) i).accept(this, argu) + "\n");
  // }
  //
  // source.append("}");
  //
  // return source.toString();
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final CallExpression n, final SymbolTable argu) {
  // final String id = n.f0.f0.tokenImage;
  //
  // if (n.f2.present()) {
  // final SizzleFunction function = argu.getFunction(id,
  // this.typefinder.check((ExpressionList) n.f2.node, argu));
  //
  // final String parameters = ((ExpressionList) n.f2.node).accept(this,
  // argu);
  //
  // if (function.hasMacro())
  // return CodeGeneratingVisitor.expand(function.getMacro(),
  // parameters.split(","));
  // else
  // return function.getCanonicalName() + "(" + parameters + ")";
  // } else {
  // final SizzleFunction function = argu.getFunction(id);
  // return function.getCanonicalName() + "()";
  // }
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final ComparisonExpression n, final SymbolTable argu)
  // {
  // final String lhs = n.f0.accept(this, argu);
  //
  // if (!n.f1.present())
  // return lhs;
  //
  // SizzleType type;
  // try {
  // type = this.typefinder.visit(n.f0, argu.cloneNonLocals());
  // } catch (final IOException e) {
  // throw new RuntimeException(e.getClass().getSimpleName() + " caught", e);
  // }
  // final List<Node> nodes = ((NodeSequence) n.f1.node).nodes;
  //
  // final String operator = ((NodeToken) ((NodeChoice)
  // nodes.get(0)).choice).tokenImage;
  //
  // final String rhs = ((PlusExpression) nodes.get(1)).accept(this, argu);
  // if (operator.equals("==") || operator.equals("!="))
  // if (type.getClass().equals(SizzleArray.class))
  // return "java.util.Arrays.equals(" + lhs + ", " + rhs + ")";
  // else if (type.getClass().equals(SizzleString.class))
  // return (operator.equals("!=") ? "!" : "") + rhs + ".equals(" + lhs + ")";
  // else if (Character.isUpperCase(type.toJavaType().toCharArray()[0]))
  // return (operator.equals("!=") ? "!" : "") + rhs + ".equals(" + lhs + ")";
  // else
  // return lhs + " " + operator + " " + " " + rhs;
  // else
  // return lhs + " " + operator + " " + rhs;
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final Expression n, final SymbolTable argu) {
  // final StringBuilder expression = new StringBuilder(n.f0.accept(this,
  // argu));
  //
  // if (n.f1.present())
  // for (final Node node : n.f1.nodes)
  // expression.append(" " + ((NodeToken) ((NodeChoice) ((NodeSequence)
  // node).nodes.get(0)).choice).tokenImage + " "
  // + ((ComparisonExpression) ((NodeSequence)
  // node).nodes.get(1)).accept(this, argu));
  //
  // return expression.toString();
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final ExpressionList n, final SymbolTable argu) {
  // final StringBuilder rest = new StringBuilder();
  // if (n.f1.present())
  // for (final Node i : n.f1.nodes)
  // rest.append(", " + ((ExpressionRest) i).accept(this, argu));
  //
  // return n.f0.accept(this, argu) + rest.toString();
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final ExpressionRest n, final SymbolTable argu) {
  // return n.f1.accept(this, argu);
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final FloatingPointLiteral n, final SymbolTable argu)
  // {
  // return n.f0.tokenImage;
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final ForStatement n, final SymbolTable argu) {
  // // when they say "for loops [...] take on their familiar form", I assume
  // // they mean K&R form, e.g. declarations not allowed in initializer.
  // String src = "for (";
  //
  // if (n.f2.present())
  // src += ((AssignmentList) n.f2.node).accept(this, argu);
  //
  // src += "; ";
  //
  // if (n.f4.present())
  // src += ((ExpressionList) n.f4.node).accept(this, argu);
  //
  // src += "; ";
  //
  // if (n.f6.present())
  // src += ((ExpressionList) n.f6.node).accept(this, argu);
  //
  // return src + ")\n" + n.f8.accept(this, argu);
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final IdentifierList n, final SymbolTable argu) {
  // throw new RuntimeException("unimplemented");
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final IdentifierRest n, final SymbolTable argu) {
  // throw new RuntimeException("unimplemented");
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final IfStatement n, final SymbolTable argu) {
  // String src = "if (" + n.f2.accept(this, argu) + ")\n" + n.f4.accept(this,
  // argu) + "\n";
  //
  // if (n.f5.present())
  // src += "else\n" + ((Statement) ((NodeSequence)
  // n.f5.node).elementAt(1)).accept(this, argu);
  //
  // return src;
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final IndexExpression n, final SymbolTable argu) {
  // final String id = n.f0.accept(this, argu);
  // final SizzleType type = argu.get(n.f0.f0.tokenImage);
  //
  // if (n.f1.present()) {
  // final String index = ((NodeSequence) n.f1.node).nodes.get(1).accept(this,
  // argu);
  // if (type.getClass().equals(SizzleArray.class))
  // return "(" + id + ".length > " + index + " ? " + id + "[(int)" + index +
  // "]" + " : null)";
  // else if (type.getClass().equals(SizzleMap.class))
  // return id + ".get(" + index + ")";
  // else
  // throw new RuntimeException("wtf");
  // } else
  // return id;
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final Initializer n, final SymbolTable argu) {
  // switch (n.f0.which) {
  // case 0: // expression
  // final SizzleType t = argu.getInitializerType();
  // final SizzleType u = this.typefinder.visit(((Expression) n.f0.choice),
  // argu);
  //
  // if (!t.assigns(u) && argu.hasCast(u, t))
  // return argu.getCast(u, t).getCanonicalName() + "(" + ((Expression)
  // n.f0.choice).accept(this, argu) + ")";
  // return ((Expression) n.f0.choice).accept(this, argu);
  // case 1: // map or array
  // final NodeOptional nodeOptional = (NodeOptional) ((NodeSequence)
  // n.f0.choice).nodes.get(1);
  // if (nodeOptional.present()) {
  // final NodeChoice node = (NodeChoice) nodeOptional.node;
  // switch (node.which) {
  // case 0: // pair list
  // argu.setStaticInitializer(((PairList) node.choice).accept(this, argu));
  // return "new " + argu.getInitializerType().toJavaType() + "()";
  // case 1: // expression list
  // return "new " + argu.getInitializerType().toJavaType() + " { " +
  // ((ExpressionList) node.choice).accept(this, argu) + " }";
  // default:
  // throw new RuntimeException("unexpected choice " + n.f0.which + " is " +
  // n.f0.choice.getClass());
  // }
  // } else
  // return "";
  // default:
  // throw new RuntimeException("unexpected choice " + n.f0.which + " is " +
  // n.f0.choice.getClass());
  // }
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final IntegerLiteral n, final SymbolTable argu) {
  // return n.f0.tokenImage;
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final MemberExpression n, final SymbolTable argu) {
  // throw new RuntimeException("unimplemented");
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final ParentheticalExpression n, final SymbolTable
  // argu) {
  // return "(" + n.f1.accept(this, argu) + ")";
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final PlusExpression n, final SymbolTable argu) {
  // final StringBuilder src = new StringBuilder();
  //
  // src.append(n.f0.accept(this, argu));
  //
  // if (n.f1.present())
  // for (final Node i : n.f1.nodes) {
  // final NodeSequence nodeSequence = (NodeSequence) i;
  // src.append(" " + ((NodeToken) ((NodeChoice)
  // nodeSequence.nodes.get(0)).choice).tokenImage + " " +
  // nodeSequence.nodes.get(1).accept(this, argu));
  // }
  //
  // return src.toString();
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final ProtoStatement n, final SymbolTable argu) {
  // throw new RuntimeException("unimplemented");
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final SliceExpression n, final SymbolTable argu) {
  // if (n.f1.present()) {
  // final String lower = ((NodeSequence)
  // n.f1.nodes.get(0)).elementAt(1).accept(this, argu);
  // final String upper = ((NodeSequence)
  // n.f1.nodes.get(0)).elementAt(3).accept(this, argu);
  // final String id = n.f0.accept(this, argu);
  // return "(" + lower + " > " + upper + " ? java.util.Arrays.copyOfRange(" +
  // id + ", " + upper + ", " + upper + ") : java.util.Arrays.copyOfRange("
  // + id + ", " + lower + ", " + upper + "))";
  // } else
  // return "";
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final Start n, final SymbolTable argu) {
  // this.staticDeclarations = this.staticfinder.visit(n, argu);
  // return n.f0.accept(this, argu);
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final Statement n, final SymbolTable argu) {
  // switch (n.f0.which) {
  // case 3: // non-static variable declaration
  // return ((VariableDeclaration) n.f0.choice).accept(this, argu);
  // case 4: // block
  // return ((Block) n.f0.choice).accept(this, argu);
  // case 6: // emit statement
  // return ((EmitStatement) n.f0.choice).accept(this, argu);
  // case 7: // if statement
  // return ((IfStatement) n.f0.choice).accept(this, argu);
  // case 9: // for statement
  // return ((ForStatement) n.f0.choice).accept(this, argu);
  // case 10: // when statement
  // return ((WhenStatement) n.f0.choice).accept(this, argu);
  // case 11: // proto statement
  // return ((ProtoStatement) n.f0.choice).accept(this, argu);
  // default:
  // throw new RuntimeException("unexpected choice " + n.f0.which + " is " +
  // n.f0.choice.getClass());
  // }
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final StringLiteral n, final SymbolTable argu) {
  // return n.f0.tokenImage;
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final Term n, final SymbolTable argu) {
  // switch (n.f0.which) {
  // case 0: // call
  // return ((CallExpression) n.f0.choice).accept(this, argu);
  // case 2: // wide index into array
  // return ((SliceExpression) n.f0.choice).accept(this, argu);
  // case 3: // index into array
  // return ((IndexExpression) n.f0.choice).accept(this, argu);
  // case 4: // expressions in parantheses
  // return ((ParentheticalExpression) n.f0.choice).accept(this, argu);
  // case 5: // atom
  // return ((Atom) n.f0.choice).accept(this, argu);
  // default:
  // throw new RuntimeException("unexpected choice " + n.f0.which + " is " +
  // n.f0.choice.getClass());
  // }
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final TimesExpression n, final SymbolTable argu) {
  // final StringBuilder src = new StringBuilder();
  //
  // src.append(n.f0.accept(this, argu));
  //
  // if (n.f1.present())
  // for (final Node i : n.f1.nodes) {
  // final NodeSequence nodeSequence = (NodeSequence) i;
  // src.append(" " + ((NodeToken) ((NodeChoice)
  // nodeSequence.nodes.get(0)).choice).tokenImage + " " +
  // nodeSequence.nodes.get(1).accept(this, argu));
  // }
  //
  // return src.toString();
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final Typle n, final SymbolTable argu) {
  // throw new RuntimeException("unimplemented");
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final TypleList n, final SymbolTable argu) {
  // throw new RuntimeException("unimplemented");
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final TypleRest n, final SymbolTable argu) {
  // throw new RuntimeException("unimplemented");
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final UnaryExpression n, final SymbolTable argu) {
  // String expression = n.f0.accept(this, argu);
  //
  // if (n.f1.present())
  // expression += ((NodeToken) ((NodeChoice) n.f1.node).choice).tokenImage;
  //
  // return expression;
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final StaticVariableDeclaration n, final SymbolTable
  // argu) {
  // return "";
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final WhenStatement n, final SymbolTable argu) {
  // SymbolTable st;
  // try {
  // st = argu.cloneNonLocals();
  // } catch (final IOException e) {
  // throw new RuntimeException(e.getClass().getSimpleName() + " caught", e);
  // }
  //
  // final StringBuilder src = new StringBuilder();
  // for (final Node node : n.f2.nodes) {
  // // String quant;
  // // switch (((NodeChoice)((NodeSequence)node).nodes.get(2)).which) {
  // // case 0:
  // // quant = "some";
  // // break;
  // // case 1:
  // // quant = "each";
  // // break;
  // // case 2:
  // // quant = "all";
  // // break;
  // // default:
  // // throw new RuntimeException("unexpected choice " +
  // // ((NodeChoice)((NodeSequence)node).nodes.get(2)).which + " is " +
  // // ((NodeChoice)((NodeSequence)node).nodes.get(2)).choice.getClass());
  // // }
  //
  // final SizzleType type = st.getType(((Identifier) ((NodeSequence)
  // node).nodes.get(3)).f0.tokenImage);
  //
  // final Set<String> ids = this.namefinder.visit((IdentifierList)
  // ((NodeSequence) node).nodes.get(0));
  //
  // for (final String id : ids)
  // st.set(id, type);
  //
  // for (final String id : ids) {
  // st.set(id, type);
  // final Set<String> indexees = this.indexeefinder.visit(n.f3, id);
  //
  // if (indexees.size() > 0) {
  // indexees.addAll(this.indexeefinder.visit(n.f5, id));
  // src.append("for (int ___" + id + " = 0; ");
  // final List<String> array = new ArrayList<String>(indexees);
  // src.append("___" + id + " < ___" + array.get(0) + ".length");
  // for (int i = 1; i < array.size(); i++)
  // src.append(" && " + id + " < " + array.get(i) + ".length");
  // src.append("; ___" + id + "++)\n");
  // }
  // }
  // }
  //
  // src.append("if (" + n.f3.accept(this, st) + ")\n");
  //
  // src.append(n.f5.accept(this, st));
  //
  // return src.toString();
  // }
  //
  // /** {@inheritDoc} */
  // @Override
  // public String visit(final WhileStatement n, final SymbolTable argu) {
  // throw new RuntimeException("unimplemented");
  // }
}
TOP

Related Classes of sizzle.compiler.TableDescription

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.