<commit_before>/*
 * Bootstrap Scheme - a quick and very dirty Scheme interpreter.
 * Copyright (C) 2010 <NAME> (http://peter.michaux.ca/)
 *
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public
 * License version 3 as published by the Free Software Foundation.
 *
 * This program 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 Affero General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License version 3 along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */

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

/**************************** MODEL ******************************/

typedef enum {BOOLEAN, FIXNUM} object_type;

typedef struct object {
    object_type type;
    union {
        struct {
            char value;
        } boolean;
        struct {
            long value;
        } fixnum;
    } data;
} object;

/* no GC so truely "unlimited extent" */
object *alloc_object(void) {
    object *obj;

    obj = malloc(sizeof(object));
    if (obj == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(1);
    }
    return obj;
}

object *false;
object *true;

char is_boolean(object *obj) {
    return obj->type == BOOLEAN;
}

char is_false(object *obj) {
    return obj == false;
}

object *make_fixnum(long value) {
    object *obj;

    obj = alloc_object();
    obj->type = FIXNUM;
    obj->data.fixnum.value = value;
    return obj;
}

char is_fixnum(object *obj) {
    return obj->type == FIXNUM;
}

void init(void) {
    false = alloc_object();
    false->type = BOOLEAN;
    false->data.boolean.value = 0;

    true = alloc_object();
    true->type = BOOLEAN;
    true->data.boolean.value = 1;
}

/***************************** READ ******************************/

char is_delimiter(char c) {
    return isspace(c) || c == EOF ||
           c == '('   || c == ')' ||
           c == '"';
}

object *read(FILE *in) {
    char c;
    short sign = 1;
    long num = 0;

    while ((c = getc(in)) != EOF) {
        if (isspace(c)) {
            continue;
        }
        else if (c == '#') { /* read a boolean */
            c = getc(in);
            switch (c) {
                case 't':
                    return true;
                case 'f':
                    return false;
                default:
                    fprintf(stderr, "unknown boolean literal\n");
                    exit(1);
            }
        }
        else if (isdigit(c) || c == '-') { /* read a fixnum */
            if (c == '-') {
                sign = -1;
            }
            else {
                ungetc(c, in);
            }
            while (isdigit(c = getc(in))) {
                num = (num * 10) + (c - '0');
            }
            num *= sign;
            if (is_delimiter(c)) {
                ungetc(c, in);
                return make_fixnum(num);
            }
            else {
                fprintf(stderr,
                        "number not followed by delimiter\n");
                exit(1);
            }
        }
        else {
            fprintf(stderr, "bad input. Unexpected '%c'\n", c);
            exit(1);
        }
    }
    fprintf(stderr, "read illegal state\n");
    exit(1);
}

/*************************** EVALUATE ****************************/

char is_self_evaluating(object *exp) {
    return is_boolean(exp) ||
           is_fixnum(exp);
}

object *eval(object *exp) {
    return exp;
}

/**************************** PRINT ******************************/

void write(object *obj) {
    switch (obj->type) {
        case BOOLEAN:
            printf("#%c", is_false(obj) ? 'f' : 't');
            break;
        case FIXNUM:
            printf("%ld", obj->data.fixnum.value);
            break;
        default:
            fprintf(stderr, "cannot write unknown type\n");
            exit(1);
    }
}

/***************************** REPL ******************************/

int main(void) {

    printf("Welcome to your Scheme REPL. "
           "Use ctrl-c to exit.\n");

    init();

    while(1) {
        printf("> ");
        write(eval(read(stdin)));
        printf("\n");
    }

    return 0;
}

/**************************** MUSIC *******************************

Slipknot, <NAME>, <NAME>, The Dead Weather,
<NAME>, Alice in Chains, White Zombie, Blind Melon,
Priestess, Puscifer, <NAME>

*/<commit_msg>code formatting<commit_after>/*
 * Bootstrap Scheme - a quick and very dirty Scheme interpreter.
 * Copyright (C) 2010 <NAME> (http://peter.michaux.ca/)
 *
 * This program is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public
 * License version 3 as published by the Free Software Foundation.
 *
 * This program 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 Affero General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License version 3 along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */

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

/**************************** MODEL ******************************/

typedef enum {BOOLEAN, FIXNUM} object_type;

typedef struct object {
    object_type type;
    union {
        struct {
            char value;
        } boolean;
        struct {
            long value;
        } fixnum;
    } data;
} object;

/* no GC so truely "unlimited extent" */
object *alloc_object(void) {
    object *obj;

    obj = malloc(sizeof(object));
    if (obj == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(1);
    }
    return obj;
}

object *false;
object *true;

char is_boolean(object *obj) {
    return obj->type == BOOLEAN;
}

char is_false(object *obj) {
    return obj == false;
}

object *make_fixnum(long value) {
    object *obj;

    obj = alloc_object();
    obj->type = FIXNUM;
    obj->data.fixnum.value = value;
    return obj;
}

char is_fixnum(object *obj) {
    return obj->type == FIXNUM;
}

void init(void) {
    false = alloc_object();
    false->type = BOOLEAN;
    false->data.boolean.value = 0;

    true = alloc_object();
    true->type = BOOLEAN;
    true->data.boolean.value = 1;
}

/***************************** READ ******************************/

char is_delimiter(char c) {
    return isspace(c) || c == EOF ||
           c == '('   || c == ')' ||
           c == '"';
}

object *read(FILE *in) {
    char c;
    short sign = 1;
    long num = 0;

    while ((c = getc(in)) != EOF) {
        if (isspace(c)) {
            continue;
        }
        else if (c == '#') { /* read a boolean */
            c = getc(in);
            switch (c) {
                case 't':
                    return true;
                case 'f':
                    return false;
                default:
                    fprintf(stderr, "unknown boolean literal\n");
                    exit(1);
            }
        }
        else if (isdigit(c) || c == '-') { /* read a fixnum */
            if (c == '-') {
                sign = -1;
            }
            else {
                ungetc(c, in);
            }
            while (isdigit(c = getc(in))) {
                num = (num * 10) + (c - '0');
            }
            num *= sign;
            if (is_delimiter(c)) {
                ungetc(c, in);
                return make_fixnum(num);
            }
            else {
                fprintf(stderr,
                        "number not followed by delimiter\n");
                exit(1);
            }
        }
        else {
            fprintf(stderr, "bad input. Unexpected '%c'\n", c);
            exit(1);
        }
    }
    fprintf(stderr, "read illegal state\n");
    exit(1);
}

/*************************** EVALUATE ****************************/

char is_self_evaluating(object *exp) {
    return is_boolean(exp) ||
           is_fixnum(exp);
}

object *eval(object *exp) {
    return exp;
}

/**************************** PRINT ******************************/

void write(object *obj) {
    switch (obj->type) {
        case BOOLEAN:
            printf("#%c", is_false(obj) ? 'f' : 't');
            break;
        case FIXNUM:
            printf("%ld", obj->data.fixnum.value);
            break;
        default:
            fprintf(stderr, "cannot write unknown type\n");
            exit(1);
    }
}

/***************************** REPL ******************************/

int main(void) {

    printf("Welcome to your Scheme REPL. "
           "Use ctrl-c to exit.\n");

    init();

    while (1) {
        printf("> ");
        write(eval(read(stdin)));
        printf("\n");
    }

    return 0;
}

/**************************** MUSIC *******************************

Slipknot, <NAME>, <NAME>, The Dead Weather,
<NAME> Band, Alice in Chains, White Zombie, Blind Melon,
Priestess, Puscifer, <NAME>

*/
{'fraction_non_alphanumeric': 0.1981397361020982, 'fraction_numerical': 0.004975124378109453, 'mean_word_length': 1.9133585381222433, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1281423', 'n_tokens_mistral': 2829, 'n_tokens_neox': 2729, 'n_words': 783}