Ejemplo n.º 1
0
// Generate a flatbuffer schema from the Parser's internal representation.
std::string GenerateFBS(const Parser &parser, const std::string &file_name,
                        const GeneratorOptions &opts) {
  std::string schema;
  schema += "// Generated from " + file_name + ".proto\n\n";
  if (opts.include_dependence_headers) {
    int num_includes = 0;
    for (auto it = parser.included_files_.begin();
         it != parser.included_files_.end(); ++it) {
      auto basename = flatbuffers::StripPath(
                        flatbuffers::StripExtension(it->first));
      if (basename != file_name) {
        schema += "include \"" + basename + ".fbs\";\n";
        num_includes++;
      }
    }
    if (num_includes) schema += "\n";
  }
  schema += "namespace ";
  auto name_space = parser.namespaces_.back();
  for (auto it = name_space->components.begin();
           it != name_space->components.end(); ++it) {
    if (it != name_space->components.begin()) schema += ".";
    schema += *it;
  }
  schema += ";\n\n";
  // Generate code for all the enum declarations.
  for (auto it = parser.enums_.vec.begin();
           it != parser.enums_.vec.end(); ++it) {
    EnumDef &enum_def = **it;
    schema += "enum " + enum_def.name + " : ";
    schema += GenType(enum_def.underlying_type) + " {\n";
    for (auto itTmp = enum_def.vals.vec.begin();
         itTmp != enum_def.vals.vec.end(); ++itTmp) {
      auto &ev = **itTmp;
      schema += "  " + ev.name + " = " + NumToString(ev.value) + ",\n";
    }
    schema += "}\n\n";
  }
  // Generate code for all structs/tables.
  for (auto it = parser.structs_.vec.begin();
           it != parser.structs_.vec.end(); ++it) {
    StructDef &struct_def = **it;
    schema += "table " + struct_def.name + " {\n";
    for (auto itTmp = struct_def.fields.vec.begin();
             itTmp != struct_def.fields.vec.end(); ++itTmp) {
      auto &field = **itTmp;
      schema += "  " + field.name + ":" + GenType(field.value.type);
      if (field.value.constant != "0") schema += " = " + field.value.constant;
      if (field.required) schema += " (required)";
      schema += ";\n";
    }
    schema += "}\n\n";
  }
  return schema;
}
Ejemplo n.º 2
0
void    GEndSubScr( itnode *arr ) {
//=================================

// Finish off a subscripting operation.

    itnode      *arg;
    int         dim_cnt;

    if( arr->opn.us & USOPN_FLD ) {
        PushOpn( arr );
        EmitOp( FC_FIELD_SUBSCRIPT );
        OutPtr( arr->sym_ptr );
        dim_cnt = _DimCount( arr->sym_ptr->u.fd.dim_ext->dim_flags );
    } else {
        EmitOp( FC_SUBSCRIPT );
        OutPtr( arr->sym_ptr );
        dim_cnt = _DimCount( arr->sym_ptr->u.ns.si.va.u.dim_ext->dim_flags );
    }
    arg = arr->list;
    while( dim_cnt-- > 0 ) {
        GenType( arg );
        arg = arg->link;
    }
    if( ( arr->opn.us & USOPN_FLD ) == 0 ) {
        if( ( StmtSw & SS_DATA_INIT ) == 0 ) {
            if( arr->sym_ptr->u.ns.u1.s.typ == FT_CHAR ) {
                OutPtr( GTempString( 0 ) );
            }
        }
    }
    SetOpn( arr, USOPN_SAFE );
}
Ejemplo n.º 3
0
void            GForceHiBound( int ss, sym_id sym ) {
//=======================================================

// Generate code to fill in ADV subscript element (hi bound).
// The hi bound is constant and the low bound is not.
// We have to force the filling in of the high bound so that the number of
// of elements gets computed.
//
// Scenario:   SUBROUTINE SAM( A, J )
//             DIMENSION A(J:3)
//
// GInitADV() fills in the lo bound and # of elements in the dimension at
// compile-time. The lo bound is unknown so the ADV does not contain the
// correct information. The lo bound gets filled in at run-time but
// since the hi bound is not dumped into the ADV at compile time we
// must fill it in at run-time and compute the correct number of elements
// in the dimension.

    AddConst( CITNode );
    PushOpn( CITNode );
    EmitOp( FC_ADV_FILL_HI );
    OutPtr( sym );
    OutU16( (uint_16)ss );
    GenType( CITNode );
}
Ejemplo n.º 4
0
static std::string GenType(const Type &type) {
  switch (type.base_type) {
    case BASE_TYPE_STRUCT: return type.struct_def->name;
    case BASE_TYPE_UNION:  return type.enum_def->name;
    case BASE_TYPE_VECTOR: return "[" + GenType(type.VectorType()) + "]";
    default: return kTypeNames[type.base_type];
  }
}
Ejemplo n.º 5
0
void    GRetIdx( void ) {
//=================

// Generate an alternate return.

    PushOpn( CITNode );
    EmitOp( FC_ASSIGN_ALT_RET );
    GenType( CITNode );
}
Ejemplo n.º 6
0
std::string GenType(const Type &type) {
  if (type.enum_def != nullptr && !type.enum_def->is_union) {
    // it is a reference to an enum type
    return GenTypeRef(type.enum_def);
  }
  switch (type.base_type) {
    case BASE_TYPE_VECTOR: {
      std::string typeline;
      typeline.append("\"type\" : \"array\", \"items\" : { ");
      if (type.element == BASE_TYPE_STRUCT) {
        typeline.append(GenTypeRef(type.struct_def));
      } else {
        typeline.append(GenType(GenNativeType(type.element)));
      }
      typeline.append(" }");
      return typeline;
    }
    case BASE_TYPE_STRUCT: {
      return GenTypeRef(type.struct_def);
    }
    case BASE_TYPE_UNION: {
      std::string union_type_string("\"anyOf\": [");
      const auto &union_types = type.enum_def->vals.vec;
      for (auto ut = union_types.cbegin(); ut < union_types.cend(); ++ut) {
        auto &union_type = *ut;
        if (union_type->union_type.base_type == BASE_TYPE_NONE) {
          continue;
        }
        if (union_type->union_type.base_type == BASE_TYPE_STRUCT) {
          union_type_string.append("{ " + GenTypeRef(union_type->union_type.struct_def) + " }");
        }
        if (union_type != *type.enum_def->vals.vec.rbegin()) {
          union_type_string.append(",");
        }
      }
      union_type_string.append("]");
      return union_type_string;
    }
    case BASE_TYPE_UTYPE:
      return GenTypeRef(type.enum_def);
    default:
      return GenType(GenNativeType(type.base_type));
  }
}
Ejemplo n.º 7
0
void            GSLoBound( int ss, sym_id sym ) {
//===================================================

// Generate code to fill in ADV subscript element (lo bound).

    PushOpn( CITNode );
    EmitOp( FC_ADV_FILL_LO );
    OutPtr( sym );
    OutU16( (uint_16)ss );
    GenType( CITNode );
}
Ejemplo n.º 8
0
void    GPassValue( FCODE rtn ) {
//===============================

// Pass the value of CITNode on the stack and emit fcode for routine.

    PushOpn( CITNode );
    EmitOp( rtn );
    if( ( rtn == FC_SET_UNIT ) || ( rtn == FC_SET_REC ) ||
        ( rtn == FC_SET_RECL ) || ( rtn == FC_SET_BLOCKSIZE ) ) {
        GenType( CITNode );
    }
}
Ejemplo n.º 9
0
void            GSHiBoundLo1( int ss, sym_id sym ) {
//======================================================

// Generate code to fill in ADV subscript element (hi bound).
// Set the low bound to 1.

    // push high bound value
    PushOpn( CITNode );
    EmitOp( FC_ADV_FILL_HI_LO_1 );
    // general information
    OutPtr( sym );
    OutU16( (uint_16)ss );
    GenType( CITNode );
}
Ejemplo n.º 10
0
static std::string GenType(const Type &type, bool underlying = false) {
  switch (type.base_type) {
    case BASE_TYPE_STRUCT:
      return type.struct_def->defined_namespace->GetFullyQualifiedName(
          type.struct_def->name);
    case BASE_TYPE_VECTOR: return "[" + GenType(type.VectorType()) + "]";
    default:
      if (type.enum_def && !underlying) {
        return type.enum_def->defined_namespace->GetFullyQualifiedName(
            type.enum_def->name);
      } else {
        return kTypeNames[type.base_type];
      }
  }
}
Ejemplo n.º 11
0
void    ExpOp( TYPE typ1, TYPE typ2, OPTR opr ) {
//===============================================

// Generate code to perform exponentiation.

    if( UnaryMul( typ1, typ2 ) ) {
        PushOpn( CITNode );
        EmitOp( FC_UNARY_MUL );
        GenType( CITNode );
        OutU16( ITIntValue( CITNode->link ) );
        SetOpn( CITNode, USOPN_SAFE );
    } else {
        BinOp( typ1, typ2, opr );
    }
}
Ejemplo n.º 12
0
static void Unary( TYPE typ, OPTR opr ) {
//=======================================

// Generate code for unary plus or unary minus.

    PushOpn( CITNode->link );
    if( opr == OPTR_SUB ) {             // unary minus
        if( TypeCmplx( typ ) ) {
            EmitOp( FC_CUMINUS );
        } else {
            EmitOp( FC_UMINUS );
        }
        GenType( CITNode->link );
    } else if( ( _IsTypeInteger( CITNode->link->typ ) ) &&
               ( CITNode->link->size < sizeof( intstar4 ) ) ) {
        // convert INTEGER*1 or INTEGER*2 to INTEGER*4
        EmitOp( FC_CONVERT );
        DumpTypes( CITNode->link->typ, CITNode->link->size, FT_INTEGER, sizeof( intstar4 ) );
    }
    SetOpn( CITNode, USOPN_SAFE );
}
Ejemplo n.º 13
0
void    GDataItem( itnode *rpt ) {
//================================

// Generate a data item.

    sym_id      data;
    intstar4    one;

    if( rpt == NULL ) {
        one = 1;
        data = STConst( &one, FT_INTEGER, TypeSize( FT_INTEGER ) );
    } else {
        data = rpt->sym_ptr;
    }
    OutPtr( data );
    if( CITNode->typ == FT_HEX ) {
        OutU16( PT_NOTYPE );
    } else {
        GenType( CITNode );
    }
    OutPtr( CITNode->sym_ptr );
}
Ejemplo n.º 14
0
void    LogOp( TYPE typ1, TYPE typ2, OPTR op ) {
//==============================================

// Generate code for a relational operator.

    bool        flip;

    op -= OPTR_FIRST_LOGOP;
    flip = FALSE;
    if( ( ( CITNode->opn.us & USOPN_WHERE ) == USOPN_SAFE ) &&
        ( ( CITNode->link->opn.us & USOPN_WHERE ) != USOPN_SAFE ) ) {
        flip = TRUE;
    }
    PushOpn( CITNode->link );
    if( typ1 == TY_NO_TYPE ) {  // unary
        if( _IsTypeInteger( typ2 ) ) {
            EmitOp( FC_BIT_NOT );
        } else {
            EmitOp( FC_NOT );
        }
        GenType( CITNode->link );
        SetOpn( CITNode, USOPN_SAFE );
    } else {
        PushOpn( CITNode );
        if( _IsTypeInteger( typ2 ) ) {
            EmitOp( FC_BITOPS + op );
        } else {
            EmitOp( FC_LOGOPS + op );
        }
        if( flip ) {
            GenTypes( CITNode->link, CITNode );
        } else {
            GenTypes( CITNode, CITNode->link );
        }
    }
}
Ejemplo n.º 15
0
 inline bool isOne(GenType a)
 {
     return areEqual<GenType>(a, GenType(1.0));
 }
Ejemplo n.º 16
0
// Generate a flatbuffer schema from the Parser's internal representation.
std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
  // Proto namespaces may clash with table names, escape the ones that were
  // generated from a table:
  for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
       ++it) {
    auto &ns = **it;
    for (size_t i = 0; i < ns.from_table; i++) {
      ns.components[ns.components.size() - 1 - i] += "_";
    }
  }

  std::string schema;
  schema += "// Generated from " + file_name + ".proto\n\n";
  if (parser.opts.include_dependence_headers) {
    // clang-format off
    #ifdef FBS_GEN_INCLUDES  // TODO: currently all in one file.
    int num_includes = 0;
    for (auto it = parser.included_files_.begin();
         it != parser.included_files_.end(); ++it) {
      if (it->second.empty())
        continue;
      auto basename = flatbuffers::StripPath(
                        flatbuffers::StripExtension(it->second));
      schema += "include \"" + basename + ".fbs\";\n";
      num_includes++;
    }
    if (num_includes) schema += "\n";
    #endif
    // clang-format on
  }
  // Generate code for all the enum declarations.
  const Namespace *last_namespace = nullptr;
  for (auto enum_def_it = parser.enums_.vec.begin();
       enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
    EnumDef &enum_def = **enum_def_it;
    GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace);
    GenComment(enum_def.doc_comment, &schema, nullptr);
    schema += "enum " + enum_def.name + " : ";
    schema += GenType(enum_def.underlying_type, true) + " {\n";
    for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
         ++it) {
      auto &ev = **it;
      GenComment(ev.doc_comment, &schema, nullptr, "  ");
      schema += "  " + ev.name + " = " + NumToString(ev.value) + ",\n";
    }
    schema += "}\n\n";
  }
  // Generate code for all structs/tables.
  for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
       ++it) {
    StructDef &struct_def = **it;
    GenNameSpace(*struct_def.defined_namespace, &schema, &last_namespace);
    GenComment(struct_def.doc_comment, &schema, nullptr);
    schema += "table " + struct_def.name + " {\n";
    for (auto field_it = struct_def.fields.vec.begin();
         field_it != struct_def.fields.vec.end(); ++field_it) {
      auto &field = **field_it;
      if (field.value.type.base_type != BASE_TYPE_UTYPE) {
        GenComment(field.doc_comment, &schema, nullptr, "  ");
        schema += "  " + field.name + ":" + GenType(field.value.type);
        if (field.value.constant != "0") schema += " = " + field.value.constant;
        if (field.required) schema += " (required)";
        schema += ";\n";
      }
    }
    schema += "}\n\n";
  }
  return schema;
}
Ejemplo n.º 17
0
static  void    DoLoop( TYPE do_type ) {
//=====================================

// Generate code for DO statement or implied-DO.

    do_entry    *doptr;
    uint        do_size;
    intstar4    incr;
    intstar4    limit;
    sym_id      loop_ctrl;
    TYPE        e1_type;
    uint        e1_size;
    itnode      *e2_node;
    itnode      *e3_node;
    bool        e2_const;

    doptr = CSHead->cs_info.do_parms;
    do_size = CITNode->sym_ptr->u.ns.xt.size;
    doptr->do_parm = CITNode->sym_ptr;          // save ptr to do variable
    AdvanceITPtr();                             // bump past the '='
    EatDoParm();                                // process e1
    PushOpn( CITNode );
    e1_type = CITNode->typ;
    e1_size = CITNode->size;
    AdvanceITPtr();
    if( ReqComma() ) {
        EatDoParm();                            // process e2
        e2_const = CITNode->opn.us == USOPN_CON;
        PushOpn( CITNode );
        e2_node = CITNode;
        AdvanceITPtr();
        e3_node = NULL;
        if( RecComma() ) {
            EatDoParm();                        // process e3
            e3_node = CITNode;
            if( !AError ) {
                if( (CITNode->opn.us == USOPN_CON) && _IsTypeInteger( do_type ) ) {
                    incr = GetIntValue( CITNode );
                    doptr->incr_value = incr;
                    doptr->increment = NULL;
                    if( (OZOpts & OZOPT_O_FASTDO) == 0 ) {
                        if( e2_const ) {
                            limit = GetIntValue( e2_node );
                            if( NeedIncrement( limit, incr, do_type ) ) {
                                PushOpn( CITNode );
                                doptr->increment = StaticAlloc( do_size, do_type );
                            }
                        } else {
                            PushOpn( CITNode );
                            doptr->increment = StaticAlloc( do_size, do_type );
                        }
                    }
                } else {
                    PushOpn( CITNode );
                    doptr->increment = StaticAlloc( do_size, do_type );
                }
                AdvanceITPtr();
            }
        } else {
            if( _IsTypeInteger( do_type ) ) {
                doptr->increment = NULL;
                doptr->incr_value = 1;
                if( (OZOpts & OZOPT_O_FASTDO) == 0 ) {
                    if( e2_const ) {
                        limit = GetIntValue( e2_node );
                        if( NeedIncrement( limit, 1, do_type ) ) {
                            PushConst( 1 );
                            doptr->increment = StaticAlloc( do_size, do_type );
                        }
                    } else {
                        PushConst( 1 );
                        doptr->increment = StaticAlloc( do_size, do_type );
                    }
                }
            } else {
                PushConst( 1 );
                doptr->increment = StaticAlloc( do_size, do_type );
            }
        }
        EmitOp( FC_DO_BEGIN );
        OutPtr( doptr->do_parm );
        OutPtr( doptr->increment );
        if( doptr->increment == NULL ) { // INTEGER do-loop with constant incr
            loop_ctrl = StaticAlloc( do_size, do_type );
            OutConst32( doptr->incr_value );
            OutPtr( loop_ctrl );
        } else {
            if( _IsTypeInteger( do_type ) ) {
                loop_ctrl = StaticAlloc( do_size, do_type );
            } else {
                loop_ctrl = StaticAlloc( sizeof( intstar4 ), FT_INTEGER );
            }
            doptr->iteration = loop_ctrl;
            OutPtr( loop_ctrl );
            if( e3_node == NULL ) {
                DumpType( FT_INTEGER, TypeSize( FT_INTEGER ) );
            } else {
                GenType( e3_node );
            }
        }
        GenType( e2_node );
        DumpType( e1_type, e1_size );
        OutU16( CSHead->branch );
        OutU16( CSHead->bottom );
    }
}
Ejemplo n.º 18
0
int main() {
  llvm::InitializeNativeTarget();

  // Make the module, which holds all the code.
  llvm::Module *TheModule = new llvm::Module("my cool jit", llvm::getGlobalContext());

  // Create the JIT.  This takes ownership of the module.
  std::string ErrStr;
  llvm::ExecutionEngine *TheExecutionEngine = llvm::EngineBuilder(TheModule).setErrorStr(&ErrStr).create();
  if (!TheExecutionEngine) {
    fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str());
    exit(1);
  }

  llvm::FunctionPassManager OurFPM(TheModule);

  // Set up the optimizer pipeline.  Start with registering info about how the
  // target lays out data structures.
  OurFPM.add(new llvm::TargetData(*TheExecutionEngine->getTargetData()));
  // Do simple "peephole" optimizations and bit-twiddling optzns.
  OurFPM.add(llvm::createInstructionCombiningPass());
  // Reassociate expressions.
  OurFPM.add(llvm::createReassociatePass());
  // Eliminate Common SubExpressions.
  OurFPM.add(llvm::createGVNPass());
  // Simplify the control flow graph (deleting unreachable blocks, etc).
  OurFPM.add(llvm::createCFGSimplificationPass());

  OurFPM.doInitialization();

  // Set the global so the code gen can use this.
  llvm::FunctionPassManager *TheFPM = &OurFPM;

  // Single argument
  std::vector<const llvm::Type*> unaryArg(1,llvm::Type::getDoubleTy(llvm::getGlobalContext()));

  // Two arguments
  std::vector<const llvm::Type*> binaryArg(2,llvm::Type::getDoubleTy(llvm::getGlobalContext()));
  
  // Two arguments in and two references
  std::vector<const llvm::Type*> genArg(4);
  genArg[0] = genArg[1] = llvm::Type::getDoubleTy(llvm::getGlobalContext());
  genArg[2] = genArg[3] = llvm::Type::getDoublePtrTy(llvm::getGlobalContext());
  
  // Unary operation
  llvm::FunctionType *unaryFun = llvm::FunctionType::get(llvm::Type::getDoubleTy(llvm::getGlobalContext()),unaryArg, false);

  // Binary operation
  llvm::FunctionType *binaryFun = llvm::FunctionType::get(llvm::Type::getDoubleTy(llvm::getGlobalContext()),binaryArg, false);

  // More generic operation, return by reference
  llvm::FunctionType *genFun = llvm::FunctionType::get(llvm::Type::getVoidTy(llvm::getGlobalContext()),genArg, false);

  // Declare sin
  llvm::Function *sin_ = llvm::Function::Create(unaryFun, llvm::Function::ExternalLinkage, "sin", TheModule);
  
  // Declare my function
  llvm::Function *myfun = llvm::Function::Create(genFun, llvm::Function::ExternalLinkage, "myfcn", TheModule);

  // Create a new basic block to start insertion into.
  llvm::BasicBlock *BB = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", myfun);
  Builder.SetInsertPoint(BB);

  // Set names for all arguments.
  llvm::Function::arg_iterator AI = myfun->arg_begin();
  AI->setName("x1");
  llvm::Value *x1 = AI;
  AI++;
  AI->setName("x2");
  llvm::Value *x2 = AI;
  AI++;
  AI->setName("r1");
  llvm::Value *r1 = AI;
  AI++;
  AI->setName("r2");
  llvm::Value *r2 = AI;
  
  llvm::Value *five = llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(5.0));
  llvm::Value *x1_plus_5 = Builder.CreateFAdd(x1, five, "x1_plus_5");
  
  // Call the sine function
  std::vector<llvm::Value*> sinarg(1,x2);
  llvm::Value* sin_x2 = Builder.CreateCall(sin_, sinarg.begin(), sinarg.end(), "callsin");
  
  // Set values
  llvm::StoreInst *what_is_this1 = Builder.CreateStore(sin_x2,r1);
  llvm::StoreInst *what_is_this2 = Builder.CreateStore(x1_plus_5,r2);

  // Finish off the function.
  Builder.CreateRetVoid();

  // Validate the generated code, checking for consistency.
  verifyFunction(*myfun);

  // Optimize the function.
  TheFPM->run(*myfun);

  // Print out all of the generated code.
  TheModule->dump();

  // JIT the function
  double x1_val = 10;
  double x2_val = 20;
  double r1_val = -1;
  double r2_val = -1;
  typedef void (*GenType)(double,double,double*,double*);
  GenType FP = GenType(intptr_t(TheExecutionEngine->getPointerToFunction(myfun)));

  FP(x1_val,x2_val,&r1_val,&r2_val);

  printf("r1 = %g\n", r1_val);
  printf("r2 = %g\n", r2_val);
  

  return 0;
}
// Generate a flatbuffer schema from the Parser's internal representation.
std::string GenerateFBS(const Parser &parser, const std::string &file_name,
                        const GeneratorOptions &opts) {
  // Proto namespaces may clash with table names, so we have to prefix all:
  for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
       ++it) {
    for (auto comp = (*it)->components.begin(); comp != (*it)->components.end();
         ++comp) {
      (*comp) = "_" + (*comp);
    }
  }

  std::string schema;
  schema += "// Generated from " + file_name + ".proto\n\n";
  if (opts.include_dependence_headers) {
    #ifdef FBS_GEN_INCLUDES  // TODO: currently all in one file.
    int num_includes = 0;
    for (auto it = parser.included_files_.begin();
         it != parser.included_files_.end(); ++it) {
      auto basename = flatbuffers::StripPath(
                        flatbuffers::StripExtension(it->first));
      if (basename != file_name) {
        schema += "include \"" + basename + ".fbs\";\n";
        num_includes++;
      }
    }
    if (num_includes) schema += "\n";
    #endif
  }
  // Generate code for all the enum declarations.
  const Namespace *last_namespace = nullptr;
  for (auto enum_def_it = parser.enums_.vec.begin();
           enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
    EnumDef &enum_def = **enum_def_it;
    GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace);
    GenComment(enum_def.doc_comment, &schema, nullptr);
    schema += "enum " + enum_def.name + " : ";
    schema += GenType(enum_def.underlying_type) + " {\n";
    for (auto it = enum_def.vals.vec.begin();
         it != enum_def.vals.vec.end(); ++it) {
      auto &ev = **it;
      GenComment(ev.doc_comment, &schema, nullptr, "  ");
      schema += "  " + ev.name + " = " + NumToString(ev.value) + ",\n";
    }
    schema += "}\n\n";
  }
  // Generate code for all structs/tables.
  for (auto it = parser.structs_.vec.begin();
           it != parser.structs_.vec.end(); ++it) {
    StructDef &struct_def = **it;
    GenNameSpace(*struct_def.defined_namespace, &schema, &last_namespace);
    GenComment(struct_def.doc_comment, &schema, nullptr);
    schema += "table " + struct_def.name + " {\n";
    for (auto field_it = struct_def.fields.vec.begin();
             field_it != struct_def.fields.vec.end(); ++field_it) {
      auto &field = **field_it;
      GenComment(field.doc_comment, &schema, nullptr, "  ");
      schema += "  " + field.name + ":" + GenType(field.value.type);
      if (field.value.constant != "0") schema += " = " + field.value.constant;
      if (field.required) schema += " (required)";
      schema += ";\n";
    }
    schema += "}\n\n";
  }
  return schema;
}
Ejemplo n.º 20
0
void    GParenExpr( void ) {
//====================

    EmitOp( FC_DONE_PAREN_EXPR );
    GenType( CITNode );
}
Ejemplo n.º 21
0
 inline bool isZero(GenType a)
 {
     return areEqual<GenType>(a, GenType(0.0));
 }
Ejemplo n.º 22
0
 inline bool areEqual(GenType a, GenType b)
 {
     // FIXME Ambiguous call to absolute value
     const GenType scale = (std::abs(a) + std::abs(b)) / GenType(2.0);
     return (std::abs(a - b) <= epsilon<GenType>() * scale);
 }
  bool generate() {
    code_.Clear();
    code_ += "{";
    code_ += "  \"$schema\": \"http://json-schema.org/draft-04/schema#\",";
    code_ += "  \"definitions\": {";
    for (auto e = parser_.enums_.vec.cbegin(); e != parser_.enums_.vec.cend();
         ++e) {
      code_ += "    \"" + GenFullName(*e) + "\" : {";
      code_ += "      " + GenType("string") + ",";
      std::string enumdef("      \"enum\": [");
      for (auto enum_value = (*e)->vals.vec.begin();
           enum_value != (*e)->vals.vec.end(); ++enum_value) {
        enumdef.append("\"" + (*enum_value)->name + "\"");
        if (*enum_value != (*e)->vals.vec.back()) { enumdef.append(", "); }
      }
      enumdef.append("]");
      code_ += enumdef;
      code_ += "    },";  // close type
    }
    for (auto s = parser_.structs_.vec.cbegin();
         s != parser_.structs_.vec.cend(); ++s) {
      const auto &structure = *s;
      code_ += "    \"" + GenFullName(structure) + "\" : {";
      code_ += "      " + GenType("object") + ",";
      std::string comment;
      const auto &comment_lines = structure->doc_comment;
      for (auto comment_line = comment_lines.cbegin();
           comment_line != comment_lines.cend(); ++comment_line) {
        comment.append(*comment_line);
      }
      if (comment.size() > 0) {
        code_ += "      \"description\" : \"" + comment + "\",";
      }
      code_ += "      \"properties\" : {";

      const auto &properties = structure->fields.vec;
      for (auto prop = properties.cbegin(); prop != properties.cend(); ++prop) {
        const auto &property = *prop;
        std::string typeLine("        \"" + property->name + "\" : { " +
                             GenType(property->value.type) + " }");
        if (property != properties.back()) { typeLine.append(","); }
        code_ += typeLine;
      }
      code_ += "      },";  // close properties

      std::vector<FieldDef *> requiredProperties;
      std::copy_if(properties.begin(), properties.end(),
                   back_inserter(requiredProperties),
                   [](FieldDef const *prop) { return prop->required; });
      if (requiredProperties.size() > 0) {
        std::string required_string("      \"required\" : [");
        for (auto req_prop = requiredProperties.cbegin();
             req_prop != requiredProperties.cend(); ++req_prop) {
          required_string.append("\"" + (*req_prop)->name + "\"");
          if (*req_prop != requiredProperties.back()) {
            required_string.append(", ");
          }
        }
        required_string.append("],");
        code_ += required_string;
      }
      code_ += "      \"additionalProperties\" : false";
      std::string closeType("    }");
      if (*s != parser_.structs_.vec.back()) { closeType.append(","); }
      code_ += closeType;  // close type
    }
    code_ += "  },";  // close definitions

    // mark root type
    code_ += "  \"$ref\" : \"#/definitions/" +
             GenFullName(parser_.root_struct_def_) + "\"";

    code_ += "}";  // close schema root
    const std::string file_path = GeneratedFileName(path_, file_name_);
    const std::string final_code = code_.ToString();
    return SaveFile(file_path.c_str(), final_code, false);
  }