Compare commits

...

7 Commits

Author SHA1 Message Date
8c056d1a39 (MOD) Changed returning type of Var_Delete and Array_Delete from "void" to "Status": It requires more plaination when encountering non-alive instances.
(MOD) Implemented Array_Equals.

(MOD) Replaced struct member "description" from InstanceStillAlive from "Given instance was yet alive." to "Given instance was still alive.".

(MOD) Removed String_GetIdx and String_SetIdx:  Meaningless functions.

(MOD) Changed the assignment value of struct member "identity" of macro unknown, normal and error from "nameof(e)" to "e.identity".
2024-06-28 13:32:48 +08:00
9f2b44bf99 (MOD) Fixed 1 bug in Memory_Reallocate: Now the size of inst is updating with the given size used for reallocation.
(MOD) Replaced struct member prev from UnknownStatus, NormalStatus and ErrorStatus from NULL to &UnknownStatus, &NormalStatus and &ErrorStatus.

(MOD) Rewrote Status_Equal, StatusUtils_Dump, StatusUtils_IsRecursive and StatusUtils_Depth in response to the change of struct member prev from UnknownStatus, NormalStatus and ErrorStatus.

(MOD) Defined 1 more macro "shift".
2024-06-27 16:01:01 +08:00
310586ab86 (MOD) Removed Array_GetIdx and Array_SetIdx due to better approach was discovered.
(MOD) Defined 2 more statuses:  InvalidOperation, InvalidOperationBetweenAliveAndNonAlive.

(MOD) Defined 1 more macro:  assign.
2024-06-26 20:20:04 +08:00
a63063de42 (MOD) Defined 1 more macro "cast". 2024-06-26 17:20:36 +08:00
8870e5e7db (MOD) Reordered struct member "members" from "Array" from 2nd to 1st for a more convenient accessing to "Var.addr in Array.member[0]".
(MOD) Modified test.c.
2024-06-26 16:54:21 +08:00
f5d82983a4 (MOD) Added Array into cmake building list. 2024-06-26 16:43:26 +08:00
bc4be4e295 (MOD) Implemented Array_Create, Array_CopyOf and Array_Delete
(MOD) Replaced project compiler from "gcc" with "clang" due to out-of-order execution keep happening after running with Array.

(MOD) Removed certain functions from Utils due to insufficiencies of usage.

(MOD) Defined 1 more macro "fail".

(MOD) Fixed 1 bug from "var.c":  Struct member "alive" was not under supervision from the entire programme cycle.

(MOD) Removed 1 useless usage for "Utils_LiteraliseInteger".

(MOD) Removed 1 useless block of commented code.
2024-06-26 15:20:47 +08:00
15 changed files with 411 additions and 333 deletions

1
.gitignore vendored
View File

@@ -22,3 +22,4 @@ CompoundTest
ccwarn ccwarn
genwarn.sh genwarn.sh
test.sh test.sh
expansion_formatted.txt

View File

@@ -4,53 +4,28 @@
# include <Compound/var.h> # include <Compound/var.h>
typedef struct { typedef struct {
int len;
Var *members; Var *members;
int len;
bool alive;
} Array; } Array;
# define ArrayIndexOutOfBound = (Status){\ DEFSTATUS(ArrayIndexOutOfBound, 1, "Given index was accessing illegal address.", STATUS_ERROR, &MemoryViolation);
.identity = nameof(ArrayIndexOutOfBound),\ DEFSTATUS(InvalidArrayLength, 1, "Given length is invalid.", STATUS_ERROR, &ErrorStatus);
.value = 1,\
.description = "Given index was accessing illegal address.",\
.characteristic = STATUS_ERROR,\
.prev = &MemoryViolation\
}
# define InvalidArrayLength (Status){\ Status Array_Create(Array *inst, int len, size_t size);
.value = 1,\
.description = "Given length is invalid.",\
.characteristic = STATUS_ERROR,\
.prev = &ErrorStatus\
}
/* Elementary. */
Status Array_Create(Array *inst, int len, size_t size)
throws(InsufficientMemory InvalidArrayLength);
Status Array_CopyOf(Array *inst, Array *other); Status Array_CopyOf(Array *inst, Array *other);
Status Array_Delete(Array *inst); Status Array_Delete(Array *inst);
Status Array_GetIdx(Array *inst, Var *store, int index);
throws(ArrayIndexOutOfBound);
Status Array_SetIdx(Array *inst, Var *source, int index);
throws(ArrayIndexOutOfBound);
bool Array_Equals(Array *arr1, Array *arr2); bool Array_Equals(Array *arr1, Array *arr2);
/* Extensional. */
Status ArrayUtils_Insert(Array *inst, Var *item, int index); Status ArrayUtils_Insert(Array *inst, Var *item, int index);
throws(ArrayIndexOutOfBound);
Status ArrayUtils_InsertArray(Array *inst, Array *items, int index); Status ArrayUtils_InsertArray(Array *inst, Array *items, int index);
throws(ArrayIndexOutOfBound);
Status ArrayUtils_Remove(Array *inst, int index); Status ArrayUtils_Remove(Array *inst, int index);
throws(ArrayIndexOutOfBound);
Status ArrayUtils_RemoveArray(Array *inst, int off, int len); Status ArrayUtils_RemoveArray(Array *inst, int off, int len);
throws(ArrayIndexOutOfBound InvalidArrayLength);
Status ArrayUtils_Subarray(Array *inst, Array *store, int off, int len); Status ArrayUtils_Subarray(Array *inst, Array *store, int off, int len);
throws(ArrayIndexOutOfBound InvalidArrayLength);
Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len); Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len);
throws(ArrayIndexOutOfBound InvalidArrayLength);
Status ArrayUtils_Search(Array *inst, Var *item, int *store); Status ArrayUtils_Search(Array *inst, Var *item, int *store);
Status ArrayUtils_SearchArray(Array *inst, Array *items, int *store); Status ArrayUtils_SearchArray(Array *inst, Array *items, int *store);
Status ArrayUtils_Split(Array *inst, Array *fore, Array *rear, int index); Status ArrayUtils_Split(Array *inst, Array *fore, Array *rear, int index);
throws(ArrayIndexOutOfBound);
Status ArrayUtils_Revert(Array *inst); Status ArrayUtils_Revert(Array *inst);
bool ArrayUtils_IsEmpty(Array *inst); bool ArrayUtils_IsEmpty(Array *inst);
bool ArrayUtils_IsBlank(Array *inst); bool ArrayUtils_IsBlank(Array *inst);

View File

@@ -3,155 +3,164 @@
Status Array_Create(Array *inst, int len, size_t size) Status Array_Create(Array *inst, int len, size_t size)
{ {
/* Skip unavailable inst and invalid param. */
nonull(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
state((len < 0), apply(InvalidArrayLength));
solve((!len), { inst->len = 0; inst->members = NULL; return apply(NormalStatus); }) /* Skip the living instances. */
state(inst && inst->alive, apply(InstanceStillAlive));
inst->len = len; /* Allocate for members from the inst. */
inst->members = calloc(len, sizeof(Var)); state(!(inst->members = calloc(len, sizeof(Var))), apply(InsufficientMemory));
/* Create for each item from members. */
int erridx = -1; int erridx = -1;
Status errstat = EMPTY;
for (register int i = 0; i < len; i++) { for (register int i = 0; i < len; i++) {
// TODO(william): Throw InsufficientMemory at following line. notok(Var_Create(&inst->members[i], size), {
// DONE(william): ensure(Var_Create(&inst->members[i], size), "Failed to create a new var.");
notok((Var_Create(&inst->members[i], size)), {
#ifdef __DEBUG__
cat("Var_Create failed!\n")
#endif
erridx = i; erridx = i;
errstat = apply(_);
break; break;
} else {
#ifdef __DEBUG__
cat("Var_Create success!\n")
#endif
}) })
} }
/* Review on erridx. Release data that allocated. */ /* Got problem during allocations. */
if (erridx != -1) { if (erridx >= 0) {
for (register int i = erridx; i >= 0; i--) { /* Release members allocated backwardly. */
for (register int i = erridx - 1; i >= 0; i--) {
Var_Delete(&inst->members[i]); Var_Delete(&inst->members[i]);
#ifdef __DEBUG__
cat("Deleted var from InsufficientMemory from Array_Create!")
#endif
} }
/* Release array itself. */ /* Release the array inst. */
free(inst->members); free(inst->members);
return apply(InsufficientMemory); return errstat;
} }
/* Assign rest of the struct members. */
inst->len = len;
inst->alive = true;
return apply(NormalStatus); return apply(NormalStatus);
} }
Status Array_CopyOf(Array *inst, Array *other) Status Array_CopyOf(Array *inst, Array *other)
{ {
// /* Skip unavailable inst and invalid param. */ /* Skip unavailble parameters. */
// nonull(inst, apply(UnavailableInstance)); nonull(other,
// nonull(other, error(InvalidParameter, "Given other was unavailable.")); apply(annot(UnavailableInstance,
"Given object for copying to inst was unavailable.")));
// /* Assign value for len. */ /* Skip invalid parameters and instances. */
// inst->len = other->len; state(inst && inst->alive,
apply(annot(InstanceStillAlive,
"Given inst for being copied was still alive.")));
// if (inst->members == NULL) return apply(NormalStatus); state(!other->alive,
// match(RuntimeError, Array_Create(inst, other->len), "Failed on recreating " apply(annot(InstanceNotAlive,
// "array."); "Given object for copying to inst was not alive.")));
// /* Copy and assign for each member from other to inst. */ state(!other->len,
// for (register int i = 0; i < inst->len; i++) { apply(annot(InvalidArrayLength,
// inst[i] = other[i]; "Given object for copying to inst has length of ZERO.")));
// }
// return apply(NormalStatus); /* Allocate for members from the inst. */
state(!(inst->members = calloc(other->len, sizeof(Var))),
apply(InsufficientMemory));
/* Create for each item from members. */
int erridx = -1;
Status errstat = EMPTY;
for (register int i = 0; i < other->len; i++) {
notok(Var_Create(&inst->members[i], other->members[0].size), {
erridx = i;
errstat = apply(_);
break;
})
notok(Var_CopyOf(&inst->members[i], &other->members[i]), {
erridx = i;
errstat = apply(_);
break;
})
}
/* Got problem during allocations. */
if (erridx >= 0) {
/* /* Release members allocated backwardly. */
if (other == NULL) return 1; for (register int i = erridx - 1; i >= 0; i--) {
Var_Delete(&inst->members[i]);
String_Create(inst, other->len);
for (register int i = 0; i < other->len; i++) {
inst->arr[i] = other->arr[i];
} }
return 0; /* Release the array inst. */
free(inst->members);
return apply(errstat);
}
/* Assign rest of the struct members. */
inst->len = other->len;
inst->alive = true;
*/ return apply(NormalStatus);
} }
Status Array_Delete(Array *inst) Status Array_Delete(Array *inst)
{ {
/* Skip unavailable inst and invalid param. */ nonull(!inst, apply(UnavailableInstance));
nonull(inst, apply(UnavailableInstance)); state(!inst->alive, apply(InstanceNotAlive));
solve((inst->members == NULL), return apply(NormalStatus));
/* Iterate through each member and delete them. */
for (register int i = 0; i < inst->len; i++) {
fail(Var_Delete(&inst->members[i]));
}
inst->len = 0;
free(inst->members); free(inst->members);
inst->members = NULL; inst->members = NULL;
inst->alive = false;
inst->len = 0;
return apply(NormalStatus); return apply(NormalStatus);
} }
Status Array_GetIdx(Array *inst, Var *store, int index) bool Array_Equals(Array *arr1, Array *arr2)
{ {
/* Skip unavailable inst and invalid param. */ /* Skip unavailable instance and parameter. */
nonull(inst, apply(UnavailableInstance)); state(!arr1 || !arr2, false);
nonull(store,
apply(error(InvalidParameter, "Given reference to store was unavailable.")));
state((index < 0 || index >= inst->len), apply(ArrayIndexOutOfBound));
*store = inst->members[index]; /* Skip when arr1 and arr2 have different length. */
state(arr1->len != arr2->len, false);
return apply(NormalStatus); /* Skip when operation is not supported. */
} state(!arr1->alive || !arr2->alive, false);
Status Array_SetIdx(Array *inst, Var *source, int index)
{
/* Skip unavailable inst and invalid param. */
nonull(inst, apply(UnavailableInstance));
nonull(source,
apply(
error(InvalidParameter, "Given reference to source was unavailable.")));
state((index < 0 || index >= inst->len), apply(ArrayIndexOutOfBound));
inst->members[index] = *source; /* Iterate through each member for comparison. */
for (register int i = 0; i < arr1->len; i++) {
return apply(NormalStatus); if (!Var_Equals(&arr1->members[i], &arr2->members[i])) {
}
bool Array_Equals(Array *a, Array *b)
{
/* Skip unavailable inst and invalid param. */
state((a == NULL || b == NULL), false);
state((a->len != b->len), false);
for (register int i = 0; i < a->len; i++) {
if (!Var_Equals(&a->members[i], &b->members[i])) {
return false; return false;
} }
} }
return true; /* Compare rest of the struct member. */
return (arr1->alive == arr2->alive);
} }
Status ArrayUtils_Insert(Array *inst, Var *item, int index);
Status ArrayUtils_InsertArray(Array *inst, Array *items, int index);
Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len) Status ArrayUtils_Remove(Array *inst, int index);
{
nonull(inst, apply(UnavailableInstance)); Status ArrayUtils_RemoveArray(Array *inst, int off, int len);
nonull(elem,
apply(error(InvalidParameter, "Given reference to elem was unavailable."))); Status ArrayUtils_Subarray(Array *inst, Array *store, int off, int len);
state((off + len > inst->len) || (off < 0) || (len < 0),
apply(ArrayIndexOutOfBound)); Status ArrayUtils_Fill(Array *inst, Var *elem, int off, int len);
/* Copy elem into each specified members from inst with off and len. */ Status ArrayUtils_Search(Array *inst, Var *item, int *store);
for (register int i = off; i < (off + len); i++) {
inst->members[i] = *elem; Status ArrayUtils_SearchArray(Array *inst, Array *items, int *store);
}
Status ArrayUtils_Split(Array *inst, Array *fore, Array *rear, int index);
return apply(NormalStatus);
} Status ArrayUtils_Revert(Array *inst);
bool ArrayUtils_IsEmpty(Array *inst);

View File

@@ -2,14 +2,14 @@ cmake_minimum_required (VERSION 3.5)
project (Compound) project (Compound)
set(CMAKE_C_COMPILER gcc) set(CMAKE_C_COMPILER clang)
add_compile_options(-g -std=c99 -Wall -Wextra -D__DEBUG__) add_compile_options(-g -std=c99 -Wall -Wextra -D__DEBUG__)
set(SHARED_SOURCE set(SHARED_SOURCE
MemMan/src/memman.c MemMan/src/memman.c
Status/src/status.c Status/src/status.c
Utils/src/utils.c Array/src/array.c
Var/src/var.c Var/src/var.c
catlog.c) catlog.c)
@@ -32,5 +32,6 @@ add_executable(CompoundTest
test.c test.c
MemMan/src/memman.c MemMan/src/memman.c
Status/src/status.c Status/src/status.c
Utils/src/utils.c Array/src/array.c
Var/src/var.c
catlog.c) catlog.c)

View File

@@ -33,7 +33,10 @@ Status Memory_Reallocate(Memory *inst, size_t size)
/* When failed on reallocating. */ /* When failed on reallocating. */
state(!(inst->addr = realloc(inst->addr, size)), state(!(inst->addr = realloc(inst->addr, size)),
apply(error(InsufficientMemory, "Unsuccessful reallocation was received."))); apply(error(InsufficientMemory, "Cannot successfully reallocate.")));
/* Update size from inst. */
inst->size = size;
return apply(NormalStatus); return apply(NormalStatus);
} }

View File

@@ -143,9 +143,9 @@ int StatusUtils_Depth(Status *inst);
// ---------------------ELEMENTARY------------------------- // ---------------------ELEMENTARY-------------------------
DEFSTATUS(UnknownStatus, -1, "An unknown status.", STATUS_UNKNOWN, NULL); DEFSTATUS(UnknownStatus, -1, "An unknown status.", STATUS_UNKNOWN, &UnknownStatus);
DEFSTATUS(NormalStatus, 0, "A normal status.", STATUS_NORMAL, NULL); DEFSTATUS(NormalStatus, 0, "A normal status.", STATUS_NORMAL, &NormalStatus);
DEFSTATUS(ErrorStatus, 1, "An error status.", STATUS_ERROR, NULL); DEFSTATUS(ErrorStatus, 1, "An error status.", STATUS_ERROR, &ErrorStatus);
// ----------------------EXTENDED-------------------------- // ----------------------EXTENDED--------------------------
@@ -165,14 +165,6 @@ DEFSTATUS(UnavailableObject, 1,
"An unavailable object was presented.", "An unavailable object was presented.",
STATUS_ERROR, &ErrorStatus); STATUS_ERROR, &ErrorStatus);
DEFSTATUS(InstanceStillAlive, 1,
"Given instance was yet alive.",
STATUS_ERROR, &ErrorStatus);
DEFSTATUS(InstanceNotAlive, 1,
"Given instance for reallocation was not alive.",
STATUS_ERROR, &ErrorStatus);
DEFSTATUS(InvalidParameter, 1, DEFSTATUS(InvalidParameter, 1,
"An invalid parameter was presented.", "An invalid parameter was presented.",
STATUS_ERROR, &InvalidObject); STATUS_ERROR, &InvalidObject);
@@ -189,10 +181,26 @@ DEFSTATUS(IntegerOverFlow, 1,
"An integer had overflowed.", "An integer had overflowed.",
STATUS_ERROR, &ArithmeticError); STATUS_ERROR, &ArithmeticError);
DEFSTATUS(InvalidOperation, 1,
"An invalid operation was detected.",
STATUS_ERROR, &ErrorStatus);
DEFSTATUS(RuntimeError, 1, DEFSTATUS(RuntimeError, 1,
"A runtime error occurred.", "A runtime error occurred.",
STATUS_ERROR, &ErrorStatus); STATUS_ERROR, &ErrorStatus);
DEFSTATUS(InstanceStillAlive, 1,
"Given instance was still alive.",
STATUS_ERROR, &RuntimeError);
DEFSTATUS(InstanceNotAlive, 1,
"Given instance for reallocation was not alive.",
STATUS_ERROR, &RuntimeError);
DEFSTATUS(InvalidOperationBetweenAliveAndNonAlive, 1,
"Given two instances were incompatible with each other for any operation.",
STATUS_ERROR, &InvalidOperation);
DEFSTATUS(InstanceCreatingFailure, 1, DEFSTATUS(InstanceCreatingFailure, 1,
"Cannot create the instance.", "Cannot create the instance.",
STATUS_ERROR, &RuntimeError); STATUS_ERROR, &RuntimeError);
@@ -320,7 +328,15 @@ static inline Status PrintStatus(Status s)
static inline void PrintStatusDump(Status s) static inline void PrintStatusDump(Status s)
{ {
/* Create dump. */ /* Create dump. */
/* Calculate depth for dumping. */
const int dump_len = StatusUtils_Depth(&s); const int dump_len = StatusUtils_Depth(&s);
/* Skip when "s" is either unavailable or is at the buttom of status stack. */
if (dump_len == -1) {
PrintStatus(s);
return;
}
Status dump[dump_len]; Status dump[dump_len];
Status current = s; Status current = s;
dump[0] = current; // Put self at leading. dump[0] = current; // Put self at leading.
@@ -328,6 +344,7 @@ static inline void PrintStatusDump(Status s)
// StatusUtils_Dump will only access (storage) the prev. // StatusUtils_Dump will only access (storage) the prev.
// It does not include this status itself. // It does not include this status itself.
StatusUtils_Dump(&current, &dump[i]); StatusUtils_Dump(&current, &dump[i]);
current = *current.prev; current = *current.prev;
} }
@@ -340,22 +357,6 @@ static inline void PrintStatusDump(Status s)
unsure(PrintStatus(dump[i]), !_.value, { unsure(PrintStatus(dump[i]), !_.value, {
(void)fprintf(stderr, "Unable to literalise.\n"); (void)fprintf(stderr, "Unable to literalise.\n");
}) })
// seek(PrintStatus(dump[i]), { // Get returning status.
// /* Handle TraditionalFunctionReturn. */
// nest(_, __, unsure(__, !__.value, { // No bytes were written to buffer.
// (void)fprintf(stderr, "Unable to literalise.\n");
// return;
// }));
// // Handle abnormal status.
// nest(_, __, notok(__, {
// /* Output the description as explanation. */
// (void)fprintf(stderr, "%s\n", __.description);
// return;
// }));
// });
} }
} }

View File

@@ -4,10 +4,6 @@ Status Location_Literalise(Location *inst, char *buff)
{ {
nonull(inst, apply(UnavailableInstance)); nonull(inst, apply(UnavailableInstance));
nonull(buff, apply(UnavailableBuffer)); nonull(buff, apply(UnavailableBuffer));
/* Literalise line. */
char line_buff[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
Utils_LiteraliseInteger(inst->line, line_buff);
where( where(
snprintf(buff, LITERALISATION_LENGTH_MAXIMUM, snprintf(buff, LITERALISATION_LENGTH_MAXIMUM,
@@ -31,13 +27,12 @@ bool Status_Equal(Status *stat1, Status *stat2)
state(stat1 == NULL || stat2 == NULL, false); state(stat1 == NULL || stat2 == NULL, false);
return ( return (
!strcmp(stat1->identity, stat2->identity) &&
stat1->value == stat2->value && stat1->value == stat2->value &&
!strcmp(stat1->description, stat2->description) && !strcmp(stat1->description, stat2->description) &&
stat1->characteristic == stat2->characteristic && stat1->characteristic == stat2->characteristic &&
Location_Equal(&stat1->loc, &stat2->loc) && Location_Equal(&stat1->loc, &stat2->loc) &&
((StatusUtils_HasPrev(*stat1) && StatusUtils_HasPrev(*stat2)) stat1->prev == stat2->prev
? Status_Equal(stat1->prev, stat2->prev)
: true)
); );
} }
@@ -91,7 +86,8 @@ bool StatusUtils_IsOkay(Status stat)
bool StatusUtils_IsRecursive(Status stat) bool StatusUtils_IsRecursive(Status stat)
{ {
return (stat.prev && stat.prev == &stat); // return (stat.prev && stat.prev == stat.prev->prev);
return (stat.prev && Status_Equal(&stat, stat.prev));
} }
void StatusUtils_Dump(Status *inst, Status *store) void StatusUtils_Dump(Status *inst, Status *store)
@@ -104,26 +100,6 @@ void StatusUtils_Dump(Status *inst, Status *store)
*store = *inst->prev; *store = *inst->prev;
} }
// void StatusUtils_Dump(Status *inst, Status **store, int idx)
// {
// /* Skip when having invalid inst, store or idx. */
// svoid(!inst || !store || idx < 0 || StatusUtils_IsRecursive(*inst));
// // store[idx] = *inst;
// *store[idx] = (Status){
// .identity = inst->identity,
// .value = inst->value,
// .description = inst->description,
// .characteristic = inst->characteristic,
// .loc = inst->loc,
// .prev = inst->prev
// };
// (void)printf("idx: %d\n", idx);
// StatusUtils_Dump(inst->prev, store, (idx - 1));
// }
int StatusUtils_Depth(Status *stat) int StatusUtils_Depth(Status *stat)
{ {
/* Skip unavailable stat. */ /* Skip unavailable stat. */
@@ -135,20 +111,14 @@ int StatusUtils_Depth(Status *stat)
Status current = *stat; Status current = *stat;
/* Iterate to accumulate. */ /* Iterate to accumulate. */
while (current.prev) { while (current.prev) {
/* Skip recursive status. */
if (StatusUtils_IsRecursive(current)) break;
current = *current.prev; current = *current.prev;
cnt += 1; cnt += 1;
} }
return cnt; return cnt;
// Status *current = stat; // Include this layer of Status.
// register int cnt;
// for (cnt = 0; (!StatusUtils_IsRecursive(*current)
// && StatusUtils_HasPrev(*current)); cnt++) {
// current = current->prev;
// }
// return cnt;
} }
// bool arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2) // bool arguestarter_equal(ArgueStarter *inst1, ArgueStarter *inst2)

View File

@@ -19,15 +19,13 @@ typedef struct {
StringEncoding encoding; StringEncoding encoding;
} String; } String;
/* Elementary. */
Status String_Create(String *inst, int len); Status String_Create(String *inst, int len);
Status String_CopyOf(String *inst, String *other); Status String_CopyOf(String *inst, String *other);
Status String_Delete(String *inst); Status String_Delete(String *inst);
Status String_GetIdx(String *inst, Char *item, int index); Status String_Encode(String *inst, StringEncoding encoding);
Status String_SetIdx(String *inst, Char *item, int index); Status String_Decode(String *inst, StringEncoding encoding);
Status String_Literalise(String *inst, String *store); Status String_Literalise(String *inst, String *store);
/* Extensional. */
Status StringUtils_FromInteger(String *inst, int value, int base); Status StringUtils_FromInteger(String *inst, int value, int base);
Status StringUtils_FromShortInteger(String *inst, short int value, int base); Status StringUtils_FromShortInteger(String *inst, short int value, int base);
Status StringUtils_FromLongInteger(String *inst, long int value, int base); Status StringUtils_FromLongInteger(String *inst, long int value, int base);
@@ -77,10 +75,8 @@ Status StringUtils_ToUnsignedComplexLongLongInteger(String *inst, unsigned _Comp
Status StringUtils_ToAddress(String *inst, void **store); Status StringUtils_ToAddress(String *inst, void **store);
Status StringUtils_ToCharBuff(String *inst, char const *buff); Status StringUtils_ToCharBuff(String *inst, char const *buff);
Status StringUtils_ToWideCharBuff(String *inst, wchar_t const *wbuff); Status StringUtils_ToWideCharBuff(String *inst, wchar_t const *wbuff);
// Status StringUtils_Format(String *inst, const String *restrict fmt, ...);
Status StringUtils_Tokenise(String *inst, const String *delim, String *store); Status StringUtils_Tokenise(String *inst, const String *delim, String *store);
Status String_Encode(String *inst, StringEncoding encoding) throws(UnsupportedEncoding EncodingError DecodingError); bool StringUtils_IsBlank(String *inst);
Status String_Decode(String *inst, StringEncoding encoding) throws(UnsupportedEncoding EncodingError DecodingError);
int StringUtils_Compare(String *a, String *b); int StringUtils_Compare(String *a, String *b);
static Status StringConversionPrecisionError = { static Status StringConversionPrecisionError = {
@@ -93,13 +89,4 @@ static Status StringConversionPrecisionError = {
.prev = (Status *)&ImprecisionError .prev = (Status *)&ImprecisionError
}; };
// # define string(str) ((String) {\
// .data =
// })
typedef Array(int) InfiniteInteger;
typedef Array(double) InfiniteFloatingPoint;
typedef Array(_Complex double) InfintieComplex;
#endif /* COMPOUND_STRING_H */ #endif /* COMPOUND_STRING_H */

View File

@@ -1,49 +1,49 @@
#include <Compound/utils.h> #include <Compound/utils.h>
int Utils_CalcDigits(long long int n) // int Utils_CalcDigits(long long int n)
{ // {
if (n == 0) { // if (n == 0) {
return 1; // return 1;
} // }
n = llabs(n); // n = llabs(n);
/* Accumulate. */ // /* Accumulate. */
register int i; // register int i;
for (i = 0; n; i++) n /= 10; // for (i = 0; n; i++) n /= 10;
return i; // return i;
} // }
int Utils_LiteraliseInteger(long long int n, char *buff) // int Utils_LiteraliseInteger(long long int n, char *buff)
{ // {
/* Invalid buffer was presented. */ // /* Invalid buffer was presented. */
if (strlen(buff) != LITERALISATION_LENGTH_MAXIMUM) { // if (strlen(buff) != LITERALISATION_LENGTH_MAXIMUM) {
buff = NULL; // buff = NULL;
return 0; // return 0;
} // }
if (!n) { // if (!n) {
buff = "0"; // buff = "0";
return 1; // return 1;
} // }
const int literalising_len = Utils_CalcDigits(n); // const int literalising_len = Utils_CalcDigits(n);
if (literalising_len >= LITERALISATION_LENGTH_MAXIMUM) { // if (literalising_len >= LITERALISATION_LENGTH_MAXIMUM) {
buff = NULL; // buff = NULL;
return 0; // return 0;
} // }
char literalising[literalising_len]; // char literalising[literalising_len];
for (register int i = 0; i < literalising_len; i++) { // for (register int i = 0; i < literalising_len; i++) {
literalising[i] = (n / (int)pow(10, i)); // literalising[i] = (n / (int)pow(10, i));
} // }
return literalising_len; // return literalising_len;
} // }
int Utils_DateTimeLiteralise(time_t timer, char *buff, // int Utils_DateTimeLiteralise(time_t timer, char *buff,
const char *__restrict format) // const char *__restrict format)
{ // {
} // }

View File

@@ -52,9 +52,9 @@ typedef struct {
Status Var_Create(Var *inst, size_t size) throws(InsufficientMemory); Status Var_Create(Var *inst, size_t size) throws(InsufficientMemory);
Status Var_CopyOf(Var *inst, Var *other); Status Var_CopyOf(Var *inst, Var *other);
Status Var_Delete(Var *inst);
Status Var_Literalise(Var *inst, char *buff); Status Var_Literalise(Var *inst, char *buff);
bool Var_Equals(Var *a, Var *b); bool Var_Equals(Var *a, Var *b);
void Var_Delete(Var *inst);
void VarUtils_Swap(Var *v1, Var *v2); void VarUtils_Swap(Var *v1, Var *v2);
// bool VarUtils_IsIdentityLegal(char *identity); // bool VarUtils_IsIdentityLegal(char *identity);

View File

@@ -1,3 +1,4 @@
#include <Compound/status.h>
#include <Compound/var.h> #include <Compound/var.h>
Status Var_Create(Var *inst, size_t size) Status Var_Create(Var *inst, size_t size)
@@ -14,22 +15,6 @@ Status Var_Create(Var *inst, size_t size)
return apply(NormalStatus); return apply(NormalStatus);
} }
// Status Var_Create(Var *inst, void *addr, size_t size, char *identity)
// {
// /* Skip when inst is unavailable. */
// nonull(inst, apply(UnavailableInstance));
// /* Skip when identity is unavailable. */
// nonull(identity, NullPointerAccounted);
// /* Skip when identity does not pass the examine. */
// state(!VarUtils_IsIdentityLegal(identity), IllegalVarIdentity);
// inst->addr = addr;
// inst->size = size;
// *inst->identity = *identity;
// return apply(NormalStatus);
// }
Status Var_CopyOf(Var *inst, Var *other) Status Var_CopyOf(Var *inst, Var *other)
{ {
/* Skip when inst or other is unavailable. */ /* Skip when inst or other is unavailable. */
@@ -45,33 +30,17 @@ Status Var_CopyOf(Var *inst, Var *other)
return apply(NormalStatus); return apply(NormalStatus);
} }
void Var_Delete(Var *inst) Status Var_Delete(Var *inst)
{ {
svoid(!inst); nonull(!inst, apply(UnavailableInstance));
state(!inst->alive, apply(InstanceNotAlive));
free(inst->addr); free(inst->addr);
inst->alive = false;
inst->addr = NULL; inst->addr = NULL;
inst->size = 0; inst->size = 0;
}
// void Var_Delete(Var *inst)
// {
// /* Skip when inst or inst->addr is unavailable. */
// svoid(!inst || inst->addr == NULL);
// inst->addr = NULL;
// inst->size = 0;
// *inst->identity = 0;
// }
void VarUtils_Swap(Var *v1, Var *v2)
{
/* Skip when v1 or v2 is unavailable. */
svoid(!v1 || !v2);
Var v3 = *v1; return apply(NormalStatus);
*v1 = *v2;
*v2 = v3;
} }
Status Var_Literalise(Var *inst, char *buff) Status Var_Literalise(Var *inst, char *buff)
@@ -95,32 +64,12 @@ bool Var_Equals(Var *a, Var *b)
return (a->addr == b->addr && a->size == b->size); return (a->addr == b->addr && a->size == b->size);
} }
// bool VarUtils_IsIdentityLegal(char *identity) void VarUtils_Swap(Var *v1, Var *v2)
// { {
// /* Skip when identity is unavailable. */ /* Skip when v1 or v2 is unavailable. */
// state(identity == NULL, false); svoid(!v1 || !v2);
// const int len = strlen(identity); Var v3 = *v1;
*v1 = *v2;
// /* Skip when identity is empty. */ *v2 = v3;
// state(len == 0, false); }
// /* Skip when the first char is not within alphabet. */
// state(ATRANGE('a', 'z', identity[0])
// || ATRANGE('A', 'Z', identity[0]), false);
// /* Skip when the length of identity is greater that VAR_IDENTITY_LENGTH. */
// state(len > VAR_IDENTITY_LENGTH, false);
// /* Skip when identity has space and illegal characters in it. */
// const int illegal_len = strlen(VAR_IDENTITY_ILLEGAL_CHAR);
// for (register int i = 0; i < len; i++) {
// for (register int j = 0; j < illegal_len; j++) {
// if (identity[i] == VAR_IDENTITY_ILLEGAL_CHAR[j]) {
// return false;
// }
// }
// }
// return true;
// }

View File

@@ -99,7 +99,7 @@ Status CatlogSender_Send(CatlogSender *inst)
} }
Status CatlogUtils_OpenFile(FILE **fileptr, const char *filepath, Status CatlogUtils_OpenFile(FILE **fileptr, const char *filepath,
const char const *restrict mode) const char *restrict mode)
{ {
/* Skip unavailable instances and parameters. */ /* Skip unavailable instances and parameters. */
nonull(fileptr, apply(UnavailableBuffer)); nonull(fileptr, apply(UnavailableBuffer));

View File

@@ -59,7 +59,7 @@ Status CatlogSender_CopyOf(CatlogSender *inst, CatlogSender *other);
Status CatlogSender_Send(CatlogSender *inst); Status CatlogSender_Send(CatlogSender *inst);
bool CatlogSender_Equals(CatlogSender *inst, CatlogSender *other); bool CatlogSender_Equals(CatlogSender *inst, CatlogSender *other);
Status CatlogUtils_OpenFile(FILE **fileptr, const char *filepath, Status CatlogUtils_OpenFile(FILE **fileptr, const char *filepath,
const char const *restrict mode); const char *restrict mode);
Status CatlogUtils_CloseFile(FILE **fileptr); Status CatlogUtils_CloseFile(FILE **fileptr);
#endif /* COMPOUND_CATLOG_H */ #endif /* COMPOUND_CATLOG_H */

View File

@@ -1,15 +1,18 @@
#ifndef COMPOUND_COMMON_H #ifndef COMPOUND_COMMON_H
# define COMPOUND_COMMON_H # define COMPOUND_COMMON_H
# ifdef __DEBUG__
# warning DEBUG IS ON
# endif /* __DEBUG__ */
# include <stdlib.h> # include <stdlib.h>
# include <stdbool.h> # include <stdbool.h>
# define EMPTY {0} # define EMPTY {0}
/*
PLEASE BE NOTICE:
MAGIC MACRO CANNOT USE "APPLY" AT RETURNING.
IT SHOULD ALWAYS RETURN THE LOCATION INDICATOR WHERE
IT CAME FROM.
*/
/* Get the literal. */ /* Get the literal. */
# define nameof(obj) #obj # define nameof(obj) #obj
@@ -40,10 +43,13 @@
/* Execute b whenever finds s is "NOT okay". */ /* Execute b whenever finds s is "NOT okay". */
# define notok(s, b) { Status _ = s; if (!StatusUtils_IsOkay(_)) b } # define notok(s, b) { Status _ = s; if (!StatusUtils_IsOkay(_)) b }
/* Return e when passing a failing e commented with c. */ /* Return e when passing a failing e. */
# define fails(e, c) { notok(e, return apply(annot(_, c));) } # define fail(e) { notok(e, return _;) }
/* Return v when passing a failing e. */ /* Return e when passing a failing e commented with c. */
# define fails(e, c) { notok(e, return annot(_, c);) }
/* Return value "v" when passing a failing e. */
# define vfail(e, v) { notok(e, return v;) } # define vfail(e, v) { notok(e, return v;) }
/* Execute b for handling UnknownStatus (TraditionalFunctionReturn). */ /* Execute b for handling UnknownStatus (TraditionalFunctionReturn). */
@@ -62,6 +68,13 @@
/* Allows different macros using "_" nested with each other. */ /* Allows different macros using "_" nested with each other. */
# define nest(v1, v2, b) { clone(v1, v2) b } # define nest(v1, v2, b) { clone(v1, v2) b }
/* Cast Var "var" into builtin type in C specified with "type". */
# define cast(var, type) (*(type *)var.addr)
/* Assign var with value under type "type".
REQUIRE BOTH VAR AND VALUE TO BE ALIVE. */
# define assign(var, value, type) { cast(var, type) = cast(value, type); }
// # define lambda(param, body, capfmt, ...) {\ // # define lambda(param, body, capfmt, ...) {\
// /* Duplicate everything from cap. */\ // /* Duplicate everything from cap. */\
// va_list ptr;\ // va_list ptr;\
@@ -72,7 +85,7 @@
/* Create a new UnknownStatus on the fly. */ /* Create a new UnknownStatus on the fly. */
# define unknown(e, c, v) ((Status) {\ # define unknown(e, c, v) ((Status) {\
.identity = nameof(e),\ .identity = e.identity,\
.value = v,\ .value = v,\
.description = c,\ .description = c,\
.characteristic = STATUS_UNKNOWN,\ .characteristic = STATUS_UNKNOWN,\
@@ -82,7 +95,7 @@
/* Create a new NormalStatus on the fly. */ /* Create a new NormalStatus on the fly. */
# define normal(e, c) ((Status) {\ # define normal(e, c) ((Status) {\
.identity = nameof(e),\ .identity = e.identity,\
.value = 0,\ .value = 0,\
.description = c,\ .description = c,\
.characteristic = STATUS_NORMAL,\ .characteristic = STATUS_NORMAL,\
@@ -92,7 +105,7 @@
/* Create a new ErrorStatus on the fly. */ /* Create a new ErrorStatus on the fly. */
# define error(e, c) ((Status) {\ # define error(e, c) ((Status) {\
.identity = nameof(e),\ .identity = e.identity,\
.value = e.value,\ .value = e.value,\
.description = c,\ .description = c,\
.characteristic = STATUS_ERROR,\ .characteristic = STATUS_ERROR,\
@@ -100,7 +113,7 @@
.prev = e.prev\ .prev = e.prev\
}) })
/* Extend the Status chain by giving 'p' for "predecessor" and 'e' for "Eval-Status". */ /* Replace the prev of e with p. */
# define extend(p, e) ((Status) {\ # define extend(p, e) ((Status) {\
.identity = e.identity,\ .identity = e.identity,\
.value = p.value,\ .value = p.value,\
@@ -110,6 +123,7 @@
.prev = (Status *)&p\ .prev = (Status *)&p\
}) })
/* Create a new Status with v as its value. */
# define value(e, v) ((Status) {\ # define value(e, v) ((Status) {\
.identity = e.identity,\ .identity = e.identity,\
.value = v,\ .value = v,\
@@ -119,6 +133,17 @@
.prev = (Status *)e.prev\ .prev = (Status *)e.prev\
}) })
/* Change the characteristic of e. */
# define shift(e, c) ((Status) {\
.identity = e.identity,\
.value = e.value,\
.description = e.description,\
.characteristic = c,\
.loc = e.loc,\
.prev= (Status *)e.prev\
})
/* Apply a new location to e where this macro is called. */
# define apply(e) ((Status) {\ # define apply(e) ((Status) {\
.identity = e.identity,\ .identity = e.identity,\
.value = e.value,\ .value = e.value,\
@@ -128,7 +153,7 @@
.prev = (Status *)e.prev\ .prev = (Status *)e.prev\
}) })
// Reannotate for e. /* Replace the description from e with c. */
# define annot(e, c) ((Status) {\ # define annot(e, c) ((Status) {\
.identity = e.identity,\ .identity = e.identity,\
.value = e.value,\ .value = e.value,\

161
test.c
View File

@@ -13,13 +13,164 @@ Status func(void)
__attribute__((constructor)) __attribute__((constructor))
void __CONSTRUCT__() { void __CONSTRUCT__() {
cat("Hello, Compound!\n"); cat("Hello, Compound!");
} }
__attribute__((destructor)) __attribute__((destructor))
void __DESTRUCT__() {} void __DESTRUCT__() {}
Status Main(void) Status Main(void)
{
return apply(NormalStatus);
}
Status MainArrayComparisonTest(void)
{
Array arr1 = EMPTY;
fail(Array_Create(&arr1, 10, 10));
Array arr2 = EMPTY;
fail(Array_Create(&arr2, 10, 10));
if (Array_Equals(&arr1, &arr2)) {
cat("Equal!");
} else {
cat("Not equal!");
}
Array_Delete(&arr2);
Array_Delete(&arr1);
return apply(NormalStatus);
}
Status MainMemoryOperationTest(void)
{
Memory mem = EMPTY;
fail(Memory_Create(&mem, sizeof(double)));
fail(Memory_Allocate(&mem));
(void)printf("%p:%ld\n", mem.addr, mem.size);
fail(Memory_Reallocate(&mem, sizeof(char)));
(void)printf("%p:%ld\n", mem.addr, mem.size);
fail(Memory_Release(&mem));
fail(Memory_Delete(&mem));
return apply(NormalStatus);
}
int tfunc(void)
{
vfail(apply(ErrorStatus), 1);
return 0;
}
Status MainMacroFailsTest(void)
{
unsure(apply(value(TraditionalFunctionReturn, tfunc())), _.value,
nest(_, __, fails(shift(__, STATUS_ERROR), "Failed on execution from tfunc.")));
return apply(NormalStatus);
}
Status MainArrayCreateAndDeleteWithModulatedMemberAccessing(void)
{
Array arr = EMPTY;
fail(Array_Create(&arr, 8, sizeof(int)));
for (register int i = 0; i < arr.len; i++) {
Var current = EMPTY;
// fails(Var_Create(&current, arr.members[0].size),
// "Failed to create Var current.");
state(!current.alive || !arr.members[i].alive,
apply(InvalidOperationBetweenAliveAndNonAlive));
assign(current, arr.members[i], int);
char buff[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
unsure(Var_Literalise(&current, buff), !_.value, {
return annot(_, "Failed to literalise Var current.");
})
(void)printf("%s\n", buff);
// Var_Delete(&current);
}
cat("Get:");
Var get = EMPTY;
fails(Var_Create(&get, arr.members[4].size), "Failed to create Var \"get\".");
state(!get.alive || !arr.members[4].alive,
apply(InvalidOperationBetweenAliveAndNonAlive));
assign(get, arr.members[4], int);
char buff[LITERALISATION_LENGTH_MAXIMUM] = EMPTY;
unsure(Var_Literalise(&get, buff), !_.value, {
return annot(_, "Failed to literalise Var current.");
})
Var_Delete(&get);
// Array_Delete(&arr);
return apply(NormalStatus);
}
Status MainArrayCreateAndDeleteWithTraditionalMemberAccessing(void)
{
// const int len = 8;
// int iarr[] = {
// 1, 2, 4, 8, 16, 32, 64, 128
// };
// Array arr;
// fails(Array_Create(&arr, len, sizeof(__typeof__(iarr[0]))),
// "Failed to create an array instance.");
// /* Array member assignments with iarr. */
// for (register int i = 0; i < arr.len; i++) {
// arr.members[i].addr = &iarr[i];
// }
// for (register int i = 0; i < arr.len; i++) {
// (void)printf("%d\n", i);
// for (register int j = 0; j < *(int *)arr.members[i].addr; j++) {
// (void)printf("#");
// }
// (void)printf("\n");
// }
// // Array_Delete(&arr);
Array arr = EMPTY;
fail(Array_Create(&arr, 8, sizeof(long long)));
for (register int i = 0; i < arr.len; i++) {
cast(arr.members[i], long long) = INT64_MAX;
(void)printf("%lld\n", cast(arr.members[i], long long));
}
Array_Delete(&arr);
return apply(NormalStatus);
}
Status MainStatus(void)
{ {
// Memory mem1; // Memory mem1;
// seek(Memory_Create(&mem1, INT64_MAX), { // seek(Memory_Create(&mem1, INT64_MAX), {
@@ -453,5 +604,11 @@ Status Main(void)
int main(void) int main(void)
{ {
return Main().value; int rtn = 0;
notok(Main(), {
rtn = _.value;
PrintStatusDump(_);
})
return rtn;
} }