Commit 949912ab authored by Chris Müller's avatar Chris Müller
Browse files

remove dependency to gc and move dynamic array implementation directly to cherry

parent a691dabb
/*
* 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
/**
* @file structures/array.h
* A dynmical, resized array implementation that hides all memory allocation for a user
*/
#include "cherry/standard.h"
#include <stdlib.h>
struct org_cherry_array;
struct org_cherry_ptrarray;
/**
* Creates an org_cherry_array instance with a given initialization- and extension size
* \param initialsize Sets the initial memory allocation for the internal buffer. Its size is always a multiple factor of the extensionsize
* and fits the given initialsize for the first initialization.
* \param extend Sets the size of memory blocks the array is dynamically extend.
* \return the reference cy_pointer_t to the constructed array, used by other array calls.
*/
struct org_cherry_array* org_cherry_array_new(size_t init_capacity);
/**
* Release all allocated memory for a created Array.
* \param array using array that should be freed
*/
size_t org_cherry_array_size(struct org_cherry_array* array);
size_t org_cherry_array_capacity(struct org_cherry_array* array);
size_t org_cherry_array_ensure(struct org_cherry_array* array, size_t min_capacity);
size_t 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);
int org_cherry_array_insert(struct org_cherry_array* array, size_t index, cy_const_pointer_t data, size_t size);
int org_cherry_array_remove(struct org_cherry_array* array, size_t index, size_t size);
int org_cherry_array_replace(struct org_cherry_array* array, size_t index, cy_const_pointer_t data, size_t size);
void org_cherry_array_clear(struct org_cherry_array* array);
cy_pointer_t org_cherry_array_clone(struct org_cherry_array* array);
cy_pointer_t org_cherry_array_get(struct org_cherry_array* array, size_t index);
struct org_cherry_ptrarray* org_cherry_ptrarray_new(size_t init_capacity);
size_t org_cherry_ptrarray_size(struct org_cherry_ptrarray* array);
size_t org_cherry_ptrarray_capacity(struct org_cherry_ptrarray* array);
size_t org_cherry_ptrarray_ensure(struct org_cherry_ptrarray* array, size_t min_capacity);
size_t org_cherry_ptrarray_trim(struct org_cherry_ptrarray* array);
void 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);
cy_pointer_t org_cherry_ptrarray_remove(struct org_cherry_ptrarray* array, size_t index);
cy_pointer_t org_cherry_ptrarray_replace(struct org_cherry_ptrarray* array, size_t index, cy_pointer_t ptr);
void org_cherry_ptrarray_clear(struct org_cherry_ptrarray* array);
cy_pointer_t org_cherry_ptrarray_get(struct org_cherry_ptrarray* array, size_t index);
......@@ -23,7 +23,7 @@
#include <stdlib.h>
#include <stdint.h>
struct CyArray;
struct org_cherry_array;
#define CY_DEFAULT 0
#define CY_SUPRESS_COMMENTS 1
......@@ -32,14 +32,13 @@ struct org_cherry_context {
const char* filename;
const byte_t* begin;
const byte_t* src;
struct CryArray* buffer;
struct org_cherry_array* buffer;
cy_flags_t flags;
};
struct org_cherry_context* org_cherry_context(const byte_t* source, const char* filename, cy_flags_t flags);
struct org_cherry_context* org_cherry_context_repl(const byte_t* source);
void org_cherry_context_free(struct org_cherry_context* context);
void org_cherry_error(struct org_cherry_context* context, const char* format, ...);
......
......@@ -23,7 +23,7 @@
#define FALSE 0
typedef void* cy_pointer_t;
typedef void* cy_const_pointer_t;
typedef const void* cy_const_pointer_t;
typedef uint8_t cy_byte_t;
typedef uint16_t cy_word_t;
......
set(CORE_SOURCES
array.c
read.c
eval.c
value.c
......@@ -11,4 +12,4 @@ set(INTERPRETER_SOURCES
add_library(cherry-core ${CORE_SOURCES})
add_executable(cherry ${INTERPRETER_SOURCES})
target_link_libraries(cherry readline crystal cherry-core gc)
target_link_libraries(cherry readline cherry-core gc)
/*
* 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 "cherry/array.h"
#include <assert.h>
#include <string.h>
#include <gc.h>
struct org_cherry_array
{
uint8_t* data;
size_t alloc;
size_t length;
};
struct org_cherry_array*
org_cherry_array_new(size_t init_capacity)
{
assert(init_capacity != 0);
struct org_cherry_array* array = GC_MALLOC(sizeof(struct org_cherry_array));
array->alloc = init_capacity;
array->length = 0;
array->data = GC_MALLOC(sizeof(uint8_t) * array->alloc);
return array;
}
size_t
org_cherry_array_size(struct org_cherry_array* array)
{
assert(array != 0);
return array->length;
}
size_t
org_cherry_array_capacity(struct org_cherry_array* array)
{
assert(array != 0);
return array->alloc;
}
size_t
org_cherry_array_ensure(struct org_cherry_array* 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(uint8_t) * array->alloc);
}
return array->alloc;
}
size_t
org_cherry_array_trim(struct org_cherry_array* array)
{
assert(array != 0);
array->data = GC_REALLOC(array->data, sizeof(uint8_t) * array->length);
array->alloc = array->length;
return array->alloc;
}
void
org_cherry_array_append(struct org_cherry_array* array, cy_const_pointer_t data, size_t size)
{
assert(array != 0);
org_cherry_array_ensure(array, array->length + size);
memcpy(array->data + array->length, data, size);
array->length += size;
}
int
org_cherry_array_insert(struct org_cherry_array* array, size_t index, cy_const_pointer_t data, size_t size)
{
assert(array != 0);
if(index >= array->length)
return FALSE;
org_cherry_array_ensure(array, array->length + size);
memmove(array->data + index + size, array->data + index, array->length - index);
memcpy(array->data + index, data, size);
array->length += size;
return TRUE;
}
int
org_cherry_array_replace(struct org_cherry_array* array, size_t index, cy_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);
memcpy(array->data + index, data, size);
}
int
org_cherry_array_remove(struct org_cherry_array* array, size_t index, size_t size)
{
assert(array != 0);
if(index >= array->length)
return FALSE;
memmove(array->data + index, array->data + index + size, array->length - index - size);
array->length -= size;
return TRUE;
}
void
org_cherry_array_clear(struct org_cherry_array* array)
{
assert(array != 0);
array->length = 0;
}
cy_pointer_t
org_cherry_array_get(struct org_cherry_array* array, size_t index)
{
assert(array != 0);
if(index < array->length)
return array->data + index;
return 0;
}
cy_pointer_t
org_cherry_array_clone(struct org_cherry_array* array)
{
assert(array != 0);
uint8_t* ptr = 0;
if(array->length > 0) {
ptr = GC_MALLOC(sizeof(uint8_t) * array->length);
memcpy(ptr, array->data, array->length);
}
return ptr;
}
struct org_cherry_ptrarray
{
cy_pointer_t* data;
size_t alloc;
size_t length;
};
struct org_cherry_ptrarray*
org_cherry_ptrarray_new(size_t init_capacity)
{
assert(init_capacity != 0);
struct org_cherry_ptrarray* array = GC_MALLOC(sizeof(struct org_cherry_ptrarray));
array->alloc = init_capacity;
array->length = 0;
array->data = GC_MALLOC(sizeof(cy_pointer_t) * array->alloc);
return array;
}
size_t
org_cherry_ptrarray_size(struct org_cherry_ptrarray* array)
{
assert(array != 0);
return array->length;
}
size_t
org_cherry_ptrarray_capacity(struct org_cherry_ptrarray* array)
{
assert(array != 0);
return array->alloc;
}
size_t
org_cherry_ptrarray_ensure(struct org_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);
}
return array->alloc;
}
size_t
org_cherry_ptrarray_trim(struct org_cherry_ptrarray* array)
{
assert(array != 0);
array->data = GC_REALLOC(array->data, sizeof(cy_pointer_t) * array->length);
array->alloc = array->length;
return array->alloc;
}
void
org_cherry_ptrarray_append(struct org_cherry_ptrarray* array, cy_pointer_t ptr)
{
assert(array != 0);
org_cherry_ptrarray_ensure(array, array->length + 1);
*(array->data + array->length) = ptr;
array->length += 1;
}
int
org_cherry_ptrarray_insert(struct org_cherry_ptrarray* array, size_t index, cy_pointer_t ptr)
{
assert(array != 0);
if(index >= array->length)
return FALSE;
org_cherry_ptrarray_ensure(array, array->length + 1);
memmove(array->data + index + 1, array->data + index, (array->length - index) * sizeof(cy_pointer_t));
*(array->data + index) = ptr;
array->length += 1;
return TRUE;
}
cy_pointer_t
org_cherry_ptrarray_replace(struct org_cherry_ptrarray* array, size_t index, cy_pointer_t ptr)
{
assert(array != 0);
if(index >= array->length)
return 0;
cy_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)
{
assert(array != 0);
if(index >= array->length)
return FALSE;
cy_pointer_t data = *(array->data + index);
memmove(array->data + index, array->data + index + 1, (array->length - index - 1) * sizeof(cy_pointer_t));
array->length -= 1;
return data;
}
cy_pointer_t
org_cherry_ptrarray_get(struct org_cherry_ptrarray* array, size_t index)
{
assert(array != 0);
if(index < array->length)
return *(array->data + index);
return 0;
}
void
org_cherry_ptrarray_clear(struct org_cherry_ptrarray* array)
{
assert(array != 0);
array->length = 0;
}
......@@ -18,22 +18,22 @@
#include "cherry.h"
#include "cherry/unicode.h"
#include <crystal/array.h>
#include "cherry/array.h"
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <gc.h>
struct org_cherry_context*
org_cherry_context(const byte_t* source, const char* filename, cy_flags_t flags)
{
struct org_cherry_context* context = malloc(sizeof(struct org_cherry_context));
struct org_cherry_context* context = GC_MALLOC(sizeof(struct org_cherry_context));
context->filename = filename;
context->begin = source;
context->src = (byte_t*) source;
context->buffer = cry_array_new(sizeof(byte_t));
context->buffer = org_cherry_array_new(sizeof(byte_t));
context->flags = flags;
return context;
......@@ -47,16 +47,6 @@ org_cherry_context_repl(const byte_t* source)
}
void
org_cherry_context_free(struct org_cherry_context* context)
{
assert(context != 0);
cry_array_free(context->buffer);
free(context);
}
void
org_cherry_error(struct org_cherry_context* context, const char* format, ...)
{
......@@ -136,7 +126,7 @@ enum FloatState {
static enum org_cherry_tok
lex_float(struct org_cherry_context* context)
{
struct CryArray* buffer = context->buffer;
struct org_cherry_array* buffer = context->buffer;
const byte_t* p = context->src;
unicode_t ch = org_cherry_utf8_get(p);
......@@ -158,7 +148,7 @@ lex_float(struct org_cherry_context* context)
state = FP_MINUSPLUS;
else if('0' > ch || ch > '9') {
org_cherry_error(context, "Unexpected character found in float literal after +/-");
cry_array_append(buffer, "0", 1);
org_cherry_array_append(buffer, "0", 1);
goto RETURN_TOKEN;
} else
state = FP_FINAL;
......@@ -168,7 +158,7 @@ lex_float(struct org_cherry_context* context)
state = FP_DECIMAL;
if('0' > ch || ch > '9') {
org_cherry_error(context, "Unexpected character found in float literal after dot");
cry_array_append(buffer, "0", 1);
org_cherry_array_append(buffer, "0", 1);
goto RETURN_TOKEN;
}
break;
......@@ -184,7 +174,7 @@ lex_float(struct org_cherry_context* context)
state = FP_FINAL;
if('0' > ch || ch > '9') {
org_cherry_error(context, "Unexpected character found in float literal");
cry_array_append(buffer, "0", 1);
org_cherry_array_append(buffer, "0", 1);
goto RETURN_TOKEN;
}
break;
......@@ -195,7 +185,7 @@ lex_float(struct org_cherry_context* context)
break;
}
cry_array_append(buffer, p, 1);
org_cherry_array_append(buffer, p, 1);
NO_APPEND_BUFFER:
p = org_cherry_utf8_next(p);
......@@ -206,7 +196,7 @@ NO_APPEND_BUFFER:
RETURN_TOKEN:
context->src = p;
cry_array_append(buffer, "\0", 1);
org_cherry_array_append(buffer, "\0", 1);
return TOK_FLOAT;
}
......@@ -228,7 +218,7 @@ enum NumberState {
static enum org_cherry_tok
lex_number(struct org_cherry_context* context)
{
struct CryArray* buffer = context->buffer;
struct org_cherry_array* buffer = context->buffer;
const byte_t* p = context->src;
unicode_t ch = org_cherry_utf8_get(p);
......@@ -264,7 +254,7 @@ lex_number(struct org_cherry_context* context)
case INT_HEX_WAIT:
if(('0' > ch || ch > '9') && ('A' > ch || ch > 'F')) {
org_cherry_error(context, "Unexpected character found in hex literal");
cry_array_append(buffer, "0", 1);
org_cherry_array_append(buffer, "0", 1);
token = TOK_HEX;
goto RETURN_TOKEN;
}
......@@ -274,7 +264,7 @@ lex_number(struct org_cherry_context* context)
case INT_BIN_WAIT:
if(ch != '0' && ch != '1') {
org_cherry_error(context, "Unexpected character found in binary literal");
cry_array_append(buffer, "0", 1);
org_cherry_array_append(buffer, "0", 1);
token = TOK_BIN;
goto RETURN_TOKEN;
}
......@@ -312,7 +302,7 @@ lex_number(struct org_cherry_context* context)
break;
}
cry_array_append(buffer, p, 1);
org_cherry_array_append(buffer, p, 1);
NO_APPEND_BUFFER:
p = org_cherry_utf8_next(p);
......@@ -321,7 +311,7 @@ NO_APPEND_BUFFER:
RETURN_TOKEN:
context->src = p;
cry_array_append(buffer, "\0", 1);
org_cherry_array_append(buffer, "\0", 1);
return token;
}
......@@ -338,13 +328,13 @@ lex_character(struct org_cherry_context* context)
{
assert(context != 0);
struct CryArray* buffer = context->buffer;
struct org_cherry_array* buffer = context->buffer;
byte_t* p = org_cherry_utf8_next(context->src);
unicode_t ch = org_cherry_utf8_get(p);
enum CharState state = CHAR_EAT;
int unicount = 0;
cry_array_append(buffer, "\\", 1);
org_cherry_array_append(buffer, "\\", 1);
while(!org_cherry_unicode_isspace(ch) && ch != '\0') {
switch(state) {
......@@ -365,7 +355,7 @@ lex_character(struct org_cherry_context* context)
if(('0' > ch || ch > '9') && ('A' > ch || ch > 'F')) {
org_cherry_error(context, "Unexpected hex sequence in unicode escape sequence");
cry_array_append(buffer, "0", 1);
org_cherry_array_append(buffer, "0", 1);
goto NO_BUFFER_APPEND;
}
break;
......@@ -374,7 +364,7 @@ lex_character(struct org_cherry_context* context)