Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features/vector #31

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions include/array.h

This file was deleted.

2 changes: 2 additions & 0 deletions include/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ Value *core_gt(const Value *args);
Value *core_is_empty(const Value *args);
Value *core_is_false(const Value *args);
Value *core_is_list(const Value *args);
Value *core_is_vector(const Value *args);
Value *core_is_nil(const Value *args);
Value *core_is_symbol(const Value *args);
Value *core_is_true(const Value *args);
Value *core_leq(const Value *args);
Value *core_list(const Value *args);
Value *core_vector(const Value *args);
Value *core_lt(const Value *args);
Value *core_map(const Value *args);
Value *core_mul(const Value *args);
Expand Down
33 changes: 20 additions & 13 deletions include/value.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#ifndef VALUE_H
#define VALUE_H

#include "array.h"
#include "env.h"
#include "gc.h"
#include "list.h"
#include "map.h"
#include "vector.h"

#define BOOL(v) (v->value.bool_)
#define BUILTIN_FN(v) (v->value.builtin_fn)
Expand All @@ -16,19 +16,21 @@
#define LIST(v) (v->value.list)
#define STRING(v) (v->value.str)
#define SYMBOL(v) (v->value.str)
#define VECTOR(v) (v->value.vector)

typedef enum {
VALUE_BOOL,
VALUE_BUILTIN_FN,
VALUE_EXCEPTION,
VALUE_FLOAT,
VALUE_FN,
VALUE_INT,
VALUE_LIST,
VALUE_MACRO_FN,
VALUE_NIL,
VALUE_STRING,
VALUE_SYMBOL
VALUE_BOOL = 1 << 0,
VALUE_BUILTIN_FN = 1 << 1,
VALUE_EXCEPTION = 1 << 2,
VALUE_FLOAT = 1 << 3,
VALUE_FN = 1 << 4,
VALUE_INT = 1 << 5,
VALUE_LIST = 1 << 6,
VALUE_MACRO_FN = 1 << 7,
VALUE_NIL = 1 << 8,
VALUE_STRING = 1 << 9,
VALUE_SYMBOL = 1 << 10,
VALUE_VECTOR = 1 << 11
} ValueType;

extern const char *value_type_names[];
Expand All @@ -46,7 +48,7 @@ typedef struct Value {
int int_;
double float_;
char *str;
Array *vector;
Vector *vector;
const List *list;
Map *map;
struct Value *(*builtin_fn)(const struct Value *);
Expand All @@ -67,6 +69,7 @@ extern Value *VALUE_CONST_NIL;
bool is_symbol(const Value *value);
bool is_macro(const Value *value);
bool is_list(const Value *value);
bool is_vector(const Value *value);
bool is_exception(const Value *value);
Value *value_new_nil();
Value *value_new_bool(const bool bool_);
Expand All @@ -81,6 +84,10 @@ Value *value_new_string(const char *str);
Value *value_new_symbol(const char *str);
Value *value_new_list(const List *l);
Value *value_make_list(Value *v);
Value *value_new_list(const List *l);
Value *value_make_list(Value *v);
Value *value_new_vector(const List *l);
Value *value_make_vector(Value *v);
Value *value_head(const Value *v);
Value *value_tail(const Value *v);
void value_delete(Value *v);
Expand Down
35 changes: 35 additions & 0 deletions include/vector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef __VECTOR_H__
#define __VECTOR_H__

#include <stddef.h>

/*
* Contiguous, indexable chunk of memory.
*/
typedef struct vector {
char *p;
size_t size;
size_t capacity;
size_t bytes;
} Vector;


Vector *vector_new(const size_t item_size);
Vector *vector_new_with_capacity(const size_t isize, const size_t capacity);
Vector *vector_dup(const Vector *vec);
void vector_delete(Vector *vec);

#define vector_size(v) (v->size)
#define vector_capacity(v) (v->capacity)

void *vector_at(Vector *v, size_t i);
#define vector_typed_at(v,i,t) ((t*) vector_at(v, i))
void vector_push_back(Vector *v, const void *value, size_t n);
void vector_push_front(Vector *v, const void *value, size_t n);
void *vector_pop_back(Vector *v);
#define vector_typed_pop_back(v,t) ((t*) vector_pop_back(v))
void *vector_pop_front(Vector *v);
#define vector_typed_pop_front(v,t) ((t*) vector_pop_front(v))
void vector_shrink(Vector *v);

#endif /* !__VECTOR_H__ */
71 changes: 56 additions & 15 deletions src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
} while (0)

#define REQUIRE_VALUE_TYPE(value, t, msg) do {\
if (value->type != t) {\
if (!(value->type & (t))) {\
LOG_CRITICAL("%s: expected %s, got %s", msg, value_type_names[t], value_type_names[value->type]);\
exc_set(value_make_exception("%s: expected %s, got %s", msg, value_type_names[t], value_type_names[value->type]));\
return NULL;\
Expand Down Expand Up @@ -102,13 +102,28 @@ Value *core_is_list(const Value *args)
return arg0->type == VALUE_LIST ? VALUE_CONST_TRUE : VALUE_CONST_FALSE;
}

Value *core_vector(const Value *args)
{
CHECK_ARGLIST(args);
return value_new_vector(LIST(args));
}

Value *core_is_vector(const Value *args)
{
CHECK_ARGLIST(args);
REQUIRE_LIST_CARDINALITY(args, 1ul, "vector? requires exactly one parameter");
Value *arg0 = ARG(args, 0);
return arg0->type == VALUE_VECTOR ? VALUE_CONST_TRUE : VALUE_CONST_FALSE;
}

Value *core_is_empty(const Value *args)
{
CHECK_ARGLIST(args);
REQUIRE_LIST_CARDINALITY(args, 1ul, "empty? requires exactly one parameter");
Value *arg0 = ARG(args, 0);
REQUIRE_VALUE_TYPE(arg0, VALUE_LIST, "empty? requires a list type");
return NARGS(arg0) == 0 ? VALUE_CONST_TRUE : VALUE_CONST_FALSE;
const Value *seq = ARG(args, 0);
REQUIRE_VALUE_TYPE(seq, VALUE_LIST | VALUE_VECTOR, "empty? requires a list type");
size_t cnt = is_list(seq) ? list_size(LIST(seq)) : vector_size(VECTOR(seq));
return cnt ? VALUE_CONST_FALSE : VALUE_CONST_TRUE;
}

static float acc_add(float acc, float x)
Expand Down Expand Up @@ -283,6 +298,9 @@ static Value *cmp_lt(const Value *a, const Value *b)
case VALUE_LIST:
exc_set(value_make_exception("Cannot order lists"));
return NULL;
case VALUE_VECTOR:
exc_set(value_make_exception("Cannot order lists"));
return NULL;
}
} else if (a->type == VALUE_INT && b->type == VALUE_FLOAT) {
return ((float) INT(a)) < FLOAT(b) ? VALUE_CONST_TRUE : VALUE_CONST_FALSE;
Expand Down Expand Up @@ -502,6 +520,17 @@ static char *core_str_inner(char *str, const Value *v)
}
str = str_append(str, strlen(str), ")", 1);
break;
case VALUE_VECTOR:
str = str_append(str, strlen(str), "[", 1);
size_t vec_size = vector_size(VECTOR(v));
for (size_t i = 0; i < vec_size; ++i) {
str = core_str_inner(str, vector_typed_at(VECTOR(v), i, Value));
if (i < vec_size - 1) {
str = str_append(str, strlen(str), " ", 1);
}
}
str = str_append(str, strlen(str), "]", 1);
break;
case VALUE_FN:
case VALUE_MACRO_FN:
str = str_append(str, strlen(str), "(lambda ", 8);
Expand Down Expand Up @@ -575,12 +604,13 @@ Value *core_prn(const Value *args)
Value *core_count(const Value *args)
{
CHECK_ARGLIST(args);
Value *list = ARG(args, 0);
if (is_nil(list)) {
return value_new_int(0);
const Value *seq = ARG(args, 0);
size_t cnt = 0;
if (!is_nil(seq)) {
REQUIRE_VALUE_TYPE(seq, VALUE_LIST | VALUE_VECTOR, "count requires a sequence argument");
cnt = is_list(seq) ? list_size(LIST(seq)) : vector_size(VECTOR(seq));
}
REQUIRE_VALUE_TYPE(list, VALUE_LIST, "count requires a list argument");
return value_new_int(NARGS(list));
return value_new_int(cnt);
}

Value *core_slurp(const Value *args)
Expand Down Expand Up @@ -797,27 +827,38 @@ Value *core_nth(const Value *args)
CHECK_ARGLIST(args);
REQUIRE_LIST_CARDINALITY(args, 2ul, "NTH takes exactly two arguments");
Value *coll = ARG(args, 0);
REQUIRE_VALUE_TYPE(coll, VALUE_LIST, "First argument to nth must be a collection");
REQUIRE_VALUE_TYPE(coll, VALUE_LIST | VALUE_VECTOR, "First argument to nth must be a list or a vector");
Value *pos = ARG(args, 1);
REQUIRE_VALUE_TYPE(pos, VALUE_INT, "Second argument to nth must be an integer");
if (INT(pos) < 0 || (unsigned) INT(pos) >= NARGS(coll)) {
exc_set(value_make_exception("Index error"));
return NULL;
}
return ARG(coll, (unsigned) INT(pos));
if (is_list(coll)) {
return list_nth(LIST(coll), INT(pos));
} else {
return vector_typed_at(VECTOR(coll), INT(pos), Value);
}
return NULL;
}

Value *core_first(const Value *args)
{
// (first coll)
CHECK_ARGLIST(args);
REQUIRE_LIST_CARDINALITY(args, 1ul, "FIRST takes exactly one argument");
Value *coll = ARG(args, 0);
if (is_nil(coll) || NARGS(coll) == 0) {
const Value *coll = ARG(args, 0);
if (is_nil(coll)) {
return VALUE_CONST_NIL;
}
REQUIRE_VALUE_TYPE(coll, VALUE_LIST, "Argument to FIRST must be a collection or NIL");
return ARG(coll, 0);
REQUIRE_VALUE_TYPE(coll, VALUE_LIST | VALUE_VECTOR, "Argument to FIRST must be a collection or NIL");
if (is_list(coll)) {
if (list_size(LIST(coll)) == 0) return VALUE_CONST_NIL;
return ARG(coll, 0);
} else {
if (vector_size(VECTOR(coll)) == 0) return VALUE_CONST_NIL;
return vector_typed_at(VECTOR(coll), 0, Value);
}
}

Value *core_rest(const Value *args)
Expand Down
2 changes: 2 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Environment *global_env()

env_set(env, "list", value_new_builtin_fn(core_list));
env_set(env, "list?", value_new_builtin_fn(core_is_list));
env_set(env, "vector", value_new_builtin_fn(core_vector));
env_set(env, "vector?", value_new_builtin_fn(core_is_vector));
env_set(env, "empty?", value_new_builtin_fn(core_is_empty));
env_set(env, "count", value_new_builtin_fn(core_count));
env_set(env, "nth", value_new_builtin_fn(core_nth));
Expand Down
42 changes: 41 additions & 1 deletion src/value.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const char *value_type_names[] = {
"VALUE_MACRO_FN",
"VALUE_NIL",
"VALUE_STRING",
"VALUE_SYMBOL"
"VALUE_SYMBOL",
"VALUE_VECTOR"
};


Expand Down Expand Up @@ -53,6 +54,11 @@ bool is_list(const Value *value)
return value->type == VALUE_LIST;
}

bool is_vector(const Value *value)
{
return value->type == VALUE_VECTOR;
}

static Value *value_new(ValueType type)
{
Value *v = (Value *) gc_malloc(&gc, sizeof(Value));
Expand Down Expand Up @@ -165,6 +171,33 @@ Value *value_make_list(Value *v)
return r;
}

Value *value_new_vector(const List *l)
{
Value *v = value_new(VALUE_VECTOR);
VECTOR(v) = vector_new(sizeof(Value));
if (l) {
for (const ListItem *i = l->head; i != NULL; i = i->next) {
vector_push_back(VECTOR(v), i->val, 1);
}
}
return v;
}

Value *value_make_vector(Value *v)
{
Value *r = value_new_vector(NULL);
if (!v) return r;
if (v->type == VALUE_VECTOR) {
VECTOR(r) = vector_dup(VECTOR(v));
} else if (v->type == VALUE_LIST) {
for (const ListItem *i = LIST(v)->head;
i != NULL; i = i->next) {
vector_push_back(VECTOR(r), i->val, 1);
}
}
return r;
}

void value_print(const Value *v)
{
if (!v) return;
Expand Down Expand Up @@ -197,6 +230,13 @@ void value_print(const Value *v)
}
fprintf(stderr, ")");
break;
case VALUE_VECTOR:
fprintf(stderr, "[ ");
for (size_t i = 0; i < vector_size(VECTOR(v)); ++i) {
value_print(vector_typed_at(VECTOR(v), i, Value));
}
fprintf(stderr, "]");
break;
case VALUE_FN:
fprintf(stderr, "lambda: ");
value_print(FN(v)->args);
Expand Down
Loading