<commit_before>//
//  AmpleGPS.cpp
//
//
//  Created by dial on 4/16/16.
//
//

#include <AmpleGPS.h>

void AmpleGPS::begin(){

    atitudeDegrees = longitudeDegrees = altitude = //geoidheight
    speedOnGround = bearing = HDOP =0.0;

    hour = minute = seconds = year = month = day =
    fixquality = satellitesCount = 0; // uint8_t

    fix = false; // boolean
    milliseconds = 0; // uint16_t

    bufferIndex = 0;

    unparsedSentence = callBack = NULL;

    mode = GPS_COMPLETE_DATA;       //default mode

}

boolean AmpleGPS::parseSentence(char *nmeaSentence) {
    // do checksum check

     char *p = nmeaSentence;
//    Serial.print("\n   ");
//    Serial.println(nmeaSentence);

    if (strstr_P(nmeaSentence, PSTR(GPGSV_NMEA))) {
//        Serial.println("$GPGSV: ");

        unsigned int totalMessageNumber = 0;
        unsigned int actualMessageNumber = 0;
        GSV_Satellite *aSatellite = satellitesBuffer;
        //        1    = Total number of messages of this type in this cycle
        //        2    = Message number
        //        3    = Total number of SVs in view
        //

        p += 3;
        //        Serial.print(*p);

        totalMessageNumber = strtol(p+1,&p,10);

        actualMessageNumber = strtol(p+1,&p,10);

        satellitesCount = strtol(p+1,&p,10);

        if(actualMessageNumber && totalMessageNumber && satellitesCount)// basic check
        {
            aSatellite = satellitesBuffer + (actualMessageNumber - 1)*4;

            int maxCount = 4;       // max 4 sats in sentence

            if(1==actualMessageNumber)// if this is the first sentence in this serie, invalidate all satellites
            {// the assumption is, that number 1 is the first in line here
                gsv_isDirty = true;
            }
            else if (totalMessageNumber == actualMessageNumber)
            {
                gsv_isDirty = false;
                maxCount = satellitesCount - (actualMessageNumber - 1)*4;

                GSV_Satellite *aSat = satellitesBuffer + satellitesCount;

                for(int i = 0; i<(MAXSATELLITES - satellitesCount);i++)// fill up the remaining slots with zeroes
                {
                    aSat -> number = aSat->elevation = aSat -> azimuth = aSat -> strength = 0;
                    aSat ++;

                }
                performCallBack(GPS_UPDATE_SATS);
            }

            // now parse all satellites
            for (int i=0; i < maxCount; i++)
            {
                p = parseSingleSatellite(p, aSatellite);
                aSatellite ++;
            }

        }
        return true;
    }

    // look for a few common sentences
    else if (strstr_P(nmeaSentence, PSTR(GPGGA_NMEA))) {// gga is broken on certain uBlox devices,

        //        Serial.println("$GPGGA");
        // get time
        p += 3;
        p=parseTime(p);

        p = parsePairOfCoords(p);

        if(NULL == p)
            return false;

        fixquality = strtol(p+1,&p,10);

        satellitesCount = strtol(p+1,&p,10);

        HDOP = strtod(p+1, &p);// not needed, only to parse

        altitude = strtod (p+1, &p);

//        skip the rest
//        p = strchr(p, ',')+1;
//        p = strchr(p, ',')+1;
//        if (',' != *p)
//        {// when will we ever use it
//            geoidheight = strtod (p, &p);
////            Serial.print("$geoidheight: "); Serial.println(geoidheight);
//
//        }

        return true;
    }

    else if (strstr_P(nmeaSentence, PSTR(GPRMC_NMEA))) {
//                Serial.println("$GPRMC");
        p += 3;
        p=parseTime(p);

        p++;

        if (*p == 'A')
            fix = true;
        else if (*p == 'V')
            fix = false;
        else
            return false;

        p++;// p hasn't changed yet.

        // parse out coords
        p = parsePairOfCoords(p);

        if(NULL == p)
            return false;

        // speedOnGround
        speedOnGround = strtod(p+1, &p);
//        Serial.print("speedOnGround: "); Serial.println(speedOnGround);

        bearing = strtod(p+1, &p);
//        Serial.print("bearing: "); Serial.println(bearing);

        uint32_t fulldate = strtol(p+1, &p, 10);
        day = fulldate / 10000;
        month = (fulldate % 10000) / 100;
        year = (fulldate % 100);

//        Serial.println(p+1);

        performCallBack(GPS_COMPLETE_DATA);

        return true;
    }

    else if (strstr_P(nmeaSentence, PSTR(GPGLL_NMEA))) {

        //        Serial.println("$GPGLL");
        // get coords
        p += 3;
        p = parsePairOfCoords(p);

        if(NULL == p)
            return false;

        p=parseTime(p);

        p++;
        // Serial.println(p);
        if (*p == 'A')
            fix = true;
        else if (*p == 'V')
            fix = false;
        else
            return false;

        return true;
    }
    return false;
}

char AmpleGPS::readSentence(char c) {

    if (mode & GPS_PAUSED) return c;

    if (c == '\n') {        // sentence is at end
        if (strstr_P(readBuffer, PSTR("$GP")))
        {
//            Serial.println("valid nmeaPrefix");

            uint32_t diff = (uint32_t)((char *)(checksumString - readBuffer));
            char *nmeaCheckString = readBuffer + diff; // real pointer to '*' in the copy

            uint16_t checkSum = strtol((nmeaCheckString+1),NULL,16); // read the checksum from the string
            if(checkSum == nmeaCheckSum)                        // do check
            {
                uint8_t length = strlen(readBuffer) - strlen(nmeaCheckString) - 3;// 3 is the prefix

                strncpy(nmeaSentence, (const char *)(readBuffer+3), length);     // copy the string; double buffer
                *(nmeaSentence + length) = '\0';

                unparsedSentence = nmeaSentence;                    // valid, but not parsed yet.

//                            Serial.println("valid checksum");
            }
//            else {
//                Serial.print(F("--: "));
//                Serial.print(checkSum);
//                Serial.print(F(", "));
//                Serial.println(nmeaCheckSum);
//                Serial.print(F(", "));
//                Serial.print(checksumString);
//
//                Serial.println((const char *)readBuffer);
//
//            }
            checksumString = NULL;

        }
//        else
//        {
//            Serial.println(F("no valid nmeaPrefix"));
//            Serial.print(nmeaPrefix);
//            Serial.println(nmeaSentence);
//
//
//        }
        if(GPS_DO_NOT_PARSE & mode)
            performCallBack(GPS_DO_NOT_PARSE);
        else
        {   //             Serial.println("will parse");

            if(true == parseSentence(nmeaSentence))
            {
                unparsedSentence = NULL;

//                Serial.println("did parse");

            }
            else
            {
                if(*nmeaSentence == '$')
                {
                    performCallBack(GPS_VIEW_UNPARSED);
                    unparsedSentence = NULL;
                }
            }
        }

    }
    else if (c == '$')
    {
        bufferIndex = 0;
        checksumString = NULL;
        nmeaCheckSum = 0;

    }
    else if (c == '*')          // set the pointer to the checksumString
    {
        checksumString = readBuffer + bufferIndex;

    }

    if(NULL == checksumString)
    {
        if(bufferIndex)     // omit the first sign ('$')
        {
            nmeaCheckSum ^= c;
        }
    }

    *(readBuffer + bufferIndex)=c;
    bufferIndex++;
    return c;
}

char *AmpleGPS::parseTime(char *p)
{
    float timed = strtod (p+1, &p);
    uint32_t time = (uint32_t)timed;
    hour = time / 10000;
    minute = (time % 10000) / 100;
    seconds = (time % 100);
    milliseconds = fmod(timed, 1.0) * 1000;

    performCallBack(GPS_NEW_TIME);

    return p;
}

char *AmpleGPS::parseSingleSatellite(char *p, GSV_Satellite *aSatellite){

    aSatellite -> number = strtol(p+1,&p,10);

    aSatellite -> elevation = strtol(p+1,&p,10);
    aSatellite -> azimuth = strtol(p+1,&p,10);

    aSatellite -> strength = strtol(p+1,&p,10);
    return p;
}

char *AmpleGPS::parsePairOfCoords (char *p){

    p = parseSingleCoord(p,&latitudeDegrees);
    //    Serial.println(*p);

    if(p)
        p = parseSingleCoord(p,&longitudeDegrees);
    //    if(p)     // debug
    //    {
    //        Serial.print("lat: ");
    //        Serial.print(latitudeDegrees,6);
    //        Serial.print("; lon: ");
    //        Serial.println(longitudeDegrees,6);
    //    }
    //    else
    //        Serial.println("something wrong");

    performCallBack(GPS_NEW_COORDS);
    return p;
}

char *AmpleGPS::parseSingleCoord(char *p, float *degreeValue){

    double val = strtod (p+1, &p)/100.0;
    int degrees = floor(val);
    val = (val - degrees)/0.6;
    *degreeValue = val + degrees;

    p++;
    if (*p == 'S' || *p == 'W')
    {
        *degreeValue *= -1.0;
    }
    else
        if(!(*p == 'N' || *p == 'E'))
        {
            p = NULL;
        }
    if(p)
        p++;// we know that for sure, single char + '\0'

    return p;
}

int AmpleGPS::performCallBack(uint8_t suggestedMode)
{

    int retVal = 0;
    if((GPS_PAUSED & suggestedMode) & mode)       // exclusive, do nothing
        return 0;

    if((GPS_DO_NOT_PARSE & suggestedMode)& mode)     // exclusive, only nmeaString can be requested
        retVal = callBack(GPS_DO_NOT_PARSE);
    else
        if((GPS_COMPLETE_DATA & suggestedMode) & mode)    // exclusive, all data can be requested, but no other calls are perfromed
            retVal= callBack(GPS_COMPLETE_DATA);

        else if(suggestedMode & mode) // GPS_NEW_COORDS GPS_NEW_TIME GPS_VIEW_UNPARSED GPS_UPDATE_SATS
            retVal =callBack(suggestedMode);
    return retVal;
}

float AmpleGPS::getDistanceInKm( float targetLat, float targetLon)
{
    //----------------------------------------

    //convert decimal degree into radian
    float latRad = latitudeDegrees * half_piRad;
    float lonRad = longitudeDegrees * half_piRad;
    float tlatRad = targetLat * half_piRad;
    float tlonRad = targetLon * half_piRad;

    //Calculate the distance in KM
    float latSin = sin((latRad - tlatRad)*0.5);
    float lonSin = sin((lonRad - tlonRad)*0.5);
    float distance = doubleEarth * asin(sqrt((latSin*latSin) + cos(latRad) * cos(tlatRad) * (lonSin * lonSin)));

    return distance;

    //convert to miles
//    distance.miles = distance.km * 0.621371192;
//    distance.feet = distance.miles *5280;
//
// --------------------------------

}

/*
 GPS_PAUSED = 0,
 GPS_DO_NOT_PARSE = (1 << 0),
 GPS_NEW_COORDS = (1 << 1),
 GPS_NEW_TIME = (1 << 2),
 GPS_UPDATE_SATS = (1 << 3),
 GPS_RESERVED = (1 << 4),
 GPS_COMPLETE_DATA = (1 << 5),
 GPS_VIEW_UNPARSED = (1 << 6),
*/

/*
 $GPVTG,,T,,M,0.052,N,0.097,K,A*2A
 +$GPGGA,061919.00,5040.58619,66359,E,1,07,1.93,68.3,M,46.8,M,,*62
 $GPGSA,A,3,16,30,23,03,07,09,06,,,,,,2.80,1.93,2.03*0C
 -$GPGSV,3,1,11,02,41,290,,03,11,119,34,05,12,297,,06,47,221,32*75
 -$GPGSV,3,2,11,07,46,168,30,09,77,061,30,16,16,062,27,23,44,069,40*77
 $GPGSV,3,3,11,26,11,034,,29,06,341,,30,20,187,30*4D
 $GPGLL,5040.58619,N,00709.66359,E,061919.00,A,A*6C
 +$GPRMC,061920.00,A,5040.58639,N,00709.66356,E,0.876,247.96,130416,,,A*6A

 */

<commit_msg>Added files via upload<commit_after>//
//  AmpleGPS.cpp
//
//
//  Created by dial on 4/16/16.
//
//

#include <AmpleGPS.h>

void AmpleGPS::begin(){

    atitudeDegrees = longitudeDegrees = altitude = //geoidheight
    speedOnGround = bearing = HDOP =0.0;

    hour = minute = seconds = year = month = day =
    fixquality = satellitesCount = 0; // uint8_t

    fix = false; // boolean
    milliseconds = 0; // uint16_t

    bufferIndex = 0;

    unparsedSentence = callBack = NULL;

    mode = GPS_COMPLETE_DATA;       //default mode

}

boolean AmpleGPS::parseSentence(char *nmeaSentence) {
    // do checksum check

     char *p = nmeaSentence;
//    Serial.print("\n   ");
//    Serial.println(nmeaSentence);

    if (strstr_P(nmeaSentence, PSTR(GPGSV_NMEA))) {
//        Serial.println("$GPGSV: ");

        unsigned int totalMessageNumber = 0;
        unsigned int actualMessageNumber = 0;
        GSV_Satellite *aSatellite = satellitesBuffer;
        //        1    = Total number of messages of this type in this cycle
        //        2    = Message number
        //        3    = Total number of SVs in view
        //

        p += 3;
        //        Serial.print(*p);

        totalMessageNumber = strtol(p+1,&p,10);

        actualMessageNumber = strtol(p+1,&p,10);

        satellitesCount = strtol(p+1,&p,10);

        if(actualMessageNumber && totalMessageNumber && satellitesCount)// basic check
        {
            aSatellite = satellitesBuffer + (actualMessageNumber - 1)*4;

            int maxCount = 4;       // max 4 sats in sentence

            if(1==actualMessageNumber)// if this is the first sentence in this serie, invalidate all satellites
            {// the assumption is, that number 1 is the first in line here
                gsv_isDirty = true;
            }
            else if (totalMessageNumber == actualMessageNumber)
            {
                gsv_isDirty = false;
                maxCount = satellitesCount - (actualMessageNumber - 1)*4;

                GSV_Satellite *aSat = satellitesBuffer + satellitesCount;

                for(int i = 0; i<(MAXSATELLITES - satellitesCount);i++)// fill up the remaining slots with zeroes
                {
                    aSat -> number = aSat->elevation = aSat -> azimuth = aSat -> strength = 0;
                    aSat ++;

                }
                performCallBack(GPS_UPDATE_SATS);
            }

            // now parse all satellites
            for (int i=0; i < maxCount; i++)
            {
                p = parseSingleSatellite(p, aSatellite);
                aSatellite ++;
            }

        }
        return true;
    }

    // look for a few common sentences
    else if (strstr_P(nmeaSentence, PSTR(GPGGA_NMEA))) {// gga is broken on certain uBlox devices,

        //        Serial.println("$GPGGA");
        // get time
        p += 3;
        p=parseTime(p);

        p = parsePairOfCoords(p);

        if(NULL == p)
            return false;

        fixquality = strtol(p+1,&p,10);

        satellitesCount = strtol(p+1,&p,10);

        HDOP = strtod(p+1, &p);// not needed, only to parse

        altitude = strtod (p+1, &p);

//        skip the rest

        return true;
    }

    else if (strstr_P(nmeaSentence, PSTR(GPRMC_NMEA))) {
//                Serial.println("$GPRMC");
        p += 3;
        p=parseTime(p);

        p++;

        if (*p == 'A')
            fix = true;
        else if (*p == 'V')
            fix = false;
        else
            return false;

        p++;// p hasn't changed yet.

        // parse out coords
        p = parsePairOfCoords(p);

        if(NULL == p)
            return false;

        // speedOnGround
        speedOnGround = strtod(p+1, &p);
//        Serial.print("speedOnGround: "); Serial.println(speedOnGround);

        bearing = strtod(p+1, &p);
//        Serial.print("bearing: "); Serial.println(bearing);

        uint32_t fulldate = strtol(p+1, &p, 10);
        day = fulldate / 10000;
        month = (fulldate % 10000) / 100;
        year = (fulldate % 100);

//        Serial.println(p+1);

        performCallBack(GPS_COMPLETE_DATA);

        return true;
    }

    else if (strstr_P(nmeaSentence, PSTR(GPGLL_NMEA))) {

        //        Serial.println("$GPGLL");
        // get coords
        p += 3;
        p = parsePairOfCoords(p);

        if(NULL == p)
            return false;

        p=parseTime(p);

        p++;
        // Serial.println(p);
        if (*p == 'A')
            fix = true;
        else if (*p == 'V')
            fix = false;
        else
            return false;

        return true;
    }
    return false;
}

char AmpleGPS::readSentence(char c) {

    if (mode & GPS_PAUSED) return c;

    if (c == '\n') {        // sentence is at end
        if (strstr_P(readBuffer, PSTR("$GP")))
        {
//            Serial.println("valid nmeaPrefix");

            uint32_t diff = (uint32_t)((char *)(checksumString - readBuffer));
            char *nmeaCheckString = readBuffer + diff; // real pointer to '*' in the copy

            uint16_t checkSum = strtol((nmeaCheckString+1),NULL,16); // read the checksum from the string
            if(checkSum == nmeaCheckSum)                        // do check
            {
                uint8_t length = strlen(readBuffer) - strlen(nmeaCheckString) - 3;// 3 is the prefix

                strncpy(nmeaSentence, (const char *)(readBuffer+3), length);     // copy the string; double buffer
                *(nmeaSentence + length) = '\0';

                unparsedSentence = nmeaSentence;                    // valid, but not parsed yet.

//                            Serial.println("valid checksum");
            }
            checksumString = NULL;

        }

        if(GPS_DO_NOT_PARSE & mode)
            performCallBack(GPS_DO_NOT_PARSE);
        else
        {   //             Serial.println("will parse");

            if(true == parseSentence(nmeaSentence))
            {
                unparsedSentence = NULL;

//                Serial.println("did parse");

            }
            else
            {
                if(*nmeaSentence == '$')
                {
                    performCallBack(GPS_VIEW_UNPARSED);
                    unparsedSentence = NULL;
                }
            }
        }

    }
    else if (c == '$')
    {
        bufferIndex = 0;
        checksumString = NULL;
        nmeaCheckSum = 0;

    }
    else if (c == '*')          // set the pointer to the checksumString
    {
        checksumString = readBuffer + bufferIndex;

    }

    if(NULL == checksumString)
    {
        if(bufferIndex)     // omit the first sign ('$')
        {
            nmeaCheckSum ^= c;
        }
    }

    *(readBuffer + bufferIndex)=c;
    bufferIndex++;
    return c;
}

char *AmpleGPS::parseTime(char *p)
{
    float timed = strtod (p+1, &p);
    uint32_t time = (uint32_t)timed;
    hour = time / 10000;
    minute = (time % 10000) / 100;
    seconds = (time % 100);
    milliseconds = fmod(timed, 1.0) * 1000;

    performCallBack(GPS_NEW_TIME);

    return p;
}

char *AmpleGPS::parseSingleSatellite(char *p, GSV_Satellite *aSatellite){

    aSatellite -> number = strtol(p+1,&p,10);

    aSatellite -> elevation = strtol(p+1,&p,10);
    aSatellite -> azimuth = strtol(p+1,&p,10);

    aSatellite -> strength = strtol(p+1,&p,10);
    return p;
}

char *AmpleGPS::parsePairOfCoords (char *p){

    p = parseSingleCoord(p,&latitudeDegrees);
    //    Serial.println(*p);

    if(p)
        p = parseSingleCoord(p,&longitudeDegrees);

    performCallBack(GPS_NEW_COORDS);
    return p;
}

char *AmpleGPS::parseSingleCoord(char *p, float *degreeValue){

    double val = strtod (p+1, &p)/100.0;
    int degrees = floor(val);
    val = (val - degrees)/0.6;
    *degreeValue = val + degrees;

    p++;
    if (*p == 'S' || *p == 'W')
    {
        *degreeValue *= -1.0;
    }
    else
        if(!(*p == 'N' || *p == 'E'))
        {
            p = NULL;
        }
    if(p)
        p++;// we know that for sure, single char + '\0'

    return p;
}

int AmpleGPS::performCallBack(uint8_t suggestedMode)
{

    int retVal = 0;
    if((GPS_PAUSED & suggestedMode) & mode)       // exclusive, do nothing
        return 0;

    if((GPS_DO_NOT_PARSE & suggestedMode)& mode)     // exclusive, only nmeaString can be requested
        retVal = callBack(GPS_DO_NOT_PARSE);
    else
        if((GPS_COMPLETE_DATA & suggestedMode) & mode)    // exclusive, all data can be requested, but no other calls are perfromed
            retVal= callBack(GPS_COMPLETE_DATA);

        else if(suggestedMode & mode) // GPS_NEW_COORDS GPS_NEW_TIME GPS_VIEW_UNPARSED GPS_UPDATE_SATS
            retVal =callBack(suggestedMode);
    return retVal;
}

float AmpleGPS::getDistanceInKm( float targetLat, float targetLon)
{
    //----------------------------------------

    //convert decimal degree into radian
    float latRad = latitudeDegrees * half_piRad;
    float lonRad = longitudeDegrees * half_piRad;
    float tlatRad = targetLat * half_piRad;
    float tlonRad = targetLon * half_piRad;

    //Calculate the distance in KM
    float latSin = sin((latRad - tlatRad)*0.5);
    float lonSin = sin((lonRad - tlonRad)*0.5);
    float distance = doubleEarth * asin(sqrt((latSin*latSin) + cos(latRad) * cos(tlatRad) * (lonSin * lonSin)));

    return distance;

    //convert to miles
//    distance.miles = distance.km * 0.621371192;
//    distance.feet = distance.miles *5280;
//
// --------------------------------

}

<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#ifndef ITEM_HH
#define ITEM_HH
#include "config.h"
#include "mutex.hh"
#include <string>
#include <string.h>
#include <stdio.h>
#include <memcached/engine.h>

/**
 * The Item structure we use to pass information between the memcached
 * core and the backend. Please note that the kvstore don't store these
 * objects, so we do have an extra layer of memory copying :(
 */
class Item {
public:
    Item() : flags(0), exptime(0), cas(0)
    {
        key.assign("");
        setData(NULL, 0);
    }

    Item(const void* k, const size_t nk, const size_t nb,
         const int fl, const rel_time_t exp, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(static_cast<const char*>(k), nk);
        setData(NULL, nb);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(k);
        setData(static_cast<const char*>(dta), nb);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const std::string &val, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(k);
        setData(val.c_str(), val.size());
    }

    Item(const void *k, uint16_t nk, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(static_cast<const char*>(k), nk);
        setData(static_cast<const char*>(dta), nb);
    }

    Item(const Item &itm) : flags(itm.flags), exptime(itm.exptime), cas(itm.cas)
    {
        key.assign(itm.key);
        setData(itm.data, itm.nbytes);
    }

    ~Item() {
        delete []data;
    }

    Item* clone() {
        return new Item(key, flags, exptime, data, nbytes, cas);
    }

    char *getData() {
        return data;
    }

    const std::string &getKey() const {
        return key;
    }

    int getNKey() const {
        return static_cast<int>(key.length());
    }

    uint32_t getNBytes() const {
        return nbytes;
    }

    rel_time_t getExptime() const {
        return exptime;
    }

    int getFlags() const {
        return flags;
    }

    uint64_t getCas() const {
        return cas;
    }

    void setCas() {
        cas = nextCas();
    }

    void setCas(uint64_t ncas) {
        cas = ncas;
    }

    /**
     * Append another item to this item
     *
     * @param item the item to append to this one
     * @return true if success
     */
    bool append(const Item &item) {
        uint32_t ns = nbytes + item.nbytes - 2;
        char *c = new char[ns];
        if (c == NULL) {
            return false;
        }

        memcpy(c, data, nbytes - 2);
        memcpy(c + nbytes - 2, item.data, item.nbytes);

        delete []data;
        data = c;
        nbytes = ns;

        return true;
    }

    /**
     * Prepend another item to this item
     *
     * @param item the item to prepend to this one
     * @return true if success
     */
    bool prepend(const Item &item) {
        uint32_t ns = nbytes + item.nbytes - 2;
        char *c = new char[ns];
        if (c == NULL) {
            return false;
        }

        memcpy(c, item.data, item.nbytes - 2);
        memcpy(c + item.nbytes - 2, data, nbytes);

        delete []data;
        data = c;
        nbytes = ns;

        return true;
    }

private:
    /**
     * Set the item's data. This is only used by constructors, so we
     * make it private.
     */
    void setData(const char *dta, const size_t nb) {
        nbytes = static_cast<uint32_t>(nb);

        if (dta != NULL) {
            if (nbytes < 2 || memcmp(dta + nb - 2, "\r\n", 2) != 0) {
                nbytes += 2;
            }
        }

        if (nbytes > 0) {
            data = new char[nbytes];
        } else {
            data = NULL;
        }

        if (data && dta) {
            memcpy(data, dta, nbytes);
            if (nb != nbytes) {
                memcpy(data + nb, "\r\n", 2);
            }
        }
    }

    int flags;
    rel_time_t exptime;
    uint32_t nbytes;
    std::string key;
    char *data;
    uint64_t cas;

    static uint64_t nextCas(void) {
        uint64_t ret;
        casMutex.aquire();
        ret = casCounter++;
        casMutex.release();
        if ((ret % casNotificationFrequency) == 0) {
            casNotifier(ret);
        }

        return ret;
    }

    static void initializeCas(uint64_t initial, void (*notifier)(uint64_t current), uint64_t frequency) {
        casCounter = initial;
        casNotifier = notifier;
        casNotificationFrequency = frequency;
    }

    static uint64_t casNotificationFrequency;
    static void (*casNotifier)(uint64_t);
    static uint64_t casCounter;
    static Mutex casMutex;
};

#endif
<commit_msg>Remove Item::clone() since it's dead code.<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#ifndef ITEM_HH
#define ITEM_HH
#include "config.h"
#include "mutex.hh"
#include <string>
#include <string.h>
#include <stdio.h>
#include <memcached/engine.h>

/**
 * The Item structure we use to pass information between the memcached
 * core and the backend. Please note that the kvstore don't store these
 * objects, so we do have an extra layer of memory copying :(
 */
class Item {
public:
    Item() : flags(0), exptime(0), cas(0)
    {
        key.assign("");
        setData(NULL, 0);
    }

    Item(const void* k, const size_t nk, const size_t nb,
         const int fl, const rel_time_t exp, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(static_cast<const char*>(k), nk);
        setData(NULL, nb);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(k);
        setData(static_cast<const char*>(dta), nb);
    }

    Item(const std::string &k, const int fl, const rel_time_t exp,
         const std::string &val, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(k);
        setData(val.c_str(), val.size());
    }

    Item(const void *k, uint16_t nk, const int fl, const rel_time_t exp,
         const void *dta, const size_t nb, uint64_t theCas = 0) :
        flags(fl), exptime(exp), cas(theCas)
    {
        key.assign(static_cast<const char*>(k), nk);
        setData(static_cast<const char*>(dta), nb);
    }

    Item(const Item &itm) : flags(itm.flags), exptime(itm.exptime), cas(itm.cas)
    {
        key.assign(itm.key);
        setData(itm.data, itm.nbytes);
    }

    ~Item() {
        delete []data;
    }

    char *getData() {
        return data;
    }

    const std::string &getKey() const {
        return key;
    }

    int getNKey() const {
        return static_cast<int>(key.length());
    }

    uint32_t getNBytes() const {
        return nbytes;
    }

    rel_time_t getExptime() const {
        return exptime;
    }

    int getFlags() const {
        return flags;
    }

    uint64_t getCas() const {
        return cas;
    }

    void setCas() {
        cas = nextCas();
    }

    void setCas(uint64_t ncas) {
        cas = ncas;
    }

    /**
     * Append another item to this item
     *
     * @param item the item to append to this one
     * @return true if success
     */
    bool append(const Item &item) {
        uint32_t ns = nbytes + item.nbytes - 2;
        char *c = new char[ns];
        if (c == NULL) {
            return false;
        }

        memcpy(c, data, nbytes - 2);
        memcpy(c + nbytes - 2, item.data, item.nbytes);

        delete []data;
        data = c;
        nbytes = ns;

        return true;
    }

    /**
     * Prepend another item to this item
     *
     * @param item the item to prepend to this one
     * @return true if success
     */
    bool prepend(const Item &item) {
        uint32_t ns = nbytes + item.nbytes - 2;
        char *c = new char[ns];
        if (c == NULL) {
            return false;
        }

        memcpy(c, item.data, item.nbytes - 2);
        memcpy(c + item.nbytes - 2, data, nbytes);

        delete []data;
        data = c;
        nbytes = ns;

        return true;
    }

private:
    /**
     * Set the item's data. This is only used by constructors, so we
     * make it private.
     */
    void setData(const char *dta, const size_t nb) {
        nbytes = static_cast<uint32_t>(nb);

        if (dta != NULL) {
            if (nbytes < 2 || memcmp(dta + nb - 2, "\r\n", 2) != 0) {
                nbytes += 2;
            }
        }

        if (nbytes > 0) {
            data = new char[nbytes];
        } else {
            data = NULL;
        }

        if (data && dta) {
            memcpy(data, dta, nbytes);
            if (nb != nbytes) {
                memcpy(data + nb, "\r\n", 2);
            }
        }
    }

    int flags;
    rel_time_t exptime;
    uint32_t nbytes;
    std::string key;
    char *data;
    uint64_t cas;

    static uint64_t nextCas(void) {
        uint64_t ret;
        casMutex.aquire();
        ret = casCounter++;
        casMutex.release();
        if ((ret % casNotificationFrequency) == 0) {
            casNotifier(ret);
        }

        return ret;
    }

    static void initializeCas(uint64_t initial, void (*notifier)(uint64_t current), uint64_t frequency) {
        casCounter = initial;
        casNotifier = notifier;
        casNotificationFrequency = frequency;
    }

    static uint64_t casNotificationFrequency;
    static void (*casNotifier)(uint64_t);
    static uint64_t casCounter;
    static Mutex casMutex;
};

#endif
<|endoftext|>


<commit_before>/*
	Copyright (c) 2012, NuoDB, Inc.
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

		 * Redistributions of source code must retain the above copyright
			notice, this list of conditions and the following disclaimer.
		 * Redistributions in binary form must reproduce the above copyright
			notice, this list of conditions and the following disclaimer in the
			documentation and/or other materials provided with the distribution.
		 * Neither the name of NuoDB, Inc. nor the names of its contributors may
			be used to endorse or promote products derived from this software
			without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
	ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	DISCLAIMED. IN NO EVENT SHALL NUODB, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
	LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
	OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
	OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
	ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

	NOTE:  global_assembly_info.cs should be kept in sync with the following
	assembly information.
 */

#include "stdafx.h"

using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;

[assembly: AssemblyCompany("NuoDB")]
[assembly: AssemblyProduct("NuoDB .NET Database Provider")]
[assembly: AssemblyCopyright("NuoDB, Inc.")]
[assembly: AssemblyTrademark("NuoDB, Inc.")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif //DEBUG

[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

[assembly: AssemblyVersion("0.1.0.0")]
[assembly: AssemblyFileVersion("0.1.0.0")]

[assembly:CLSCompliantAttribute(true)];
<commit_msg>And in the cpp file too<commit_after>/*
	Copyright (c) 2012, NuoDB, Inc.
	All rights reserved.

	Redistribution and use in source and binary forms, with or without
	modification, are permitted provided that the following conditions are met:

		 * Redistributions of source code must retain the above copyright
			notice, this list of conditions and the following disclaimer.
		 * Redistributions in binary form must reproduce the above copyright
			notice, this list of conditions and the following disclaimer in the
			documentation and/or other materials provided with the distribution.
		 * Neither the name of NuoDB, Inc. nor the names of its contributors may
			be used to endorse or promote products derived from this software
			without specific prior written permission.

	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
	ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
	DISCLAIMED. IN NO EVENT SHALL NUODB, INC. BE LIABLE FOR ANY DIRECT, INDIRECT,
	INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
	LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
	OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
	OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
	ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

	NOTE:  global_assembly_info.cs should be kept in sync with the following
	assembly information.
 */

#include "stdafx.h"

using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;

[assembly: AssemblyCompany("NuoDB")]
[assembly: AssemblyProduct("NuoDB .NET Database Provider")]
[assembly: AssemblyCopyright("Copyright (c) 2012, NuoDB, Inc.")]
[assembly: AssemblyTrademark("NuoDB, Inc.")]

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif //DEBUG

[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

[assembly: AssemblyVersion("0.1.0.0")]
[assembly: AssemblyFileVersion("0.1.0.0")]

[assembly:CLSCompliantAttribute(true)];
<|endoftext|>


<commit_before>#include "variable.h"
#include "atom.h"
#include "list.h"
#include <iostream>

string Variable::value() const {
  if (_inst){
    string ret =_inst->symbol();
  //   if(_inst->get()=="List"){
  //   ret.insert(5," ");
  // }
    return ret;
  }
  else
    return Term::symbol();
}

string Variable::get() const {
    return "Variable";
}

bool Variable::match( Term & term ){
  if (this == &term)
    return true;
  if(!_inst){
    _inst = &term ;
    return true;
  }
  return _inst->match(term);
}
<commit_msg>Delete Variable.cpp<commit_after><|endoftext|>


<commit_before>//
// Copyright 2015 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "Firebase.h"

namespace {
const char* kFirebaseFingerprint = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A";
const uint16_t kFirebasePort = 443;

String makeUrl(const String& path, const String& auth) {
  String url;
  if (path[0] != '/') {
    url = "/";
  }
  url += path + ".json";
  if (auth.length() > 0) {
    url += "?auth=" + auth;
  }
  return url;
}

}  // namespace

Firebase::Firebase(const String& host) : host_(host) {
  http_.setReuse(true);
}

Firebase& Firebase::auth(const String& auth) {
  auth_ = auth;
  return *this;
}

FirebaseCall Firebase::get(const String& path) {
  return FirebaseCall(host_, auth_, "GET", path, &http_);
}

FirebaseCall Firebase::push(const String& path, const String& value) {
  return FirebaseCall(host_, auth_, "POST", path, value, &http_);
}

FirebaseCall Firebase::remove(const String& path) {
  return FirebaseCall(host_, auth_, "DELETE", path, &http_);
}

FirebaseEventStream Firebase::stream(const String& path) {
  return FirebaseEventStream(host_, auth_, path);
}

/* FirebaseEventStream */

FirebaseEventStream::FirebaseEventStream(const String& host, const String& auth,
                                         const String& path) {
  const String url = makeUrl(path, auth);
  http_.setReuse(true);
  http_.begin(host.c_str(), kFirebasePort, url.c_str(), true,
              kFirebaseFingerprint);
  const char* headers[] = {"Location"};
  http_.collectHeaders(headers, 1);
  http_.addHeader("Accept", "text/event-stream");
  status_ = http_.sendRequest("GET", (uint8_t*)NULL, 0);

  String location;
  // TODO(proppy): Add a max redirect check
  while (status_ == HTTP_CODE_TEMPORARY_REDIRECT) {
    location = http_.header("Location");
    http_.setReuse(false);
    http_.end();
    http_.setReuse(true);
    http_.begin(location, kFirebaseFingerprint);
    status_ = http_.sendRequest("GET", (uint8_t*)NULL, 0);
  }
}

bool FirebaseEventStream::connected() {
  return http_.connected();
}

bool FirebaseEventStream::available() {
  return http_.getStreamPtr()->available();
}

FirebaseEventStream::Event FirebaseEventStream::read(String& event) {
  auto client = http_.getStreamPtr();
  Event type;
  String typeStr = client->readStringUntil('\n').substring(7);
  if (typeStr == "put") {
    type = FirebaseEventStream::Event::PUT;
  } else if (typeStr == "patch") {
    type = FirebaseEventStream::Event::PATCH;
  } else {
    type = FirebaseEventStream::Event::UNKNOWN;
  }
  event = client->readStringUntil('\n').substring(6);
  client->readStringUntil('\n'); // consume separator
  return type;
}

bool FirebaseEventStream::isError() const {
  return status_ < 0;
}

String FirebaseEventStream::errorMessage() const {
  return error_message_;
}

/* FirebaseCall */
FirebaseCall::FirebaseCall(const String& host, const String& auth,
                           const char* method, const String& path, const String& value,
                           HTTPClient* http) : http_(http) {
  const String url = makeUrl(path, auth);
  http_->begin(host.c_str(), kFirebasePort, url.c_str(), true, kFirebaseFingerprint);
  status_ =  http_->sendRequest(method, (uint8_t*)value.c_str(), value.length());
  if (isError()) {
    error_message_ = String(method) + " " + url + ": " + HTTPClient::errorToString(status_);
  }
}

FirebaseCall::FirebaseCall(const String& host, const String& auth,
                           const char* method, const String& path,
                           HTTPClient* http) : FirebaseCall(host, auth, method, path, "", http) {
}

bool FirebaseCall::isOk() const {
  return status_ == HTTP_CODE_OK;
}

bool FirebaseCall::isError() const {
  return status_ < 0;
}

String FirebaseCall::errorMessage() const {
  return error_message_;
}

String FirebaseCall::rawResponse() {
  return http_->getString();
}
<commit_msg>Added error message back to streaming imp<commit_after>//
// Copyright 2015 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "Firebase.h"

namespace {
const char* kFirebaseFingerprint = "7A 54 06 9B DC 7A 25 B3 86 8D 66 53 48 2C 0B 96 42 C7 B3 0A";
const uint16_t kFirebasePort = 443;

String makeUrl(const String& path, const String& auth) {
  String url;
  if (path[0] != '/') {
    url = "/";
  }
  url += path + ".json";
  if (auth.length() > 0) {
    url += "?auth=" + auth;
  }
  return url;
}

}  // namespace

Firebase::Firebase(const String& host) : host_(host) {
  http_.setReuse(true);
}

Firebase& Firebase::auth(const String& auth) {
  auth_ = auth;
  return *this;
}

FirebaseCall Firebase::get(const String& path) {
  return FirebaseCall(host_, auth_, "GET", path, &http_);
}

FirebaseCall Firebase::push(const String& path, const String& value) {
  return FirebaseCall(host_, auth_, "POST", path, value, &http_);
}

FirebaseCall Firebase::remove(const String& path) {
  return FirebaseCall(host_, auth_, "DELETE", path, &http_);
}

FirebaseEventStream Firebase::stream(const String& path) {
  return FirebaseEventStream(host_, auth_, path);
}

/* FirebaseCall */

FirebaseCall::FirebaseCall(const String& host, const String& auth,
                           const char* method, const String& path, const String& value,
                           HTTPClient* http) : http_(http) {
  const String url = makeUrl(path, auth);
  http_->begin(host.c_str(), kFirebasePort, url.c_str(), true, kFirebaseFingerprint);
  status_ =  http_->sendRequest(method, (uint8_t*)value.c_str(), value.length());
  if (isError()) {
    error_message_ = String(method) + " " + url + ": " + HTTPClient::errorToString(status_);
  }
}

FirebaseCall::FirebaseCall(const String& host, const String& auth,
                           const char* method, const String& path,
                           HTTPClient* http) : FirebaseCall(host, auth, method, path, "", http) {
}

bool FirebaseCall::isOk() const {
  return status_ == HTTP_CODE_OK;
}

bool FirebaseCall::isError() const {
  return status_ < 0;
}

String FirebaseCall::errorMessage() const {
  return error_message_;
}

String FirebaseCall::rawResponse() {
  return http_->getString();
}

/* FirebaseEventStream */

FirebaseEventStream::FirebaseEventStream(const String& host, const String& auth,
                                         const String& path) {
  const String url = makeUrl(path, auth);
  http_.setReuse(true);
  http_.begin(host.c_str(), kFirebasePort, url.c_str(), true,
              kFirebaseFingerprint);
  const char* headers[] = {"Location"};
  http_.collectHeaders(headers, 1);
  http_.addHeader("Accept", "text/event-stream");
  status_ = http_.sendRequest("GET", (uint8_t*)NULL, 0);

  String location;
  // TODO(proppy): Add a max redirect check
  while (status_ == HTTP_CODE_TEMPORARY_REDIRECT) {
    location = http_.header("Location");
    http_.setReuse(false);
    http_.end();
    http_.setReuse(true);
    http_.begin(location, kFirebaseFingerprint);
    status_ = http_.sendRequest("GET", (uint8_t*)NULL, 0);
  }

  if (status_ != 200) {
    error_message_ = "stream " + location + ": "
       + HTTPClient::errorToString(status_);
  }
}

bool FirebaseEventStream::connected() {
  return http_.connected();
}

bool FirebaseEventStream::available() {
  return http_.getStreamPtr()->available();
}

FirebaseEventStream::Event FirebaseEventStream::read(String& event) {
  auto client = http_.getStreamPtr();
  Event type;
  String typeStr = client->readStringUntil('\n').substring(7);
  if (typeStr == "put") {
    type = FirebaseEventStream::Event::PUT;
  } else if (typeStr == "patch") {
    type = FirebaseEventStream::Event::PATCH;
  } else {
    type = FirebaseEventStream::Event::UNKNOWN;
  }
  event = client->readStringUntil('\n').substring(6);
  client->readStringUntil('\n'); // consume separator
  return type;
}

bool FirebaseEventStream::isError() const {
  return status_ < 0;
}

String FirebaseEventStream::errorMessage() const {
  return error_message_;
}

<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "ast/DebugVisitor.hpp"
#include "ast/SourceFile.hpp"

#include "assert.hpp"
#include "VisitorUtils.hpp"
#include "Variable.hpp"

using namespace eddic;

ast::DebugVisitor::DebugVisitor() : level(0) {}

std::string ast::DebugVisitor::indent() const {
    std::string acc = "";
    for(int i = 0; i < level; ++i){
        acc += "    ";
    }
    return acc;
}

std::string toStringType(ast::Type type){
    if(auto* ptr = boost::get<ast::SimpleType>(&type)){
        return ptr->type;
    } else if(auto* ptr = boost::get<ast::ArrayType>(&type)){
        return ptr->type + "[]";
    } else {
        ASSERT_PATH_NOT_TAKEN("Unhandled type");
    }
}

void ast::DebugVisitor::operator()(ast::SourceFile& program) const {
    std::cout << indent() << "SourceFile" << std::endl;

    ++level;

    visit_each(*this, program.Content->blocks);
}

void ast::DebugVisitor::operator()(ast::Import& import) const {
    std::cout << indent() << "include \"" << import.file << "\"" << std::endl;
}

void ast::DebugVisitor::operator()(ast::StandardImport& import) const {
    std::cout << indent() << "include <" << import.header << ">" << std::endl;
}

template<typename Visitor, typename Container>
void print_each_sub(Visitor& visitor, Container& container){
    visitor.level++;
    visit_each(visitor, container);
    visitor.level--;
}

template<typename Visitor, typename Container>
void print_sub(Visitor& visitor, Container& container){
    visitor.level++;
    visit(visitor, container);
    visitor.level--;
}

void ast::DebugVisitor::operator()(ast::FunctionDeclaration& declaration) const {
    std::cout << indent() << "Function " << declaration.Content->functionName << std::endl;
    std::cout << indent() << "Parameters:" << std::endl;
    level++;
    for(auto param : declaration.Content->parameters){
        std::cout << indent() << param.parameterName << std::endl;
    }
    level--;
    std::cout << indent() << "Instructions:" << std::endl;
    print_each_sub(*this, declaration.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Struct& struct_) const {
    std::cout << indent() << "Structure declaration: " << struct_.Content->name << std::endl;
    level++;
    std::cout << indent() << "Members:" << std::endl;
    level++;
    visit_each_non_variant(*this, struct_.Content->members);
    level--;
    std::cout << indent() << "Functions:" << std::endl;
    level++;
    visit_each_non_variant(*this, struct_.Content->functions);
    level--;
    level--;
}

void ast::DebugVisitor::operator()(ast::MemberDeclaration& declaration) const {
    std::cout << indent() << toStringType(declaration.Content->type)  << " " << declaration.Content->name << std::endl;
}

void ast::DebugVisitor::operator()(ast::GlobalVariableDeclaration&) const {
    std::cout << indent() << "Global Variable" << std::endl;
}

void ast::DebugVisitor::operator()(ast::GlobalArrayDeclaration&) const {
    std::cout << indent() << "Global Array" << std::endl;
}

void ast::DebugVisitor::operator()(ast::For& for_) const {
    std::cout << indent() << "For" << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Foreach& for_) const {
    std::cout << indent() << "Foreach" << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::ForeachIn& for_) const {
    std::cout << indent() << "Foreach in " << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(Switch& switch_) const {
    std::cout << indent() << "Switch " << std::endl;

    ++level;
    std::cout << indent() << "Value" << std::endl;
    print_sub(*this, switch_.Content->value);
    for(auto& case_ : switch_.Content->cases){
        (*this)(case_);
    }
    if(switch_.Content->default_case){
        (*this)(*switch_.Content->default_case);
    }
    --level;
}

void ast::DebugVisitor::operator()(SwitchCase& switch_case) const {
    std::cout << indent() << "Case" << std::endl;

    ++level;
    std::cout << indent() << "Value" << std::endl;
    print_sub(*this, switch_case.value);
    std::cout << indent() << "Instructions" << std::endl;
    print_each_sub(*this, switch_case.instructions);
    --level;
}

void ast::DebugVisitor::operator()(DefaultCase& default_case) const {
    std::cout << indent() << "Default Case" << std::endl;

    print_each_sub(*this, default_case.instructions);
}

void ast::DebugVisitor::operator()(ast::While& while_) const {
    std::cout << indent() << "While" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, while_.Content->condition);
    print_each_sub(*this, while_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::DoWhile& while_) const {
    std::cout << indent() << "Do while" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, while_.Content->condition);
    std::cout << indent() << "Body:" << std::endl;
    print_each_sub(*this, while_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Swap&) const {
    std::cout << indent() << "Swap" << std::endl;
}

void ast::DebugVisitor::operator()(ast::If& if_) const {
    std::cout << indent() << "If" << std::endl;

    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, if_.Content->condition);

    std::cout << indent() << "Instructions" << std::endl;
    print_each_sub(*this, if_.Content->instructions);

    for(auto& else_if : if_.Content->elseIfs){
        std::cout << indent() << "ElseIf" << std::endl;

        std::cout << indent() << "Condition:" << std::endl;
        print_sub(*this, if_.Content->condition);

        std::cout << indent() << "Instructions" << std::endl;
        print_each_sub(*this, else_if.instructions);
    }

    if(if_.Content->else_){
        std::cout << indent() << "Else" << std::endl;

        std::cout << indent() << "Instructions" << std::endl;
        print_each_sub(*this, (*if_.Content->else_).instructions);
    }
}

void ast::DebugVisitor::operator()(ast::FunctionCall& call) const {
    std::cout << indent() << "FunctionCall " << call.Content->functionName << std::endl;
    print_each_sub(*this, call.Content->values);
}

void ast::DebugVisitor::operator()(ast::MemberFunctionCall& call) const {
    std::cout << indent() << "Member FunctionCall " << call.Content->object_name << "." << call.Content->function_name << std::endl;
    print_each_sub(*this, call.Content->values);
}

void ast::DebugVisitor::operator()(ast::BuiltinOperator& builtin) const {
    std::cout << indent() << "Builtin Operator " << (int) builtin.Content->type << std::endl;
    print_each_sub(*this, builtin.Content->values);
}

void ast::DebugVisitor::operator()(ast::VariableDeclaration& declaration) const {
    std::cout << indent() << "Variable declaration [" << declaration.Content->variableName << "]" << std::endl;

    if(declaration.Content->value){
        print_sub(*this, *declaration.Content->value);
    }
}

void ast::DebugVisitor::operator()(ast::ArrayDeclaration&) const {
    std::cout << indent() << "Array declaration" << std::endl;
}

void ast::DebugVisitor::operator()(ast::SuffixOperation& op) const {
    std::cout << indent() << op.Content->variableName << "(suffix)" << (int)op.Content->op << std::endl;
}

void ast::DebugVisitor::operator()(ast::PrefixOperation& op) const {
    std::cout << indent() << (int)op.Content->op << "(prefix)" << op.Content->variableName << std::endl;
}

void ast::DebugVisitor::operator()(ast::Assignment& assign) const {
    std::cout << indent() << "Assignment [operator = " << static_cast<int>(assign.Content->op) << " ] " << std::endl;

    std::cout << indent() << "Left Value:" << std::endl;
    print_sub(*this, assign.Content->left_value);

    std::cout << indent() << "Right Value:" << std::endl;
    print_sub(*this, assign.Content->value);
}

void ast::DebugVisitor::operator()(ast::Ternary& ternary) const {
    std::cout << indent() << "Ternary" << std::endl;

    std::cout << indent() << "Condition Value:" << std::endl;
    print_sub(*this, ternary.Content->condition);

    std::cout << indent() << "True Value:" << std::endl;
    print_sub(*this, ternary.Content->true_value);

    std::cout << indent() << "False Value:" << std::endl;
    print_sub(*this, ternary.Content->false_value);
}

void ast::DebugVisitor::operator()(ast::Return& return_) const {
    std::cout << indent() << "Function return" << std::endl;
    print_sub(*this, return_.Content->value);
}

void ast::DebugVisitor::operator()(ast::Litteral& litteral) const {
    std::cout << indent() << "Litteral [" << litteral.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Integer& integer) const {
    std::cout << indent() << "Integer [" << integer.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::IntegerSuffix& integer) const {
    std::cout << indent() << "Float (suffix) [" << integer.value << "f]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Float& float_) const {
    std::cout << indent() << "Float [" << float_.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::True&) const {
    std::cout << indent() << "true" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Null&) const {
    std::cout << indent() << "null" << std::endl;
}

void ast::DebugVisitor::operator()(ast::False&) const {
    std::cout << indent() << "false" << std::endl;
}

void ast::DebugVisitor::operator()(ast::VariableValue& value) const {
    std::cout << indent() << "Variable " << value.Content->var->name();

    for(auto& member : value.Content->memberNames){
        std::cout << "." << member;
    }

    std::cout << std::endl;
}

void ast::DebugVisitor::operator()(ast::DereferenceValue& value) const {
    std::cout << indent() << "Dereference Variable Value" << std::endl;;

    std::cout << indent() << "Left Value:" << std::endl;
    print_sub(*this, value.Content->ref);
}

void ast::DebugVisitor::operator()(ast::ArrayValue& value) const {
    std::cout << indent() << "Array value [" << value.Content->arrayName << "]" << std::endl;
    print_sub(*this, value.Content->indexValue);
}

void ast::DebugVisitor::operator()(ast::Expression& value) const {
    std::cout << indent() << "Expression [" << value.Content->operations.size() << "]" << std::endl;
    ++level;
    visit(*this, value.Content->first);
    for(auto& operation : value.Content->operations){
        std::cout << indent() << (int) operation.get<0>() << std::endl;
        visit(*this, operation.get<1>());
    }
    --level;
}

void ast::DebugVisitor::operator()(ast::Unary& value) const {
    std::cout << indent() << "Unary " << static_cast<int>(value.Content->op) << std::endl;
    print_sub(*this, value.Content->value);
}

void ast::DebugVisitor::operator()(ast::Cast& cast) const {
    std::cout << indent() << "Cast " << std::endl;
    std::cout << indent() << "\tType: " << toStringType(cast.Content->type) << std::endl;
    print_sub(*this, cast.Content->value);
}
<commit_msg>Fix printing of the condition of the else if clauses<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "ast/DebugVisitor.hpp"
#include "ast/SourceFile.hpp"

#include "assert.hpp"
#include "VisitorUtils.hpp"
#include "Variable.hpp"

using namespace eddic;

ast::DebugVisitor::DebugVisitor() : level(0) {}

std::string ast::DebugVisitor::indent() const {
    std::string acc = "";
    for(int i = 0; i < level; ++i){
        acc += "    ";
    }
    return acc;
}

std::string toStringType(ast::Type type){
    if(auto* ptr = boost::get<ast::SimpleType>(&type)){
        return ptr->type;
    } else if(auto* ptr = boost::get<ast::ArrayType>(&type)){
        return ptr->type + "[]";
    } else {
        ASSERT_PATH_NOT_TAKEN("Unhandled type");
    }
}

void ast::DebugVisitor::operator()(ast::SourceFile& program) const {
    std::cout << indent() << "SourceFile" << std::endl;

    ++level;

    visit_each(*this, program.Content->blocks);
}

void ast::DebugVisitor::operator()(ast::Import& import) const {
    std::cout << indent() << "include \"" << import.file << "\"" << std::endl;
}

void ast::DebugVisitor::operator()(ast::StandardImport& import) const {
    std::cout << indent() << "include <" << import.header << ">" << std::endl;
}

template<typename Visitor, typename Container>
void print_each_sub(Visitor& visitor, Container& container){
    visitor.level++;
    visit_each(visitor, container);
    visitor.level--;
}

template<typename Visitor, typename Container>
void print_sub(Visitor& visitor, Container& container){
    visitor.level++;
    visit(visitor, container);
    visitor.level--;
}

void ast::DebugVisitor::operator()(ast::FunctionDeclaration& declaration) const {
    std::cout << indent() << "Function " << declaration.Content->functionName << std::endl;
    std::cout << indent() << "Parameters:" << std::endl;
    level++;
    for(auto param : declaration.Content->parameters){
        std::cout << indent() << param.parameterName << std::endl;
    }
    level--;
    std::cout << indent() << "Instructions:" << std::endl;
    print_each_sub(*this, declaration.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Struct& struct_) const {
    std::cout << indent() << "Structure declaration: " << struct_.Content->name << std::endl;
    level++;
    std::cout << indent() << "Members:" << std::endl;
    level++;
    visit_each_non_variant(*this, struct_.Content->members);
    level--;
    std::cout << indent() << "Functions:" << std::endl;
    level++;
    visit_each_non_variant(*this, struct_.Content->functions);
    level--;
    level--;
}

void ast::DebugVisitor::operator()(ast::MemberDeclaration& declaration) const {
    std::cout << indent() << toStringType(declaration.Content->type)  << " " << declaration.Content->name << std::endl;
}

void ast::DebugVisitor::operator()(ast::GlobalVariableDeclaration&) const {
    std::cout << indent() << "Global Variable" << std::endl;
}

void ast::DebugVisitor::operator()(ast::GlobalArrayDeclaration&) const {
    std::cout << indent() << "Global Array" << std::endl;
}

void ast::DebugVisitor::operator()(ast::For& for_) const {
    std::cout << indent() << "For" << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Foreach& for_) const {
    std::cout << indent() << "Foreach" << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::ForeachIn& for_) const {
    std::cout << indent() << "Foreach in " << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(Switch& switch_) const {
    std::cout << indent() << "Switch " << std::endl;

    ++level;
    std::cout << indent() << "Value" << std::endl;
    print_sub(*this, switch_.Content->value);
    for(auto& case_ : switch_.Content->cases){
        (*this)(case_);
    }
    if(switch_.Content->default_case){
        (*this)(*switch_.Content->default_case);
    }
    --level;
}

void ast::DebugVisitor::operator()(SwitchCase& switch_case) const {
    std::cout << indent() << "Case" << std::endl;

    ++level;
    std::cout << indent() << "Value" << std::endl;
    print_sub(*this, switch_case.value);
    std::cout << indent() << "Instructions" << std::endl;
    print_each_sub(*this, switch_case.instructions);
    --level;
}

void ast::DebugVisitor::operator()(DefaultCase& default_case) const {
    std::cout << indent() << "Default Case" << std::endl;

    print_each_sub(*this, default_case.instructions);
}

void ast::DebugVisitor::operator()(ast::While& while_) const {
    std::cout << indent() << "While" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, while_.Content->condition);
    print_each_sub(*this, while_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::DoWhile& while_) const {
    std::cout << indent() << "Do while" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, while_.Content->condition);
    std::cout << indent() << "Body:" << std::endl;
    print_each_sub(*this, while_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Swap&) const {
    std::cout << indent() << "Swap" << std::endl;
}

void ast::DebugVisitor::operator()(ast::If& if_) const {
    std::cout << indent() << "If" << std::endl;

    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, if_.Content->condition);

    std::cout << indent() << "Instructions" << std::endl;
    print_each_sub(*this, if_.Content->instructions);

    for(auto& else_if : if_.Content->elseIfs){
        std::cout << indent() << "ElseIf" << std::endl;

        std::cout << indent() << "Condition:" << std::endl;
        print_sub(*this, else_if.condition);

        std::cout << indent() << "Instructions" << std::endl;
        print_each_sub(*this, else_if.instructions);
    }

    if(if_.Content->else_){
        std::cout << indent() << "Else" << std::endl;

        std::cout << indent() << "Instructions" << std::endl;
        print_each_sub(*this, (*if_.Content->else_).instructions);
    }
}

void ast::DebugVisitor::operator()(ast::FunctionCall& call) const {
    std::cout << indent() << "FunctionCall " << call.Content->functionName << std::endl;
    print_each_sub(*this, call.Content->values);
}

void ast::DebugVisitor::operator()(ast::MemberFunctionCall& call) const {
    std::cout << indent() << "Member FunctionCall " << call.Content->object_name << "." << call.Content->function_name << std::endl;
    print_each_sub(*this, call.Content->values);
}

void ast::DebugVisitor::operator()(ast::BuiltinOperator& builtin) const {
    std::cout << indent() << "Builtin Operator " << (int) builtin.Content->type << std::endl;
    print_each_sub(*this, builtin.Content->values);
}

void ast::DebugVisitor::operator()(ast::VariableDeclaration& declaration) const {
    std::cout << indent() << "Variable declaration [" << declaration.Content->variableName << "]" << std::endl;

    if(declaration.Content->value){
        print_sub(*this, *declaration.Content->value);
    }
}

void ast::DebugVisitor::operator()(ast::ArrayDeclaration&) const {
    std::cout << indent() << "Array declaration" << std::endl;
}

void ast::DebugVisitor::operator()(ast::SuffixOperation& op) const {
    std::cout << indent() << op.Content->variableName << "(suffix)" << (int)op.Content->op << std::endl;
}

void ast::DebugVisitor::operator()(ast::PrefixOperation& op) const {
    std::cout << indent() << (int)op.Content->op << "(prefix)" << op.Content->variableName << std::endl;
}

void ast::DebugVisitor::operator()(ast::Assignment& assign) const {
    std::cout << indent() << "Assignment [operator = " << static_cast<int>(assign.Content->op) << " ] " << std::endl;

    std::cout << indent() << "Left Value:" << std::endl;
    print_sub(*this, assign.Content->left_value);

    std::cout << indent() << "Right Value:" << std::endl;
    print_sub(*this, assign.Content->value);
}

void ast::DebugVisitor::operator()(ast::Ternary& ternary) const {
    std::cout << indent() << "Ternary" << std::endl;

    std::cout << indent() << "Condition Value:" << std::endl;
    print_sub(*this, ternary.Content->condition);

    std::cout << indent() << "True Value:" << std::endl;
    print_sub(*this, ternary.Content->true_value);

    std::cout << indent() << "False Value:" << std::endl;
    print_sub(*this, ternary.Content->false_value);
}

void ast::DebugVisitor::operator()(ast::Return& return_) const {
    std::cout << indent() << "Function return" << std::endl;
    print_sub(*this, return_.Content->value);
}

void ast::DebugVisitor::operator()(ast::Litteral& litteral) const {
    std::cout << indent() << "Litteral [" << litteral.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Integer& integer) const {
    std::cout << indent() << "Integer [" << integer.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::IntegerSuffix& integer) const {
    std::cout << indent() << "Float (suffix) [" << integer.value << "f]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Float& float_) const {
    std::cout << indent() << "Float [" << float_.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::True&) const {
    std::cout << indent() << "true" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Null&) const {
    std::cout << indent() << "null" << std::endl;
}

void ast::DebugVisitor::operator()(ast::False&) const {
    std::cout << indent() << "false" << std::endl;
}

void ast::DebugVisitor::operator()(ast::VariableValue& value) const {
    std::cout << indent() << "Variable " << value.Content->var->name();

    for(auto& member : value.Content->memberNames){
        std::cout << "." << member;
    }

    std::cout << std::endl;
}

void ast::DebugVisitor::operator()(ast::DereferenceValue& value) const {
    std::cout << indent() << "Dereference Variable Value" << std::endl;;

    std::cout << indent() << "Left Value:" << std::endl;
    print_sub(*this, value.Content->ref);
}

void ast::DebugVisitor::operator()(ast::ArrayValue& value) const {
    std::cout << indent() << "Array value [" << value.Content->arrayName << "]" << std::endl;
    print_sub(*this, value.Content->indexValue);
}

void ast::DebugVisitor::operator()(ast::Expression& value) const {
    std::cout << indent() << "Expression [" << value.Content->operations.size() << "]" << std::endl;
    ++level;
    visit(*this, value.Content->first);
    for(auto& operation : value.Content->operations){
        std::cout << indent() << (int) operation.get<0>() << std::endl;
        visit(*this, operation.get<1>());
    }
    --level;
}

void ast::DebugVisitor::operator()(ast::Unary& value) const {
    std::cout << indent() << "Unary " << static_cast<int>(value.Content->op) << std::endl;
    print_sub(*this, value.Content->value);
}

void ast::DebugVisitor::operator()(ast::Cast& cast) const {
    std::cout << indent() << "Cast " << std::endl;
    std::cout << indent() << "\tType: " << toStringType(cast.Content->type) << std::endl;
    print_sub(*this, cast.Content->value);
}
<|endoftext|>


<commit_before>/*
Copyright (C) 1988 Free Software Foundation
    written by Doug Lea (dl@rocky.oswego.edu)

This file is part of the GNU C++ Library.  This library is free
software; you can redistribute it and/or modify it under the terms of
the GNU Library General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.  This library 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

/*
  Regex class implementation

  NB: I tried to replace the lib_error_handler() calls with STL exceptions,
  but I can't figure out where/if gcc 3.2.2 defines the children of
  exception. 06/06/03 jhrg
 */

#ifdef __GNUG__
#pragma implementation
#endif

#include <stdlib.h>
#include <string.h>
#include <builtin.h>

#include <new>

extern "C" {
#ifdef WIN32
#define __STDC__		/*  Needed for rx.h prototypes.               */
#include "regex-0.12/regex.h"   /*  Lack of case distinction on win32         */
#else				/*  Means regex.h and Regex.h are same file.  */
#include "regex.h"
#endif
}

#include <Regex.h>

using namespace std;

Regex::~Regex()
{
  if (buf->buffer) free(buf->buffer);
  if (buf->fastmap) free(buf->fastmap);
  if (buf->translate) free (buf->translate);

  if (reg->start)
    free (reg->start);
  if (reg->end)
    free (reg->end);

  delete(buf);
  delete(reg);
}

Regex::Regex(const char* t, int fast, int bufsize,
               const char* transtable)
{
  int tlen = (t == 0)? 0 : strlen(t);
  buf = new re_pattern_buffer;
  memset (buf, 0, sizeof(re_pattern_buffer));
  reg = new re_registers;
  reg->start = 0;
  reg->end = 0;
  if (fast)
    buf->fastmap = (char*)malloc(256);
  else
    buf->fastmap = 0;
#if 0
  buf->translate = (unsigned char*)transtable;
#endif
  buf->translate = (char*)transtable;
  if (tlen > bufsize)
    bufsize = tlen;
  buf->allocated = bufsize;
  buf->buffer = (unsigned char *)malloc(buf->allocated);
#if 0
  buf->buffer = (char *)malloc(buf->allocated);
#endif
  const char* msg = re_compile_pattern((const char*)t, tlen, buf);
  if (msg != 0)
#if 0
    throw invalid_argument(string("Regex: ") + string(msg));
#endif
    (*lib_error_handler)("Regex", msg);
  else if (fast)
    re_compile_fastmap(buf);
}

int Regex::match_info(int& start, int& length, int nth) const
{
  if ((unsigned)(nth) >= RE_NREGS)
    return 0;
  else
  {
    start = reg->start[nth];
    length = reg->end[nth] - start;
    return start >= 0 && length >= 0;
  }
}

int Regex::search(const char* s, int len, int& matchlen, int startpos) const
{
  int matchpos, pos, range;
  if (startpos >= 0)
  {
    pos = startpos;
    range = len - startpos;
  }
  else
  {
    pos = len + startpos;
    range = -pos;
  }
  matchpos = re_search_2(buf, 0, 0, (char*)s, len, pos, range, reg, len);
  if (matchpos >= 0)
    matchlen = reg->end[0] - reg->start[0];
  else
    matchlen = 0;
  return matchpos;
}

int Regex::match(const char*s, int len, int p) const
{
  if (p < 0)
  {
    p += len;
    if (p > len)
      return -1;
    return re_match_2(buf, 0, 0, (char*)s, p, 0, reg, p);
  }
  else if (p > len)
    return -1;
  else
    return re_match_2(buf, 0, 0, (char*)s, len, p, reg, len);
}

int Regex::OK() const
{
// can't verify much, since we've lost the original string
  int v = buf != 0;             // have a regex buf
  v &= buf->buffer != 0;        // with a pat
  if (!v) (*lib_error_handler)("Regex", "invariant failure");
#if 0
  if (!v) throw domain_error(string("Regex") + string("invariant failure"));
#endif
  return v;
}

/*
 some built-in Regular expressions
*/

#if 0
// See my comment about these in Regex.h. 11/05/02 jhrg
const Regex RXwhite("[ \n\t\r\v\f]+", 1);
const Regex RXint("-?[0-9]+", 1);
#if 0
const Regex RXdouble("-?\\(\\([0-9]+\\.[0-9]*\\)\\|\\([0-9]+\\)\\|\\(\\.[0-9]+\\)\\)\\([eE][---+]?[0-9]+\\)?", 1, 200);
#endif
const Regex RXalpha("[A-Za-z]+", 1);
const Regex RXlowercase("[a-z]+", 1);
const Regex RXuppercase("[A-Z]+", 1);
const Regex RXalphanum("[0-9A-Za-z]+", 1);
const Regex RXidentifier("[A-Za-z_][A-Za-z0-9_]*", 1);
#endif

<commit_msg>Make the regular-expression code compile under OS X.<commit_after>/*
Copyright (C) 1988 Free Software Foundation
    written by Doug Lea (dl@rocky.oswego.edu)

This file is part of the GNU C++ Library.  This library is free
software; you can redistribute it and/or modify it under the terms of
the GNU Library General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.  This library 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

/*
  Regex class implementation

  NB: I tried to replace the lib_error_handler() calls with STL exceptions,
  but I can't figure out where/if gcc 3.2.2 defines the children of
  exception. 06/06/03 jhrg
 */

#ifdef __GNUG__
#pragma implementation
#endif

#include <stdlib.h>
#include <string.h>
#include <builtin.h>

#include <new>

extern "C" {
#if defined(WIN32) || defined(__POWERPC__)
#define __STDC__		/*  Needed for rx.h prototypes.               */
#include "regex-0.12/regex.h"   /*  Lack of case distinction on win32         */
#else				/*  Means regex.h and Regex.h are same file.  */
#include "regex.h"
#endif
}

#include <Regex.h>

using namespace std;

Regex::~Regex()
{
  if (buf->buffer) free(buf->buffer);
  if (buf->fastmap) free(buf->fastmap);
  if (buf->translate) free (buf->translate);

  if (reg->start)
    free (reg->start);
  if (reg->end)
    free (reg->end);

  delete(buf);
  delete(reg);
}

Regex::Regex(const char* t, int fast, int bufsize,
               const char* transtable)
{
  int tlen = (t == 0)? 0 : strlen(t);
  buf = new re_pattern_buffer;
  memset (buf, 0, sizeof(re_pattern_buffer));
  reg = new re_registers;
  reg->start = 0;
  reg->end = 0;
  if (fast)
    buf->fastmap = (char*)malloc(256);
  else
    buf->fastmap = 0;
#if 0
  buf->translate = (unsigned char*)transtable;
#endif
  buf->translate = (char*)transtable;
  if (tlen > bufsize)
    bufsize = tlen;
  buf->allocated = bufsize;
  buf->buffer = (unsigned char *)malloc(buf->allocated);
#if 0
  buf->buffer = (char *)malloc(buf->allocated);
#endif
  const char* msg = re_compile_pattern((const char*)t, tlen, buf);
  if (msg != 0)
#if 0
    throw invalid_argument(string("Regex: ") + string(msg));
#endif
    (*lib_error_handler)("Regex", msg);
  else if (fast)
    re_compile_fastmap(buf);
}

int Regex::match_info(int& start, int& length, int nth) const
{
  if ((unsigned)(nth) >= RE_NREGS)
    return 0;
  else
  {
    start = reg->start[nth];
    length = reg->end[nth] - start;
    return start >= 0 && length >= 0;
  }
}

int Regex::search(const char* s, int len, int& matchlen, int startpos) const
{
  int matchpos, pos, range;
  if (startpos >= 0)
  {
    pos = startpos;
    range = len - startpos;
  }
  else
  {
    pos = len + startpos;
    range = -pos;
  }
  matchpos = re_search_2(buf, 0, 0, (char*)s, len, pos, range, reg, len);
  if (matchpos >= 0)
    matchlen = reg->end[0] - reg->start[0];
  else
    matchlen = 0;
  return matchpos;
}

int Regex::match(const char*s, int len, int p) const
{
  if (p < 0)
  {
    p += len;
    if (p > len)
      return -1;
    return re_match_2(buf, 0, 0, (char*)s, p, 0, reg, p);
  }
  else if (p > len)
    return -1;
  else
    return re_match_2(buf, 0, 0, (char*)s, len, p, reg, len);
}

int Regex::OK() const
{
// can't verify much, since we've lost the original string
  int v = buf != 0;             // have a regex buf
  v &= buf->buffer != 0;        // with a pat
  if (!v) (*lib_error_handler)("Regex", "invariant failure");
#if 0
  if (!v) throw domain_error(string("Regex") + string("invariant failure"));
#endif
  return v;
}

/*
 some built-in Regular expressions
*/

#if 0
// See my comment about these in Regex.h. 11/05/02 jhrg
const Regex RXwhite("[ \n\t\r\v\f]+", 1);
const Regex RXint("-?[0-9]+", 1);
#if 0
const Regex RXdouble("-?\\(\\([0-9]+\\.[0-9]*\\)\\|\\([0-9]+\\)\\|\\(\\.[0-9]+\\)\\)\\([eE][---+]?[0-9]+\\)?", 1, 200);
#endif
const Regex RXalpha("[A-Za-z]+", 1);
const Regex RXlowercase("[a-z]+", 1);
const Regex RXuppercase("[A-Z]+", 1);
const Regex RXalphanum("[0-9A-Za-z]+", 1);
const Regex RXidentifier("[A-Za-z_][A-Za-z0-9_]*", 1);
#endif

<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "ast/DebugVisitor.hpp"
#include "ast/SourceFile.hpp"

#include "assert.hpp"
#include "VisitorUtils.hpp"
#include "Variable.hpp"

using namespace eddic;

ast::DebugVisitor::DebugVisitor() : level(0) {}

std::string ast::DebugVisitor::indent() const {
    std::string acc = "";
    for(int i = 0; i < level; ++i){
        acc += "\t";
    }
    return acc;
}

std::string toStringType(ast::Type type){
    if(auto* ptr = boost::get<ast::SimpleType>(&type)){
        return ptr->type;
    } else if(auto* ptr = boost::get<ast::ArrayType>(&type)){
        return ptr->type + "[]";
    } else {
        ASSERT_PATH_NOT_TAKEN("Unhandled type");
    }
}

void ast::DebugVisitor::operator()(ast::SourceFile& program) const {
    std::cout << indent() << "SourceFile" << std::endl;

    ++level;

    visit_each(*this, program.Content->blocks);
}

void ast::DebugVisitor::operator()(ast::Import& import) const {
    std::cout << indent() << "include \"" << import.file << "\"" << std::endl;
}

void ast::DebugVisitor::operator()(ast::StandardImport& import) const {
    std::cout << indent() << "include <" << import.header << ">" << std::endl;
}

template<typename Visitor, typename Container>
void print_each_sub(Visitor& visitor, Container& container){
    visitor.level++;
    visit_each(visitor, container);
    visitor.level--;
}

template<typename Visitor, typename Container>
void print_sub(Visitor& visitor, Container& container){
    visitor.level++;
    visit(visitor, container);
    visitor.level--;
}

void ast::DebugVisitor::operator()(ast::FunctionDeclaration& declaration) const {
    std::cout << indent() << "Function " << declaration.Content->functionName << std::endl;
    std::cout << indent() << "Parameters:" << std::endl;
    level++;
    for(auto param : declaration.Content->parameters){
        std::cout << indent() << param.parameterName << std::endl;
    }
    level--;
    std::cout << indent() << "Instructions:" << std::endl;
    print_each_sub(*this, declaration.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Struct& struct_) const {
    std::cout << indent() << "Structure declaration: " << struct_.Content->name << std::endl;
    level++;
    std::cout << indent() << "Members:" << std::endl;
    level++;
    visit_each_non_variant(*this, struct_.Content->members);
    level--;
    std::cout << indent() << "Functions:" << std::endl;
    level++;
    visit_each_non_variant(*this, struct_.Content->functions);
    level--;
    level--;
}

void ast::DebugVisitor::operator()(ast::MemberDeclaration& declaration) const {
    std::cout << indent() << toStringType(declaration.Content->type)  << " " << declaration.Content->name << std::endl;
}

void ast::DebugVisitor::operator()(ast::GlobalVariableDeclaration&) const {
    std::cout << indent() << "Global Variable" << std::endl;
}

void ast::DebugVisitor::operator()(ast::GlobalArrayDeclaration&) const {
    std::cout << indent() << "Global Array" << std::endl;
}

void ast::DebugVisitor::operator()(ast::For& for_) const {
    std::cout << indent() << "For" << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Foreach& for_) const {
    std::cout << indent() << "Foreach" << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::ForeachIn& for_) const {
    std::cout << indent() << "Foreach in " << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(Switch& switch_) const {
    std::cout << indent() << "Switch " << std::endl;

    ++level;
    std::cout << "Value" << std::endl;
    print_sub(*this, switch_.Content->value);
    for(auto& case_ : switch_.Content->cases){
        (*this)(case_);
    }
    if(switch_.Content->default_case){
        (*this)(*switch_.Content->default_case);
    }
    --level;
}

void ast::DebugVisitor::operator()(SwitchCase& switch_case) const {
    std::cout << "Case" << std::endl;

    ++level;
    std::cout << "Value" << std::endl;
    print_sub(*this, switch_case.value);
    print_each_sub(*this, switch_case.instructions);
    --level;
}

void ast::DebugVisitor::operator()(DefaultCase& default_case) const {
    std::cout << "Default Case" << std::endl;

    ++level;
    print_each_sub(*this, default_case.instructions);
    --level;
}

void ast::DebugVisitor::operator()(ast::While& while_) const {
    std::cout << indent() << "While" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, while_.Content->condition);
    print_each_sub(*this, while_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::DoWhile& while_) const {
    std::cout << indent() << "Do while" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, while_.Content->condition);
    std::cout << indent() << "Body:" << std::endl;
    print_each_sub(*this, while_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Swap&) const {
    std::cout << indent() << "Swap" << std::endl;
}

void ast::DebugVisitor::operator()(ast::If& if_) const {
    std::cout << indent() << "If" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, if_.Content->condition);
    std::cout << indent() << "Body:" << std::endl;
    print_each_sub(*this, if_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::FunctionCall& call) const {
    std::cout << indent() << "FunctionCall " << call.Content->functionName << std::endl;
    print_each_sub(*this, call.Content->values);
}

void ast::DebugVisitor::operator()(ast::MemberFunctionCall& call) const {
    std::cout << indent() << "Member FunctionCall " << call.Content->object_name << "." << call.Content->function_name << std::endl;
    print_each_sub(*this, call.Content->values);
}

void ast::DebugVisitor::operator()(ast::BuiltinOperator& builtin) const {
    std::cout << indent() << "Builtin Operator " << (int) builtin.Content->type << std::endl;
    print_each_sub(*this, builtin.Content->values);
}

void ast::DebugVisitor::operator()(ast::VariableDeclaration& declaration) const {
    std::cout << indent() << "Variable declaration [" << declaration.Content->variableName << "]" << std::endl;

    if(declaration.Content->value){
        print_sub(*this, *declaration.Content->value);
    }
}

void ast::DebugVisitor::operator()(ast::ArrayDeclaration&) const {
    std::cout << indent() << "Array declaration" << std::endl;
}

void ast::DebugVisitor::operator()(ast::SuffixOperation& op) const {
    std::cout << indent() << op.Content->variableName << "(suffix)" << (int)op.Content->op << std::endl;
}

void ast::DebugVisitor::operator()(ast::PrefixOperation& op) const {
    std::cout << indent() << (int)op.Content->op << "(prefix)" << op.Content->variableName << std::endl;
}

void ast::DebugVisitor::operator()(ast::Assignment& assign) const {
    std::cout << indent() << "Assignment [operator = " << static_cast<int>(assign.Content->op) << " ] " << std::endl;

    std::cout << indent() << "Left Value:" << std::endl;
    print_sub(*this, assign.Content->left_value);

    std::cout << indent() << "Right Value:" << std::endl;
    print_sub(*this, assign.Content->value);
}

void ast::DebugVisitor::operator()(ast::Ternary& ternary) const {
    std::cout << indent() << "Ternary" << std::endl;

    std::cout << indent() << "Condition Value:" << std::endl;
    print_sub(*this, ternary.Content->condition);

    std::cout << indent() << "True Value:" << std::endl;
    print_sub(*this, ternary.Content->true_value);

    std::cout << indent() << "False Value:" << std::endl;
    print_sub(*this, ternary.Content->false_value);
}

void ast::DebugVisitor::operator()(ast::Return& return_) const {
    std::cout << indent() << "Function return" << std::endl;
    print_sub(*this, return_.Content->value);
}

void ast::DebugVisitor::operator()(ast::Litteral& litteral) const {
    std::cout << indent() << "Litteral [" << litteral.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Integer& integer) const {
    std::cout << indent() << "Integer [" << integer.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::IntegerSuffix& integer) const {
    std::cout << indent() << "Float (suffix) [" << integer.value << "f]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Float& float_) const {
    std::cout << indent() << "Float [" << float_.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::True&) const {
    std::cout << indent() << "true" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Null&) const {
    std::cout << indent() << "null" << std::endl;
}

void ast::DebugVisitor::operator()(ast::False&) const {
    std::cout << indent() << "false" << std::endl;
}

void ast::DebugVisitor::operator()(ast::VariableValue& value) const {
    std::cout << indent() << "Variable " << value.Content->var->name();

    for(auto& member : value.Content->memberNames){
        std::cout << "." << member;
    }

    std::cout << std::endl;
}

void ast::DebugVisitor::operator()(ast::DereferenceValue& value) const {
    std::cout << indent() << "Dereference Variable Value" << std::endl;;

    std::cout << indent() << "Left Value:" << std::endl;
    print_sub(*this, value.Content->ref);
}

void ast::DebugVisitor::operator()(ast::ArrayValue& value) const {
    std::cout << indent() << "Array value [" << value.Content->arrayName << "]" << std::endl;
    print_sub(*this, value.Content->indexValue);
}

void ast::DebugVisitor::operator()(ast::Expression& value) const {
    std::cout << indent() << "Expression [" << value.Content->operations.size() << "]" << std::endl;
    ++level;
    visit(*this, value.Content->first);
    for(auto& operation : value.Content->operations){
        std::cout << indent() << (int) operation.get<0>() << std::endl;
        visit(*this, operation.get<1>());
    }
    --level;
}

void ast::DebugVisitor::operator()(ast::Unary& value) const {
    std::cout << indent() << "Unary " << static_cast<int>(value.Content->op) << std::endl;
    print_sub(*this, value.Content->value);
}

void ast::DebugVisitor::operator()(ast::Cast& cast) const {
    std::cout << indent() << "Cast " << std::endl;
    std::cout << indent() << "\tType: " << toStringType(cast.Content->type) << std::endl;
    print_sub(*this, cast.Content->value);
}
<commit_msg>Improve output of the AST Printer<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <iostream>

#include "ast/DebugVisitor.hpp"
#include "ast/SourceFile.hpp"

#include "assert.hpp"
#include "VisitorUtils.hpp"
#include "Variable.hpp"

using namespace eddic;

ast::DebugVisitor::DebugVisitor() : level(0) {}

std::string ast::DebugVisitor::indent() const {
    std::string acc = "";
    for(int i = 0; i < level; ++i){
        acc += "    ";
    }
    return acc;
}

std::string toStringType(ast::Type type){
    if(auto* ptr = boost::get<ast::SimpleType>(&type)){
        return ptr->type;
    } else if(auto* ptr = boost::get<ast::ArrayType>(&type)){
        return ptr->type + "[]";
    } else {
        ASSERT_PATH_NOT_TAKEN("Unhandled type");
    }
}

void ast::DebugVisitor::operator()(ast::SourceFile& program) const {
    std::cout << indent() << "SourceFile" << std::endl;

    ++level;

    visit_each(*this, program.Content->blocks);
}

void ast::DebugVisitor::operator()(ast::Import& import) const {
    std::cout << indent() << "include \"" << import.file << "\"" << std::endl;
}

void ast::DebugVisitor::operator()(ast::StandardImport& import) const {
    std::cout << indent() << "include <" << import.header << ">" << std::endl;
}

template<typename Visitor, typename Container>
void print_each_sub(Visitor& visitor, Container& container){
    visitor.level++;
    visit_each(visitor, container);
    visitor.level--;
}

template<typename Visitor, typename Container>
void print_sub(Visitor& visitor, Container& container){
    visitor.level++;
    visit(visitor, container);
    visitor.level--;
}

void ast::DebugVisitor::operator()(ast::FunctionDeclaration& declaration) const {
    std::cout << indent() << "Function " << declaration.Content->functionName << std::endl;
    std::cout << indent() << "Parameters:" << std::endl;
    level++;
    for(auto param : declaration.Content->parameters){
        std::cout << indent() << param.parameterName << std::endl;
    }
    level--;
    std::cout << indent() << "Instructions:" << std::endl;
    print_each_sub(*this, declaration.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Struct& struct_) const {
    std::cout << indent() << "Structure declaration: " << struct_.Content->name << std::endl;
    level++;
    std::cout << indent() << "Members:" << std::endl;
    level++;
    visit_each_non_variant(*this, struct_.Content->members);
    level--;
    std::cout << indent() << "Functions:" << std::endl;
    level++;
    visit_each_non_variant(*this, struct_.Content->functions);
    level--;
    level--;
}

void ast::DebugVisitor::operator()(ast::MemberDeclaration& declaration) const {
    std::cout << indent() << toStringType(declaration.Content->type)  << " " << declaration.Content->name << std::endl;
}

void ast::DebugVisitor::operator()(ast::GlobalVariableDeclaration&) const {
    std::cout << indent() << "Global Variable" << std::endl;
}

void ast::DebugVisitor::operator()(ast::GlobalArrayDeclaration&) const {
    std::cout << indent() << "Global Array" << std::endl;
}

void ast::DebugVisitor::operator()(ast::For& for_) const {
    std::cout << indent() << "For" << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Foreach& for_) const {
    std::cout << indent() << "Foreach" << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::ForeachIn& for_) const {
    std::cout << indent() << "Foreach in " << std::endl;
    print_each_sub(*this, for_.Content->instructions);
}

void ast::DebugVisitor::operator()(Switch& switch_) const {
    std::cout << indent() << "Switch " << std::endl;

    ++level;
    std::cout << indent() << "Value" << std::endl;
    print_sub(*this, switch_.Content->value);
    for(auto& case_ : switch_.Content->cases){
        (*this)(case_);
    }
    if(switch_.Content->default_case){
        (*this)(*switch_.Content->default_case);
    }
    --level;
}

void ast::DebugVisitor::operator()(SwitchCase& switch_case) const {
    std::cout << indent() << "Case" << std::endl;

    ++level;
    std::cout << indent() << "Value" << std::endl;
    print_sub(*this, switch_case.value);
    std::cout << indent() << "Instructions" << std::endl;
    print_each_sub(*this, switch_case.instructions);
    --level;
}

void ast::DebugVisitor::operator()(DefaultCase& default_case) const {
    std::cout << indent() << "Default Case" << std::endl;

    print_each_sub(*this, default_case.instructions);
}

void ast::DebugVisitor::operator()(ast::While& while_) const {
    std::cout << indent() << "While" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, while_.Content->condition);
    print_each_sub(*this, while_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::DoWhile& while_) const {
    std::cout << indent() << "Do while" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, while_.Content->condition);
    std::cout << indent() << "Body:" << std::endl;
    print_each_sub(*this, while_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::Swap&) const {
    std::cout << indent() << "Swap" << std::endl;
}

void ast::DebugVisitor::operator()(ast::If& if_) const {
    std::cout << indent() << "If" << std::endl;
    std::cout << indent() << "Condition:" << std::endl;
    print_sub(*this, if_.Content->condition);
    std::cout << indent() << "Body:" << std::endl;
    print_each_sub(*this, if_.Content->instructions);
}

void ast::DebugVisitor::operator()(ast::FunctionCall& call) const {
    std::cout << indent() << "FunctionCall " << call.Content->functionName << std::endl;
    print_each_sub(*this, call.Content->values);
}

void ast::DebugVisitor::operator()(ast::MemberFunctionCall& call) const {
    std::cout << indent() << "Member FunctionCall " << call.Content->object_name << "." << call.Content->function_name << std::endl;
    print_each_sub(*this, call.Content->values);
}

void ast::DebugVisitor::operator()(ast::BuiltinOperator& builtin) const {
    std::cout << indent() << "Builtin Operator " << (int) builtin.Content->type << std::endl;
    print_each_sub(*this, builtin.Content->values);
}

void ast::DebugVisitor::operator()(ast::VariableDeclaration& declaration) const {
    std::cout << indent() << "Variable declaration [" << declaration.Content->variableName << "]" << std::endl;

    if(declaration.Content->value){
        print_sub(*this, *declaration.Content->value);
    }
}

void ast::DebugVisitor::operator()(ast::ArrayDeclaration&) const {
    std::cout << indent() << "Array declaration" << std::endl;
}

void ast::DebugVisitor::operator()(ast::SuffixOperation& op) const {
    std::cout << indent() << op.Content->variableName << "(suffix)" << (int)op.Content->op << std::endl;
}

void ast::DebugVisitor::operator()(ast::PrefixOperation& op) const {
    std::cout << indent() << (int)op.Content->op << "(prefix)" << op.Content->variableName << std::endl;
}

void ast::DebugVisitor::operator()(ast::Assignment& assign) const {
    std::cout << indent() << "Assignment [operator = " << static_cast<int>(assign.Content->op) << " ] " << std::endl;

    std::cout << indent() << "Left Value:" << std::endl;
    print_sub(*this, assign.Content->left_value);

    std::cout << indent() << "Right Value:" << std::endl;
    print_sub(*this, assign.Content->value);
}

void ast::DebugVisitor::operator()(ast::Ternary& ternary) const {
    std::cout << indent() << "Ternary" << std::endl;

    std::cout << indent() << "Condition Value:" << std::endl;
    print_sub(*this, ternary.Content->condition);

    std::cout << indent() << "True Value:" << std::endl;
    print_sub(*this, ternary.Content->true_value);

    std::cout << indent() << "False Value:" << std::endl;
    print_sub(*this, ternary.Content->false_value);
}

void ast::DebugVisitor::operator()(ast::Return& return_) const {
    std::cout << indent() << "Function return" << std::endl;
    print_sub(*this, return_.Content->value);
}

void ast::DebugVisitor::operator()(ast::Litteral& litteral) const {
    std::cout << indent() << "Litteral [" << litteral.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Integer& integer) const {
    std::cout << indent() << "Integer [" << integer.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::IntegerSuffix& integer) const {
    std::cout << indent() << "Float (suffix) [" << integer.value << "f]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Float& float_) const {
    std::cout << indent() << "Float [" << float_.value << "]" << std::endl;
}

void ast::DebugVisitor::operator()(ast::True&) const {
    std::cout << indent() << "true" << std::endl;
}

void ast::DebugVisitor::operator()(ast::Null&) const {
    std::cout << indent() << "null" << std::endl;
}

void ast::DebugVisitor::operator()(ast::False&) const {
    std::cout << indent() << "false" << std::endl;
}

void ast::DebugVisitor::operator()(ast::VariableValue& value) const {
    std::cout << indent() << "Variable " << value.Content->var->name();

    for(auto& member : value.Content->memberNames){
        std::cout << "." << member;
    }

    std::cout << std::endl;
}

void ast::DebugVisitor::operator()(ast::DereferenceValue& value) const {
    std::cout << indent() << "Dereference Variable Value" << std::endl;;

    std::cout << indent() << "Left Value:" << std::endl;
    print_sub(*this, value.Content->ref);
}

void ast::DebugVisitor::operator()(ast::ArrayValue& value) const {
    std::cout << indent() << "Array value [" << value.Content->arrayName << "]" << std::endl;
    print_sub(*this, value.Content->indexValue);
}

void ast::DebugVisitor::operator()(ast::Expression& value) const {
    std::cout << indent() << "Expression [" << value.Content->operations.size() << "]" << std::endl;
    ++level;
    visit(*this, value.Content->first);
    for(auto& operation : value.Content->operations){
        std::cout << indent() << (int) operation.get<0>() << std::endl;
        visit(*this, operation.get<1>());
    }
    --level;
}

void ast::DebugVisitor::operator()(ast::Unary& value) const {
    std::cout << indent() << "Unary " << static_cast<int>(value.Content->op) << std::endl;
    print_sub(*this, value.Content->value);
}

void ast::DebugVisitor::operator()(ast::Cast& cast) const {
    std::cout << indent() << "Cast " << std::endl;
    std::cout << indent() << "\tType: " << toStringType(cast.Content->type) << std::endl;
    print_sub(*this, cast.Content->value);
}
<|endoftext|>