libicl.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 2,613 行 · 第 1/5 页
C
2,613 行
(void)memset(tmp, 0, tmpBufSz);
snprintf(tmp, tmpBufSz, "%f", icl_Float(t));
res = tmp;
}
else if (icl_IsStr(t)) {
if(t->hadQuotes == 1) {
res = strdup(icl_stQuoteForce(t->p));
}
else {
res = strdup(icl_stQuote(t->p));
}
}
else if(icl_IsDataQ(t)) {
/* icldataq("") */
res = (char*)malloc(icl_Len(t) + 1);
res = memcpy(res, icl_DataQ(t), icl_Len(t));
res[icl_Len(t)] = '\0';
}
else if (icl_IsStruct(t)) {
int first = TRUE;
ICLListType *args;
/* Checks for struct that are operators */
if (icl_stIsOperator(icl_Functor(t))>0) {
args = icl_Arguments(t);
/* Left operand */
icl_stAppend(&res, icl_NewStringFromTerm(args->elt));
/* Operator */
icl_stAppend(&res, icl_Functor(t));
/* Right operand */
args = args->next;
if (args) {
icl_stAppend(&res, icl_NewStringFromTerm(args->elt));
}
}
else {
res = strdup(icl_Functor(t));
args = icl_Arguments(t);
icl_stAppend(&res, "(");
while (args) {
char *arg;
arg = icl_NewStringFromTerm(args->elt);
if (first) {
first = FALSE;
}
else {
icl_stAppend(&res, ",");
}
icl_stAppend(&res, arg);
icl_stFree(arg);
args = args->next;
}
icl_stAppend(&res, ")");
}
}
else if (icl_IsList(t)) {
int first = TRUE;
ICLListType *args;
args = icl_List(t);
res = strdup("[");
while (args) {
char *arg;
arg = icl_NewStringFromTerm(args->elt);
if (first)
first = FALSE;
else icl_stAppend(&res, ",");
icl_stAppend(&res, arg);
icl_stFree(arg);
args = args->next;
}
icl_stAppend(&res, "]");
}
else if (icl_IsGroup(t)) {
int first = TRUE;
ICLListType *args;
char start;
char *separator;
icl_GetGroupChars(t, &start, &separator);
args = icl_List(t);
res = strdup("[");
res[0] = start;
while (args) {
char *arg;
arg = icl_NewStringFromTerm(args->elt);
if (first)
first = FALSE;
else icl_stAppend(&res, separator);
icl_stAppend(&res, arg);
icl_stFree(arg);
args = args->next;
}
icl_stAppend(&res, "]");
if (start == '(')
res[strlen(res)-1] = start + 1; /* () */
else
res[strlen(res)-1] = start + 2; /* {|} and [\] */
icl_stFree(separator);
}
else {
fprintf(stderr, "Unknown term type for icl_NewStringFromTerm: %i\n", t->iclType);
}
return (res);
}
/****************************************************************************
* name: pt
* purpose: Debug
****************************************************************************/
EXPORT_MSCPP
char * EXPORT_BORLAND
pt(ICLTerm *t)
{
return icl_NewStringFromTerm(t);
}
/**
* Creates a string representation from an ICL term.
* The string value is created in a new space which should be
* icl_stFree'd when finished using.
* @see icl_stFree
*/
EXPORT_MSCPP
char * EXPORT_BORLAND
icl_NewStringStructFromTerm(ICLTerm *t)
{
int tmpBufSz = 0;
char *res = NULL;
char* tmp = NULL;
/* Make sure the term is OK */
if (!icl_IsValid(t)) {
return NULL;
}
if (icl_IsVar(t)) {
tmpBufSz = snprintf(tmp, 0, "var(%s)", (char*)(t->p));
++tmpBufSz;
tmp = (char*)malloc(tmpBufSz * sizeof(char));
memset(tmp, 0, tmpBufSz);
snprintf(tmp, tmpBufSz, "var(%s)", (char*)(t->p));
res = tmp;
}
else if (icl_IsInt(t)) {
tmpBufSz = snprintf(tmp, 0, "int(%lld)", icl_Int(t));
++tmpBufSz;
tmp = (char*)malloc(tmpBufSz * sizeof(char));
memset(tmp, 0, tmpBufSz);
snprintf(tmp, tmpBufSz, "int(%lld)", icl_Int(t));
res = tmp;
}
else if (icl_IsFloat(t)) {
tmpBufSz = snprintf(tmp, 0, "float(%f)", icl_Float(t));
++tmpBufSz;
tmp = (char*)malloc(tmpBufSz * sizeof(char));
memset(tmp, 0, tmpBufSz);
snprintf(tmp, tmpBufSz, "float(%f)", icl_Float(t));
res = tmp;
}
else if (icl_IsStr(t)) {
tmpBufSz = snprintf(tmp, 0, "str(%s)", icl_stQuote(t->p));
++tmpBufSz;
tmp = (char*)malloc(tmpBufSz * sizeof(char));
memset(tmp, 0, tmpBufSz);
snprintf(tmp, tmpBufSz, "str(%s)", icl_stQuote(t->p));
res = tmp;
}
else if (icl_IsStruct(t)) {
int first = TRUE;
ICLListType *args;
tmpBufSz = snprintf(tmp, 0, "struct(%s,", icl_Functor(t));
++tmpBufSz;
tmp = (char*)malloc(tmpBufSz * sizeof(char));
memset(tmp, 0, tmpBufSz);
snprintf(tmp, tmpBufSz, "struct(%s,", icl_Functor(t));
res = tmp;
args = icl_Arguments(t);
icl_stAppend(&res, "(");
while (args) {
char *arg;
arg = icl_NewStringStructFromTerm(args->elt);
if (first) {
first = FALSE;
}
else {
icl_stAppend(&res, ",");
}
icl_stAppend(&res, arg);
icl_stFree(arg);
args = args->next;
}
icl_stAppend(&res, ")");
}
else if (icl_IsList(t)) {
int first = TRUE;
ICLListType *args;
args = icl_List(t);
res = strdup("list([");
while (args) {
char *arg;
arg = icl_NewStringStructFromTerm(args->elt);
if (first) {
first = FALSE;
}
else {
icl_stAppend(&res, ",");
}
icl_stAppend(&res, arg);
icl_stFree(arg);
args = args->next;
}
icl_stAppend(&res, "])");
}
else if (icl_IsGroup(t)) {
int first = TRUE;
ICLListType *args;
char start;
char *separator;
icl_GetGroupChars(t, &start, &separator);
args = icl_List(t);
res = strdup("group([");
while (args) {
char *arg;
arg = icl_NewStringStructFromTerm(args->elt);
if (first) {
first = FALSE;
}
else {
icl_stAppend(&res, separator);
}
icl_stAppend(&res, arg);
icl_stFree(arg);
args = args->next;
}
icl_stAppend(&res, "])");
if (start == '(') {
res[strlen(res)-1] = start + 1; /* () */
}
else {
res[strlen(res)-1] = start + 2; /* {|} and [\] */
}
icl_stFree(separator);
}
return (res);
}
enum CompoundType {
compound_sentinel_type,
compound_struct_type,
compound_list_type,
compound_group_type
}
;
struct CompoundInfo
{
enum CompoundType cType;
void* p;
int numArgsExpected;
}
;
struct CompoundStructType
{
char* functor;
ICLListType* args;
}
;
struct CompoundListType
{
ICLListType* args;
}
;
struct CompoundGroupType
{
char startC;
char* sep;
ICLListType* args;
}
;
struct CompoundSentinelType
{
ICLTerm* term;
}
;
static void icl_add_compound_argument(struct CompoundInfo* ci, ICLTerm* t)
{
struct CompoundStructType* structCompound;
struct CompoundListType* listCompound;
struct CompoundGroupType* groupCompound;
switch(ci->cType) {
case compound_struct_type:
structCompound = (struct CompoundStructType*)ci->p;
if(!structCompound->args) {
structCompound->args = icl_NewCons(t, NULL);
}
else {
structCompound->args = icl_NewCons(t, structCompound->args);
}
ci->numArgsExpected--;
break;
case compound_list_type:
listCompound = (struct CompoundListType*)ci->p;
if(!listCompound->args) {
listCompound->args = icl_NewCons(t, NULL);
}
else {
listCompound->args = icl_NewCons(t, listCompound->args);
}
ci->numArgsExpected--;
break;
case compound_group_type:
groupCompound = (struct CompoundGroupType*)ci->p;
if(!groupCompound->args) {
groupCompound->args = icl_NewCons(t, NULL);
}
else {
groupCompound->args = icl_NewCons(t, groupCompound->args);
}
ci->numArgsExpected--;
break;
case compound_sentinel_type:
((struct CompoundSentinelType*)ci->p)->term = t;
ci->numArgsExpected--;
break;
default:
fprintf(stderr, "Unknown compound type\n");
break;
}
if(ci->numArgsExpected < 0) {
fprintf(stderr, "numArgsExpected < 0\n");
}
}
/**
* Creates a copy of the term, all in new memory.
* Deref vars from binding list if available. Nonrecursive.
*/
EXPORT_MSCPP
ICLTerm *EXPORT_BORLAND
icl_copy_term_nonrec(ICLTerm* t, struct dyn_array* vars)
{
struct dyn_array termStack;
struct dyn_array compoundStack;
ICLTerm* currTerm = NULL;
struct CompoundInfo* currCompound;
struct CompoundStructType* structCompound;
struct CompoundListType* listCompound;
struct CompoundGroupType* groupCompound;
struct CompoundSentinelType sentinelCompound;
struct CompoundInfo sentinelCI;
if(t == NULL) {
return NULL;
}
icl_init_dyn_array(&termStack);
icl_append_dyn_array(&termStack, t);
icl_init_dyn_array(&compoundStack);
sentinelCI.p = &sentinelCompound;
sentinelCI.cType = compound_sentinel_type;
sentinelCI.numArgsExpected = 1;
icl_append_dyn_array(&compoundStack, &sentinelCI);
if(termStack.count == 0) {
fprintf(stderr, "icl_copy_term_nonrec termStack count is 0!\n");
}
while(termStack.count != 0) {
currTerm = (ICLTerm*)termStack.item[termStack.count - 1];
termStack.item[termStack.count - 1] = NULL;
termStack.count--;
if(vars) {
icl_deref(&currTerm, *vars);
}
if(icl_IsVar(currTerm)) {
currTerm = icl_NewVar(icl_Str(currTerm));
}
else if(icl_IsInt(currTerm)) {
currTerm = icl_NewInt(icl_Int(currTerm));
}
else if(icl_IsFloat(currTerm)) {
currTerm = icl_NewFloat(icl_Float(currTerm));
}
else if(icl_IsStr(currTerm)) {
currTerm = icl_NewStr(icl_Str(currTerm));
}
else if(icl_IsDataQ(currTerm)) {
currTerm = icl_NewDataQ(icl_DataQ(currTerm), icl_Len(currTerm));
}
else if(icl_IsStruct(currTerm)) {
/* Take the arguments of the struct, and put them into
* the termStack, in the current order. Note that this
* means when we recreate the struct, we have to reverse
* the order of the arguments!
*/
struct CompoundInfo* ci = (struct CompoundInfo*)malloc(sizeof(struct CompoundInfo)) ;
struct CompoundStructType* c = (struct CompoundStructType*)malloc(sizeof(struct CompoundStructType));
ICLListType* args = icl_Arguments(currTerm);
ci->p = c;
ci->cType = compound_struct_type;
ci->numArgsExpected = 0;
c->functor = icl_Functor(currTerm);
c->args = NULL;
while(args) {
ci->numArgsExpected++;
icl_append_dyn_array(&termStack, args->elt);
args = args->next;
}
icl_append_dyn_array(&compoundStack, ci);
if(ci->numArgsExpected > 0) {
continue;
}
}
else if(icl_IsList(currTerm)) {
struct CompoundInfo* ci = (struct CompoundInfo*)malloc(sizeof(struct CompoundInfo));
struct CompoundListType* c = (struct CompoundListType*)malloc(sizeof(struct CompoundListType));
ICLListType* args = icl_List(currTerm);
ci->p = c;
ci->cType = compound_list_type;
ci->numArgsExpected = 0;
c->args = NULL;
while(args) {
ci->numArgsExpected++;
icl_append_dyn_array(&termStack, args->elt);
args = args->next;
}
icl_append_dyn_array(&compoundStack, ci);
if(ci->numArgsExpected > 0) {
continue;
}
}
else if(icl_IsGroup(currTerm)) {
struct CompoundInfo* ci = (struct CompoundInfo*)malloc(sizeof(struct CompoundInfo));
struct CompoundGroupType* c = (struct CompoundGroupType*)malloc(sizeof(struct CompoundGroupType));
ICLListType* args = icl_List(currTerm);
ci->p = c;
ci->cType = compound_group_type;
ci->numArgsExpected = 0;
c->args = NULL;
icl_GetGroupChars(currTerm, &(c->startC), &(c->sep));
while(args) {
ci->numArgsExpected++;
icl_append_dyn_array(&termStack, args->elt);
args = args->next;
}
icl_append_dyn_array(&compoundStack, ci);
if(ci->numArgsExpected > 0) {
continue;
}
}
else if(currTerm == NULL) {
currTerm = NULL;
}
else {
char* s = icl_NewStringFromTerm(t);
fprintf(stderr, "Unknown type in icl_copy_term_nonrec: [%s]\n", s);
icl_stFree(s);
currTerm = NULL;
}
/* currTerm == NULL or some term; add it to the current compound
info structure
*/
currCompound = (struct CompoundInfo*)compoundStack.item[compoundStack.count - 1];
if(currCompound->numArgsExpected > 0) {
icl_add_compound_argument(currCompound, currTerm);
}
while(currCompound->numArgsExpected == 0) {
switch(currCompound->cType) {
case compound_struct_type:
structCompound = (struct CompoundStructType*)currCompound->p;
currTerm = icl_NewStructFromList(structCompound->functor, icl_NewList(structCompound->args));
free(structCompound);
free(currCompound);
structCompound = NULL;
currCompound = NULL;
break;
case compound_list_type:
listCompound = (struct CompoundListType*)currCompound->p;
currTerm = icl_NewList(listCompound->args);
free(listCompound);
free(currCompound);
listCompound = NULL;
currCompound = NULL;
break;
case compound_group_type:
groupCompound = (struct CompoundGroupType*)currCompound->p;
currTerm = icl_NewGroup(groupCompound->startC, groupCompound->sep, groupCompound->args);
free(groupCompound);
free(currCompound);
groupCompound = NULL;
currCompound = NULL;
break;
case compound_sentinel_type:
if(compoundStack.count != 1) {
fprintf(stderr, "icl_copy_term_nonrec got sentinel but nonempty compoundStack\n");
}
if(compoundStack.item != NULL) {
free(compoundStack.item);
}
if(termStack.item != NULL) {
free(termStack.item);
}
CHECK_LEAKS();
return ((struct CompoundSentinelType*)(currCompound->p))->term;
break;
default:
fprintf(stderr, "icl_copy_term_nonrec got unknown compound type\n");
if(compoundStack.item != NULL) {
free(compoundStack.item);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?