All pastes #1871828 Raw Edit

Untitled

public c v1 · immutable
#1871828 ·published 2010-05-08 15:58 UTC
rendered paste body
/* * Bootstrap Scheme - a quick and very dirty Scheme interpreter. * Copyright (C) 2010 Peter Michaux (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 {FIXNUM} object_type;typedef struct object {    object_type type;    union {        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 *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;}/***************************** READ ******************************/char is_delimiter(int c) {    return isspace(c) || c == EOF ||           c == '('   || c == ')' ||           c == '"'   || c == ';';}int peek(FILE *in) {    int c;    c = getc(in);    ungetc(c, in);    return c;}void eat_whitespace(FILE *in) {    int c;        while ((c = getc(in)) != EOF) {        if (isspace(c)) {            continue;        }        else if (c == ';') { /* comments are whitespace also */            printf("c is %c", c);            c = getc(in);            while ((c != EOF) && (c != '\n'));            {            c = getc(in);            printf("%i", c == '\n');            continue;            }        }        ungetc(c, in);        break;    }}object *read(FILE *in) {    int c;    short sign = 1;    long num = 0;    eat_whitespace(in);    c = getc(in);        if (isdigit(c) || (c == '-' && (isdigit(peek(in))))) {        /* 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 ****************************//* until we have lists and symbols just echo */object *eval(object *exp) {    return exp;}/**************************** PRINT ******************************/void write(object *obj) {    switch (obj->type) {        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 Bootstrap Scheme. "           "Use ctrl-c to exit.\n");    while (1) {        printf("> ");        write(eval(read(stdin)));        printf("\n");    }    return 0;}/**************************** MUSIC *******************************Slipknot, Neil Young, Pearl Jam, The Dead Weather,Dave Matthews Band, Alice in Chains, White Zombie, Blind Melon,Priestess, Puscifer*/