Commit 63f7a1ed authored by Chris Müller's avatar Chris Müller
Browse files

Move sources into its own bootstrap build

parent dee7ec4a
......@@ -12,6 +12,7 @@ set(CHERRY_VERSION 0.1)
include_directories(crystal/include)
include_directories(include)
add_subdirectory(source)
add_subdirectory(test)
#add_subdirectory(source)
add_subdirectory(bootstrap)
#add_subdirectory(test)
set(BOOTSTRAP_SOURCES
bootstrap.c
array.c
read.c
eval.c
value.c
unicode.c
tables.c
runtime.c
primitives.c)
add_executable(bootstrap-cherry ${BOOTSTRAP_SOURCES})
target_link_libraries(bootstrap-cherry readline gc)
......@@ -16,12 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cherry/array.h"
#include "bootstrap.h"
#include <assert.h>
#include <string.h>
#include <gc.h>
struct org_cherry_array
struct cherry_array
{
uint8_t* data;
size_t alloc;
......@@ -31,12 +31,12 @@ struct org_cherry_array
struct org_cherry_array*
org_cherry_array_new(size_t init_capacity)
struct cherry_array*
cherry_array_new(size_t init_capacity)
{
assert(init_capacity != 0);
struct org_cherry_array* array = GC_MALLOC(sizeof(struct org_cherry_array));
struct cherry_array* array = GC_MALLOC(sizeof(struct cherry_array));
array->alloc = init_capacity;
array->length = 0;
array->data = GC_MALLOC(sizeof(uint8_t) * array->alloc);
......@@ -47,7 +47,7 @@ org_cherry_array_new(size_t init_capacity)
size_t
org_cherry_array_size(struct org_cherry_array* array)
cherry_array_size(struct cherry_array* array)
{
assert(array != 0);
......@@ -57,7 +57,7 @@ org_cherry_array_size(struct org_cherry_array* array)
size_t
org_cherry_array_capacity(struct org_cherry_array* array)
cherry_array_capacity(struct cherry_array* array)
{
assert(array != 0);
......@@ -66,7 +66,7 @@ org_cherry_array_capacity(struct org_cherry_array* array)
size_t
org_cherry_array_ensure(struct org_cherry_array* array, size_t min_capacity)
cherry_array_ensure(struct cherry_array* array, size_t min_capacity)
{
assert(array != 0);
......@@ -81,7 +81,7 @@ org_cherry_array_ensure(struct org_cherry_array* array, size_t min_capacity)
size_t
org_cherry_array_trim(struct org_cherry_array* array)
cherry_array_trim(struct cherry_array* array)
{
assert(array != 0);
......@@ -93,11 +93,11 @@ org_cherry_array_trim(struct org_cherry_array* array)
void
org_cherry_array_append(struct org_cherry_array* array, cy_const_pointer_t data, size_t size)
cherry_array_append(struct cherry_array* array, const_pointer_t data, size_t size)
{
assert(array != 0);
org_cherry_array_ensure(array, array->length + size);
cherry_array_ensure(array, array->length + size);
memcpy(array->data + array->length, data, size);
......@@ -106,14 +106,14 @@ org_cherry_array_append(struct org_cherry_array* array, cy_const_pointer_t data,
int
org_cherry_array_insert(struct org_cherry_array* array, size_t index, cy_const_pointer_t data, size_t size)
cherry_array_insert(struct cherry_array* array, size_t index, const_pointer_t data, size_t size)
{
assert(array != 0);
if(index >= array->length)
return FALSE;
org_cherry_array_ensure(array, array->length + size);
cherry_array_ensure(array, array->length + size);
memmove(array->data + index + size, array->data + index, array->length - index);
memcpy(array->data + index, data, size);
......@@ -125,20 +125,20 @@ org_cherry_array_insert(struct org_cherry_array* array, size_t index, cy_const_p
int
org_cherry_array_replace(struct org_cherry_array* array, size_t index, cy_const_pointer_t data, size_t size)
cherry_array_replace(struct cherry_array* array, size_t index, const_pointer_t data, size_t size)
{
assert(array != 0);
if(index >= array->length && index + size > array->length)
return FALSE;
org_cherry_array_ensure(array, array->length + size);
cherry_array_ensure(array, array->length + size);
memcpy(array->data + index, data, size);
}
int
org_cherry_array_remove(struct org_cherry_array* array, size_t index, size_t size)
cherry_array_remove(struct cherry_array* array, size_t index, size_t size)
{
assert(array != 0);
......@@ -155,7 +155,7 @@ org_cherry_array_remove(struct org_cherry_array* array, size_t index, size_t siz
void
org_cherry_array_clear(struct org_cherry_array* array)
cherry_array_clear(struct cherry_array* array)
{
assert(array != 0);
......@@ -164,8 +164,8 @@ org_cherry_array_clear(struct org_cherry_array* array)
cy_pointer_t
org_cherry_array_get(struct org_cherry_array* array, size_t index)
pointer_t
cherry_array_get(struct cherry_array* array, size_t index)
{
assert(array != 0);
......@@ -176,8 +176,8 @@ org_cherry_array_get(struct org_cherry_array* array, size_t index)
}
cy_pointer_t
org_cherry_array_clone(struct org_cherry_array* array)
pointer_t
cherry_array_clone(struct cherry_array* array)
{
assert(array != 0);
......@@ -192,23 +192,23 @@ org_cherry_array_clone(struct org_cherry_array* array)
}
struct org_cherry_ptrarray
struct cherry_ptrarray
{
cy_pointer_t* data;
pointer_t* data;
size_t alloc;
size_t length;
};
struct org_cherry_ptrarray*
org_cherry_ptrarray_new(size_t init_capacity)
struct cherry_ptrarray*
cherry_ptrarray_new(size_t init_capacity)
{
assert(init_capacity != 0);
struct org_cherry_ptrarray* array = GC_MALLOC(sizeof(struct org_cherry_ptrarray));
struct cherry_ptrarray* array = GC_MALLOC(sizeof(struct cherry_ptrarray));
array->alloc = init_capacity;
array->length = 0;
array->data = GC_MALLOC(sizeof(cy_pointer_t) * array->alloc);
array->data = GC_MALLOC(sizeof(pointer_t) * array->alloc);
return array;
}
......@@ -216,7 +216,7 @@ org_cherry_ptrarray_new(size_t init_capacity)
size_t
org_cherry_ptrarray_size(struct org_cherry_ptrarray* array)
cherry_ptrarray_size(struct cherry_ptrarray* array)
{
assert(array != 0);
......@@ -225,7 +225,7 @@ org_cherry_ptrarray_size(struct org_cherry_ptrarray* array)
size_t
org_cherry_ptrarray_capacity(struct org_cherry_ptrarray* array)
cherry_ptrarray_capacity(struct cherry_ptrarray* array)
{
assert(array != 0);
......@@ -234,14 +234,14 @@ org_cherry_ptrarray_capacity(struct org_cherry_ptrarray* array)
size_t
org_cherry_ptrarray_ensure(struct org_cherry_ptrarray* array, size_t min_capacity)
cherry_ptrarray_ensure(struct cherry_ptrarray* array, size_t min_capacity)
{
assert(array != 0);
if(array->alloc < min_capacity) {
size_t new_capacity = (array->alloc >> 1);
array->alloc = (new_capacity > min_capacity) ? new_capacity : min_capacity;
array->data = GC_REALLOC(array->data, sizeof(cy_pointer_t) * array->alloc);
array->data = GC_REALLOC(array->data, sizeof(pointer_t) * array->alloc);
}
return array->alloc;
......@@ -249,11 +249,11 @@ org_cherry_ptrarray_ensure(struct org_cherry_ptrarray* array, size_t min_capacit
size_t
org_cherry_ptrarray_trim(struct org_cherry_ptrarray* array)
cherry_ptrarray_trim(struct cherry_ptrarray* array)
{
assert(array != 0);
array->data = GC_REALLOC(array->data, sizeof(cy_pointer_t) * array->length);
array->data = GC_REALLOC(array->data, sizeof(pointer_t) * array->length);
array->alloc = array->length;
return array->alloc;
......@@ -261,11 +261,11 @@ org_cherry_ptrarray_trim(struct org_cherry_ptrarray* array)
void
org_cherry_ptrarray_append(struct org_cherry_ptrarray* array, cy_pointer_t ptr)
cherry_ptrarray_append(struct cherry_ptrarray* array, pointer_t ptr)
{
assert(array != 0);
org_cherry_ptrarray_ensure(array, array->length + 1);
cherry_ptrarray_ensure(array, array->length + 1);
*(array->data + array->length) = ptr;
......@@ -274,16 +274,16 @@ org_cherry_ptrarray_append(struct org_cherry_ptrarray* array, cy_pointer_t ptr)
int
org_cherry_ptrarray_insert(struct org_cherry_ptrarray* array, size_t index, cy_pointer_t ptr)
cherry_ptrarray_insert(struct cherry_ptrarray* array, size_t index, pointer_t ptr)
{
assert(array != 0);
if(index >= array->length)
return FALSE;
org_cherry_ptrarray_ensure(array, array->length + 1);
cherry_ptrarray_ensure(array, array->length + 1);
memmove(array->data + index + 1, array->data + index, (array->length - index) * sizeof(cy_pointer_t));
memmove(array->data + index + 1, array->data + index, (array->length - index) * sizeof(pointer_t));
*(array->data + index) = ptr;
......@@ -293,32 +293,32 @@ org_cherry_ptrarray_insert(struct org_cherry_ptrarray* array, size_t index, cy_p
}
cy_pointer_t
org_cherry_ptrarray_replace(struct org_cherry_ptrarray* array, size_t index, cy_pointer_t ptr)
pointer_t
cherry_ptrarray_replace(struct cherry_ptrarray* array, size_t index, pointer_t ptr)
{
assert(array != 0);
if(index >= array->length)
return 0;
cy_pointer_t data = *(array->data + index);
pointer_t data = *(array->data + index);
*(array->data + index) = ptr;
return data;
}
cy_pointer_t
org_cherry_ptrarray_remove(struct org_cherry_ptrarray* array, size_t index)
pointer_t
cherry_ptrarray_remove(struct cherry_ptrarray* array, size_t index)
{
assert(array != 0);
if(index >= array->length)
return FALSE;
cy_pointer_t data = *(array->data + index);
pointer_t data = *(array->data + index);
memmove(array->data + index, array->data + index + 1, (array->length - index - 1) * sizeof(cy_pointer_t));
memmove(array->data + index, array->data + index + 1, (array->length - index - 1) * sizeof(pointer_t));
array->length -= 1;
......@@ -326,8 +326,8 @@ org_cherry_ptrarray_remove(struct org_cherry_ptrarray* array, size_t index)
}
cy_pointer_t
org_cherry_ptrarray_get(struct org_cherry_ptrarray* array, size_t index)
pointer_t
cherry_ptrarray_get(struct cherry_ptrarray* array, size_t index)
{
assert(array != 0);
......@@ -338,7 +338,7 @@ org_cherry_ptrarray_get(struct org_cherry_ptrarray* array, size_t index)
}
void
org_cherry_ptrarray_clear(struct org_cherry_ptrarray* array)
cherry_ptrarray_clear(struct cherry_ptrarray* array)
{
assert(array != 0);
array->length = 0;
......
#include <stdio.h>
#include <stdlib.h>
/*
* Cherry programming language
* Copyright (C) 2013 Christoph Mueller
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bootstrap.h"
#include <getopt.h>
#include <readline/readline.h>
#include <gc.h>
#include "cherry/array.h"
#include "cherry/read.h"
static void
print_usage(FILE* out, const char* prog) {
......@@ -16,7 +32,7 @@ print_usage(FILE* out, const char* prog) {
}
static const cy_byte_t*
static const byte_t*
get_text(const char* filename, const char* mode) {
FILE* file = fopen(filename, mode);
size_t filesize;
......@@ -28,8 +44,8 @@ get_text(const char* filename, const char* mode) {
filesize = ftell(file);
rewind(file);
cy_byte_t* data = GC_MALLOC(filesize * sizeof(cy_byte_t));
fread(data, sizeof(cy_byte_t), filesize, file);
byte_t* data = GC_MALLOC(filesize * sizeof(byte_t));
fread(data, sizeof(byte_t), filesize, file);
fclose(file);
return data;
......@@ -37,77 +53,77 @@ get_text(const char* filename, const char* mode) {
static void
org_cherry_process_file(const char* filename, const cy_byte_t* method, struct org_cherry_value* arguments)
cherry_process_file(const char* filename, const byte_t* method, struct cherry_value* arguments)
{
const cy_byte_t* src = get_text(filename, "rb");
const byte_t* src = get_text(filename, "rb");
if(src == 0) {
fprintf(stderr, "cherry: couldn't load %s\n", filename);
exit(EXIT_FAILURE);
}
struct org_cherry_environment* env = org_cherry_environment();
struct org_cherry_context* context = org_cherry_context(src, filename, CY_SUPRESS_COMMENTS);
struct cherry_environment* env = cherry_environment();
struct cherry_context* context = cherry_context(src, filename, SUPRESS_COMMENTS);
struct org_cherry_value* exp = org_cherry_read(context);
struct cherry_value* exp = cherry_read(context);
org_cherry_env_push_exception_point(env);
cherry_env_push_exception_point(env);
if(!setjmp(EXCEPTION_JUMP(env))) {
while(exp != 0) {
org_cherry_eval(env, exp);
exp = org_cherry_read(context);
cherry_eval(env, exp);
exp = cherry_read(context);
}
if(method) {
struct org_cherry_value* main = org_cherry_list_cons(org_cherry_symbol(method), arguments);
struct cherry_value* main = cherry_list_cons(cherry_symbol(method), arguments);
org_cherry_eval(env, main);
cherry_eval(env, main);
}
} else {
fprintf(stderr, "EXCEPTION: ");
org_cherry_print(stderr, HEAD(EXCEPTION_DATA(env)));
cherry_print(stderr, HEAD(EXCEPTION_DATA(env)));
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
org_cherry_env_pop_exception_point(env);
cherry_env_pop_exception_point(env);
exit(EXIT_SUCCESS);
}
static void
org_cherry_start_repl(void)
cherry_start_repl(void)
{
printf("Cherry Interpreter 0.1\n\n");
printf("Welcome to bootstrap-cherry\n\n");
struct org_cherry_environment* env = org_cherry_environment();
struct cherry_environment* env = cherry_environment();
org_cherry_env_push_exception_point(env);
cherry_env_push_exception_point(env);
cy_byte_t* line = (cy_byte_t*) readline("> ");
struct org_cherry_context* context = org_cherry_context_repl(line);
byte_t* line = (byte_t*) readline("> ");
struct cherry_context* context = cherry_context_repl(line);
while(1) {
struct org_cherry_value* exp = org_cherry_read(context);
struct cherry_value* exp = cherry_read(context);
if(!setjmp(EXCEPTION_JUMP(env))) {
org_cherry_print(stdout, org_cherry_eval(env, exp));
cherry_print(stdout, cherry_eval(env, exp));
printf("\n");
} else {
fprintf(stderr, "EXCEPTION: ");
org_cherry_print(stderr, EXCEPTION_DATA(env));
cherry_print(stderr, EXCEPTION_DATA(env));
fprintf(stderr, "\n");
}
free(line);
line = (cy_byte_t*) readline("> ");
org_cherry_context_repl_set_source(context, line);
line = (byte_t*) readline("> ");
cherry_context_repl_set_source(context, line);
}
org_cherry_env_pop_exception_point(env);
cherry_env_pop_exception_point(env);
}
......@@ -120,13 +136,13 @@ main(int argc, char** argv)
{"main", optional_argument, 0, 'M'}
};
org_cherry_initialize(0);
cherry_initialize(0);
int ch;
const char* filename = 0;
const cy_byte_t* method = 0;
struct org_cherry_ptrarray* load_path = org_cherry_ptrarray_new(4);
struct org_cherry_value* arguments = org_cherry_emptylist;
const byte_t* method = 0;
struct cherry_ptrarray* load_path = cherry_ptrarray_new(4);
struct cherry_value* arguments = cherry_emptylist;
while( (ch = getopt_long(argc, argv, "hI:M:", options, 0)) != -1) {
switch(ch) {
......@@ -134,7 +150,7 @@ main(int argc, char** argv)
print_usage(stdout, argv[0]);
exit(EXIT_SUCCESS);
case 'I':
org_cherry_ptrarray_append(load_path, optarg);
cherry_ptrarray_append(load_path, optarg);
break;
case 'M':
method = optarg;
......@@ -152,14 +168,14 @@ main(int argc, char** argv)
filename = argv[optind++];
while(optind < argc) {
arguments = org_cherry_list_cons(org_cherry_string(argv[optind++]), arguments);
arguments = cherry_list_cons(cherry_string(argv[optind++]), arguments);
}
if(filename)
org_cherry_process_file(filename, method, org_cherry_list_reverse(arguments));
cherry_process_file(filename, method, cherry_list_reverse(arguments));
else
org_cherry_start_repl();
cherry_start_repl();
return EXIT_SUCCESS;
return EXIT_SUCCESS;
}
/*
* Cherry programming language
* Copyright (C) 2013 Christoph Mueller
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <setjmp.h>
#include <string.h>
struct cherry_environment;
struct cherry_value;
#define TRUE 1
#define FALSE 0
typedef void* pointer_t;
typedef const void* const_pointer_t;
typedef uint8_t byte_t;
typedef int64_t fixnum_t;
typedef double float_t;
typedef char boolean_t;
typedef uint32_t unicode_t;
typedef uint32_t flags_t;
typedef struct cherry_value* (*primitive_t)(struct cherry_environment* env, struct cherry_value* args);
enum cherry_value_type {
EMPTYLIST, BOOLEAN, DOT,
FIXNUM, FLOAT, STRING, CHAR, PAIR,
TUPLE, SYMBOL, PRIMITIVE, PROCEDURE
};
struct cherry_value {
enum cherry_value_type tag;
union {
// trivial
boolean_t boolean_value;
fixnum_t fixnum_value;
float_t float_value;
unicode_t char_value;
primitive_t fun_value;
const byte_t* string_value;
const byte_t* symbol_value;
// lists
struct {
struct cherry_value* head;
struct cherry_value* tail;
} pair;
// tuples
struct {
struct cherry_value** data;
size_t size;
} tuple;
// procedures
struct {
struct cherry_value* param;
struct cherry_value* body;
struct cherry_environment* env;
} proc;
};
};
#define TYPE(value) (value->tag)
#define IS_NULL(value) (value->tag == EMPTYLIST)
#define IS_BOOLEAN(value) (value->tag == BOOLEAN)
#define IS_DOT(value) (value->tag == DOT)
#define IS_FIXNUM(value) (value->tag == FIXNUM)
#define IS_STRING(value) (value->tag == STRING)
#define IS_SYMBOL(value) (value->tag == SYMBOL)
#define IS_FLOAT(value) (value->tag == FLOAT)
#define IS_CHAR(value) (value->tag == CHAR)
#define IS_PAIR(value) (value->tag == PAIR)
#define IS_PRIMITIVE(value) (value->tag == PRIMITIVE)
#define IS_PROCEDURE(value) (value->tag == PROCEDURE)