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

add array utils for language toolchain

parent 760d80fc
set(SOURCES
array.c)
add_library(cherry-core ${SOURCES})
/*
* 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 "array.h"
#include <assert.h>
#include <string.h>
struct CyArray
{
uint8_t* data;
size_t alloc;
size_t length;
};
struct CyArray*
cy_array_new(size_t init_capacity)
{
assert(init_capacity != 0);
struct CyArray* array = cy_malloc(struct CyArray);
array->alloc = init_capacity;
array->length = 0;
array->data = cy_calloc(uint8_t, array->alloc);
return array;
}
void
cy_array_free(struct CyArray* array)
{
assert(array != 0);
cy_free(array->data);
cy_free(array);
}
size_t
cy_array_size(struct CyArray* array)
{
assert(array != 0);
return array->length;
}
size_t
cy_array_capacity(struct CyArray* array)
{
assert(array != 0);
return array->alloc;
}
size_t
cy_array_ensure(struct CyArray* 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 = cy_realloc(uint8_t, array->data, array->alloc);
}
return array->alloc;
}
size_t
cy_array_trim(struct CyArray* array)
{
assert(array != 0);
array->data = cy_realloc(uint8_t, array->data, array->length);
array->alloc = array->length;
return array->alloc;
}
void
cy_array_append(struct CyArray* array, const_pointer data, size_t size)
{
assert(array != 0);
cy_array_ensure(array, array->length + size);
memcpy(array->data + array->length, data, size);
array->length += size;
}
int
cy_array_insert(struct CyArray* array, size_t index, const_pointer data, size_t size)
{
assert(array != 0);
if(index >= array->length)
return CHERRY_OUT_OF_INDEX_ERROR;
cy_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 CHERRY_OK;
}
int
cy_array_replace(struct CyArray* array, size_t index, const_pointer data, size_t size)
{
assert(array != 0);
if(index >= array->length && index + size > array->length)
return CHERRY_OUT_OF_INDEX_ERROR;
cy_array_ensure(array, array->length + size);
memcpy(array->data + index, data, size);
}
int
cy_array_remove(struct CyArray* array, size_t index, size_t size)
{
assert(array != 0);
if(index >= array->length)
return CHERRY_OUT_OF_INDEX_ERROR;
memmove(array->data + index, array->data + index + size, array->length - index - size);
array->length -= size;
return CHERRY_OK;
}
void
cy_array_clear(struct CyArray* array)
{
assert(array != 0);
array->length = 0;
}
pointer
cy_array_get(struct CyArray* array, size_t index)
{
assert(array != 0);
if(index < array->length)
return array->data + index;
return 0;
}
pointer
cy_array_clone(struct CyArray* array)
{
assert(array != 0);
uint8_t* ptr = 0;
if(array->length > 0) {
ptr = cy_calloc(uint8_t, array->length);
memcpy(ptr, array->data, array->length);
}
return ptr;
}
struct CyPtrArray
{
pointer* data;
size_t alloc;
size_t length;
};
struct CyPtrArray*
cy_ptr_array_new(size_t init_capacity)
{
assert(init_capacity != 0);
struct CyPtrArray* array = cy_malloc(struct CyPtrArray);
array->alloc = init_capacity;
array->length = 0;
array->data = cy_calloc(pointer, array->alloc);
return array;
}
void
cy_ptr_array_free(struct CyPtrArray* array)
{
assert(array != 0);
cy_free(array->data);
cy_free(array);
}
size_t
cy_ptr_array_size(struct CyPtrArray* array)
{
assert(array != 0);
return array->length;
}
size_t
cy_ptr_array_capacity(struct CyPtrArray* array)
{
assert(array != 0);
return array->alloc;
}
size_t
cy_ptr_array_ensure(struct CyPtrArray* 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 = cy_realloc(pointer, array->data, array->alloc);
}
return array->alloc;
}
size_t
cy_ptr_array_trim(struct CyPtrArray* array)
{
assert(array != 0);
array->data = cy_realloc(pointer, array->data, array->length);
array->alloc = array->length;
return array->alloc;
}
void
cy_ptr_array_append(struct CyPtrArray* array, pointer ptr)
{
assert(array != 0);
cy_ptr_array_ensure(array, array->length + 1);
*(array->data + array->length) = ptr;
array->length += 1;
}
int
cy_ptr_array_insert(struct CyPtrArray* array, size_t index, pointer ptr)
{
assert(array != 0);
if(index >= array->length)
return CHERRY_OUT_OF_INDEX_ERROR;
cy_ptr_array_ensure(array, array->length + 1);
memmove(array->data + index + 1, array->data + index, (array->length - index) * sizeof(pointer));
*(array->data + index) = ptr;
array->length += 1;
return CHERRY_OK;
}
pointer
cy_ptr_array_replace(struct CyPtrArray* array, size_t index, pointer ptr)
{
assert(array != 0);
if(index >= array->length)
return 0;
pointer data = *(array->data + index);
*(array->data + index) = ptr;
return data;
}
pointer
cy_ptr_array_remove(struct CyPtrArray* array, size_t index)
{
assert(array != 0);
if(index >= array->length)
return 0;
pointer data = *(array->data + index);
memmove(array->data + index, array->data + index + 1, (array->length - index - 1) * sizeof(pointer));
array->length -= 1;
return data;
}
pointer
cy_ptr_array_get(struct CyPtrArray* array, size_t index)
{
assert(array != 0);
if(index < array->length)
return *(array->data + index);
return 0;
}
void
cy_ptr_array_clear(struct CyPtrArray* array, cy_free_funptr fun)
{
assert(array != 0);
if(fun != 0) {
size_t index = 0;
for(index = 0; index < array->length; ++index)
fun(*(array->data + index));
}
array->length = 0;
}
/*
* 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 "standard.h"
typedef void (*cy_free_funptr)(pointer data);
#define CHERRY_OUT_OF_INDEX_ERROR -1
struct CyArray;
struct CyPtrArray;
struct CyArray* cy_array_new(size_t init_capacity);
void cy_array_free(struct CyArray* array);
size_t cy_array_size(struct CyArray* array);
size_t cy_array_capacity(struct CyArray* array);
size_t cy_array_ensure(struct CyArray* array, size_t min_capacity);
size_t cy_array_trim(struct CyArray* array);
void cy_array_append(struct CyArray* array, const_pointer data, size_t size);
int cy_array_insert(struct CyArray* array, size_t index, const_pointer data, size_t size);
int cy_array_remove(struct CyArray* array, size_t index, size_t size);
int cy_array_replace(struct CyArray* array, size_t index, const_pointer data, size_t size);
void cy_array_clear(struct CyArray* array);
pointer cy_array_clone(struct CyArray* array);
pointer cy_array_get(struct CyArray* array, size_t index);
struct CyPtrArray* cy_ptr_array_new(size_t init_capacity);
void cy_ptr_array_free(struct CyPtrArray* array);
size_t cy_ptr_array_size(struct CyPtrArray* array);
size_t cy_ptr_array_capacity(struct CyPtrArray* array);
size_t cy_ptr_array_ensure(struct CyPtrArray* array, size_t min_capacity);
size_t cy_ptr_array_trim(struct CyPtrArray* array);
void cy_ptr_array_append(struct CyPtrArray* array, pointer ptr);
int cy_ptr_array_insert(struct CyPtrArray* array, size_t index, pointer ptr);
pointer cy_ptr_array_remove(struct CyPtrArray* array, size_t index);
pointer cy_ptr_array_replace(struct CyPtrArray* array, size_t index, pointer ptr);
void cy_ptr_array_clear(struct CyPtrArray* array, cy_free_funptr fun);
pointer cy_ptr_array_get(struct CyPtrArray* array, size_t index);
......@@ -19,11 +19,50 @@
#pragma once
#include <stdlib.h>
#include <stdint.h>
#define CHERRY_OK 0
#define TRUE (1)
#define FALSE (0)
typedef void* pointer;
typedef const void* const_pointer;
typedef uint8_t byte;
typedef uint16_t word;
/**
* Crystal's malloc macro for allocating memory based on a type
* @param Type Set directly the type for this memory block (dont use sizeof)
*/
#define cy_malloc(Type) malloc(sizeof(Type))
/**
* Crystal's calloc macro for allocating memory based on a type
* @param Type Set directly the type for this memory block (dont use sizeof)
* @param num Set the number of elements (of type Type)
*/
#define cy_calloc(Type, num) calloc(num, sizeof(Type))
/**
* Crystal's realloc macro for allocating memory based on a type
* @param Type Set directly the type for this memory block (dont use sizeof)
* @param Pointer Set the Adress of the existing memory block that should be reallocated.
* @param num Set the number of elements (of type Type)
*/
#define cy_realloc(Type, Pointer, num) realloc(Pointer, sizeof(Pointer) * num)
/**
* Crystal renaming for deallocating memory (equivalent to free(Pointer))
* @param Pointer The address of the freeing memory block
*/
static void (*cy_free)(pointer data) = free;
/**
* Convenient casting operator for cleaner code similar to c++ static_cast in its appearance.
* @param Type The type the variable Var should be casted
* @param Var The given variable that should be casted
*/
#define cy_cast(Type, Var) ((Type)Var)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment