/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "vm/Keywords.h"

static const char * const keyword_list[] = {
#define KEYWORD_STRING(keyword, name, type) #keyword,
    FOR_EACH_JAVASCRIPT_KEYWORD(KEYWORD_STRING)
#undef KEYWORD_STRING
};

struct gen_opt {
    FILE* output;                       /* output file for generated source */
    unsigned use_if_threshold;          /* max number of choices to generate
                                           "if" selector instead of "switch" */
    unsigned char_tail_test_threshold;  /* max number of unprocessed columns
                                           to use inlined char compare
                                           for remaining chars and not generic
                                           string compare code */
    unsigned indent_level;              /* current source identation level */
};

static unsigned column_to_compare;

static int
length_comparator(const void* a, const void* b)
{
    const char* str1 = keyword_list[*(unsigned*)a];
    const char* str2 = keyword_list[*(unsigned*)b];
    return (int)strlen(str1) - (int)strlen(str2);
}

static int
column_comparator(const void* a, const void* b)
{
    const char* str1 = keyword_list[*(unsigned*)a];
    const char* str2 = keyword_list[*(unsigned*)b];
    return (int)str1[column_to_compare] - (int)str2[column_to_compare];
}

static unsigned
count_different_lengths(unsigned indexes[], unsigned nelem)
{
    unsigned nlength, current_length, i, l;

    current_length = 0;
    nlength = 0;
    for (i = 0; i != nelem; ++i) {
        l = (unsigned)strlen(keyword_list[indexes[i]]);
        assert(l != 0);
        if (current_length != l) {
            ++nlength;
            current_length = l;
        }
    }
    return nlength;
}

static void
find_char_span_and_count(unsigned indexes[], unsigned nelem, unsigned column,
                         unsigned* span_result, unsigned* count_result)
{
    unsigned i, count;
    unsigned char c, prev, minc, maxc;

    assert(nelem != 0);
    minc = maxc = prev = (unsigned char)keyword_list[indexes[0]][column];
    count = 1;
    for (i = 1; i != nelem; ++i) {
        c = (unsigned char)keyword_list[indexes[i]][column];
        if (prev != c) {
            prev = c;
            ++count;
            if (minc > c) {
                minc = c;
            } else if (maxc < c) {
                maxc = c;
            }
        }
    }

    *span_result = maxc - minc + 1;
    *count_result = count;
}

static unsigned
find_optimal_switch_column(struct gen_opt* opt,
                           unsigned indexes[], unsigned nelem,
                           unsigned columns[], unsigned unprocessed_columns,
                           int* use_if_result)
{
    unsigned i;
    unsigned span, min_span, min_span_index;
    unsigned nchar, min_nchar, min_nchar_index;

    assert(unprocessed_columns != 0);
    i = 0;
    min_nchar = min_span = (unsigned)-1;
    min_nchar_index = min_span_index = 0;
    do {
        column_to_compare = columns[i];
        qsort(indexes, nelem, sizeof(indexes[0]), column_comparator);
        find_char_span_and_count(indexes, nelem, column_to_compare,
                                 &span, &nchar);
        assert(span != 0);
        if (span == 1) {
            assert(nchar == 1);
            *use_if_result = 1;
            return 1;
        }
        assert(nchar != 1);
        if (min_span > span) {
            min_span = span;
            min_span_index = i;
        }
        if (min_nchar > nchar) {
            min_nchar = nchar;
            min_nchar_index = i;
        }
    } while (++i != unprocessed_columns);

    if (min_nchar <= opt->use_if_threshold) {
        *use_if_result = 1;
        i = min_nchar_index;
    } else {
        *use_if_result = 0;
        i = min_span_index;
    }

    /*
     * Restore order corresponding to i if it was destroyed by
     * subsequent sort.
     */
    if (i != unprocessed_columns - 1) {
        column_to_compare = columns[i];
        qsort(indexes, nelem, sizeof(indexes[0]), column_comparator);
    }

    return i;
}


static void
p(struct gen_opt* opt, const char* format, ...)
{
    va_list ap;

    va_start(ap, format);
    vfprintf(opt->output, format, ap);
    va_end(ap);
}

/* Size for '\xxx' where xxx is octal escape */
#define MIN_QUOTED_CHAR_BUFFER 7

static char*
qchar(char c, char* quoted_buffer)
{
    char* s;

    s = quoted_buffer;
    *s++ = '\'';
    switch (c) {
      case '\n': c = 'n'; goto one_char_escape;
      case '\r': c = 'r'; goto one_char_escape;
      case '\t': c = 't'; goto one_char_escape;
      case '\f': c = 't'; goto one_char_escape;
      case '\0': c = '0'; goto one_char_escape;
      case '\'': goto one_char_escape;
      one_char_escape:
        *s++ = '\\';
        break;
      default:
        if (!isprint(c)) {
            *s++ = '\\';
            *s++ = (char)('0' + (0x3 & (((unsigned char)c) >> 6)));
            *s++ = (char)('0' + (0x7 & (((unsigned char)c) >> 3)));
            c = (char)('0' + (0x7 & ((unsigned char)c)));
        }
    }
    *s++ = c;
    *s++ = '\'';
    *s = '\0';
    assert(s + 1 <= quoted_buffer + MIN_QUOTED_CHAR_BUFFER);
    return quoted_buffer;
}

static void
nl(struct gen_opt* opt)
{
    putc('\n', opt->output);
}

static void
indent(struct gen_opt* opt)
{
    unsigned n = opt->indent_level;
    while (n != 0) {
        --n;
        fputs("    ", opt->output);
    }
}

static void
line(struct gen_opt* opt, const char* format, ...)
{
    va_list ap;

    indent(opt);
    va_start(ap, format);
    vfprintf(opt->output, format, ap);
    va_end(ap);
    nl(opt);
}

static void
generate_letter_switch_r(struct gen_opt* opt,
                         unsigned indexes[], unsigned nelem,
                         unsigned columns[], unsigned unprocessed_columns)
{
    char qbuf[MIN_QUOTED_CHAR_BUFFER];

    assert(nelem != 0);
    if (nelem == 1) {
        unsigned kw_index = indexes[0];
        const char* keyword = keyword_list[kw_index];

        if (unprocessed_columns == 0) {
            line(opt, "JSKW_GOT_MATCH(%u) /* %s */", kw_index, keyword);
        } else if (unprocessed_columns > opt->char_tail_test_threshold) {
            line(opt, "JSKW_TEST_GUESS(%u) /* %s */", kw_index, keyword);
        } else {
            unsigned i, column;

            indent(opt); p(opt, "if (");
            for (i = 0; i != unprocessed_columns; ++i) {
                column = columns[i];
                qchar(keyword[column], qbuf);
                p(opt, "%sJSKW_AT(%u)==%s", (i == 0) ? "" : " && ",
                  column, qbuf);
            }
            p(opt, ") {"); nl(opt);
            ++opt->indent_level;
            line(opt, "JSKW_GOT_MATCH(%u) /* %s */", kw_index, keyword);
            --opt->indent_level;
            line(opt, "}");
            line(opt, "JSKW_NO_MATCH()");
        }
    } else {
        unsigned optimal_column_index, optimal_column;
        unsigned i;
        int use_if;
        char current;

        assert(unprocessed_columns != 0);
        optimal_column_index = find_optimal_switch_column(opt, indexes, nelem,
                                                          columns,
                                                          unprocessed_columns,
                                                          &use_if);
        optimal_column = columns[optimal_column_index];
        columns[optimal_column_index] = columns[unprocessed_columns - 1];

        if (!use_if)
            line(opt, "switch (JSKW_AT(%u)) {", optimal_column);

        current = keyword_list[indexes[0]][optimal_column];
        for (i = 0; i != nelem;) {
            unsigned same_char_begin = i;
            char next = current;

            for (++i; i != nelem; ++i) {
                next = keyword_list[indexes[i]][optimal_column];
                if (next != current)
                    break;
            }
            qchar(current, qbuf);
            if (use_if) {
                line(opt, "if (JSKW_AT(%u) == %s) {", optimal_column, qbuf);
            } else {
                line(opt, "  case %s:", qbuf);
            }
            ++opt->indent_level;
            generate_letter_switch_r(opt, indexes + same_char_begin,
                                     i - same_char_begin,
                                     columns, unprocessed_columns - 1);
            --opt->indent_level;
            if (use_if) {
                line(opt, "}");
            }
            current = next;
        }

        if (!use_if) {
            line(opt, "}");
        }

        columns[optimal_column_index] = optimal_column;

        line(opt, "JSKW_NO_MATCH()");
    }
}

static void
generate_letter_switch(struct gen_opt* opt,
                       unsigned indexes[], unsigned nelem,
                       unsigned current_length)
{
    unsigned* columns;
    unsigned i;

    columns = (unsigned*) malloc(sizeof(columns[0]) * current_length);
    if (!columns) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    for (i = 0; i != current_length; ++i) {
        columns[i] = i;
    }
    generate_letter_switch_r(opt, indexes, nelem, columns, current_length);
    free(columns);
}


static void
generate_switch(struct gen_opt* opt)
{
    unsigned* indexes;
    unsigned nlength;
    unsigned i, current;
    int use_if;
    unsigned nelem;

    nelem = sizeof(keyword_list)/sizeof(keyword_list[0]);

    line(opt, "/*");
    line(opt, " * Generating switch for the list of %u entries:", nelem);
    for (i = 0; i != nelem; ++i) {
        line(opt, " * %s", keyword_list[i]);
    }
    line(opt, " */");

    indexes = (unsigned*) malloc(sizeof(indexes[0]) * nelem);
    if (!indexes) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    for (i = 0; i != nelem; ++i)
        indexes[i] = i;
    qsort(indexes, nelem, sizeof(indexes[i]), length_comparator);
    nlength = count_different_lengths(indexes, nelem);

    use_if = (nlength <= opt->use_if_threshold);

    if (!use_if)
        line(opt, "switch (JSKW_LENGTH()) {");

    current = (unsigned)strlen(keyword_list[indexes[0]]);
    for (i = 0; i != nelem;) {
        unsigned same_length_begin = i;
        unsigned next = current;

        for (++i; i != nelem; ++i) {
            next = (unsigned)strlen(keyword_list[indexes[i]]);
            if (next != current)
                break;
        }
        if (use_if) {
            line(opt, "if (JSKW_LENGTH() == %u) {", current);
        } else {
            line(opt, "  case %u:", current);
        }
        ++opt->indent_level;
        generate_letter_switch(opt, indexes + same_length_begin,
                               i - same_length_begin,
                               current);
        --opt->indent_level;
        if (use_if) {
            line(opt, "}");
        }
        current = next;
    }
    if (!use_if)
        line(opt, "}");
    line(opt, "JSKW_NO_MATCH()");
    free(indexes);
}

int main(int argc, char** argv)
{
    struct gen_opt opt;

    if (argc < 2) {
        opt.output = stdout;
    } else {
        opt.output = fopen(argv[1], "w");
        if (!opt.output) {
            perror("fopen");
            exit(EXIT_FAILURE);
        }
    }
    opt.indent_level = 1;
    opt.use_if_threshold = 3;
    opt.char_tail_test_threshold = 4;

    generate_switch(&opt);

    if (opt.output != stdout) {
        if (fclose(opt.output)) {
            perror("fclose");
            exit(EXIT_FAILURE);
        }
    }

    return EXIT_SUCCESS;
}
