Compare commits

...

5 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
11 changed files with 263 additions and 179 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,8 +4,8 @@
# include <Compound/var.h> # include <Compound/var.h>
typedef struct { typedef struct {
int len;
Var *members; Var *members;
int len;
bool alive; bool alive;
} Array; } Array;
@@ -14,9 +14,7 @@ DEFSTATUS(InvalidArrayLength, 1, "Given length is invalid.", STATUS_ERROR, &Erro
Status Array_Create(Array *inst, int len, size_t size); Status Array_Create(Array *inst, int len, size_t size);
Status Array_CopyOf(Array *inst, Array *other); Status Array_CopyOf(Array *inst, Array *other);
void Array_Delete(Array *inst); Status Array_Delete(Array *inst);
Status Array_GetIdx(Array *inst, Var *store, int index);
Status Array_SetIdx(Array *inst, Var *source, int index);
bool Array_Equals(Array *arr1, Array *arr2); bool Array_Equals(Array *arr1, Array *arr2);
Status ArrayUtils_Insert(Array *inst, Var *item, int index); Status ArrayUtils_Insert(Array *inst, Var *item, int index);

View File

@@ -3,6 +3,8 @@
Status Array_Create(Array *inst, int len, size_t size) Status Array_Create(Array *inst, int len, size_t size)
{ {
nonull(inst, apply(UnavailableInstance));
/* Skip the living instances. */ /* Skip the living instances. */
state(inst && inst->alive, apply(InstanceStillAlive)); state(inst && inst->alive, apply(InstanceStillAlive));
@@ -91,7 +93,7 @@ Status Array_CopyOf(Array *inst, Array *other)
/* Release the array inst. */ /* Release the array inst. */
free(inst->members); free(inst->members);
return errstat; return apply(errstat);
} }
/* Assign rest of the struct members. */ /* Assign rest of the struct members. */
@@ -101,26 +103,45 @@ Status Array_CopyOf(Array *inst, Array *other)
return apply(NormalStatus); return apply(NormalStatus);
} }
void Array_Delete(Array *inst) Status Array_Delete(Array *inst)
{ {
svoid(!inst || !inst->alive); nonull(!inst, apply(UnavailableInstance));
state(!inst->alive, apply(InstanceNotAlive));
/* Iterate through each member and delete them. */
for (register int i = 0; i < inst->len; i++) { for (register int i = 0; i < inst->len; i++) {
Var_Delete(&inst->members[i]); fail(Var_Delete(&inst->members[i]));
} }
free(inst->members); free(inst->members);
inst->members = NULL;
inst->alive = false; inst->alive = false;
inst->len = 0; inst->len = 0;
return apply(NormalStatus);
} }
Status Array_GetIdx(Array *inst, Var *store, int index); bool Array_Equals(Array *arr1, Array *arr2)
{
/* Skip unavailable instance and parameter. */
state(!arr1 || !arr2, false);
Status Array_SetIdx(Array *inst, Var *source, int index); /* Skip when arr1 and arr2 have different length. */
state(arr1->len != arr2->len, false);
bool Array_Equals(Array *arr1, Array *arr2); /* Skip when operation is not supported. */
state(!arr1->alive || !arr2->alive, false);
/* Iterate through each member for comparison. */
for (register int i = 0; i < arr1->len; i++) {
if (!Var_Equals(&arr1->members[i], &arr2->members[i])) {
return false;
}
}
/* Compare rest of the struct member. */
return (arr1->alive == arr2->alive);
}
Status ArrayUtils_Insert(Array *inst, Var *item, int index); Status ArrayUtils_Insert(Array *inst, Var *item, int index);
@@ -143,6 +164,3 @@ Status ArrayUtils_Split(Array *inst, Array *fore, Array *rear, int index);
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);

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

@@ -27,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)
); );
} }
@@ -87,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)
@@ -100,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. */
@@ -131,6 +111,9 @@ 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;
} }

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

@@ -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,34 +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 || !inst->alive); nonull(!inst, apply(UnavailableInstance));
state(!inst->alive, apply(InstanceNotAlive));
free(inst->addr); free(inst->addr);
inst->alive = false; inst->alive = false;
inst->addr = NULL; inst->addr = NULL;
inst->size = 0; inst->size = 0;
}
// void Var_Delete(Var *inst) return apply(NormalStatus);
// {
// /* 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;
*v1 = *v2;
*v2 = v3;
} }
Status Var_Literalise(Var *inst, char *buff) Status Var_Literalise(Var *inst, char *buff)
@@ -96,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

@@ -6,6 +6,13 @@
# 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
@@ -36,13 +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. */
# define fails(e, c) { notok(e, return apply(annot(_, c));) }
/* Return e when passing a failing e. */ /* Return e when passing a failing e. */
# define fail(e) { notok(e, return apply(_);) } # 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). */
@@ -61,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;\
@@ -71,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,\
@@ -81,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,\
@@ -91,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,\
@@ -99,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,\
@@ -109,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,\
@@ -118,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,\
@@ -127,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,\

153
test.c
View File

@@ -13,7 +13,7 @@ Status func(void)
__attribute__((constructor)) __attribute__((constructor))
void __CONSTRUCT__() { void __CONSTRUCT__() {
cat("Hello, Compound!\n"); cat("Hello, Compound!");
} }
__attribute__((destructor)) __attribute__((destructor))
@@ -21,36 +21,155 @@ void __DESTRUCT__() {}
Status Main(void) Status Main(void)
{ {
const int len = 8;
int iarr[] = {
1, 2, 4, 8, 16, 32, 64, 128
};
Array arr; return apply(NormalStatus);
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];
} }
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++) { for (register int i = 0; i < arr.len; i++) {
(void)printf("%d\n", i); Var current = EMPTY;
for (register int j = 0; j < *(int *)arr.members[i].addr; j++) { // fails(Var_Create(&current, arr.members[0].size),
(void)printf("#"); // "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);
} }
(void)printf("\n"); 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); // Array_Delete(&arr);
return apply(NormalStatus); 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) Status MainStatus(void)
{ {
// Memory mem1; // Memory mem1;