Package AGEvalSwipl

Source Code of AGEvalSwipl.FlatCppFieldsHelper$Field

package AGEvalSwipl;

import java.util.HashSet;

import AGEval.IFace;
import AGEval.InvalidGrammarException;
import AGEvalSwipl.AGEvaluatorSwipl.Schedule;
import aleGrammar.ALEParser;
import aleGrammar.ALEParser.ExtendedVertex;

class FlatCppFieldsHelper {
  // The the placeholder FTL type name to use when we're dealing with one of the grammar tokens that we hold in a
  // enum in C++ code
  public static final String enum_type_name = "GrammarTokens";
  // The name of the num in C++ which holds the grammar tokens
  public static final String enum_name = "unionvariants";
 
  private ALEParser ast;
  @SuppressWarnings("unused")
  private Schedule sched;
  private HashSet<Field> fields;
 
 
  public FlatCppFieldsHelper(ALEParser ast, Schedule sched) throws InvalidGrammarException {
    fields = new HashSet<Field>();
   
    parseAstAndSchedule(ast, sched);
   
    // Add in refname and display by default. They have no specific class.
    addField(null, "display", enum_type_name);
    addField(null, "refname", enum_type_name);
   
    // Ditto rightSibling
    addField(null, "right_siblings", "NodeIndex");
  }
 
  public HashSet<Field> getFields() {
    return fields;
  }
 
 
  // Called by constructor to generate Field objects for each variable in
  // a given AST
  private void parseAstAndSchedule(ALEParser ast, Schedule sched) throws InvalidGrammarException {
    this.ast = ast;
   
    // For each interface
    for (IFace interf : ast.interfaces) {
      ALEParser.ExtendedClass ec = ast.extendedClasses.get(interf);
     
      // Parse the positioned input fields (ignore positioning for now)
      for(String property : ec.positionedInputs.values()) {
        addField(interf, property);
      }
     
      // Parse the public unpositioned variables
      for(String property : interf.getPubAttributes().keySet()) {
        addField(interf, property);
      }

      // Parse the interface's public fields
      for(String property : interf.getPubFields().keySet()) {
        addField(interf, property);
      }
    }
   
    // Now go through the classes parsing their fields as well
    for (AGEval.Class c : ast.classes) {
      for (String property : c.getPrivFields().keySet()) {
        addField(c, property);
      }
     
      for (String property : c.getPrivAttributes().keySet()) {
        addField(c, property);
      }
     
      // Generate collections
      for (String child_field : c.getChildMappings().keySet()) {
        addField(c, "child_" + child_field + "_leftmost_child", "NodeIndex");
        addField(c, "child_" + child_field + "_count", "int");
      }
     
      // Generate sinks
      for (String sink : sched.reductions.sinks.get(c)) {
        String sink_type;
       
        // Check if the property in question is actually from a child
        if(sink.contains("@") && !sink.contains("self@")) {
          String child_name = sink.split("@")[0];
          AGEval.IFace child_iface = c.getChildMappings().get(child_name);
          sink_type = astPropertyToCppTypeString(sink.split("@")[1], child_iface);
        } else {
          sink_type = astPropertyToCppTypeString(sink, c);
        }
       
        if(sink.contains("@") && !sink.contains("self@")) {
          sink = sink.replace("@", "_");
        }
        addField(c, sink + "_init", sink_type);
        addField(c, sink + "_last", sink_type);
      }
    }
  }

 
  // Finds the Field object corresponding a given FTL class and property name.
  // Returns null if can not find existing Field matching FTL data.
  // cls may be null.
  public Field findCppField(AGEval.IFace cls, String property) {
    String clean_prop_name = property.toLowerCase();
    if(property.contains("@") && !property.contains("self@")) {
      clean_prop_name = property.replace("@", "_");
    }
   
    // Fields with null classes match all classes (handles refname, display)
    // The property may also come from the cls' interface
    for(Field field : fields) {
      if(field.ftlName.toLowerCase().equals(clean_prop_name) && (cls == null || field.getCls() == null || field.getCls() == cls || field.getCls() == cls.getInterface())) {
        return field;
      }
    }
   
    return null;
  }
 
 
  // Adds a given field to our list of fields
  // This version allows one to provide an explicit C++ type rather than
  // automatically inferring it as in the other version. cls may be null.
  public Field addField(AGEval.IFace cls, String property, String cppType) throws InvalidGrammarException {
    Field new_field;

    // Check if this field already exists and, if so, don't re-add it
    new_field = findCppField(cls, property);
    if(new_field != null) {
      return new_field;
    }

    new_field = new Field(cls, property, cppType);
    fields.add(new_field);
   
    // If this is a maybe type, we have to add a maybe field
    if(new_field.isMaybeType()) {
      System.err.println(new_field.getCppName() + " is a maybe type");
    }
   
    // TODO: Add support for 'maybe' types
    if(new_field.isMaybeType()) {
      throw new InvalidGrammarException("'maybe' types are not yet implemented in the Flat C++ backend. Go yell at Matt.");
    }
   
    return new_field;
  }
 
  // Adds a given field to our list of fields. Automatically infers correct
  // C++ type for a given property of a class.
  public Field addField(AGEval.IFace cls, String property) throws InvalidGrammarException {
    String type = typeStringToFlatCppType(astPropertyToCppTypeString(property, cls));
   
    return addField(cls, property, type);
  }
 
 
  // Takes a String representing the FTL type of a field, returns a String
  // representing the C++ type.
  // Taken for CppGenerator
  public static String typeStringToFlatCppType(String type) throws InvalidGrammarException {
    String lType = type.toLowerCase();
   
    if (lType.equals("int") || lType.equals("time") || lType.equals("color") || lType.equals("px")) {
      return "int";
    } else if (lType.equals("bool")) {
      return "bool";
    } else if(lType.equals("float")) {
      return "float";
    } else if (lType.equals("string") || lType.equals("std::string") || lType.equals("const char *")) {
      return "const char*";
    } else if (lType.equals("vbo")) {
      // VBO HACK
      return "float";
    } else {
      return enum_type_name;
    }
  }
 
  // Converts an FTL property's type to equivalent C++ type
  public String astPropertyToCppTypeString(String property, AGEval.IFace cls) throws InvalidGrammarException {
    // If the class doesn't have it, check its interface
    if(ast.extendedClasses.get(cls).extendedVertices.get(property) == null) {
      cls = cls.getInterface();
    }
   
    String ftl_type = ast.extendedClasses.get(cls).extendedVertices.get(property).strType;
   
    return typeStringToFlatCppType(ftl_type);
  }
 
 
  ///////////////////////////////////////////////////////////////////////////
  // Simple struct class to hold one data on a single field from the AST
  ///////////////////////////////////////////////////////////////////////////
  class Field {   
    // Can be null only in case of refname or display or may not actually
    // contain property (as in case of _leftmost_child)
    private AGEval.IFace cls;
    private String type;
    private String ftlName;
   
    public Field(IFace cls, String ftl_name, String cppType) {
      this.ftlName = ftl_name;
      this.type = cppType;
     
      // display and refname have no class
      if(ftl_name.equals("display") || ftl_name.equals("refname")) {
        this.cls = null;
      } else {
        this.cls = cls;
      }
    }

    public String getCppName() {
      String clean_prop_name =  ftlName.toLowerCase().replaceAll("-", "").replaceAll(" ", "");

      // Handle things like refname and rightSiblings
      if(cls == null) {
        if(ftlName.equals("display")) {
          return "displayname";
        }
        return clean_prop_name;
      }
     
      String clean_class_name =  cls.getName().toLowerCase().replaceAll("-", "").replaceAll(" ", "");
     
      return "fld_" + clean_class_name + "_" + clean_prop_name;
    }
   
    // This function returns the name to use when accessing this field as a rhs.
    // Main difference is that it will cast token enum types correctly
    public String getCppRhsName() {
      String cast = "";
      if(type == FlatCppFieldsHelper.enum_type_name) {
        cast = "(enum " + FlatCppFieldsHelper.enum_name + ") ";
      }
     
      return cast + getCppName();
    }
       
    public AGEval.IFace getCls() {
      return cls;
    }
   
    public String getFtlName() {
      return ftlName;
    }
   
    public String getCppType() {
      return type;
    }
   
    public Boolean isMaybeType() {
      if(cls == null) {
        return false;
      }
     
      ALEParser.ExtendedClass ec = ast.extendedClasses.get(cls);
      ExtendedVertex v = ec.extendedVertices.get(ftlName);
     
      if(v == null) {
        return false;
      } else {
        return v.isMaybeType;
      }
    }
  }
}
TOP

Related Classes of AGEvalSwipl.FlatCppFieldsHelper$Field

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.