<commit_before>#include "itkCommandLineArgumentParser.h"
#include "CommandLineArgumentHelper.h"

#include "itkImageFileReader.h"
#include "itkImageToVectorImageFilter.h"
#include "itkImageFileWriter.h"

//-------------------------------------------------------------------------------------

/** run: A macro to call a function. */
#define run( function, type, dim ) \
if ( ComponentTypeIn == #type && Dimension == dim ) \
{ \
  typedef itk::Image< type, dim >       InputImageType; \
  typedef itk::VectorImage< type, dim > OutputImageType; \
  function< InputImageType, OutputImageType >( inputFileNames, outputFileName ); \
  supported = true; \
}

//-------------------------------------------------------------------------------------

/** Declare ComposeVectorImage. */
template< class InputImageType, class OutputImageType >
void ComposeVectorImage(
  const std::vector<std::string> & inputFileNames,
  const std::string & outputFileName );

/** Declare PrintHelp. */
void PrintHelp( void );

//-------------------------------------------------------------------------------------

int main( int argc, char ** argv )
{
  /** Check arguments for help. */
  if ( argc < 4 )
  {
    PrintHelp();
    return 1;
  }

  /** Create a command line argument parser. */
  itk::CommandLineArgumentParser::Pointer parser = itk::CommandLineArgumentParser::New();
  parser->SetCommandLineArguments( argc, argv );

  /** Get arguments. */
  std::vector<std::string>  inputFileNames( 0, "" );
  bool retin = parser->GetCommandLineArgument( "-in", inputFileNames );

  std::string outputFileName = "VECTOR.mhd";
  bool retout = parser->GetCommandLineArgument( "-out", outputFileName );

  /** Check if the required arguments are given. */
  if ( !retin )
  {
    std::cerr << "ERROR: You should specify \"-in\"." << std::endl;
    return 1;
  }
  if ( inputFileNames.size() < 2 )
  {
    std::cerr << "ERROR: You should specify at least two (2) input files." << std::endl;
    return 1;
  }

  /** Determine image properties. */
  std::string ComponentTypeIn = "short";
  std::string PixelType; //we don't use this
  unsigned int Dimension = 3;
  unsigned int NumberOfComponents = 1;
  std::vector<unsigned int> imagesize( Dimension, 0 );
  int retgip = GetImageProperties(
    inputFileNames[ 0 ],
    PixelType,
    ComponentTypeIn,
    Dimension,
    NumberOfComponents,
    imagesize );
  if ( retgip != 0 )
  {
    return 1;
  }

  /** Check for vector images. */
  if ( NumberOfComponents > 1 )
  {
    std::cerr << "ERROR: The NumberOfComponents is larger than 1!" << std::endl;
    std::cerr << "Cannot make vector of vector images." << std::endl;
    return 1;
  }

  /** Get rid of the possible "_" in ComponentType. */
  ReplaceUnderscoreWithSpace( ComponentTypeIn );

  /** Run the program. */
  bool supported = false;
  try
  {
    run( ComposeVectorImage, char, 2 );
    run( ComposeVectorImage, unsigned char, 2 );
    run( ComposeVectorImage, short, 2 );
    run( ComposeVectorImage, unsigned short, 2 );
    run( ComposeVectorImage, int, 2 );
    run( ComposeVectorImage, unsigned int, 2 );
    run( ComposeVectorImage, long, 2 );
    run( ComposeVectorImage, unsigned long, 2 );
    run( ComposeVectorImage, float, 2 );
    run( ComposeVectorImage, double, 2 );

    run( ComposeVectorImage, char, 3 );
    run( ComposeVectorImage, unsigned char, 3 );
    run( ComposeVectorImage, short, 3 );
    run( ComposeVectorImage, unsigned short, 3 );
    run( ComposeVectorImage, int, 3 );
    run( ComposeVectorImage, unsigned int, 3 );
    run( ComposeVectorImage, long, 3 );
    run( ComposeVectorImage, unsigned long, 3 );
    run( ComposeVectorImage, float, 3 );
    run( ComposeVectorImage, double, 3 );
  }
  catch( itk::ExceptionObject &e )
  {
    std::cerr << "Caught ITK exception: " << e << std::endl;
    return 1;
  }
  if ( !supported )
  {
    std::cerr << "ERROR: this combination of pixeltype and dimension is not supported!" << std::endl;
    std::cerr
      << "pixel (component) type = " << ComponentTypeIn
      << " ; dimension = " << Dimension
      << std::endl;
    return 1;
  }

  /** End program. */
  return 0;

} // end main

  /**
   * ******************* ComposeVectorImage *******************
   */

template< class InputImageType, class OutputImageType >
void ComposeVectorImage( const std::vector<std::string> & inputFileNames,
  const std::string & outputFileName )
{
  /** Typedef's. */
  typedef itk::ImageFileReader< InputImageType >          ReaderType;
  typedef itk::ImageToVectorImageFilter< InputImageType > FilterType;;
  typedef itk::ImageFileWriter< OutputImageType >         WriterType;

  /** Read in the input images. */
  std::vector<typename ReaderType::Pointer> readers( inputFileNames.size() );
  for ( unsigned int i = 0; i < inputFileNames.size(); ++i )
  {
    readers[ i ] = ReaderType::New();
    readers[ i ]->SetFileName( inputFileNames[ i ] );
    readers[ i ]->Update();
  }

  /** Create index extractor and writer. */
  typename FilterType::Pointer composer = FilterType::New();
  for ( unsigned int i = 0; i < inputFileNames.size(); ++i )
  {
    composer->SetNthInput( i, readers[ i ]->GetOutput() );
  }

  /** Write vector image. */
  typename WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( outputFileName );
  writer->SetInput( composer->GetOutput() );
  writer->Update();

} // end ComposeVectorImage()

  /**
   * ******************* PrintHelp *******************
   */
void PrintHelp()
{
  std::cout << "Usage:" << std::endl << "pximagetovectorimage" << std::endl;
  std::cout << "  -in      inputFilenames, at least 2" << std::endl;
  std::cout << "  [-out]   outputFilename, default VECTOR.mhd" << std::endl;
  std::cout << "Supported: 2D, 3D, (unsigned) char, (unsigned) short, (unsigned) int, (unsigned) long, float, double." << std::endl;
  std::cout << "Note: make sure that the input images are of the same type, size, etc." << std::endl;
} // end PrintHelp()

<commit_msg>MS:<commit_after>#include "itkCommandLineArgumentParser.h"
#include "CommandLineArgumentHelper.h"

#include "itkImageFileReader.h"
#include "itkImageToVectorImageFilter.h"
#include "itkImageFileWriter.h"

//-------------------------------------------------------------------------------------

/** run: A macro to call a function. */
#define run( function, type, dim ) \
if ( ComponentTypeIn == #type && Dimension == dim ) \
{ \
  typedef itk::Image< type, dim >       InputImageType; \
  typedef itk::VectorImage< type, dim > OutputImageType; \
  function< InputImageType, OutputImageType >( inputFileNames, outputFileName, numberOfStreams ); \
  supported = true; \
}

//-------------------------------------------------------------------------------------

/** Declare ComposeVectorImage. */
template< class InputImageType, class OutputImageType >
void ComposeVectorImage(
  const std::vector<std::string> & inputFileNames,
  const std::string & outputFileName,
  const unsigned int & numberOfStreams );

/** Declare PrintHelp. */
void PrintHelp( void );

//-------------------------------------------------------------------------------------

int main( int argc, char ** argv )
{
  /** Check arguments for help. */
  if ( argc < 4 )
  {
    PrintHelp();
    return 1;
  }

  /** Create a command line argument parser. */
  itk::CommandLineArgumentParser::Pointer parser = itk::CommandLineArgumentParser::New();
  parser->SetCommandLineArguments( argc, argv );

  /** Get arguments. */
  std::vector<std::string>  inputFileNames( 0, "" );
  bool retin = parser->GetCommandLineArgument( "-in", inputFileNames );

  std::string outputFileName = "VECTOR.mhd";
  bool retout = parser->GetCommandLineArgument( "-out", outputFileName );

  /** Support for streaming. */
  unsigned int numberOfStreams = 1;
  bool rets = parser->GetCommandLineArgument( "-s", numberOfStreams );

  /** Check if the required arguments are given. */
  if ( !retin )
  {
    std::cerr << "ERROR: You should specify \"-in\"." << std::endl;
    return 1;
  }
  if ( inputFileNames.size() < 2 )
  {
    std::cerr << "ERROR: You should specify at least two (2) input files." << std::endl;
    return 1;
  }

  /** Determine image properties. */
  std::string ComponentTypeIn = "short";
  std::string PixelType; //we don't use this
  unsigned int Dimension = 3;
  unsigned int NumberOfComponents = 1;
  std::vector<unsigned int> imagesize( Dimension, 0 );
  int retgip = GetImageProperties(
    inputFileNames[ 0 ],
    PixelType,
    ComponentTypeIn,
    Dimension,
    NumberOfComponents,
    imagesize );
  if ( retgip != 0 )
  {
    return 1;
  }

  /** Check for vector images. */
  if ( NumberOfComponents > 1 )
  {
    std::cerr << "ERROR: The NumberOfComponents is larger than 1!" << std::endl;
    std::cerr << "Cannot make vector of vector images." << std::endl;
    return 1;
  }

  /** Get rid of the possible "_" in ComponentType. */
  ReplaceUnderscoreWithSpace( ComponentTypeIn );

  /** Run the program. */
  bool supported = false;
  try
  {
    run( ComposeVectorImage, char, 2 );
    run( ComposeVectorImage, unsigned char, 2 );
    run( ComposeVectorImage, short, 2 );
    run( ComposeVectorImage, unsigned short, 2 );
    run( ComposeVectorImage, int, 2 );
    run( ComposeVectorImage, unsigned int, 2 );
    run( ComposeVectorImage, long, 2 );
    run( ComposeVectorImage, unsigned long, 2 );
    run( ComposeVectorImage, float, 2 );
    run( ComposeVectorImage, double, 2 );

    run( ComposeVectorImage, char, 3 );
    run( ComposeVectorImage, unsigned char, 3 );
    run( ComposeVectorImage, short, 3 );
    run( ComposeVectorImage, unsigned short, 3 );
    run( ComposeVectorImage, int, 3 );
    run( ComposeVectorImage, unsigned int, 3 );
    run( ComposeVectorImage, long, 3 );
    run( ComposeVectorImage, unsigned long, 3 );
    run( ComposeVectorImage, float, 3 );
    run( ComposeVectorImage, double, 3 );
  }
  catch( itk::ExceptionObject &e )
  {
    std::cerr << "Caught ITK exception: " << e << std::endl;
    return 1;
  }
  if ( !supported )
  {
    std::cerr << "ERROR: this combination of pixeltype and dimension is not supported!" << std::endl;
    std::cerr
      << "pixel (component) type = " << ComponentTypeIn
      << " ; dimension = " << Dimension
      << std::endl;
    return 1;
  }

  /** End program. */
  return 0;

} // end main

  /**
   * ******************* ComposeVectorImage *******************
   */

template< class InputImageType, class OutputImageType >
void ComposeVectorImage(
  const std::vector<std::string> & inputFileNames,
  const std::string & outputFileName,
  const unsigned int & numberOfStreams )
{
  /** Typedef's. */
  typedef itk::ImageFileReader< InputImageType >          ReaderType;
  typedef itk::ImageToVectorImageFilter< InputImageType > FilterType;;
  typedef itk::ImageFileWriter< OutputImageType >         WriterType;

  /** Read in the input images. */
  std::vector<typename ReaderType::Pointer> readers( inputFileNames.size() );
  for ( unsigned int i = 0; i < inputFileNames.size(); ++i )
  {
    readers[ i ] = ReaderType::New();
    readers[ i ]->SetFileName( inputFileNames[ i ] );
  }

  /** Create index extractor and writer. */
  typename FilterType::Pointer composer = FilterType::New();
  for ( unsigned int i = 0; i < inputFileNames.size(); ++i )
  {
    composer->SetNthInput( i, readers[ i ]->GetOutput() );
  }

  /** Write vector image. */
  typename WriterType::Pointer writer = WriterType::New();
  writer->SetFileName( outputFileName );
  writer->SetInput( composer->GetOutput() );
  writer->SetNumberOfStreamDivisions( numberOfStreams );
  writer->Update();

} // end ComposeVectorImage()

/**
 * ******************* PrintHelp *******************
 */

void PrintHelp( void )
{
  std::cout << "Usage:" << std::endl << "pximagetovectorimage\n";
  std::cout << "  -in      inputFilenames, at least 2\n";
  std::cout << "  [-out]   outputFilename, default VECTOR.mhd\n";
  std::cout << "  [-s]     number of streams, default 1.\n";
  std::cout << "Supported: 2D, 3D, (unsigned) char, (unsigned) short, "
    << "(unsigned) int, (unsigned) long, float, double.\n";
  std::cout << "Note: make sure that the input images are of the same type, size, etc." << std::endl;

} // end PrintHelp()

<|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include "InputPacket.h"
#include "Server.h"

using namespace ni;

Server::Server(short port) : m_socket(createSocket(port)), m_running(true) {

}

void Server::run() {
	InputPacket packet;
	while(m_running) {
		recvfrom(m_socket, &packet, sizeof(InputPacket), 0, nullptr, nullptr);
		if(packet.isValid()) {
			processPacket(packet);
		}
	}
}

void Server::processPacket(const InputPacket& packet) {
	if(packet.isSafe()) {

	}
}

FileDesc Server::createSocket(short port) {
	sockaddr_in address;
	FileDesc sock = socket(AF_INET, SOCK_DGRAM, 0);

	address.sin_family = AF_INET;
	address.sin_addr.s_addr = htonl(INADDR_ANY);
	address.sin_port = htons(port);

	bind(sock, (sockaddr *)&address, sizeof(address));
	return sock;
}<commit_msg>Implement more of the Server.<commit_after>#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstring>
#include "MouseEvent.h"
#include "InputPacket.h"
#include "Server.h"

using namespace ni;

Server::Server(DeviceType devices, short port) : m_inputSystem(devices),
												 m_socket(createSocket(port)),
												 m_running(true)
{

}

void Server::run() {
	InputPacket packet;
	while(m_running) {
		recvfrom(m_socket, &packet, sizeof(InputPacket), 0, nullptr, nullptr);
		if(packet.isValid()) {
			processPacket(packet);
		}
	}
}

void Server::processPacket(const InputPacket& packet) {
	if(packet.isSafe()) {
		if(packet.type == DeviceType::Mouse && packet.length == sizeof(MouseEvent)) {
			const MouseEvent event = *reinterpret_cast<const MouseEvent*>(packet.data);
			m_inputSystem.sendMouseEvent(event);
		}
	}
}

FileDesc Server::createSocket(short port) {
	sockaddr_in address;
	FileDesc sock = socket(AF_INET, SOCK_DGRAM, 0);

	address.sin_family = AF_INET;
	address.sin_addr.s_addr = htonl(INADDR_ANY);
	address.sin_port = htons(port);

	bind(sock, (sockaddr *)&address, sizeof(address));
	return sock;
}<|endoftext|>


<commit_before>#include <string.h>
#include <float.h>
#include "reductions.h"
#include "rand48.h"

using namespace LEARNER;

struct LRQstate {
  vw* all;
  bool lrindices[256];
  size_t orig_size[256];
  std::vector<std::string> lrpairs;
  bool dropout;
  uint64_t seed;
  uint64_t initial_seed;
};

bool valid_int (const char* s)
{
  char* endptr;

  int v = strtoul (s, &endptr, 0);
  (void) v;

  return (*s != '\0' && *endptr == '\0');
}

inline bool
cheesyrbit (uint64_t& seed)
{
  return merand48 (seed) > 0.5;
}

inline float
cheesyrand (uint32_t x)
{
  uint64_t seed = x;

  return merand48 (seed);
}

inline bool
example_is_test (example& ec)
{
  return ec.l.simple.label == FLT_MAX;
}

void
reset_seed (LRQstate& lrq)
{
  if (lrq.all->bfgs)
    lrq.seed = lrq.initial_seed;
}

template <bool is_learn>
void predict_or_learn(LRQstate& lrq, base_learner& base, example& ec)
{
  vw& all = *lrq.all;

  // Remember original features

  for (unsigned char* i = ec.indices.begin; i != ec.indices.end; ++i)
    {
      if (lrq.lrindices[*i])
	lrq.orig_size[*i] = ec.atomics[*i].size ();
    }

  size_t which = ec.example_counter;
  float first_prediction;
  float first_loss;
  unsigned int maxiter = (is_learn && ! example_is_test (ec)) ? 2 : 1;

  bool do_dropout = lrq.dropout && is_learn && ! example_is_test (ec);
  float scale = (! lrq.dropout || do_dropout) ? 1.f : 0.5f;

  for (unsigned int iter = 0; iter < maxiter; ++iter, ++which)
    {
      // Add left LRQ features, holding right LRQ features fixed
      //     and vice versa
      // TODO: what happens with --lrq ab2 --lrq ac2
      //       i.e. namespace occurs multiple times (?)

      for (vector<string>::iterator i = lrq.lrpairs.begin ();
             i != lrq.lrpairs.end ();
             ++i)
          {
            unsigned char left = (*i)[which%2];
            unsigned char right = (*i)[(which+1)%2];
            unsigned int k = atoi (i->c_str () + 2);

            for (unsigned int lfn = 0; lfn < lrq.orig_size[left]; ++lfn)
              {
                feature* lf = ec.atomics[left].begin + lfn;
                float lfx = lf->x;
                size_t lindex = lf->weight_index + ec.ft_offset;

                for (unsigned int n = 1; n <= k; ++n)
                  {
                    if (! do_dropout || cheesyrbit (lrq.seed))
                      {
                        uint32_t lwindex = (uint32_t)(lindex + (n << all.reg.stride_shift));

                        float* lw = &all.reg.weight_vector[lwindex & all.reg.weight_mask];

                        // perturb away from saddle point at (0, 0)
                        if (is_learn && ! example_is_test (ec) && *lw == 0)
                          *lw = cheesyrand (lwindex);

                        for (unsigned int rfn = 0;
                             rfn < lrq.orig_size[right];
                             ++rfn)
                          {
                            feature* rf = ec.atomics[right].begin + rfn;
                            audit_data* ra = ec.audit_features[right].begin + rfn;

                            // NB: ec.ft_offset added by base learner
                            float rfx = rf->x;
                            size_t rindex = rf->weight_index;
                            uint32_t rwindex = (uint32_t)(rindex + (n << all.reg.stride_shift));

                            feature lrq;
                            lrq.x = scale * *lw * lfx * rfx;
                            lrq.weight_index = rwindex;

                            ec.atomics[right].push_back (lrq);

                            if (all.audit || all.hash_inv)
                              {
                                std::stringstream new_feature_buffer;

                                new_feature_buffer << right << '^'
                                                   << ra->feature << '^'
                                                   << n;

                                char* new_space = strdup("lrq");
                                char* new_feature =
                                  strdup (new_feature_buffer.str().c_str());

                                audit_data ad = { new_space, new_feature, lrq.weight_index, lrq.x, true };
                                ec.audit_features[right].push_back (ad);
                              }
                          }
                      }
                  }
              }
          }

	if (is_learn)
	  base.learn(ec);
	else
	  base.predict(ec);

        // Restore example
        if (iter == 0)
          {
            first_prediction = ec.pred.scalar;
            first_loss = ec.loss;
          }
        else
          {
            ec.pred.scalar = first_prediction;
            ec.loss = first_loss;
          }

        for (vector<string>::iterator i = lrq.lrpairs.begin ();
             i != lrq.lrpairs.end ();
             ++i)
          {
            unsigned char right = (*i)[(which+1)%2];

            ec.atomics[right].end =
              ec.atomics[right].begin + lrq.orig_size[right];

            if (all.audit || all.hash_inv)
              {
                for (audit_data* a = ec.audit_features[right].begin + lrq.orig_size[right];
                     a < ec.audit_features[right].end;
                     ++a)
                  {
                    free (a->space);
                    free (a->feature);
                  }

                ec.audit_features[right].end =
                  ec.audit_features[right].begin + lrq.orig_size[right];
              }
          }
      }
  }

  base_learner* lrq_setup(vw& all)
  {//parse and set arguments
    if (missing_option<vector<string>>(all, "lrq", "use low rank quadratic features"))
      return NULL;
    new_options(all, "Lrq options")
      ("lrqdropout", "use dropout training for low rank quadratic features");
    add_options(all);

    if(!all.vm.count("lrq"))
      return NULL;

    LRQstate& lrq = calloc_or_die<LRQstate>();
    size_t maxk = 0;
    lrq.all = &all;

    size_t random_seed = 0;
    if (all.vm.count("random_seed")) random_seed = all.vm["random_seed"].as<size_t> ();

    lrq.initial_seed = lrq.seed = random_seed | 8675309;
    if (all.vm.count("lrqdropout"))
      {
        lrq.dropout = true;
        *all.file_options << " --lrqdropout ";
      }
    else
      lrq.dropout = false;

    lrq.lrpairs = all.vm["lrq"].as<vector<string> > ();

    for (vector<string>::iterator i = lrq.lrpairs.begin ();
	 i != lrq.lrpairs.end ();
	 ++i)
      *all.file_options << " --lrq " << *i;

    if (! all.quiet)
      {
        cerr << "creating low rank quadratic features for pairs: ";
        if (lrq.dropout)
          cerr << "(using dropout) ";
      }

    for (vector<string>::iterator i = lrq.lrpairs.begin ();
         i != lrq.lrpairs.end ();
         ++i)
      {
        if(!all.quiet){
          if (( i->length() < 3 ) || ! valid_int (i->c_str () + 2)) {
            cerr << endl << "error, low-rank quadratic features must involve two sets and a rank.\n";
            throw exception();
          }
          cerr << *i << " ";
        }
        // TODO: colon-syntax

        unsigned int k = atoi (i->c_str () + 2);

        lrq.lrindices[(int) (*i)[0]] = 1;
        lrq.lrindices[(int) (*i)[1]] = 1;

        maxk = max (maxk, k);
      }

    if(!all.quiet)
      cerr<<endl;

	all.wpp = all.wpp * (uint32_t)(1 + maxk);
    learner<LRQstate>& l = init_learner(&lrq, setup_base(all), predict_or_learn<true>,
					predict_or_learn<false>, 1 + maxk);
    l.set_end_pass(reset_seed);

    // TODO: leaks memory ?
    return make_base(l);
  }
<commit_msg>compiler cannot determine these variables are always set, so set them<commit_after>#include <string.h>
#include <float.h>
#include "reductions.h"
#include "rand48.h"

using namespace LEARNER;

struct LRQstate {
  vw* all;
  bool lrindices[256];
  size_t orig_size[256];
  std::vector<std::string> lrpairs;
  bool dropout;
  uint64_t seed;
  uint64_t initial_seed;
};

bool valid_int (const char* s)
{
  char* endptr;

  int v = strtoul (s, &endptr, 0);
  (void) v;

  return (*s != '\0' && *endptr == '\0');
}

inline bool
cheesyrbit (uint64_t& seed)
{
  return merand48 (seed) > 0.5;
}

inline float
cheesyrand (uint32_t x)
{
  uint64_t seed = x;

  return merand48 (seed);
}

inline bool
example_is_test (example& ec)
{
  return ec.l.simple.label == FLT_MAX;
}

void
reset_seed (LRQstate& lrq)
{
  if (lrq.all->bfgs)
    lrq.seed = lrq.initial_seed;
}

template <bool is_learn>
void predict_or_learn(LRQstate& lrq, base_learner& base, example& ec)
{
  vw& all = *lrq.all;

  // Remember original features

  for (unsigned char* i = ec.indices.begin; i != ec.indices.end; ++i)
    {
      if (lrq.lrindices[*i])
	lrq.orig_size[*i] = ec.atomics[*i].size ();
    }

  size_t which = ec.example_counter;
  float first_prediction = 0;
  float first_loss = 0;
  unsigned int maxiter = (is_learn && ! example_is_test (ec)) ? 2 : 1;

  bool do_dropout = lrq.dropout && is_learn && ! example_is_test (ec);
  float scale = (! lrq.dropout || do_dropout) ? 1.f : 0.5f;

  for (unsigned int iter = 0; iter < maxiter; ++iter, ++which)
    {
      // Add left LRQ features, holding right LRQ features fixed
      //     and vice versa
      // TODO: what happens with --lrq ab2 --lrq ac2
      //       i.e. namespace occurs multiple times (?)

      for (vector<string>::iterator i = lrq.lrpairs.begin ();
             i != lrq.lrpairs.end ();
             ++i)
          {
            unsigned char left = (*i)[which%2];
            unsigned char right = (*i)[(which+1)%2];
            unsigned int k = atoi (i->c_str () + 2);

            for (unsigned int lfn = 0; lfn < lrq.orig_size[left]; ++lfn)
              {
                feature* lf = ec.atomics[left].begin + lfn;
                float lfx = lf->x;
                size_t lindex = lf->weight_index + ec.ft_offset;

                for (unsigned int n = 1; n <= k; ++n)
                  {
                    if (! do_dropout || cheesyrbit (lrq.seed))
                      {
                        uint32_t lwindex = (uint32_t)(lindex + (n << all.reg.stride_shift));

                        float* lw = &all.reg.weight_vector[lwindex & all.reg.weight_mask];

                        // perturb away from saddle point at (0, 0)
                        if (is_learn && ! example_is_test (ec) && *lw == 0)
                          *lw = cheesyrand (lwindex);

                        for (unsigned int rfn = 0;
                             rfn < lrq.orig_size[right];
                             ++rfn)
                          {
                            feature* rf = ec.atomics[right].begin + rfn;
                            audit_data* ra = ec.audit_features[right].begin + rfn;

                            // NB: ec.ft_offset added by base learner
                            float rfx = rf->x;
                            size_t rindex = rf->weight_index;
                            uint32_t rwindex = (uint32_t)(rindex + (n << all.reg.stride_shift));

                            feature lrq;
                            lrq.x = scale * *lw * lfx * rfx;
                            lrq.weight_index = rwindex;

                            ec.atomics[right].push_back (lrq);

                            if (all.audit || all.hash_inv)
                              {
                                std::stringstream new_feature_buffer;

                                new_feature_buffer << right << '^'
                                                   << ra->feature << '^'
                                                   << n;

                                char* new_space = strdup("lrq");
                                char* new_feature =
                                  strdup (new_feature_buffer.str().c_str());

                                audit_data ad = { new_space, new_feature, lrq.weight_index, lrq.x, true };
                                ec.audit_features[right].push_back (ad);
                              }
                          }
                      }
                  }
              }
          }

	if (is_learn)
	  base.learn(ec);
	else
	  base.predict(ec);

        // Restore example
        if (iter == 0)
          {
            first_prediction = ec.pred.scalar;
            first_loss = ec.loss;
          }
        else
          {
            ec.pred.scalar = first_prediction;
            ec.loss = first_loss;
          }

        for (vector<string>::iterator i = lrq.lrpairs.begin ();
             i != lrq.lrpairs.end ();
             ++i)
          {
            unsigned char right = (*i)[(which+1)%2];

            ec.atomics[right].end =
              ec.atomics[right].begin + lrq.orig_size[right];

            if (all.audit || all.hash_inv)
              {
                for (audit_data* a = ec.audit_features[right].begin + lrq.orig_size[right];
                     a < ec.audit_features[right].end;
                     ++a)
                  {
                    free (a->space);
                    free (a->feature);
                  }

                ec.audit_features[right].end =
                  ec.audit_features[right].begin + lrq.orig_size[right];
              }
          }
      }
  }

  base_learner* lrq_setup(vw& all)
  {//parse and set arguments
    if (missing_option<vector<string>>(all, "lrq", "use low rank quadratic features"))
      return NULL;
    new_options(all, "Lrq options")
      ("lrqdropout", "use dropout training for low rank quadratic features");
    add_options(all);

    if(!all.vm.count("lrq"))
      return NULL;

    LRQstate& lrq = calloc_or_die<LRQstate>();
    size_t maxk = 0;
    lrq.all = &all;

    size_t random_seed = 0;
    if (all.vm.count("random_seed")) random_seed = all.vm["random_seed"].as<size_t> ();

    lrq.initial_seed = lrq.seed = random_seed | 8675309;
    if (all.vm.count("lrqdropout"))
      {
        lrq.dropout = true;
        *all.file_options << " --lrqdropout ";
      }
    else
      lrq.dropout = false;

    lrq.lrpairs = all.vm["lrq"].as<vector<string> > ();

    for (vector<string>::iterator i = lrq.lrpairs.begin ();
	 i != lrq.lrpairs.end ();
	 ++i)
      *all.file_options << " --lrq " << *i;

    if (! all.quiet)
      {
        cerr << "creating low rank quadratic features for pairs: ";
        if (lrq.dropout)
          cerr << "(using dropout) ";
      }

    for (vector<string>::iterator i = lrq.lrpairs.begin ();
         i != lrq.lrpairs.end ();
         ++i)
      {
        if(!all.quiet){
          if (( i->length() < 3 ) || ! valid_int (i->c_str () + 2)) {
            cerr << endl << "error, low-rank quadratic features must involve two sets and a rank.\n";
            throw exception();
          }
          cerr << *i << " ";
        }
        // TODO: colon-syntax

        unsigned int k = atoi (i->c_str () + 2);

        lrq.lrindices[(int) (*i)[0]] = 1;
        lrq.lrindices[(int) (*i)[1]] = 1;

        maxk = max (maxk, k);
      }

    if(!all.quiet)
      cerr<<endl;

	all.wpp = all.wpp * (uint32_t)(1 + maxk);
    learner<LRQstate>& l = init_learner(&lrq, setup_base(all), predict_or_learn<true>,
					predict_or_learn<false>, 1 + maxk);
    l.set_end_pass(reset_seed);

    // TODO: leaks memory ?
    return make_base(l);
  }
<|endoftext|>


<commit_before>
#include "include/Shapes.h"

double sumOfArea(const std::vector<Shape *> & shapes) {

    double total =0;

    for (Shape *shapePoint: shapes)
        total += shapePoint->area();

    return total;

}

double sumOfPerimeter(const std::vector<Shape *> & shapes){

    double total = 0;

    for (Shape *shapePoint: shapes)
        total += shapePoint->perimeter();

    return total;

}

Shape* theLargestArea(const std::vector<Shape *> & shapes){

    Shape *largestShape = nullptr;
    double largestArea = 0;

    for (Shape *shapePoint: shapes)
        if(shapePoint->area() >= largestArea){
            largestArea = shapePoint->area();
            largestShape = shapePoint;
        }

    return largestShape;

}

double distanceOfVertexs(const vertex vertex_1, const vertex vertex_2) {
    double diff_X, diff_Y, distance;

    diff_X = vertex_1.x - vertex_2.x;
    diff_Y = vertex_1.y - vertex_2.y;

    distance = sqrt(((diff_X * diff_X) + (diff_Y * diff_Y)));

    return distance;
}

void sortByDecreasingPerimeter(std::vector<Shape *> & shapes) {
    // use the shakeSort
    int left = 0;
    int right = shapes.size()-1;
    int shift = 0;
    Shape *temp;

    while(left < right){
        for(int i = left; i < right; i++) {
            if(shapes[i]->perimeter() < shapes[i+1]->perimeter()){
                temp = shapes[i];
                shapes[i] = shapes[i+1];
                shapes[i+1] = temp;
                shift = i;
            }
        }
        right = shift;
        for(int i = right; i > left; i--){
            if(shapes[i]->perimeter() > shapes[i-1]->perimeter()){
                temp = shapes[i];
                shapes[i] = shapes[i-1];
                shapes[i-1] = temp;
                shift = i;
            }
        }
        left = shift;
    }
}
<commit_msg>Delete Shapes.cpp<commit_after><|endoftext|>


<commit_before>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
 */
#include <sstream>
#include <float.h>
#include <math.h>
#include "reductions.h"
#include "rand48.h"
#include "vw_exception.h"
#include "vw.h"

using namespace std;

struct oaa
{ size_t k;
  vw* all; // for raw
  polyprediction* pred;  // for multipredict
  size_t num_subsample; // for randomized subsampling, how many negatives to draw?
  uint32_t* subsample_order; // for randomized subsampling, in what order should we touch classes
  size_t subsample_id; // for randomized subsampling, where do we live in the list
};

void learn_randomized(oaa& o, LEARNER::base_learner& base, example& ec)
{ MULTICLASS::label_t ld = ec.l.multi;
  if (ld.label == 0 || (ld.label > o.k && ld.label != (uint32_t)-1))
    cout << "label " << ld.label << " is not in {1,"<< o.k << "} This won't work right." << endl;

  ec.l.simple = { 1., 0.f, 0.f }; // truth
  base.learn(ec, ld.label-1);

  size_t prediction = ld.label;
  float best_partial_prediction = ec.partial_prediction;

  ec.l.simple.label = -1.;
  ec.weight *= ((float)o.k) / (float)o.num_subsample;
  size_t p = o.subsample_id;
  size_t count = 0;
  while (count < o.num_subsample)
  { uint32_t l = o.subsample_order[p];
    p = (p+1) % o.k;
    if (l == ld.label-1) continue;
    base.learn(ec, l);
    if (ec.partial_prediction > best_partial_prediction)
    { best_partial_prediction = ec.partial_prediction;
      prediction = l+1;
    }
    count++;
  }
  o.subsample_id = p;

  ec.pred.multiclass = (uint32_t)prediction;
  ec.l.multi = ld;
}

template <bool is_learn, bool print_all, bool scores>
void predict_or_learn(oaa& o, LEARNER::base_learner& base, example& ec)
{ MULTICLASS::label_t mc_label_data = ec.l.multi;
  if (mc_label_data.label == 0 || (mc_label_data.label > o.k && mc_label_data.label != (uint32_t)-1))
    cout << "label " << mc_label_data.label << " is not in {1,"<< o.k << "} This won't work right." << endl;

  stringstream outputStringStream;
  uint32_t prediction = 1;
  v_array<float> scores_array;
  if (scores)
    scores_array = ec.pred.scalars;

  ec.l.simple = { FLT_MAX, 0.f, 0.f };
  base.multipredict(ec, 0, o.k, o.pred, true);
  for (uint32_t i=2; i<=o.k; i++)
    if (o.pred[i-1].scalar > o.pred[prediction-1].scalar)
      prediction = i;

  if (ec.passthrough)
    for (uint32_t i=1; i<=o.k; i++)
      add_passthrough_feature(ec, i, o.pred[i-1].scalar);

  if (is_learn)
  { for (uint32_t i=1; i<=o.k; i++)
    { ec.l.simple = { (mc_label_data.label == i) ? 1.f : -1.f, 0.f, 0.f };
      ec.pred.scalar = o.pred[i-1].scalar;
	  base.update(ec, i-1);
    }
  }

  if (print_all)
  { outputStringStream << "1:" << o.pred[0].scalar;
    for (uint32_t i=2; i<=o.k; i++) outputStringStream << ' ' << i << ':' << o.pred[i-1].scalar;
    o.all->print_text(o.all->raw_prediction, outputStringStream.str(), ec.tag);
  }

  if (scores)
  {
    scores_array.erase();
    for (uint32_t i=0; i<o.k; i++)
      scores_array.push_back(o.pred[i].scalar);
    ec.pred.scalars = scores_array;
  }
  else
    ec.pred.multiclass = prediction;

  ec.l.multi = mc_label_data;
}

void finish(oaa&o)
{ free(o.pred);
  free(o.subsample_order);
}

// TODO: partial code duplication with multiclass.cc:finish_example
template<bool probabilities>
void finish_example_scores(vw& all, oaa& o, example& ec)
{ // === Compute multiclass_log_loss
  // TODO:
  // What to do if the correct label is unknown, i.e. (uint32_t)-1?
  //   Suggestion: increase all.sd->weighted_unlabeled_examples???,
  //               but not sd.example_number, so the average loss is not influenced.
  // What to do if the correct_class_prob==0?
  //   Suggestion: have some maximal multiclass_log_loss limit, e.g. 999.
  float multiclass_log_loss = 999; // -log(0) = plus infinity
  float correct_class_prob = 0;
  if (probabilities)
    {
      float sum_prob = 0;
      for(uint32_t i =0; i< o.k; i++)
	{
	  ec.pred.scalars[i] =  1.f / (1.f + exp(- o.pred[i].scalar));
	  sum_prob += ec.pred.scalars[i];
	}
      float inv_sum_prob = 1. / sum_prob;
      for(uint32_t i =0; i< o.k; i++)
	ec.pred.scalars[i] *= inv_sum_prob;

      if (ec.l.multi.label <= o.k) // prevent segmentation fault if labeĺ==(uint32_t)-1
	correct_class_prob = ec.pred.scalars[ec.l.multi.label-1];
      if (correct_class_prob > 0)
	multiclass_log_loss = -log(correct_class_prob) * ec.l.multi.weight;
      if (ec.test_only)
	all.sd->holdout_multiclass_log_loss += multiclass_log_loss;
      else
	all.sd->multiclass_log_loss += multiclass_log_loss;
    }
  // === Compute `prediction` and zero_one_loss
  // We have already computed `prediction` in predict_or_learn,
  // but we cannot store it in ec.pred union because we store ec.pred.probs there.
  uint32_t prediction = 0;
  for (uint32_t i = 1; i < o.k; i++)
    if (ec.pred.scalars[i] > ec.pred.scalars[prediction])
      prediction = i;
  prediction++; // prediction is 1-based index (not 0-based)
  float zero_one_loss = 0;
  if (ec.l.multi.label != prediction)
    zero_one_loss = ec.l.multi.weight;

  // === Print probabilities for all classes
  char temp_str[10];
  ostringstream outputStringStream;
  for (uint32_t i = 0; i < o.k; i++)
  { if (i > 0) outputStringStream << ' ';
    if (all.sd->ldict)
    { substring ss = all.sd->ldict->get(i+1);
      outputStringStream << string(ss.begin, ss.end - ss.begin);
    }
    else
      outputStringStream << i+1;
    sprintf(temp_str, "%f", ec.pred.scalars[i]); // 0.123 -> 0.123000
    outputStringStream << ':' << temp_str;
  }
  for (int sink : all.final_prediction_sink)
    all.print_text(sink, outputStringStream.str(), ec.tag);

  // === Report updates using zero-one loss
  all.sd->update(ec.test_only, zero_one_loss, ec.l.multi.weight, ec.num_features);
  // Alternatively, we could report multiclass_log_loss.
  //all.sd->update(ec.test_only, multiclass_log_loss, ec.l.multi.weight, ec.num_features);
  // Even better would be to report both losses, but this would mean to increase
  // the number of columns and this would not fit narrow screens.
  // So let's report (average) multiclass_log_loss only in the final resume.

  // === Print progress report
  if (probabilities)
    MULTICLASS::print_update_with_probability(all, ec, prediction);
  else
    MULTICLASS::print_update_with_score(all, ec, prediction);
  VW::finish_example(all, &ec);
}

LEARNER::base_learner* oaa_setup(vw& all)
{ if (missing_option<size_t, true>(all, "oaa", "One-against-all multiclass with <k> labels"))
    return nullptr;
  new_options(all, "oaa options")
  ("oaa_subsample", po::value<size_t>(), "subsample this number of negative examples when learning")
  ("probabilities", "predict probabilites of all classes")
  ("scores", "output raw scores per class");
  add_options(all);

  oaa* data_ptr = calloc_or_throw<oaa>(1);
  oaa& data = *data_ptr;
  data.k = all.vm["oaa"].as<size_t>(); // number of classes

  if (all.sd->ldict && (data.k != all.sd->ldict->getK()))
  { free(data_ptr);
    THROW("error: you have " << all.sd->ldict->getK() << " named labels; use that as the argument to oaa")
  }

  data.all = &all;
  data.pred = calloc_or_throw<polyprediction>(data.k);
  data.num_subsample = 0;
  data.subsample_order = nullptr;
  data.subsample_id = 0;
  if (all.vm.count("oaa_subsample"))
  { data.num_subsample = all.vm["oaa_subsample"].as<size_t>();
    if (data.num_subsample >= data.k)
    { data.num_subsample = 0;
      cerr << "oaa is turning off subsampling because your parameter >= K" << endl;
    }
    else
    { data.subsample_order = calloc_or_throw<uint32_t>(data.k);
      for (size_t i=0; i<data.k; i++) data.subsample_order[i] = (uint32_t) i;
      for (size_t i=0; i<data.k; i++)
      { size_t j = (size_t)(frand48() * (float)(data.k-i)) + i;
        uint32_t tmp = data.subsample_order[i];
        data.subsample_order[i] = data.subsample_order[j];
        data.subsample_order[j] = tmp;
      }
    }
  }

  LEARNER::learner<oaa>* l;
  if( all.vm.count("probabilities") || all.vm.count("scores") )
  {
    if (!all.vm.count("loss_function") || all.vm["loss_function"].as<string>() != "logistic" )
      cerr << "WARNING: --probabilities should be used only with --loss_function=logistic" << endl;
    // the three boolean template parameters are: is_learn, print_all and scores
    l = &LEARNER::init_multiclass_learner(data_ptr, setup_base(all), predict_or_learn<true, false, true>,
                                          predict_or_learn<false, false, true>, all.p, data.k, prediction_type::scalars);
    all.delete_prediction = delete_scalars;
    if (all.vm.count("probabilities"))
      {
	all.sd->report_multiclass_log_loss = true;
	l->set_finish_example(finish_example_scores<true>);
      }
    else
      l->set_finish_example(finish_example_scores<false>);
  }
  else if (all.raw_prediction > 0)
    l = &LEARNER::init_multiclass_learner(data_ptr, setup_base(all), predict_or_learn<true, true, false>,
                                          predict_or_learn<false, true, false>, all.p, data.k, prediction_type::multiclass);
  else
    l = &LEARNER::init_multiclass_learner(data_ptr, setup_base(all),predict_or_learn<true, false, false>,
                                          predict_or_learn<false, false, false>, all.p, data.k, prediction_type::multiclass);

  if (data.num_subsample > 0)
    l->set_learn(learn_randomized);
  l->set_finish(finish);

  return make_base(*l);
}
<commit_msg>little bump<commit_after>/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved.  Released under a BSD (revised)
license as described in the file LICENSE.
 */
#include <sstream>
#include <float.h>
#include <math.h>
#include "reductions.h"
#include "rand48.h"
#include "vw_exception.h"
#include "vw.h"

using namespace std;
struct oaa
{ size_t k;
  vw* all; // for raw
  polyprediction* pred;  // for multipredict
  size_t num_subsample; // for randomized subsampling, how many negatives to draw?
  uint32_t* subsample_order; // for randomized subsampling, in what order should we touch classes
  size_t subsample_id; // for randomized subsampling, where do we live in the list
};

void learn_randomized(oaa& o, LEARNER::base_learner& base, example& ec)
{ MULTICLASS::label_t ld = ec.l.multi;
  if (ld.label == 0 || (ld.label > o.k && ld.label != (uint32_t)-1))
    cout << "label " << ld.label << " is not in {1,"<< o.k << "} This won't work right." << endl;

  ec.l.simple = { 1., 0.f, 0.f }; // truth
  base.learn(ec, ld.label-1);

  size_t prediction = ld.label;
  float best_partial_prediction = ec.partial_prediction;

  ec.l.simple.label = -1.;
  ec.weight *= ((float)o.k) / (float)o.num_subsample;
  size_t p = o.subsample_id;
  size_t count = 0;
  while (count < o.num_subsample)
  { uint32_t l = o.subsample_order[p];
    p = (p+1) % o.k;
    if (l == ld.label-1) continue;
    base.learn(ec, l);
    if (ec.partial_prediction > best_partial_prediction)
    { best_partial_prediction = ec.partial_prediction;
      prediction = l+1;
    }
    count++;
  }
  o.subsample_id = p;

  ec.pred.multiclass = (uint32_t)prediction;
  ec.l.multi = ld;
}

template <bool is_learn, bool print_all, bool scores>
void predict_or_learn(oaa& o, LEARNER::base_learner& base, example& ec)
{ MULTICLASS::label_t mc_label_data = ec.l.multi;
  if (mc_label_data.label == 0 || (mc_label_data.label > o.k && mc_label_data.label != (uint32_t)-1))
    cout << "label " << mc_label_data.label << " is not in {1,"<< o.k << "} This won't work right." << endl;

  stringstream outputStringStream;
  uint32_t prediction = 1;
  v_array<float> scores_array;
  if (scores)
    scores_array = ec.pred.scalars;

  ec.l.simple = { FLT_MAX, 0.f, 0.f };
  base.multipredict(ec, 0, o.k, o.pred, true);
  for (uint32_t i=2; i<=o.k; i++)
    if (o.pred[i-1].scalar > o.pred[prediction-1].scalar)
      prediction = i;

  if (ec.passthrough)
    for (uint32_t i=1; i<=o.k; i++)
      add_passthrough_feature(ec, i, o.pred[i-1].scalar);

  if (is_learn)
  { for (uint32_t i=1; i<=o.k; i++)
    { ec.l.simple = { (mc_label_data.label == i) ? 1.f : -1.f, 0.f, 0.f };
      ec.pred.scalar = o.pred[i-1].scalar;
	  base.update(ec, i-1);
    }
  }

  if (print_all)
  { outputStringStream << "1:" << o.pred[0].scalar;
    for (uint32_t i=2; i<=o.k; i++) outputStringStream << ' ' << i << ':' << o.pred[i-1].scalar;
    o.all->print_text(o.all->raw_prediction, outputStringStream.str(), ec.tag);
  }

  if (scores)
  {
    scores_array.erase();
    for (uint32_t i=0; i<o.k; i++)
      scores_array.push_back(o.pred[i].scalar);
    ec.pred.scalars = scores_array;
  }
  else
    ec.pred.multiclass = prediction;

  ec.l.multi = mc_label_data;
}

void finish(oaa&o)
{ free(o.pred);
  free(o.subsample_order);
}

// TODO: partial code duplication with multiclass.cc:finish_example
template<bool probabilities>
void finish_example_scores(vw& all, oaa& o, example& ec)
{ // === Compute multiclass_log_loss
  // TODO:
  // What to do if the correct label is unknown, i.e. (uint32_t)-1?
  //   Suggestion: increase all.sd->weighted_unlabeled_examples???,
  //               but not sd.example_number, so the average loss is not influenced.
  // What to do if the correct_class_prob==0?
  //   Suggestion: have some maximal multiclass_log_loss limit, e.g. 999.
  float multiclass_log_loss = 999; // -log(0) = plus infinity
  float correct_class_prob = 0;
  if (probabilities)
    {
      float sum_prob = 0;
      for(uint32_t i =0; i< o.k; i++)
	{
	  ec.pred.scalars[i] =  1.f / (1.f + exp(- o.pred[i].scalar));
	  sum_prob += ec.pred.scalars[i];
	}
      float inv_sum_prob = 1. / sum_prob;
      for(uint32_t i =0; i< o.k; i++)
	ec.pred.scalars[i] *= inv_sum_prob;

      if (ec.l.multi.label <= o.k) // prevent segmentation fault if labeĺ==(uint32_t)-1
	correct_class_prob = ec.pred.scalars[ec.l.multi.label-1];
      if (correct_class_prob > 0)
	multiclass_log_loss = -log(correct_class_prob) * ec.l.multi.weight;
      if (ec.test_only)
	all.sd->holdout_multiclass_log_loss += multiclass_log_loss;
      else
	all.sd->multiclass_log_loss += multiclass_log_loss;
    }
  // === Compute `prediction` and zero_one_loss
  // We have already computed `prediction` in predict_or_learn,
  // but we cannot store it in ec.pred union because we store ec.pred.probs there.
  uint32_t prediction = 0;
  for (uint32_t i = 1; i < o.k; i++)
    if (ec.pred.scalars[i] > ec.pred.scalars[prediction])
      prediction = i;
  prediction++; // prediction is 1-based index (not 0-based)
  float zero_one_loss = 0;
  if (ec.l.multi.label != prediction)
    zero_one_loss = ec.l.multi.weight;

  // === Print probabilities for all classes
  char temp_str[10];
  ostringstream outputStringStream;
  for (uint32_t i = 0; i < o.k; i++)
  { if (i > 0) outputStringStream << ' ';
    if (all.sd->ldict)
    { substring ss = all.sd->ldict->get(i+1);
      outputStringStream << string(ss.begin, ss.end - ss.begin);
    }
    else
      outputStringStream << i+1;
    sprintf(temp_str, "%f", ec.pred.scalars[i]); // 0.123 -> 0.123000
    outputStringStream << ':' << temp_str;
  }
  for (int sink : all.final_prediction_sink)
    all.print_text(sink, outputStringStream.str(), ec.tag);

  // === Report updates using zero-one loss
  all.sd->update(ec.test_only, zero_one_loss, ec.l.multi.weight, ec.num_features);
  // Alternatively, we could report multiclass_log_loss.
  //all.sd->update(ec.test_only, multiclass_log_loss, ec.l.multi.weight, ec.num_features);
  // Even better would be to report both losses, but this would mean to increase
  // the number of columns and this would not fit narrow screens.
  // So let's report (average) multiclass_log_loss only in the final resume.

  // === Print progress report
  if (probabilities)
    MULTICLASS::print_update_with_probability(all, ec, prediction);
  else
    MULTICLASS::print_update_with_score(all, ec, prediction);
  VW::finish_example(all, &ec);
}

LEARNER::base_learner* oaa_setup(vw& all)
{ if (missing_option<size_t, true>(all, "oaa", "One-against-all multiclass with <k> labels"))
    return nullptr;
  new_options(all, "oaa options")
  ("oaa_subsample", po::value<size_t>(), "subsample this number of negative examples when learning")
  ("probabilities", "predict probabilites of all classes")
  ("scores", "output raw scores per class");
  add_options(all);

  oaa* data_ptr = calloc_or_throw<oaa>(1);
  oaa& data = *data_ptr;
  data.k = all.vm["oaa"].as<size_t>(); // number of classes

  if (all.sd->ldict && (data.k != all.sd->ldict->getK()))
  { free(data_ptr);
    THROW("error: you have " << all.sd->ldict->getK() << " named labels; use that as the argument to oaa")
  }

  data.all = &all;
  data.pred = calloc_or_throw<polyprediction>(data.k);
  data.num_subsample = 0;
  data.subsample_order = nullptr;
  data.subsample_id = 0;
  if (all.vm.count("oaa_subsample"))
  { data.num_subsample = all.vm["oaa_subsample"].as<size_t>();
    if (data.num_subsample >= data.k)
    { data.num_subsample = 0;
      cerr << "oaa is turning off subsampling because your parameter >= K" << endl;
    }
    else
    { data.subsample_order = calloc_or_throw<uint32_t>(data.k);
      for (size_t i=0; i<data.k; i++) data.subsample_order[i] = (uint32_t) i;
      for (size_t i=0; i<data.k; i++)
      { size_t j = (size_t)(frand48() * (float)(data.k-i)) + i;
        uint32_t tmp = data.subsample_order[i];
        data.subsample_order[i] = data.subsample_order[j];
        data.subsample_order[j] = tmp;
      }
    }
  }

  LEARNER::learner<oaa>* l;
  if( all.vm.count("probabilities") || all.vm.count("scores") )
  {
    if (!all.vm.count("loss_function") || all.vm["loss_function"].as<string>() != "logistic" )
      cerr << "WARNING: --probabilities should be used only with --loss_function=logistic" << endl;
    // the three boolean template parameters are: is_learn, print_all and scores
    l = &LEARNER::init_multiclass_learner(data_ptr, setup_base(all), predict_or_learn<true, false, true>,
                                          predict_or_learn<false, false, true>, all.p, data.k, prediction_type::scalars);
    all.delete_prediction = delete_scalars;
    if (all.vm.count("probabilities"))
      {
	all.sd->report_multiclass_log_loss = true;
	l->set_finish_example(finish_example_scores<true>);
      }
    else
      l->set_finish_example(finish_example_scores<false>);
  }
  else if (all.raw_prediction > 0)
    l = &LEARNER::init_multiclass_learner(data_ptr, setup_base(all), predict_or_learn<true, true, false>,
                                          predict_or_learn<false, true, false>, all.p, data.k, prediction_type::multiclass);
  else
    l = &LEARNER::init_multiclass_learner(data_ptr, setup_base(all),predict_or_learn<true, false, false>,
                                          predict_or_learn<false, false, false>, all.p, data.k, prediction_type::multiclass);

  if (data.num_subsample > 0)
    l->set_learn(learn_randomized);
  l->set_finish(finish);

  return make_base(*l);
}
<|endoftext|>


<commit_before>/*
    This file is part of solidity.

    solidity is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    solidity is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Alex Beregszaszi
 * @date 2016
 * Unit tests for the LLL parser.
 */

#include <string>
#include <memory>
#include <boost/test/unit_test.hpp>
#include <liblll/Compiler.h>

using namespace std;

namespace dev
{
namespace lll
{
namespace test
{

namespace
{

bool successParse(std::string const& _source)
{
	std::string ret = eth::parseLLL(_source);
	return ret.size() != 0;
}

std::string parse(std::string const& _source)
{
	return eth::parseLLL(_source);
}

}

BOOST_AUTO_TEST_SUITE(LLLParser)

BOOST_AUTO_TEST_CASE(smoke_test)
{
	char const* text = "1";
	BOOST_CHECK(successParse(text));
}

BOOST_AUTO_TEST_CASE(string)
{
	char const* text = "\"string\"";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"("string")");
}

BOOST_AUTO_TEST_CASE(symbol)
{
	char const* text = "symbol";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(symbol)");

	BOOST_CHECK(successParse("'symbol"));
	BOOST_CHECK_EQUAL(parse(text), R"(symbol)");
}

BOOST_AUTO_TEST_CASE(decimals)
{
	char const* text = "1234";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(1234)");
}

BOOST_AUTO_TEST_CASE(hexadecimals)
{
	char const* text = "0x1234";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(4660)");

	BOOST_CHECK(!successParse("0x"));
}

BOOST_AUTO_TEST_CASE(sequence)
{
	char const* text = "{ 1234 }";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"({ 1234 })");
}

BOOST_AUTO_TEST_CASE(empty_sequence)
{
	char const* text = "{}";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"({ })");
}

BOOST_AUTO_TEST_CASE(mload)
{
	char const* text = "@0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(@ 0)");

	BOOST_CHECK(successParse("@0x0"));
	BOOST_CHECK(successParse("@symbol"));
	BOOST_CHECK(!successParse("@"));
}

BOOST_AUTO_TEST_CASE(sload)
{
	char const* text = "@@0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(@@ 0)");

	BOOST_CHECK(successParse("@@0x0"));
	BOOST_CHECK(successParse("@@symbol"));
	BOOST_CHECK(!successParse("@@"));
}

BOOST_AUTO_TEST_CASE(mstore)
{
	char const* text = "[0]:0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"([ 0 ] 0)");

	BOOST_CHECK(successParse("[0] 0"));
	BOOST_CHECK(successParse("[0x0]:0x0"));
	BOOST_CHECK(successParse("[symbol]:symbol"));
	BOOST_CHECK(!successParse("[]"));
	BOOST_CHECK(!successParse("[0]"));
}

BOOST_AUTO_TEST_CASE(sstore)
{
	char const* text = "[[0]]:0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"([[ 0 ]] 0)");

	BOOST_CHECK(successParse("[[0]] 0"));
	BOOST_CHECK(successParse("[[0x0]]:0x0"));
	BOOST_CHECK(successParse("[[symbol]]:symbol"));
	BOOST_CHECK(!successParse("[[]]"));
	BOOST_CHECK(!successParse("[[0x0]]"));
}

BOOST_AUTO_TEST_CASE(calldataload)
{
	char const* text = "$0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"($ 0)");

	BOOST_CHECK(successParse("$0x0"));
	BOOST_CHECK(successParse("$symbol"));
	BOOST_CHECK(!successParse("$"));
}

BOOST_AUTO_TEST_CASE(list)
{
	char const* text = "( 1234 )";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(( 1234 ))");

	BOOST_CHECK(successParse("( 1234 5467 )"));
	BOOST_CHECK(!successParse("()"));
}

BOOST_AUTO_TEST_SUITE_END()

}
}
} // end namespaces
<commit_msg>Add a test that fails about an LLL macro with no arguments<commit_after>/*
    This file is part of solidity.

    solidity is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    solidity is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with solidity.  If not, see <http://www.gnu.org/licenses/>.
*/
/**
 * @author Alex Beregszaszi
 * @date 2016
 * Unit tests for the LLL parser.
 */

#include <string>
#include <memory>
#include <boost/test/unit_test.hpp>
#include <liblll/Compiler.h>

using namespace std;

namespace dev
{
namespace lll
{
namespace test
{

namespace
{

bool successParse(std::string const& _source)
{
	std::string ret = eth::parseLLL(_source);
	return ret.size() != 0;
}

std::string parse(std::string const& _source)
{
	return eth::parseLLL(_source);
}

}

BOOST_AUTO_TEST_SUITE(LLLParser)

BOOST_AUTO_TEST_CASE(smoke_test)
{
	char const* text = "1";
	BOOST_CHECK(successParse(text));
}

BOOST_AUTO_TEST_CASE(string)
{
	char const* text = "\"string\"";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"("string")");
}

BOOST_AUTO_TEST_CASE(symbol)
{
	char const* text = "symbol";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(symbol)");

	BOOST_CHECK(successParse("'symbol"));
	BOOST_CHECK_EQUAL(parse(text), R"(symbol)");
}

BOOST_AUTO_TEST_CASE(decimals)
{
	char const* text = "1234";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(1234)");
}

BOOST_AUTO_TEST_CASE(hexadecimals)
{
	char const* text = "0x1234";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(4660)");

	BOOST_CHECK(!successParse("0x"));
}

BOOST_AUTO_TEST_CASE(sequence)
{
	char const* text = "{ 1234 }";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"({ 1234 })");
}

BOOST_AUTO_TEST_CASE(empty_sequence)
{
	char const* text = "{}";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"({ })");
}

BOOST_AUTO_TEST_CASE(mload)
{
	char const* text = "@0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(@ 0)");

	BOOST_CHECK(successParse("@0x0"));
	BOOST_CHECK(successParse("@symbol"));
	BOOST_CHECK(!successParse("@"));
}

BOOST_AUTO_TEST_CASE(sload)
{
	char const* text = "@@0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(@@ 0)");

	BOOST_CHECK(successParse("@@0x0"));
	BOOST_CHECK(successParse("@@symbol"));
	BOOST_CHECK(!successParse("@@"));
}

BOOST_AUTO_TEST_CASE(mstore)
{
	char const* text = "[0]:0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"([ 0 ] 0)");

	BOOST_CHECK(successParse("[0] 0"));
	BOOST_CHECK(successParse("[0x0]:0x0"));
	BOOST_CHECK(successParse("[symbol]:symbol"));
	BOOST_CHECK(!successParse("[]"));
	BOOST_CHECK(!successParse("[0]"));
}

BOOST_AUTO_TEST_CASE(sstore)
{
	char const* text = "[[0]]:0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"([[ 0 ]] 0)");

	BOOST_CHECK(successParse("[[0]] 0"));
	BOOST_CHECK(successParse("[[0x0]]:0x0"));
	BOOST_CHECK(successParse("[[symbol]]:symbol"));
	BOOST_CHECK(!successParse("[[]]"));
	BOOST_CHECK(!successParse("[[0x0]]"));
}

BOOST_AUTO_TEST_CASE(calldataload)
{
	char const* text = "$0";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"($ 0)");

	BOOST_CHECK(successParse("$0x0"));
	BOOST_CHECK(successParse("$symbol"));
	BOOST_CHECK(!successParse("$"));
}

BOOST_AUTO_TEST_CASE(list)
{
	char const* text = "( 1234 )";
	BOOST_CHECK(successParse(text));
	BOOST_CHECK_EQUAL(parse(text), R"(( 1234 ))");

	BOOST_CHECK(successParse("( 1234 5467 )"));
	BOOST_CHECK(!successParse("()"));
}

BOOST_AUTO_TEST_CASE(macro_with_zero_args)
{
	char const* text = "(def 'zeroargs () (asm INVALID))";
	BOOST_CHECK(successParse(text));
}

BOOST_AUTO_TEST_SUITE_END()

}
}
} // end namespaces
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2007,2008,2009  Red Hat, Inc.
 *
 *  This is part of HarfBuzz, an OpenType Layout engine library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Red Hat Author(s): Behdad Esfahbod
 */

#ifndef HB_OT_LAYOUT_GDEF_PRIVATE_HH
#define HB_OT_LAYOUT_GDEF_PRIVATE_HH

#include "hb-ot-layout-common-private.hh"

#include "hb-font-private.h"

struct GlyphClassDef : ClassDef
{
  enum {
    BaseGlyph		= 0x0001u,
    LigatureGlyph	= 0x0002u,
    MarkGlyph		= 0x0003u,
    ComponentGlyph	= 0x0004u,
  };
};

/*
 * Attachment List Table
 */

typedef ArrayOf<USHORT> AttachPoint;	/* Array of contour point indices--in
					 * increasing numerical order */
ASSERT_SIZE (AttachPoint, 2);

struct AttachList
{
  inline bool get_attach_points (hb_codepoint_t glyph_id,
				 unsigned int *point_count /* IN/OUT */,
				 unsigned int *point_array /* OUT */) const
  {
    unsigned int index = (this+coverage) (glyph_id);
    if (index == NOT_COVERED)
    {
      *point_count = 0;
      return false;
    }
    const AttachPoint &points = this+attachPoint[index];

    unsigned int count = MIN (points.len, *point_count);
    for (unsigned int i = 0; i < count; i++)
      point_array[i] = points[i];

    *point_count = points.len;

    return true;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_THIS2 (coverage, attachPoint);
  }

  private:
  OffsetTo<Coverage>
		coverage;		/* Offset to Coverage table -- from
					 * beginning of AttachList table */
  OffsetArrayOf<AttachPoint>
		attachPoint;		/* Array of AttachPoint tables
					 * in Coverage Index order */
};
ASSERT_SIZE (AttachList, 4);

/*
 * Ligature Caret Table
 */

struct CaretValueFormat1
{
  friend struct CaretValue;

  private:
  inline int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id) const
  {
    /* TODO vertical */
    return context->font->x_scale * coordinate / 0x10000;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_SELF ();
  }

  private:
  USHORT	caretValueFormat;	/* Format identifier--format = 1 */
  SHORT		coordinate;		/* X or Y value, in design units */
};
ASSERT_SIZE (CaretValueFormat1, 4);

struct CaretValueFormat2
{
  friend struct CaretValue;

  private:
  inline int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id) const
  {
    return /* TODO contour point */ 0;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_SELF ();
  }

  private:
  USHORT	caretValueFormat;	/* Format identifier--format = 2 */
  USHORT	caretValuePoint;	/* Contour point index on glyph */
};
ASSERT_SIZE (CaretValueFormat2, 4);

struct CaretValueFormat3
{
  friend struct CaretValue;

  inline int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id) const
  {
    /* TODO vertical */
    return context->font->x_scale * coordinate / 0x10000 +
	   ((this+deviceTable).get_delta (context->font->x_ppem) << 6);
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_SELF () && SANITIZE_THIS (deviceTable);
  }

  private:
  USHORT	caretValueFormat;	/* Format identifier--format = 3 */
  SHORT		coordinate;		/* X or Y value, in design units */
  OffsetTo<Device>
		deviceTable;		/* Offset to Device table for X or Y
					 * value--from beginning of CaretValue
					 * table */
};
ASSERT_SIZE (CaretValueFormat3, 6);

struct CaretValue
{
  int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id) const
  {
    switch (u.format) {
    case 1: return u.format1->get_caret_value (context, glyph_id);
    case 2: return u.format2->get_caret_value (context, glyph_id);
    case 3: return u.format3->get_caret_value (context, glyph_id);
    default:return 0;
    }
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    if (!SANITIZE (u.format)) return false;
    switch (u.format) {
    case 1: return u.format1->sanitize (SANITIZE_ARG);
    case 2: return u.format2->sanitize (SANITIZE_ARG);
    case 3: return u.format3->sanitize (SANITIZE_ARG);
    default:return true;
    }
  }

  private:
  union {
  USHORT		format;		/* Format identifier */
  CaretValueFormat1	format1[];
  CaretValueFormat2	format2[];
  CaretValueFormat3	format3[];
  } u;
};
ASSERT_SIZE (CaretValue, 2);

struct LigGlyph
{
  inline void get_lig_carets (hb_ot_layout_context_t *context,
			      hb_codepoint_t glyph_id,
			      unsigned int *caret_count /* IN/OUT */,
			      int *caret_array /* OUT */) const
  {

    unsigned int count = MIN (carets.len, *caret_count);
    for (unsigned int i = 0; i < count; i++)
      caret_array[i] = (this+carets[i]).get_caret_value (context, glyph_id);

    *caret_count = carets.len;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE (carets);
  }

  private:
  OffsetArrayOf<CaretValue>
		carets;			/* Offset rrray of CaretValue tables
					 * --from beginning of LigGlyph table
					 * --in increasing coordinate order */
};
ASSERT_SIZE (LigGlyph, 2);

struct LigCaretList
{
  inline bool get_lig_carets (hb_ot_layout_context_t *context,
			      hb_codepoint_t glyph_id,
			      unsigned int *caret_count /* IN/OUT */,
			      int *caret_array /* OUT */) const
  {
    unsigned int index = (this+coverage) (glyph_id);
    if (index == NOT_COVERED)
    {
      *caret_count = 0;
      return false;
    }
    const LigGlyph &lig_glyph = this+ligGlyph[index];
    lig_glyph.get_lig_carets (context, glyph_id, caret_count, caret_array);
    return true;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_THIS2 (coverage, ligGlyph);
  }

  private:
  OffsetTo<Coverage>
		coverage;		/* Offset to Coverage table--from
					 * beginning of LigCaretList table */
  OffsetArrayOf<LigGlyph>
		ligGlyph;		/* Array of LigGlyph tables
					 * in Coverage Index order */
};
ASSERT_SIZE (LigCaretList, 4);

struct MarkGlyphSetsFormat1
{
  inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
  { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_THIS (coverage);
  }

  private:
  USHORT	format;			/* Format identifier--format = 1 */
  LongOffsetArrayOf<Coverage>
		coverage;		/* Array of long offsets to mark set
					 * coverage tables */
};
ASSERT_SIZE (MarkGlyphSetsFormat1, 4);

struct MarkGlyphSets
{
  inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
  {
    switch (u.format) {
    case 1: return u.format1->covers (set_index, glyph_id);
    default:return false;
    }
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    if (!SANITIZE (u.format)) return false;
    switch (u.format) {
    case 1: return u.format1->sanitize (SANITIZE_ARG);
    default:return true;
    }
  }

  private:
  union {
  USHORT		format;		/* Format identifier */
  MarkGlyphSetsFormat1	format1[];
  } u;
};
ASSERT_SIZE (MarkGlyphSets, 2);

/*
 * GDEF
 */

struct GDEF
{
  static const hb_tag_t Tag	= HB_OT_TAG_GDEF;

  enum {
    UnclassifiedGlyph	= 0,
    BaseGlyph		= 1,
    LigatureGlyph	= 2,
    MarkGlyph		= 3,
    ComponentGlyph	= 4,
  };

  STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (GDEF, 1, 1);

  inline bool has_glyph_classes () const { return glyphClassDef != 0; }
  inline hb_ot_layout_class_t get_glyph_class (hb_codepoint_t glyph) const
  { return (this+glyphClassDef).get_class (glyph); }

  inline bool has_mark_attachment_types () const { return markAttachClassDef != 0; }
  inline hb_ot_layout_class_t get_mark_attachment_type (hb_codepoint_t glyph) const
  { return (this+markAttachClassDef).get_class (glyph); }

  inline bool has_attach_points () const { return attachList != 0; }
  inline bool get_attach_points (hb_codepoint_t glyph_id,
				 unsigned int *point_count /* IN/OUT */,
				 unsigned int *point_array /* OUT */) const
  { return (this+attachList).get_attach_points (glyph_id, point_count, point_array); }

  inline bool has_lig_carets () const { return ligCaretList != 0; }
  inline bool get_lig_carets (hb_ot_layout_context_t *context,
			      hb_codepoint_t glyph_id,
			      unsigned int *caret_count /* IN/OUT */,
			      int *caret_array /* OUT */) const
  { return (this+ligCaretList).get_lig_carets (context, glyph_id, caret_count, caret_array); }

  inline bool has_mark_sets () const { return version >= 0x00010002 && markGlyphSetsDef[0] != 0; }
  inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
  { return version >= 0x00010002 && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }

  bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    if (!SANITIZE (version)) return false;
    if (version.major != 1) return true;
    return SANITIZE_THIS2 (glyphClassDef, attachList) &&
	   SANITIZE_THIS2 (ligCaretList, markAttachClassDef) &&
	   (version < 0x00010002 || SANITIZE_THIS (markGlyphSetsDef[0]));
  }

  private:
  FixedVersion	version;		/* Version of the GDEF table--currently
					 * 0x00010002 */
  OffsetTo<ClassDef>
		glyphClassDef;		/* Offset to class definition table
					 * for glyph type--from beginning of
					 * GDEF header (may be Null) */
  OffsetTo<AttachList>
		attachList;		/* Offset to list of glyphs with
					 * attachment points--from beginning
					 * of GDEF header (may be Null) */
  OffsetTo<LigCaretList>
		ligCaretList;		/* Offset to list of positioning points
					 * for ligature carets--from beginning
					 * of GDEF header (may be Null) */
  OffsetTo<ClassDef>
		markAttachClassDef;	/* Offset to class definition table for
					 * mark attachment type--from beginning
					 * of GDEF header (may be Null) */
  OffsetTo<MarkGlyphSets>
		markGlyphSetsDef[0];	/* Offset to the table of mark set
					 * definitions--from beginning of GDEF
					 * header (may be NULL).  Introduced
					 * in version 00010002. */
};
ASSERT_SIZE (GDEF, 12);

#endif /* HB_OT_LAYOUT_GDEF_PRIVATE_HH */
<commit_msg>[HB] Remove unused code<commit_after>/*
 * Copyright (C) 2007,2008,2009  Red Hat, Inc.
 *
 *  This is part of HarfBuzz, an OpenType Layout engine library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Red Hat Author(s): Behdad Esfahbod
 */

#ifndef HB_OT_LAYOUT_GDEF_PRIVATE_HH
#define HB_OT_LAYOUT_GDEF_PRIVATE_HH

#include "hb-ot-layout-common-private.hh"

#include "hb-font-private.h"

/*
 * Attachment List Table
 */

typedef ArrayOf<USHORT> AttachPoint;	/* Array of contour point indices--in
					 * increasing numerical order */
ASSERT_SIZE (AttachPoint, 2);

struct AttachList
{
  inline bool get_attach_points (hb_codepoint_t glyph_id,
				 unsigned int *point_count /* IN/OUT */,
				 unsigned int *point_array /* OUT */) const
  {
    unsigned int index = (this+coverage) (glyph_id);
    if (index == NOT_COVERED)
    {
      *point_count = 0;
      return false;
    }
    const AttachPoint &points = this+attachPoint[index];

    unsigned int count = MIN (points.len, *point_count);
    for (unsigned int i = 0; i < count; i++)
      point_array[i] = points[i];

    *point_count = points.len;

    return true;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_THIS2 (coverage, attachPoint);
  }

  private:
  OffsetTo<Coverage>
		coverage;		/* Offset to Coverage table -- from
					 * beginning of AttachList table */
  OffsetArrayOf<AttachPoint>
		attachPoint;		/* Array of AttachPoint tables
					 * in Coverage Index order */
};
ASSERT_SIZE (AttachList, 4);

/*
 * Ligature Caret Table
 */

struct CaretValueFormat1
{
  friend struct CaretValue;

  private:
  inline int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id) const
  {
    /* TODO vertical */
    return context->font->x_scale * coordinate / 0x10000;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_SELF ();
  }

  private:
  USHORT	caretValueFormat;	/* Format identifier--format = 1 */
  SHORT		coordinate;		/* X or Y value, in design units */
};
ASSERT_SIZE (CaretValueFormat1, 4);

struct CaretValueFormat2
{
  friend struct CaretValue;

  private:
  inline int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id) const
  {
    return /* TODO contour point */ 0;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_SELF ();
  }

  private:
  USHORT	caretValueFormat;	/* Format identifier--format = 2 */
  USHORT	caretValuePoint;	/* Contour point index on glyph */
};
ASSERT_SIZE (CaretValueFormat2, 4);

struct CaretValueFormat3
{
  friend struct CaretValue;

  inline int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id) const
  {
    /* TODO vertical */
    return context->font->x_scale * coordinate / 0x10000 +
	   ((this+deviceTable).get_delta (context->font->x_ppem) << 6);
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_SELF () && SANITIZE_THIS (deviceTable);
  }

  private:
  USHORT	caretValueFormat;	/* Format identifier--format = 3 */
  SHORT		coordinate;		/* X or Y value, in design units */
  OffsetTo<Device>
		deviceTable;		/* Offset to Device table for X or Y
					 * value--from beginning of CaretValue
					 * table */
};
ASSERT_SIZE (CaretValueFormat3, 6);

struct CaretValue
{
  int get_caret_value (hb_ot_layout_context_t *context, hb_codepoint_t glyph_id) const
  {
    switch (u.format) {
    case 1: return u.format1->get_caret_value (context, glyph_id);
    case 2: return u.format2->get_caret_value (context, glyph_id);
    case 3: return u.format3->get_caret_value (context, glyph_id);
    default:return 0;
    }
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    if (!SANITIZE (u.format)) return false;
    switch (u.format) {
    case 1: return u.format1->sanitize (SANITIZE_ARG);
    case 2: return u.format2->sanitize (SANITIZE_ARG);
    case 3: return u.format3->sanitize (SANITIZE_ARG);
    default:return true;
    }
  }

  private:
  union {
  USHORT		format;		/* Format identifier */
  CaretValueFormat1	format1[];
  CaretValueFormat2	format2[];
  CaretValueFormat3	format3[];
  } u;
};
ASSERT_SIZE (CaretValue, 2);

struct LigGlyph
{
  inline void get_lig_carets (hb_ot_layout_context_t *context,
			      hb_codepoint_t glyph_id,
			      unsigned int *caret_count /* IN/OUT */,
			      int *caret_array /* OUT */) const
  {

    unsigned int count = MIN (carets.len, *caret_count);
    for (unsigned int i = 0; i < count; i++)
      caret_array[i] = (this+carets[i]).get_caret_value (context, glyph_id);

    *caret_count = carets.len;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE (carets);
  }

  private:
  OffsetArrayOf<CaretValue>
		carets;			/* Offset rrray of CaretValue tables
					 * --from beginning of LigGlyph table
					 * --in increasing coordinate order */
};
ASSERT_SIZE (LigGlyph, 2);

struct LigCaretList
{
  inline bool get_lig_carets (hb_ot_layout_context_t *context,
			      hb_codepoint_t glyph_id,
			      unsigned int *caret_count /* IN/OUT */,
			      int *caret_array /* OUT */) const
  {
    unsigned int index = (this+coverage) (glyph_id);
    if (index == NOT_COVERED)
    {
      *caret_count = 0;
      return false;
    }
    const LigGlyph &lig_glyph = this+ligGlyph[index];
    lig_glyph.get_lig_carets (context, glyph_id, caret_count, caret_array);
    return true;
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_THIS2 (coverage, ligGlyph);
  }

  private:
  OffsetTo<Coverage>
		coverage;		/* Offset to Coverage table--from
					 * beginning of LigCaretList table */
  OffsetArrayOf<LigGlyph>
		ligGlyph;		/* Array of LigGlyph tables
					 * in Coverage Index order */
};
ASSERT_SIZE (LigCaretList, 4);

struct MarkGlyphSetsFormat1
{
  inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
  { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    return SANITIZE_THIS (coverage);
  }

  private:
  USHORT	format;			/* Format identifier--format = 1 */
  LongOffsetArrayOf<Coverage>
		coverage;		/* Array of long offsets to mark set
					 * coverage tables */
};
ASSERT_SIZE (MarkGlyphSetsFormat1, 4);

struct MarkGlyphSets
{
  inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
  {
    switch (u.format) {
    case 1: return u.format1->covers (set_index, glyph_id);
    default:return false;
    }
  }

  inline bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    if (!SANITIZE (u.format)) return false;
    switch (u.format) {
    case 1: return u.format1->sanitize (SANITIZE_ARG);
    default:return true;
    }
  }

  private:
  union {
  USHORT		format;		/* Format identifier */
  MarkGlyphSetsFormat1	format1[];
  } u;
};
ASSERT_SIZE (MarkGlyphSets, 2);

/*
 * GDEF
 */

struct GDEF
{
  static const hb_tag_t Tag	= HB_OT_TAG_GDEF;

  enum {
    UnclassifiedGlyph	= 0,
    BaseGlyph		= 1,
    LigatureGlyph	= 2,
    MarkGlyph		= 3,
    ComponentGlyph	= 4,
  };

  STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (GDEF, 1, 1);

  inline bool has_glyph_classes () const { return glyphClassDef != 0; }
  inline hb_ot_layout_class_t get_glyph_class (hb_codepoint_t glyph) const
  { return (this+glyphClassDef).get_class (glyph); }

  inline bool has_mark_attachment_types () const { return markAttachClassDef != 0; }
  inline hb_ot_layout_class_t get_mark_attachment_type (hb_codepoint_t glyph) const
  { return (this+markAttachClassDef).get_class (glyph); }

  inline bool has_attach_points () const { return attachList != 0; }
  inline bool get_attach_points (hb_codepoint_t glyph_id,
				 unsigned int *point_count /* IN/OUT */,
				 unsigned int *point_array /* OUT */) const
  { return (this+attachList).get_attach_points (glyph_id, point_count, point_array); }

  inline bool has_lig_carets () const { return ligCaretList != 0; }
  inline bool get_lig_carets (hb_ot_layout_context_t *context,
			      hb_codepoint_t glyph_id,
			      unsigned int *caret_count /* IN/OUT */,
			      int *caret_array /* OUT */) const
  { return (this+ligCaretList).get_lig_carets (context, glyph_id, caret_count, caret_array); }

  inline bool has_mark_sets () const { return version >= 0x00010002 && markGlyphSetsDef[0] != 0; }
  inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
  { return version >= 0x00010002 && (this+markGlyphSetsDef[0]).covers (set_index, glyph_id); }

  bool sanitize (SANITIZE_ARG_DEF) {
    SANITIZE_DEBUG ();
    if (!SANITIZE (version)) return false;
    if (version.major != 1) return true;
    return SANITIZE_THIS2 (glyphClassDef, attachList) &&
	   SANITIZE_THIS2 (ligCaretList, markAttachClassDef) &&
	   (version < 0x00010002 || SANITIZE_THIS (markGlyphSetsDef[0]));
  }

  private:
  FixedVersion	version;		/* Version of the GDEF table--currently
					 * 0x00010002 */
  OffsetTo<ClassDef>
		glyphClassDef;		/* Offset to class definition table
					 * for glyph type--from beginning of
					 * GDEF header (may be Null) */
  OffsetTo<AttachList>
		attachList;		/* Offset to list of glyphs with
					 * attachment points--from beginning
					 * of GDEF header (may be Null) */
  OffsetTo<LigCaretList>
		ligCaretList;		/* Offset to list of positioning points
					 * for ligature carets--from beginning
					 * of GDEF header (may be Null) */
  OffsetTo<ClassDef>
		markAttachClassDef;	/* Offset to class definition table for
					 * mark attachment type--from beginning
					 * of GDEF header (may be Null) */
  OffsetTo<MarkGlyphSets>
		markGlyphSetsDef[0];	/* Offset to the table of mark set
					 * definitions--from beginning of GDEF
					 * header (may be NULL).  Introduced
					 * in version 00010002. */
};
ASSERT_SIZE (GDEF, 12);

#endif /* HB_OT_LAYOUT_GDEF_PRIVATE_HH */
<|endoftext|>


<commit_before>#include "clay.hpp"
#include "libclaynames.hpp"

ExprPtr desugarCharLiteral(char c) {
    ExprPtr nameRef = prelude_expr_Char();
    CallPtr call = new Call(nameRef, new ExprList());
    ostringstream out;
    out << (int)c;
    call->args->add(new IntLiteral(out.str(), "i8"));
    return call.ptr();
}

ExprPtr desugarFieldRef(FieldRefPtr x) {
    ExprListPtr args = new ExprList(x->expr);
    args->add(new ObjectExpr(x->name.ptr()));
    return new Call(prelude_expr_fieldRef(), args);
}

ExprPtr desugarStaticIndexing(StaticIndexingPtr x) {
    ExprListPtr args = new ExprList(x->expr);
    ValueHolderPtr vh = sizeTToValueHolder(x->index);
    args->add(new StaticExpr(new ObjectExpr(vh.ptr())));
    return new Call(prelude_expr_staticIndex(), args);
}

ExprPtr desugarUnaryOp(UnaryOpPtr x) {
    ExprPtr callable;
    switch (x->op) {
    case DEREFERENCE :
        callable = prelude_expr_dereference();
        break;
    case ADDRESS_OF :
        callable = primitive_expr_addressOf();
        break;
    case PLUS :
        callable = prelude_expr_plus();
        break;
    case MINUS :
        callable = prelude_expr_minus();
        break;
    case NOT :
        callable = primitive_expr_boolNot();
        break;
    default :
        assert(false);
    }
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->expr);
    return call.ptr();
}

ExprPtr desugarBinaryOp(BinaryOpPtr x) {
    ExprPtr callable;
    switch (x->op) {
    case ADD :
        callable = prelude_expr_add();
        break;
    case SUBTRACT :
        callable = prelude_expr_subtract();
        break;
    case MULTIPLY :
        callable = prelude_expr_multiply();
        break;
    case DIVIDE :
        callable = prelude_expr_divide();
        break;
    case REMAINDER :
        callable = prelude_expr_remainder();
        break;
    case EQUALS :
        callable = prelude_expr_equalsP();
        break;
    case NOT_EQUALS :
        callable = prelude_expr_notEqualsP();
        break;
    case LESSER :
        callable = prelude_expr_lesserP();
        break;
    case LESSER_EQUALS :
        callable = prelude_expr_lesserEqualsP();
        break;
    case GREATER :
        callable = prelude_expr_greaterP();
        break;
    case GREATER_EQUALS :
        callable = prelude_expr_greaterEqualsP();
        break;
    default :
        assert(false);
    }
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->expr1);
    call->args->add(x->expr2);
    return call.ptr();
}

ExprPtr desugarIfExpr(IfExprPtr x) {
    ExprPtr callable = prelude_expr_ifExpression();
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->condition);
    call->args->add(x->thenPart);
    call->args->add(x->elsePart);
    return call.ptr();
}

ExprPtr desugarNew(NewPtr x) {
    ExprPtr callable = prelude_expr_allocateShared();
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->expr);
    return call.ptr();
}

ExprPtr desugarStaticExpr(StaticExprPtr x) {
    ExprPtr callable = prelude_expr_wrapStatic();
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->expr);
    return call.ptr();
}

ExprPtr updateOperatorExpr(int op) {
    switch (op) {
    case UPDATE_ADD : return prelude_expr_addAssign();
    case UPDATE_SUBTRACT : return prelude_expr_subtractAssign();
    case UPDATE_MULTIPLY : return prelude_expr_multiplyAssign();
    case UPDATE_DIVIDE : return prelude_expr_divideAssign();
    case UPDATE_REMAINDER : return prelude_expr_remainderAssign();
    default :
        assert(false);
        return NULL;
    }
}

static vector<IdentifierPtr> identV(IdentifierPtr x) {
    vector<IdentifierPtr> v;
    v.push_back(x);
    return v;
}

StatementPtr desugarForStatement(ForPtr x) {
    IdentifierPtr exprVar = new Identifier("%expr");
    IdentifierPtr iterVar = new Identifier("%iter");

    BlockPtr block = new Block();
    vector<StatementPtr> &bs = block->statements;
    bs.push_back(new Binding(REF, identV(exprVar), new ExprList(x->expr)));

    CallPtr iteratorCall = new Call(prelude_expr_iterator(), new ExprList());
    iteratorCall->args->add(new NameRef(exprVar));
    bs.push_back(new Binding(VAR,
                             identV(iterVar),
                             new ExprList(iteratorCall.ptr())));

    CallPtr hasNextCall = new Call(prelude_expr_hasNextP(), new ExprList());
    hasNextCall->args->add(new NameRef(iterVar));
    CallPtr nextCall = new Call(prelude_expr_next(), new ExprList());
    nextCall->args->add(new NameRef(iterVar));
    ExprPtr unpackNext = new Unpack(nextCall.ptr());
    BlockPtr whileBody = new Block();
    vector<StatementPtr> &ws = whileBody->statements;
    ws.push_back(new Binding(REF, x->variables, new ExprList(unpackNext)));
    ws.push_back(x->body);

    bs.push_back(new While(hasNextCall.ptr(), whileBody.ptr()));
    return block.ptr();
}

StatementPtr desugarCatchBlocks(const vector<CatchPtr> &catchBlocks) {
    bool lastWasAny = false;
    IfPtr lastIf;
    StatementPtr result;
    for (unsigned i = 0; i < catchBlocks.size(); ++i) {
        CatchPtr x = catchBlocks[i];
        if (lastWasAny)
            error(x, "unreachable catch block");
        if (x->exceptionType.ptr()) {
            ExprListPtr typeArg = new ExprList(x->exceptionType);
            CallPtr cond = new Call(prelude_expr_exceptionIsP(), typeArg);
            cond->location = x->exceptionType->location;

            BlockPtr block = new Block();
            CallPtr getter = new Call(prelude_expr_exceptionAs(), typeArg);
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            vector<IdentifierPtr>(1, x->exceptionVar),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;

            block->statements.push_back(binding.ptr());
            block->statements.push_back(x->body);

            IfPtr ifStatement = new If(cond.ptr(), block.ptr());
            ifStatement->location = x->location;
            if (!result)
                result = ifStatement.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = ifStatement.ptr();
            lastIf = ifStatement;
        }
        else {
            BlockPtr block = new Block();
            block->location = x->location;
            CallPtr getter = new Call(prelude_expr_exceptionAsAny(),
                                      new ExprList());
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            vector<IdentifierPtr>(1, x->exceptionVar),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;
            block->statements.push_back(binding.ptr());
            block->statements.push_back(x->body);

            if (!result)
                result = block.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = block.ptr();

            lastWasAny = true;
            lastIf = NULL;
        }
    }
    assert(result.ptr());
    if (!lastWasAny) {
        assert(lastIf.ptr());
        BlockPtr block = new Block();
        CallPtr continueException = new Call(prelude_expr_continueException(),
                                             new ExprList());
        StatementPtr stmt = new ExprStatement(continueException.ptr());
        block->statements.push_back(stmt);
//         block->statements.push_back(new Unreachable());
        lastIf->elsePart = block.ptr();
    }
    return result;
}

StatementPtr desugarSwitchStatement(SwitchPtr x) {
    BlockPtr block = new Block();
    block->location = x->location;

    // %thing is the value being switched on
    IdentifierPtr thing = new Identifier("%thing");
    thing->location = x->expr->location;
    NameRefPtr thingRef = new NameRef(thing);
    thingRef->location = x->expr->location;

    // initialize %thing
    {
        BindingPtr b = new Binding(REF, identV(thing), new ExprList(x->expr));
        block->statements.push_back(b.ptr());
    }

    StatementPtr root;
    StatementPtr *nextPtr = &root;

    // dispatch logic
    for (unsigned i = 0; i < x->caseBlocks.size(); ++i) {
        CaseBlockPtr y = x->caseBlocks[i];

        ExprPtr condition;
        for (unsigned j = 0; j < y->caseLabels->size(); ++j) {
            ExprPtr caseValue = y->caseLabels->exprs[j];
            ExprPtr compare = new BinaryOp(EQUALS, thingRef.ptr(), caseValue);
            compare->location = caseValue->location;
            if (!condition) {
                condition = compare;
            }
            else {
                condition = new Or(condition, compare);
                condition->location = y->location;
            }
        }
        assert(condition.ptr());

        IfPtr ifStmt = new If(condition, y->body);
        ifStmt->location = y->location;
        *nextPtr = ifStmt.ptr();
        nextPtr = &(ifStmt->elsePart);
    }

    if (x->defaultCase.ptr())
        *nextPtr = x->defaultCase;
    else
        *nextPtr = new Break();

    block->statements.push_back(root);

    return block.ptr();
}
<commit_msg>oops. uncomment the critical line.<commit_after>#include "clay.hpp"
#include "libclaynames.hpp"

ExprPtr desugarCharLiteral(char c) {
    ExprPtr nameRef = prelude_expr_Char();
    CallPtr call = new Call(nameRef, new ExprList());
    ostringstream out;
    out << (int)c;
    call->args->add(new IntLiteral(out.str(), "i8"));
    return call.ptr();
}

ExprPtr desugarFieldRef(FieldRefPtr x) {
    ExprListPtr args = new ExprList(x->expr);
    args->add(new ObjectExpr(x->name.ptr()));
    return new Call(prelude_expr_fieldRef(), args);
}

ExprPtr desugarStaticIndexing(StaticIndexingPtr x) {
    ExprListPtr args = new ExprList(x->expr);
    ValueHolderPtr vh = sizeTToValueHolder(x->index);
    args->add(new StaticExpr(new ObjectExpr(vh.ptr())));
    return new Call(prelude_expr_staticIndex(), args);
}

ExprPtr desugarUnaryOp(UnaryOpPtr x) {
    ExprPtr callable;
    switch (x->op) {
    case DEREFERENCE :
        callable = prelude_expr_dereference();
        break;
    case ADDRESS_OF :
        callable = primitive_expr_addressOf();
        break;
    case PLUS :
        callable = prelude_expr_plus();
        break;
    case MINUS :
        callable = prelude_expr_minus();
        break;
    case NOT :
        callable = primitive_expr_boolNot();
        break;
    default :
        assert(false);
    }
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->expr);
    return call.ptr();
}

ExprPtr desugarBinaryOp(BinaryOpPtr x) {
    ExprPtr callable;
    switch (x->op) {
    case ADD :
        callable = prelude_expr_add();
        break;
    case SUBTRACT :
        callable = prelude_expr_subtract();
        break;
    case MULTIPLY :
        callable = prelude_expr_multiply();
        break;
    case DIVIDE :
        callable = prelude_expr_divide();
        break;
    case REMAINDER :
        callable = prelude_expr_remainder();
        break;
    case EQUALS :
        callable = prelude_expr_equalsP();
        break;
    case NOT_EQUALS :
        callable = prelude_expr_notEqualsP();
        break;
    case LESSER :
        callable = prelude_expr_lesserP();
        break;
    case LESSER_EQUALS :
        callable = prelude_expr_lesserEqualsP();
        break;
    case GREATER :
        callable = prelude_expr_greaterP();
        break;
    case GREATER_EQUALS :
        callable = prelude_expr_greaterEqualsP();
        break;
    default :
        assert(false);
    }
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->expr1);
    call->args->add(x->expr2);
    return call.ptr();
}

ExprPtr desugarIfExpr(IfExprPtr x) {
    ExprPtr callable = prelude_expr_ifExpression();
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->condition);
    call->args->add(x->thenPart);
    call->args->add(x->elsePart);
    return call.ptr();
}

ExprPtr desugarNew(NewPtr x) {
    ExprPtr callable = prelude_expr_allocateShared();
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->expr);
    return call.ptr();
}

ExprPtr desugarStaticExpr(StaticExprPtr x) {
    ExprPtr callable = prelude_expr_wrapStatic();
    CallPtr call = new Call(callable, new ExprList());
    call->args->add(x->expr);
    return call.ptr();
}

ExprPtr updateOperatorExpr(int op) {
    switch (op) {
    case UPDATE_ADD : return prelude_expr_addAssign();
    case UPDATE_SUBTRACT : return prelude_expr_subtractAssign();
    case UPDATE_MULTIPLY : return prelude_expr_multiplyAssign();
    case UPDATE_DIVIDE : return prelude_expr_divideAssign();
    case UPDATE_REMAINDER : return prelude_expr_remainderAssign();
    default :
        assert(false);
        return NULL;
    }
}

static vector<IdentifierPtr> identV(IdentifierPtr x) {
    vector<IdentifierPtr> v;
    v.push_back(x);
    return v;
}

StatementPtr desugarForStatement(ForPtr x) {
    IdentifierPtr exprVar = new Identifier("%expr");
    IdentifierPtr iterVar = new Identifier("%iter");

    BlockPtr block = new Block();
    vector<StatementPtr> &bs = block->statements;
    bs.push_back(new Binding(REF, identV(exprVar), new ExprList(x->expr)));

    CallPtr iteratorCall = new Call(prelude_expr_iterator(), new ExprList());
    iteratorCall->args->add(new NameRef(exprVar));
    bs.push_back(new Binding(VAR,
                             identV(iterVar),
                             new ExprList(iteratorCall.ptr())));

    CallPtr hasNextCall = new Call(prelude_expr_hasNextP(), new ExprList());
    hasNextCall->args->add(new NameRef(iterVar));
    CallPtr nextCall = new Call(prelude_expr_next(), new ExprList());
    nextCall->args->add(new NameRef(iterVar));
    ExprPtr unpackNext = new Unpack(nextCall.ptr());
    BlockPtr whileBody = new Block();
    vector<StatementPtr> &ws = whileBody->statements;
    ws.push_back(new Binding(REF, x->variables, new ExprList(unpackNext)));
    ws.push_back(x->body);

    bs.push_back(new While(hasNextCall.ptr(), whileBody.ptr()));
    return block.ptr();
}

StatementPtr desugarCatchBlocks(const vector<CatchPtr> &catchBlocks) {
    bool lastWasAny = false;
    IfPtr lastIf;
    StatementPtr result;
    for (unsigned i = 0; i < catchBlocks.size(); ++i) {
        CatchPtr x = catchBlocks[i];
        if (lastWasAny)
            error(x, "unreachable catch block");
        if (x->exceptionType.ptr()) {
            ExprListPtr typeArg = new ExprList(x->exceptionType);
            CallPtr cond = new Call(prelude_expr_exceptionIsP(), typeArg);
            cond->location = x->exceptionType->location;

            BlockPtr block = new Block();
            CallPtr getter = new Call(prelude_expr_exceptionAs(), typeArg);
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            vector<IdentifierPtr>(1, x->exceptionVar),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;

            block->statements.push_back(binding.ptr());
            block->statements.push_back(x->body);

            IfPtr ifStatement = new If(cond.ptr(), block.ptr());
            ifStatement->location = x->location;
            if (!result)
                result = ifStatement.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = ifStatement.ptr();
            lastIf = ifStatement;
        }
        else {
            BlockPtr block = new Block();
            block->location = x->location;
            CallPtr getter = new Call(prelude_expr_exceptionAsAny(),
                                      new ExprList());
            getter->location = x->exceptionVar->location;
            BindingPtr binding =
                new Binding(VAR,
                            vector<IdentifierPtr>(1, x->exceptionVar),
                            new ExprList(getter.ptr()));
            binding->location = x->exceptionVar->location;
            block->statements.push_back(binding.ptr());
            block->statements.push_back(x->body);

            if (!result)
                result = block.ptr();
            if (lastIf.ptr())
                lastIf->elsePart = block.ptr();

            lastWasAny = true;
            lastIf = NULL;
        }
    }
    assert(result.ptr());
    if (!lastWasAny) {
        assert(lastIf.ptr());
        BlockPtr block = new Block();
        CallPtr continueException = new Call(prelude_expr_continueException(),
                                             new ExprList());
        StatementPtr stmt = new ExprStatement(continueException.ptr());
        block->statements.push_back(stmt);
        block->statements.push_back(new Unreachable());
        lastIf->elsePart = block.ptr();
    }
    return result;
}

StatementPtr desugarSwitchStatement(SwitchPtr x) {
    BlockPtr block = new Block();
    block->location = x->location;

    // %thing is the value being switched on
    IdentifierPtr thing = new Identifier("%thing");
    thing->location = x->expr->location;
    NameRefPtr thingRef = new NameRef(thing);
    thingRef->location = x->expr->location;

    // initialize %thing
    {
        BindingPtr b = new Binding(REF, identV(thing), new ExprList(x->expr));
        block->statements.push_back(b.ptr());
    }

    StatementPtr root;
    StatementPtr *nextPtr = &root;

    // dispatch logic
    for (unsigned i = 0; i < x->caseBlocks.size(); ++i) {
        CaseBlockPtr y = x->caseBlocks[i];

        ExprPtr condition;
        for (unsigned j = 0; j < y->caseLabels->size(); ++j) {
            ExprPtr caseValue = y->caseLabels->exprs[j];
            ExprPtr compare = new BinaryOp(EQUALS, thingRef.ptr(), caseValue);
            compare->location = caseValue->location;
            if (!condition) {
                condition = compare;
            }
            else {
                condition = new Or(condition, compare);
                condition->location = y->location;
            }
        }
        assert(condition.ptr());

        IfPtr ifStmt = new If(condition, y->body);
        ifStmt->location = y->location;
        *nextPtr = ifStmt.ptr();
        nextPtr = &(ifStmt->elsePart);
    }

    if (x->defaultCase.ptr())
        *nextPtr = x->defaultCase;
    else
        *nextPtr = new Break();

    block->statements.push_back(root);

    return block.ptr();
}
<|endoftext|>