Skip to content

Latest commit

 

History

History
648 lines (521 loc) · 21.7 KB

api-base.org

File metadata and controls

648 lines (521 loc) · 21.7 KB

Base library

CPARSEC3 Base library provides basic functionality of general purpose Generic Data Types, Traits, and Generic Macros.

Generic Data Type

Generic Data Type is a parametric typed struct/union.

Generic Data Type is a similar concept as known as parameterized type, polymorphic type, template class (C++), and so on.

The below sections show Generic Data Types provided by CPARSEC3 Base library.

Array(T) - an array of objects

Array(T)
Array of objects of T type.
See also ArrayT(T) trait.

List(T) - a linked-list of objects or NULL

List(T)
Linked-list of objects of T type or NULL.
See also ListT(T) trait.

Maybe(T) - wraps an object or nothing

Maybe(T)
Wraps an object of T type or nothing.
See also MaybeT(T) trait.

Itr(C) - an iterator that points to a container’s item.

Itr(C)
An iterator that points to an item (or nothing) of the container of C type. An Itr(C) object is used to operate iteration / traversal for each item of a container of C type.
See also ItrT(C) trait.

Slice(C) - a partial (or whole) view of the underlying container.

Slice(C)
A partial (or whole) view of the underlying containter of C type. In other words, a Slice(C) object is a reference to a portion of underlying container. A Slice(C) object is also iterable (i.e. Itr(Slice(C)) is available). The C must be iterable (i.e. Itr(C) must be available). Therefore C shall be Array(T) or List(T) for now.
See also SliceT(C) trait.

Result(T, E) - wraps an ok value or an error value.

Result(T, E)
Wraps an ok value of T type or an error value of E type.

Tuple(T1, …) - a tuple of values of various types.

Tuple(T1)
1-tuple of a value of T1 type.
Tuple(T1, T2)
2-tuple of values of T1 and T2 type.
Tuple(T1, T2, T3)
3-tuple of values of T1, T2, and T3 type.
Tuple(T1, T2, T3, T4)
4-tuple of values of T1, T2, T3, and T4 type.
Tuple(T1, T2, T3, T4, T5)
5-tuple of values of T1, T2, T3, T4, and T5 type.
Tuple(T1, T2, T3, T4, T5, T6)
6-tuple of values of T1, T2, T3, T4, T5, and T6 type.

Trait

Trait provides a set of functions against a particular concrete type.

Trait is a similar concept as known as type class (Haskell), trait (Rust), interface (Java), and so on.

To use Trait, calling to trait(M) creates a concrete trait object.

The below sections show Traits provided by CPARSEC3 Base library.

Eq(T) - trait to test equality of two values

/* Eq(String) is a trait type to test equality of two String values */
Eq(String) E = trait(Eq(String));
if (E.eq("foo", "foo")) { printf("foo == foo\n"); }
if (E.neq("foo", "foo")) { printf("foo != foo\n");}
// -> foo == foo
Eq(T)
Type of a trait that provides a set of functions to test equality of two values of T type.
trait(Eq(T))
Constructs a new trait of Eq(T) type.
For example, trait(Eq(int)) creates an object of Eq(int) type.

An Eq(T) trait provides the following member functions :

bool eq(T a, T b)
Returns true if a = b
bool neq(T a, T b)
Returns true if a ≠ b

Ord(T) - trait to compare two values

String s = "foo";
Ord(String) O = trait(Ord(String));
if (O.le("foo", "bar")) {
  printf("foo <= bar\n")
}
if (O.lt("foo", "bar")) {
  printf("foo < bar\n")
}
if (O.ge("foo", "bar")) {
  printf("foo >= bar\n")
}
if (O.gt("foo", "bar")) {
  printf("foo > bar\n")
}
printf("%d\n", O.compare("foo", "bar"));
Ord(T)
Type of a trait that provides a set of functions to compare two values of T type.
trait(Ord(T))
Constructs a new trait of Ord(T) type.
For example, trait(Ord(int)) creates an object of Ord(int) type.

An Ord(T) trait provides the following member functions :

bool le(T a, T b)
Returns true if a ≤ b
bool lt(T a, T b)
Returns true if a < b
bool ge(T a, T b)
Returns true if a ≥ b
bool gt(T a, T b)
Returns true if a > b
T min(T a, T b)
Returns a if a ≤ b, b otherwise.
T max(T a, T b)
Returns a if a ≥ b, b otherwise.
int compare(T a, T b)
Returns
  • -1 if a < b,
  • 0 if a = b, or
  • 1 if a > b

MemT(T) - trait to allocate/deallocate memory

MemT(int) m = trait(Mem(int));
int* p = m.create(5);           /* allocate int[5] */
m.free(p);                      /* free memoty */
MemT(T)
Type of a trait that provides a set of functions to malloc/free memory of T type.
trait(Mem(T))
Constructs a new trait of MemT(T) type.
For example, trait(Mem(int)) creates an object of MemT(int) type.

An MemT(T) trait provides the following member functions :

T* create(size_t n)
Allocates T[n] and returns the address of head of the allocated memory.
i.e. returns malloc(sizeof(T) * n).
T* recreate(T* ptr, size_t n)
Re-allocates T[n] and returns the new address of head of the allocated memory.
i.e. returns realloc(ptr, sizeof(T) * n).
void free(T* ptr)
Deallocates (free) the allocated memory.
i.e. free(ptr).

ArrayT(T) - trait for Array(T) container.

/* ArrayT(int) is a trait type to construct, destruct, and manipulate Array(T) */
ArrayT(int) m = trait(Array(int));
Array(int) a = m.create(5);
size_t n = m.length(a); /* -> n = 5 */
for (int* it = m.begin(a); it != m.end(a); *it++ = n--)
  ;
for (int* it = m.begin(a); it != m.end(a); it++) {
  printf("%d ", *it); /* -> 5 4 3 2 1 */
}
m.free(&a);
ArrayT(T)
Type of a trait that provides a set of functions to construct, destruct, and manipulate Array(T).
trait(Array(T))
Constructs a new trait of ArrayT(T) type.
For example, trait(Array(int)) creates an object of ArrayT(int) type.

An ArrayT(T) trait provides the following member variables/functions :

Array(T) empty
An empty array.
i.e. 0-length array.
bool null(Array(T) a)
Returns true if length of the array a was 0, false otherwise.
i.e. returns !a.length
size_t length(Array(T) a)
Returns the length of the array a.
i.e. returns a.length.
Array(T) create(size_t n)
Constructs an array of length n.
void free(Array(T)* pa)
Destructs the array that the pa points to.
i.e. free(pa->data).
T* begin(Array(T) a)
Returns the address of the 1st item of the array a.
i.e. returns a.data.
T* end(Array(T) a)
Returns the out of bounds address over the last item of the array a.
i.e. returns a.data + a.length.
void reverse(Array(T)* ptr)
Reverses the order of items in the array that the pointer ptr points to. Note that the ptr must not be NULL.

ListT(T) - trait for List(T) container.

ListT(int) m = trait(List(int));
List(int) xs = m.cons(1, m.cons(2, m.cons(3, m.empty)));
for (List(int) ys = xs; !m.null(ys); ys = m.tail(ys)) {
  printf("%d ", m.head(ys));    /* -> 1 2 3 */
}
m.free(&xs);
ListT(T)
Type of a trait that provides a set of functions to construct, destruct, and manipulate List(T).
trait(List(T))
Constructs a new trait of ListT(T) type.
For example, trait(List(int)) creates an object of ListT(int) type.

An ListT(T) trait provides the following member variables/functions :

List(T) empty
An empty list.
i.e. NULL
bool null(List(T) xs)
Returns true if the list xs was NULL, false otherwise.
i.e. returns !xs.
size_t length(List(T) xs)
Returns the length of the list xs.
List(T) cons(T x, List(T) xs)
Constructs a linked-list (cons-cell).
void free(List(T)* pxs)
Destructs the list that the pxs points to.
List(T) drop(size_t n, List(T) xs)
Destructs leading at most n cells of the list xs, and returns remaining list.
T head(List(T) xs)
Returns the head value of the list xs.
i.e. returns xs->head.
List(T) tail(List(T) xs)
Returns the tail list of the list xs.
i.e. returns xs->tail.
void reverse(List(T)* ptr)
Reverses the order of items in the list that the pointer ptr points to. Note that the ptr must not be NULL.

MaybeT(T) - trait for Maybe(T) container.

/* MaybeT(int) is a trait type to construct and manipulate Maybe(T) */
MaybeT(int) M = trait(Maybe(int));

Maybe(int) m = M.just(5);
assert(M.length(m) == 1);
assert(!M.null(m));
assert(!m.none);
assert(m.value == 5);

Maybe(int) e = M.empty;
assert(M.length(e) == 0);
assert(M.null(e));
assert(e.none);
int x = e.value; // undefined behaviour
MaybeT(T)
Type of a trait that provides a set of functions to construct and manipulate Maybe(T).
trait(Maybe(T))
Constructs a new trait of MaybeT(T) type.
For example, trait(Maybe(int)) creates an object of MaybeT(int) type.

A MaybeT(T) trait provides the following member variables/functions :

Maybe(T) empty
An object that represents nothing.
i.e. empty.none = true.
bool null(Maybe(T) m)
Returns true if the m was nothing, false otherwise.
i.e. returns m.none
size_t length(Maybe(T) m)
Returns 0 if the m was nothing, 1 otherwise.
i.e. returns (m.none ? 0 : 1).
Maybe(T) just(T value)
Constructs a Maybe(T) object that represents the value.
i.e. returns (Maybe(T)){.none = false, .value = value}.

ItrT(C) - trait to construct and manipulate an iterator

Iterable(List(int)) J = trait(Iterable(List(int)));
ItrT(List(int)) I = trait(Itr(List(int)));
ListT(int) m = trait(List(int));
List(int) xs = m.cons(1, m.cons(2, m.cons(3, m.empty)));
for (Itr(List(int)) it = J.itr(xs); !I.null(it); it = I.next(it)) {
  printf("%d ", I.get(it));    /* -> 1 2 3 */
}
m.free(&xs);
ItrT(C)
Type of a trait that provides a set of functions to construct and manipulate Itr(C).
Item(C)
Type of an item of C type.
  • NOTE : Item(C) type is a type alias of T when C was Array(T) or List(T).
trait(Itr(C))
Constructs a new trait of ItrT(C) type.
For example, trait(Itr(List(int))) creates an object of ItrT(List(int)) type.

An ItrT(C) trait provides the following member variables/functions :

Itr(C) itr(C c)
Constructs an iterator that points to the 1st item (or nothing) of the container c. The type of c shall be a Array(T) or a List(T).
Item(C)* ptr(Itr(C) it)
Returns the pointer to the container’s item of that the iterator it points to.
  • NOTE :
    • Item(C)* ptr(Itr(C) it) is introduced for easy to implement typical iterator.
    • ptr(it) is called from typical implementation of null(it), get(it), and set(v, it).
    • Use null(it), get(it), or set(v, it) instead of ptr(it) unless you have necessary to call ptr(it).
Itr(C) next(Itr(C) it)
Returns the iterator that points to the next item (or nothing) of the iterator it points to.
  • NOTE : If the iterator it was empty (i.e. null(it) = `true`), causes assertion failed.
Itr(C) skip(size_t n, Itr(C) it)
Skips at most `n` items of the it and returns the iterator followed.
  • NOTE : Returns an empty iterator (i.e. an iterator that points to nothing), if n was greater than or equals to the length of the sequence represented by the iterator it.
bool null(Itr(C) it)
Returns true if it was empty (i.e. it points to nothing), otherwise false.
Item(C) get(Itr(C) it)
Returns the value of the container’s item of that the iterator it points to.
void set(Item(C) v, Itr(C) it)
Assign the value v to the container’s item of that the iterator it points to.

SliceT(C) - trait to construct and manipulate a slice of container

ListT(int) L = trait(List(int));
SliceT(List(int)) S = trait(Slice(List(int)));
Iterable(Slice(List(int))) J = trait(Iterable(Slice(List(int))));
ItrT(Slice(List(int))) I = trait(Itr(Slice(List(int))));

List(int) xs = L.cons(1, L.cons(2, L.cons(3, L.cons(4, L.cons(5, L.empty)))));
Slice(List(int)) s = S.slice(xs, 0, 3);
for (Itr(Slice(List(int))) it = J.itr(xs); !I.null(it); it = I.next(it)) {
  printf("%d ", I.get(it));    /* -> 1 2 3 */
}
m.free(&xs);
SliceT(C)
Type of a trait that provides a set of functions to construct and manipulate Slice(C).
trait(Slice(C))
Constructs a new trait of SliceT(C) type.
For example, trait(Slice(List(int))) creates an object of SliceT(List(int)) type.

An SliceT(C) trait provides the following member variables/functions :

Slice(C) empty
An empty slice.
bool null(Slice(C) s)
Returns true if the slice s was empty, false otherwise.
size_t length(Slice(C) s)
Returns the length of the slice s.
Slice(C) slice(C c, int start, int stop)
Constructs a new Slice(C) object that is a reference to a portion of underlying container c of C type. Returns an empty Slice(C) object if f(start)f(stop). Otherwise, returns a Slice(C) object refering to a range of the c that starts with index f(start) (included) and ends with index f(stop) (excluded), where
  • f(x) = x if 0 ≤ xlength(c)
  • f(x) = length(c) if length(c)x
  • f(x) = x + length(c) if x < 0 and 0 ≤ x + length(c)
  • f(x) = 0 if x + length(c) < 0
  • note that always 0 ≤ length(c)
void reverse(Slice(C)* ptr)
Reverses the order of items in the range of contaner refered by the slice that the pointer ptr points to. Note that the ptr must not be NULL.

Show(T) - trait to represent a value as a string

  • NOTE : Not implemented yet.
Show(T)
Type of a trait that provides a set of functions to represent a value of T type as a String.
trait(Show(T))
Constructs a new trait of Show(T) type.
For example, trait(Show(int)) creates an object of Show(int) type.

An Show(T) trait provides the following member functions :

String show(T a)
Returns a String representation of a.

Generic Macros

CPARSEC3 provides also Generic Macros for easy to use various traits and containers.

Pros of Generic Macros
Makes it easy to use various traits and containers.
Cons of Generic Macros
Needs much more compile time / memory.

The below sections show Generic Macros provided by CPARSEC3 Base library.

Tests Equality of two objects

g_eq(a, b)
Returns true if a = b, false otherwise.
g_neq(a, b)
Returns true if ab, false otherwise.

Tests Ordering of two objects

g_le(a, b)
Returns true if ab, false otherwise.
g_lt(a, b)
Returns true if a < b, false otherwise.
g_ge(a, b)
Returns true if ab, false otherwise.
g_gt(a, b)
Returns true if a > b, false otherwise.
g_min(a, b)
Returns a if ab, b otherwise.
g_max(a, b)
Returns a if ab, b otherwise.
g_cmp(a, b)
  • Returns -1 if a < b
  • Returns 0 if a = b
  • Returns 1 if a > b
g_compare(a, b)
Same as g_cmp(a, b).

Array Constructors, Destructors, and Manipulators

g_array(T, …)
Constructs a new Array(T) object.
For example, g_array(int, 1, 2, 3) creates a 3 length array.
g_begin(a)
Returns the address of the 1st item of the array a.
g_end(a)
Returns the out of bounds address over the last item of the array a.
g_free(a)
Destructs the array a.

List Constructors, Destructors, and Manipulators

g_list(T, …)
Constructs a new List(T) object.
For example, g_list(int, 1, 2, 3) creates a 3 length list.
g_cons(x, xs)
Constructs a new List(T) object.
x shall be a T and xs shall be a List(T).
g_head(xs)
Returns the head value of the list xs.
g_tail(xs)
Returns the tail list of the list xs.
g_drop(n, xs)
Destructs leading at most n cells of the list xs, and returns remaining list.
g_free(xs)
Destructs the list xs.

Slice Constructors

g_slice(c, start, stop)
Constructs a new Slice(C) object that is a reference to a portion of underlying container c of C type. Returns an empty Slice(C) object if f(start)f(stop). Otherwise, returns a Slice(C) object refering to a range of the c that starts with index f(start) (included) and ends with index f(stop) (excluded), where
  • f(x) = x if 0 ≤ xlength(c)
  • f(x) = length(c) if length(c)x
  • f(x) = x + length(c) if x < 0 and 0 ≤ x + length(c)
  • f(x) = 0 if x + length(c) < 0
  • note that always 0 ≤ length(c)
g_slice(c, n)
Same as g_slice(c, 0, n). This is a syntax sugar to construct a slice that refers the leading portion of the container.

Container Length

g_null(c)
Returns true if c was empty, otherwise false.
c shall be an Array(T), List(T), Maybe(T), Slice(Array(T)), or Slice(List(T)). (see also g_null(it))
g_length(c)
Returns length of the container c.
c shall be an Array(T), List(T), Maybe(T), Slice(Array(T)), or Slice(List(T)).

Reverse order

g_reverse(c)
Reverses the order of items in the c. Note that the c must be a lvalue.
c shall be an Array(T), List(T), Slice(Array(T)), or Slice(List(T)).

Iterator

g_itr(c)
Constructs an iterator Itr(C) object.
c shall be an Array(T), List(T), Slice(Array(T)), or Slice(List(T)).
g_null(it)
Returns true if it was empty, otherwise false.
it shall be an Itr(Array(T)), Itr(List(T)), Itr(Slice(Array(T)), or Itr(Slice(List(T)). (see also g_null(c))
g_next(it)
Returns the next iterator of the it.
it shall be an Itr(Array(T)), Itr(List(T)), Itr(Slice(Array(T)), or Itr(Slice(List(T)).
g_skip(n, it)
Skips at most `n` items of the it and returns the iterator followed.
it shall be an Itr(Array(T)), Itr(List(T)), Itr(Slice(Array(T)), or Itr(Slice(List(T)).
g_get(it)
Returns the value of container’s item of that the iterator it points to.
it shall be an Itr(Array(T)), Itr(List(T)), Itr(Slice(Array(T)), or Itr(Slice(List(T)).
g_set(v, it)
Assign the value v to the container’s item of that the iterator it points to.
it shall be an Itr(Array(T)), Itr(List(T)), Itr(Slice(Array(T)), or Itr(Slice(List(T)), thus v shall be a T.

For-Loop (GCC only)

g_for(it, c)
Expanded to for (__auto_type it = g_itr(c); !g_null(it); it = g_next(it)).
it is the name of variable to be used as an iterator, c shall be an Array(T), List(T), Slice(Array(T)), or Slice(List(T)).
  • NOTE : Available if and only if __GNUC__ was defined.
g_for(it, c, step)
Expanded to for (__auto_type it = g_itr(c); !g_null(it); it = g_skip(step, it)).
it is the name of variable to be used as an iterator, c shall be an Array(T), List(T), Slice(Array(T)), or Slice(List(T)).
  • NOTE : Available if and only if __GNUC__ was defined.

Structured bindings (multiple assignment) (GCC only)

g_bind((a,b,…), t)
Expanded to __auto_type a = t.e1; __auto_type b = t.e2; ....
(a,b,...) is a list of the name of variables to be defined. t is a tuple. For each item in the tuple t, the item is assigned to the variable in the given list in order. If a variable in the list was not specified, the corresponding assignment is omitted.
  • NOTE : Available if and only if __GNUC__ was defined.
{
  g_bind((a,b,c), (Tuple(int, char, String)){1, 'X', "hello"});
  // -> __auto_type a = 1; __auto_type b = 'X'; __auto_type c = "hello";
}
{
  g_bind((a,b), (Tuple(int, char, String)){1, 'X', "hello"});
  // -> __auto_type a = 1; __auto_type b = 'X';
}
{
  g_bind(a, (Tuple(int, char, String)){1, 'X', "hello"});
  // -> __auto_type a = 1;
}
{
  g_bind((a,,c), (Tuple(int, char, String)){1, 'X', "hello"});
  // -> __auto_type a = 1; __auto_type c = "hello";
}

RAII (Resource Acquisition Is Initialization) GCC only

g_scoped(C) c = …;
Declares/defines a variable c of type C as a RAII object that will be automatically deallocated when leave the current scope.
C shall be Array(T) or List(T).
  • NOTE : Available if and only if __GNUC__ was defined.
void foo(void) {
  g_scoped(Array(int)) a = g_array(int, 1, 2, 3, 4, 5);
  // do something...
} // at here, g_free(a) is automatically called before leaving the function.