void initGlobalEnvironment(){ sSTDIN = stdin; sSTDOUT = stdout; sExpression *temp = (sExpression *)malloc(sizeof(sExpression *)); sTrue.type = TRUE_TAG; sTrue.value = temp; sFalse.type = FALSE_TAG; sFalse.value = temp; sNull.type = NULL_TAG; sNull.value = temp; sError.type = ERROR_TAG; sError.value = temp; sTypeSize[NULL_TAG] = sizeof(sExpression); sTypeSize[TRUE_TAG] = sizeof(sExpression); sTypeSize[FALSE_TAG] = sizeof(sExpression); sTypeSize[NUMBER_TAG] = sizeof(sNumber); sTypeSize[SYMBOL_TAG] = sizeof(sSymbol); sTypeSize[LIST_TAG] = sizeof(sList); sTypeSize[LAMBDA_TAG] = sizeof(sLambda); sTypeSize[STRING_TAG] = sizeof(sString); sTypeSize[PROC_TAG] = sizeof(sProc); sTypeSize[ERROR_TAG] = sizeof(sExpression); sTypeSize[EXPRESSION_TAG] = sizeof(sExpression); sTypeSize[SYNTAX_TAG] = sizeof(sSyntax); sTypeSize[THUNK_TAG] = sizeof(sThunk); sGlobalEnvironment = newEnvironment(cons(&sNull, &sNull), cons(&sNull, &sNull)); initPrimitiveProcs(); initPrimitiveVariable(); }
// Extends an environment by a certain number of elements. int extendEnvironment(int32_t env, int32_t by, int32_t* node) { int err; int32_t old_size = memory[env+SLOT_SIZE] - BASE_SIZE_ENVIRONMENT; if((err = newEnvironment(old_size+by, node)) != OK) { return err; } int32_t i; if(memory[env+SLOT_FORWARD] != -1) { env = memory[env+SLOT_FORWARD]; } for(i = memory[env+SLOT_FIRST_CHILD]; i<=memory[env+SLOT_LAST_CHILD]; i++) { memory[*node+i] = memory[env+i]; } return OK; }
void renewEnvironment(char *name, char *opt_param, char *begdef, char *enddef, int params) /************************************************************************** purpose: allocates and initializes a \renewenvironment **************************************************************************/ { int i; i = existsEnvironment(name); if (i<0) { newEnvironment(name, opt_param, begdef, enddef, params); diagnostics(WARNING, "No existing \\newevironment{%s}", name); } else { free(NewEnvironments[i].begdef); free(NewEnvironments[i].enddef); free(NewEnvironments[i].begname); free(NewEnvironments[i].endname); if (NewEnvironments[i].opt_param) free(NewEnvironments[i].opt_param); if (opt_param) { NewEnvironments[i].opt_param=strdup(opt_param); if (NewEnvironments[i].opt_param==NULL) { diagnostics(ERROR, "\nCannot allocate opt_param for \\renewenvironment{%s}", name); } } else { NewEnvironments[i].opt_param=NULL; } NewEnvironments[i].params = params; NewEnvironments[i].begdef = strdup(begdef); NewEnvironments[i].enddef = strdup(enddef); if (NewEnvironments[i].begdef==NULL || NewEnvironments[i].enddef==NULL) { diagnostics(ERROR, "Cannot allocate memory for \\renewenvironment{%s}", name); } } }
END_DESCRIBE DESCRIBE(newPrimFunction, "tap_prim_fun* newPrimFunction (void(*address)(expression*[], int, exprvals*, datatype*), int minargs, int maxargs, typelist* types)") IT("Creates a new primitive tap function") tap_prim_fun* fun = newPrimFunction(prim_iAdd, 1, ARGLEN_INF, newTypelist(TYPE_INT)); SHOULD_EQUAL(fun->address, prim_iAdd) SHOULD_EQUAL(fun->minargs, 1) SHOULD_EQUAL(fun->maxargs, ARGLEN_INF) SHOULD_EQUAL(fun->types->type, TYPE_INT) freePrimFun(fun); END_IT END_DESCRIBE DESCRIBE(newEnvironment, "environment* newEnvironment (hashtable* variables, int parent)") IT("Creates a new environment") environment* env = newEnvironment(newHashtable(100), 0); SHOULD_NOT_EQUAL(env->variables, NULL) insertPrimHash(env->variables, "+", newPrimFunction(&prim_iAdd, 1, ARGLEN_INF, newTypelist(TYPE_INT))); SHOULD_EQUAL(env->types, NULL) freeEnv(env); END_IT END_DESCRIBE DESCRIBE(newStringlist, "newStringlist (string* str, stringlist* next)") IT("Creates a new list of strings") string* str1 = newString(strDup("a")); string* str2 = newString(strDup("b")); string* str3 = newString(strDup("c")); stringlist* sl = newStringlist(str1, newStringlist(str2, newStringlist(str3, NULL))); SHOULD_EQUAL(strcmp(sl->str->content, "a"), 0) SHOULD_EQUAL(strcmp(sl->next->str->content, "b"), 0)
sEnvironment *extendEnvironment(sList *parameterNames, sList *arguments, sEnvironment *parentEnv){ sEnvironment *newEnv = newEnvironment(parameterNames, arguments); newEnv->parent = parentEnv; return newEnv; }