////////////////////////////////////////////////////////////////////////////// // This file is part of Teyjus. // // // // Teyjus is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // (at your option) any later version. // // // // Teyjus is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with Teyjus. If not, see . // ////////////////////////////////////////////////////////////////////////////// /***************************************************************************/ /* ocamlcode.c. */ /* This file defines auxiliary functions in making pervasive.mli and */ /* pervasive.ml. */ /* Since space and time efficiency is not an important concern in the */ /* system source code generation phase, the code here is structured in the */ /* way for the convenience of making changes on pervasive.mli{ml}. */ /***************************************************************************/ #include #include #include #include "ocamlcode.h" /***************************************************************************/ /* Functions for making various language constructs */ /***************************************************************************/ /* Make a string of form . */ static char* OC_mkDotStr(char* first, char* second) { size_t length = strlen(first) + strlen(second) + 1; char* ptr = UTIL_mallocStr(length+1); strcpy(ptr, first); strcat(ptr, "."); strcat(ptr, second); return ptr; } /* (Some ) */ char* OC_mkSome(char* info) { size_t length = strlen(info) + 10; char* rtptr = UTIL_mallocStr(length + 1); strcpy(rtptr, "(Some "); strcat(rtptr, info); strcat(rtptr, ")"); return rtptr; } /* (ref ) */ char* OC_mkRef(char* info) { size_t length = strlen(info) + 10; char* rtptr = UTIL_mallocStr(length + 1); strcpy(rtptr, "(ref "); strcat(rtptr, info); strcat(rtptr, ")"); return rtptr; } /* Make a variable definition: let = */ static char* OC_mkVarDef(char* varName, char* defs) { size_t length = strlen(varName) + strlen(defs) + 10; char* vardef = UTIL_mallocStr(length + 1); strcpy(vardef, "let "); strcat(vardef, varName); strcat(vardef, " = "); strcat(vardef, defs); return vardef; } /* Make a variable declaration: val : "\n" */ static char* OC_mkVarDec(char* varName, char* varType) { size_t length = strlen(varName) + strlen(varType) + 10; char* vardec = UTIL_mallocStr(length + 1); strcpy(vardec, "val "); strcat(vardec, varName); strcat(vardec, " : "); strcat(vardec, varType); strcat(vardec, "\n"); return vardec; } /* Make arrow type: -> */ static char* OC_mkArrowType(char* ty1, char* ty2) { size_t length = strlen(ty1) + strlen(ty2) + 5; char* arrowType = UTIL_mallocStr(length); strcpy(arrowType, ty1); strcat(arrowType, " -> "); strcat(arrowType, ty2); return arrowType; } /**************************************************************************/ /* Names from other modules */ /**************************************************************************/ /********************************************************/ /* Fixities */ /********************************************************/ #define INFIX "Absyn.Infix" #define INFIXL "Absyn.Infixl" #define INFIXR "Absyn.Infixr" #define PREFIX "Absyn.Prefix" #define PREFIXR "Absyn.Prefixr" #define POSTFIX "Absyn.Postfix" #define POSTFIXL "Absyn.Postfixl" #define NOFIXITY "Absyn.NoFixity" #define MAXPREC "maxPrec + 1" /********************************************************/ /* module names */ /********************************************************/ #define ABSYN "Absyn" #define SYMBOL "Symbol" #define ERRORMSG "Errormsg" #define TABLE "Table" /********************************************************/ /* types */ /********************************************************/ //absyn #define TY_KIND "akind" #define TY_CONST "aconstant" #define TY_TERM "aterm" #define TY_TYABBREV "atypeabbrev" //table #define TY_SYMTAB "SymbolTable.t" /********************************************************/ /* value constructors */ /********************************************************/ //absyn #define VCTR_KIND "Kind" #define VCTR_KINDTYPE "PervasiveKind" #define VCTR_CONSTANT "Constant" #define VCTR_PERVCONST "PervasiveConstant" #define VCTR_TYSKEL "Skeleton" #define VCTR_APPTYPE "ApplicationType" #define VCTR_ARROWTYPE "ArrowType" #define VCTR_SKELVARTYPE "SkeletonVarType" #define VCTR_BUILTIN "Builtin" //errormsg #define VCTR_NULLPOS "none" //symbol #define VCTR_SYMBOL "symbol" #define VCTR_SYMBOL_ALIAS "symbolAlias" //table #define VCTR_EMPTYTAB "SymbolTable.empty" /********************************************************/ /* functions */ /********************************************************/ //table #define FUNC_ADD "add" //absyn #define FUNC_MAKETYSETVAR "makeTypeSetVariable" /***************************************************************************/ /* Local names */ /***************************************************************************/ #define BUILDPERVKIND "buildPervasiveKinds" #define BUILDPERVCONST "buildPervasiveConstants" #define PERVKIND "pervasiveKinds" #define PERVCONST "pervasiveConstants" #define PERVTYABBR "pervasiveTypeAbbrevs" #define KVAR_PREFIX "k" #define CVAR_POSTFIX "Constant" #define TSKVAR_PREFIX "tyskel" #define TAB "t" #define IS "is" #define SETVARIR "tysetvarIR" #define SETVARIRS "tysetvarIRS" #define OVERLOADTYSKEL1 "overloadTySkel1" #define OVERLOADTYSKEL2 "overloadTySkel2" #define OVERLOADTYSKEL3 "overloadTySkel3" /***************************************************************************/ /* Functions for making program components */ /***************************************************************************/ /* (Symbol.symbol "") */ static char* OC_mkSymbol(char* name) { char* symbolCtr = OC_mkDotStr(SYMBOL, VCTR_SYMBOL); size_t length = strlen(symbolCtr) + strlen(name) + 10; char* rtptr= UTIL_mallocStr(length + 1); strcpy(rtptr, "("); strcat(rtptr, symbolCtr); free(symbolCtr); strcat(rtptr, " \""); strcat(rtptr, name); strcat(rtptr, "\")"); return rtptr; } /* (Symbol.symbolAlias "" "") */ static char* OC_mkSymbolAlias(char *name, char *printName) { char* symbolCtr = OC_mkDotStr(SYMBOL, VCTR_SYMBOL_ALIAS); size_t length = strlen(symbolCtr) + strlen(name) + strlen(printName) + 10; char* rtptr= UTIL_mallocStr(length + 1); strcpy(rtptr, "("); strcat(rtptr, symbolCtr); free(symbolCtr); strcat(rtptr, " \""); strcat(rtptr, name); strcat(rtptr, "\" \""); strcat(rtptr, printName); strcat(rtptr, "\")"); return rtptr; } /* let t = Table.add (Symbol.symbol "") t in\n */ char* OC_mkTabEntry(char* name, char* varName) { char* entry; char* tableAdd = OC_mkDotStr(TABLE, FUNC_ADD); char* symbol = OC_mkSymbol(name); size_t length = strlen(tableAdd) + strlen(symbol) + strlen(varName) + strlen(TAB) + 15; char* def = UTIL_mallocStr(length + 1); strcpy(def, tableAdd); free(tableAdd); strcat(def, " "); strcat(def, symbol); free(symbol); strcat(def, " "); strcat(def, varName); strcat(def, " "); strcat(def, TAB); strcat(def, " in\n "); entry = OC_mkVarDef(TAB, def); free(def); return entry; } /* let t = Table.SymbolTable.empty in \n*/ static char* OC_mkTabInit() { char* init; char* emptyTab = OC_mkDotStr(TABLE, VCTR_EMPTYTAB); size_t length = strlen(emptyTab) + 10; char* def = UTIL_mallocStr(length + 1); strcpy(def, emptyTab); free(emptyTab); strcat(def, " in\n "); init = OC_mkVarDef(TAB, def); free(def); return init; } /* let = function () ->\n let t = Table.SymbolTable.empty in t\n\n */ static char* OC_mkBuildTabFunc(char* funcName, char* entries) { char* func; char* inits = OC_mkTabInit(); size_t length = strlen(entries) + strlen(TAB) + strlen(inits) + 30; char* def = UTIL_mallocStr(length + 1); strcpy(def, "function () ->\n "); strcat(def, inits); free(inits); strcat(def, entries); strcat(def, TAB); strcat(def, "\n\n"); func = OC_mkVarDef(funcName, def); free(def); return func; } /* let = ()\n\n */ static char* OC_mkTab(char* tabName, char* buildFuncName) { char* tab; size_t length = strlen(buildFuncName) + 10; char* def = UTIL_mallocStr(length + 1); strcpy(def, buildFuncName); strcat(def, " ()\n\n"); tab = OC_mkVarDef(tabName, def); free(def); return tab; } /* val = Absyn. Table.SymbolTable.t\n */ static char* OC_mkTabDec(char* tabName, char* typeName) { char* dec; char* symbolTab = OC_mkDotStr(TABLE, TY_SYMTAB); char* myType = OC_mkDotStr(ABSYN, typeName); size_t length = strlen(symbolTab) + strlen(myType) + 5; char* typedec = UTIL_mallocStr(length + 1); strcpy(typedec, myType); free(myType); strcat(typedec, " "); strcat(typedec, symbolTab); free(symbolTab); strcat(typedec, "\n"); dec = OC_mkVarDec(tabName, typedec); free(typedec); return dec; } /****************************************************************************/ /* functions for making pervasive kind relevant components */ /****************************************************************************/ /* k */ char* OC_mkKVarName(char* name) { return UTIL_appendStr(KVAR_PREFIX, name); } /* is */ char* OC_mkIsKindFuncName(char* name) { return UTIL_appendStr(IS, name); } /* val : Absyn.akind \n*/ char* OC_mkKindVarDec(char* kindVarName) { char* kindType = OC_mkDotStr(ABSYN, TY_KIND); char* dec = OC_mkVarDec(kindVarName, kindType); free(kindType); return dec; } /* val : Absyn.akind -> bool */ char* OC_mkIsKindFuncDec(char* funcName) { char* kindType = OC_mkDotStr(ABSYN, TY_KIND); char* arrowType = OC_mkArrowType(kindType, "bool"); char* dec = OC_mkVarDec(funcName, arrowType); free(kindType); free(arrowType); return dec; } /* let tm = tm == */ char* OC_mkIsKindFuncDef(char* funcName, char* kindVarName) { char* funchead = UTIL_mallocStr(strlen(funcName) + 3); char* defbody = UTIL_mallocStr(strlen(kindVarName) + 10); char* def; strcpy(funchead, funcName); strcat(funchead, " tm"); strcpy(defbody, "(tm == "); strcat(defbody, kindVarName); strcat(defbody, ")"); def = OC_mkVarDef(funchead, defbody); free(funchead); free(defbody); return def; } /*Kind variable definition: let = Absyn.PervasiveKind(Symbol.symbol "", (Some ), ref offset, Errormsg.none) */ char* OC_mkKindVar(char* varName, char* kindName, char* arity, char* offset) { char* kindvar; char* ctr = OC_mkDotStr(ABSYN, VCTR_KIND); char* symbol = OC_mkSymbol(kindName); char* nargs = OC_mkSome(arity); char* index = OC_mkRef(offset); char* ktype = OC_mkDotStr(ABSYN, VCTR_KINDTYPE); char* pos = OC_mkDotStr(ERRORMSG, VCTR_NULLPOS); size_t length = strlen(ctr) + strlen(symbol) + strlen(nargs) + strlen(index) + strlen(ktype) + strlen(pos) + 10; char* def = UTIL_mallocStr(length + 1); strcpy(def, ctr); free(ctr); strcat(def, "("); strcat(def, symbol); free(symbol); strcat(def, ", "); strcat(def, nargs); free(nargs); strcat(def, ", "); strcat(def, index); free(index); strcat(def, ", "); strcat(def, ktype); free(ktype); strcat(def, ", "); strcat(def, pos); free(pos); strcat(def, ")"); kindvar = OC_mkVarDef(varName, def); free(def); return kindvar; } /* let buildPervasiveKinds = function () ->\n \n \n\n */ char* OC_mkBuildKTabFunc(char* entries) { return OC_mkBuildTabFunc(BUILDPERVKIND, entries); } /****************************************************************************/ /* functions for making pervasive type skeleton components */ /****************************************************************************/ /* Absyn.SkeletonVarType(ref ) */ static char* genTySkelVar(char* ind) { char* ctr = OC_mkDotStr(ABSYN, VCTR_SKELVARTYPE); char* ref = OC_mkRef(ind); size_t length = strlen(ctr) + strlen(ref) + 5; char* skelVar = UTIL_mallocStr(length + 1); strcpy(skelVar, ctr); free(ctr); strcat(skelVar, "("); strcat(skelVar, ref); free(ref); strcat(skelVar, ")"); return skelVar; } /* Absyn.ArrowType(, ) */ static char* genTySkelArrow(char* type1, char* type2) { char* ctr = OC_mkDotStr(ABSYN, VCTR_ARROWTYPE); size_t length = strlen(ctr) + strlen(type1) + strlen(type2) + 5; char* arrowtype = UTIL_mallocStr(length + 1); strcpy(arrowtype, ctr); free(ctr); strcat(arrowtype, "("); strcat(arrowtype, type1); strcat(arrowtype, ", "); strcat(arrowtype, type2); strcat(arrowtype, ")"); return arrowtype; } /* Absyn.AppType(k, ) */ static char* genTySkelApp(char* sortName, char* args) { char* ctr = OC_mkDotStr(ABSYN, VCTR_APPTYPE); char* sortVar = OC_mkKVarName(sortName); size_t length = strlen(ctr) + strlen(sortVar) + strlen(args) + 5; char* apptype = UTIL_mallocStr(length + 1); strcpy(apptype, ctr); free(ctr); strcat(apptype, "("); strcat(apptype, sortVar); free(sortVar); strcat(apptype, ", "); strcat(apptype, args); strcat(apptype, ")"); return apptype; } /* Absyn.AppType(k, []) */ static char* genTySkelSort(char* sortName) { return genTySkelApp(sortName, "[]"); } //forward declaration char* OC_genTySkel(Type args); static char* OC_genTySkelArgs(TypeList args) { size_t length; char* mytext1 = NULL; char* mytext = NULL; char* oneTypeText = NULL; Type oneType = args -> oneType; args = args -> next; mytext1 = OC_genTySkel(oneType); while (args) { oneType = args -> oneType; args = args -> next; oneTypeText = OC_genTySkel(oneType); length = strlen(mytext1) + strlen(oneTypeText) + 5; mytext = UTIL_mallocStr(length + 1); strcpy(mytext, mytext1); free(mytext1); strcat(mytext, " :: "); strcat(mytext, oneTypeText); free(oneTypeText); mytext1 = mytext; } length = strlen(mytext1) + 10; mytext = UTIL_mallocStr(length + 1); strcpy(mytext, "("); strcat(mytext, mytext1); free(mytext1); strcat(mytext, " :: [])"); return mytext; } char* OC_genTySkel(Type tyskel) { char* mytext1; char* mytext2; char* mytext3; switch(tyskel -> tag) { case SORT: { mytext1 = genTySkelSort(tyskel -> data.sort); return mytext1; } case SKVAR: { mytext1 = genTySkelVar(tyskel -> data.skvar); return mytext1; } case STR: { mytext1 = OC_genTySkelArgs(tyskel -> data.str.args); mytext2 = genTySkelApp((tyskel -> data.str.functor)->data.func.name, mytext1); free(mytext1); return mytext2; } case ARROW: { mytext1 = OC_genTySkel(tyskel -> data.arrow.lop); mytext2 = OC_genTySkel(tyskel -> data.arrow.rop); mytext3 = genTySkelArrow(mytext1, mytext2); free(mytext1); free(mytext2); return mytext3; } default: return strdup(""); } } /* tyskel */ char* OC_mkTySkelVarName(char* number) { return UTIL_appendStr(TSKVAR_PREFIX, number); } /* Type Skeleton variable definition: let = Some(Absyn.Skeleton(, ref None, ref false)) */ char* OC_mkTYSkelVar(char* varName, char* tySkel) { char* tyskelvar; char* ctr = OC_mkDotStr(ABSYN, VCTR_TYSKEL); char* index = OC_mkRef("None"); char* adjust = OC_mkRef("false"); size_t length = strlen(ctr) + strlen(index) + strlen(adjust) + strlen(tySkel) + 15; char* def = UTIL_mallocStr(length + 1); char* somedef; strcpy(def, "("); strcat(def, ctr); free(ctr); strcat(def, "("); strcat(def, tySkel); strcat(def, ", "); strcat(def, index); free(index); strcat(def, ", "); strcat(def, adjust); free(adjust); strcat(def, "))"); somedef = OC_mkSome(def); free(def); tyskelvar = OC_mkVarDef(varName, somedef); free(somedef); return tyskelvar; } static char* OC_mkTypeSetVar(char* defaultty, char* arglist, char* tyName) { char* setVar; char* func = OC_mkDotStr(ABSYN, FUNC_MAKETYSETVAR); char* def = UTIL_mallocStr(strlen(func) + strlen(arglist) + strlen(defaultty) + 2); strcpy(def, func); free(func); strcat(def, " "); strcat(def, defaultty); strcat(def, " "); strcat(def, arglist); setVar = OC_mkVarDef(tyName, def); free(def); return setVar; } /*********************************************/ /* generate tyskels for overloaded constants */ /*********************************************/ static char* OC_mkTySkelRef(char* tySkel) { char* ctr = OC_mkDotStr(ABSYN, VCTR_TYSKEL); char* index = OC_mkRef("None"); char* adjust = OC_mkRef("false"); size_t length = strlen(ctr) + strlen(index) + strlen(adjust) + strlen(tySkel) + 15; char* def = UTIL_mallocStr(length + 1); char* somedef; char* ref; strcpy(def, "("); strcat(def, ctr); free(ctr); strcat(def, "("); strcat(def, tySkel); strcat(def, ", "); strcat(def, index); free(index); strcat(def, ", "); strcat(def, adjust); free(adjust); strcat(def, "))"); somedef = OC_mkSome(def); free(def); ref = OC_mkRef(somedef); free(somedef); return ref; } char* OC_mkFixedTySkels(char* tySkels) { char *text; char* setvarIntReal = OC_mkTypeSetVar("(Absyn.ApplicationType(kint,[]))", "(Absyn.ApplicationType(kint,[]) :: Absyn.ApplicationType(kreal,[]) :: [])", SETVARIR); char* setvarIntRealStr = OC_mkTypeSetVar("(Absyn.ApplicationType(kint,[]))", "(Absyn.ApplicationType(kint,[]) :: Absyn.ApplicationType(kreal,[]) :: Absyn.ApplicationType(kstring, []) :: [])", SETVARIRS); char *tyskelBody, *tyskelBody2; char *tyskel, *tyskelText; text = UTIL_appendStr(tySkels, setvarIntReal); free(setvarIntReal); tySkels = UTIL_appendStr(text, "\n"); free(text); tyskelBody = genTySkelArrow(SETVARIR, SETVARIR); tyskelText = OC_mkTySkelRef(tyskelBody); tyskel = OC_mkVarDef(OVERLOADTYSKEL1, tyskelText); free(tyskelText); text = UTIL_appendStr(tySkels, tyskel); free(tyskel); tySkels = UTIL_appendStr(text, "\n"); free(text); tyskelBody2 = genTySkelArrow(SETVARIR, tyskelBody); free(tyskelBody); tyskelText = OC_mkTySkelRef(tyskelBody2); free(tyskelBody2); tyskel = OC_mkVarDef(OVERLOADTYSKEL2, tyskelText); free(tyskelText); text = UTIL_appendStr(tySkels, tyskel); free(tyskel); tySkels = UTIL_appendStr(text, "\n\n"); free(text); text = UTIL_appendStr(tySkels, setvarIntRealStr); free(setvarIntRealStr); tySkels = UTIL_appendStr(text, "\n"); free(text); tyskelBody = genTySkelArrow(SETVARIRS, "Absyn.ApplicationType(kbool, [])"); tyskelBody2 = genTySkelArrow(SETVARIRS, tyskelBody); free(tyskelBody); tyskelText = OC_mkTySkelRef(tyskelBody2); free(tyskelBody2); tyskel = OC_mkVarDef(OVERLOADTYSKEL3, tyskelText); free(tyskelText); text = UTIL_appendStr(tySkels, tyskel); free(tyskel); tySkels = UTIL_appendStr(text, "\n\n"); free(text); return tySkels; } /****************************************************************************/ /* functions for making pervasive constants components */ /****************************************************************************/ /* Constant */ char* OC_mkCVarName(char* name) { return UTIL_appendStr(name, CVAR_POSTFIX); } /* isConstant */ char* OC_mkIsConstFuncName(char* name) { return UTIL_appendStr(IS, name); } /* val : Absyn.aconstant \n*/ char* OC_mkConstVarDec(char* constVarName) { char* constType = OC_mkDotStr(ABSYN, TY_CONST); char* dec = OC_mkVarDec(constVarName, constType); free(constType); return dec; } /* val : Absyn.aconstant -> bool */ char* OC_mkIsConstFuncDec(char* funcName) { char* constType = OC_mkDotStr(ABSYN, TY_CONST); char* arrowType = OC_mkArrowType(constType, "bool"); char* dec = OC_mkVarDec(funcName, arrowType); free(constType); free(arrowType); return dec; } /* let tm = tm == */ char* OC_mkIsConstFuncDef(char* funcName, char* constVarName) { char* funchead = UTIL_mallocStr(strlen(funcName) + 3); char* defbody = UTIL_mallocStr(strlen(constVarName) + 10); char* def; strcpy(funchead, funcName); strcat(funchead, " tm"); strcpy(defbody, "(tm == "); strcat(defbody, constVarName); strcat(defbody, ")"); def = OC_mkVarDef(funchead, defbody); free(funchead); free(defbody); return def; } /* (ref fixity) */ static char* OC_mkFixity(OP_Fixity fixity) { switch (fixity){ case OP_INFIX : return OC_mkRef(strdup(INFIX)); case OP_INFIXL : return OC_mkRef(strdup(INFIXL)); case OP_INFIXR : return OC_mkRef(strdup(INFIXR)); case OP_PREFIX : return OC_mkRef(strdup(PREFIX)); case OP_PREFIXR : return OC_mkRef(strdup(PREFIXR)); case OP_POSTFIX : return OC_mkRef(strdup(POSTFIX)); case OP_POSTFIXL : return OC_mkRef(strdup(POSTFIXL)); case OP_NONE : return OC_mkRef(strdup(NOFIXITY)); default : return OC_mkRef(strdup(NOFIXITY)); } } /* (ref prec) */ static char* OC_mkPrec(OP_Prec prec) { char* precNum; char* precText; if (OP_precIsMax(prec)) { char* temp = OC_mkDotStr(ABSYN, MAXPREC); precNum = UTIL_mallocStr(strlen(temp) + 2); strcpy(precNum, "("); strcat(precNum, temp); strcat(precNum, ")"); } else precNum = UTIL_itoa(prec.data.prec); precText = OC_mkRef(precNum); free(precNum); return precText; } /* (ref true/false ) */ static char* OC_mkRefBool(UTIL_Bool value) { if (value) return OC_mkRef("true"); else return OC_mkRef("false"); } static char* OC_mkRefInt(int value) { char* valueText = UTIL_itoa(value); char* text = OC_mkRef(valueText); free(valueText); return text; } static char* OC_mkCodeInfo(OP_Code codeInfo) { char* code; char* ref; if (OP_codeInfoIsNone(codeInfo)) { code = strdup("None"); } else { char* codeInd = UTIL_itoa(codeInfo); char* ctr = OC_mkDotStr(ABSYN, VCTR_BUILTIN); char* codeText = UTIL_mallocStr(strlen(codeInd) + strlen(ctr) + 10); strcpy(codeText, "("); strcat(codeText, ctr); free(ctr); strcat(codeText, "("); strcat(codeText, codeInd); free(codeInd); strcat(codeText, "))"); code = OC_mkSome(codeText); free(codeText); } ref = OC_mkRef(code); free(code); return ref; } static char* OC_mkConstCat(UTIL_Bool redef) { char* ctr = OC_mkDotStr(ABSYN,VCTR_PERVCONST); char* boolValue; char* cat; char* ref; if (redef) boolValue = strdup("true"); else boolValue = strdup("false"); cat = UTIL_mallocStr(strlen(ctr) + strlen(boolValue) + 10); strcpy(cat, "("); strcat(cat, ctr); free(ctr); strcat(cat, "("); strcat(cat, boolValue); free(boolValue); strcat(cat, "))"); ref = OC_mkRef(cat); free(cat); return ref; } static char* OC_mkSkelNeededness(int tyenvsize) { char* length = UTIL_itoa(tyenvsize); char* some; char* ref; char* init = UTIL_mallocStr(strlen(length) + 20); strcpy(init, "(Array.make "); strcat(init, length); free(length); strcat(init, " true)"); some = OC_mkSome(init); free(init); ref = OC_mkRef(some); free(some); return ref; } static char* OC_mkNeededness(int neededness, int tyenvsize) { char* length = UTIL_itoa(tyenvsize); char* init; char* some; char* ref; if (neededness == tyenvsize) { init = UTIL_mallocStr(strlen(length) + 20); strcpy(init, "(Array.make "); strcat(init, length); free(length); strcat(init, " true)"); } else { char* num = UTIL_itoa(neededness); init = UTIL_mallocStr(strlen(length) + strlen(num) + 60); strcpy(init, "(Array.init "); strcat(init, length); free(length); strcat(init, " (fun x -> if x >= "); strcat(init, num); free(num); strcat(init, " then false else true))"); } some = OC_mkSome(init); free(init); ref = OC_mkRef(some); free(some); return ref; } static char* OC_mkConstVarText(char* constName, char* fixity, char* prec, char* typrev, char* tyskel, char* tyenvsize, char* skelneededness, char* neededness, char* codeinfo, char* constcat, char* varname, char* offset, char* printName) { char* constVar; char* ctr = OC_mkDotStr(ABSYN, VCTR_CONSTANT); char* symbol = OC_mkSymbolAlias(constName, printName); char* refFalse = OC_mkRef("false"); char* refTrue = OC_mkRef("true"); char* index = OC_mkRef(offset); char* pos = OC_mkDotStr(ERRORMSG, VCTR_NULLPOS); size_t length = strlen(ctr) + strlen(symbol) + strlen(fixity) + strlen(prec) + strlen(typrev) + strlen(tyskel) + strlen(tyenvsize) + strlen(skelneededness) + strlen(neededness) + strlen(codeinfo) + strlen(constcat) + strlen(index) + strlen(pos) + strlen(refFalse) * 6 + 35; char* def = UTIL_mallocStr(length); strcpy(def, ctr); free(ctr); strcat(def, "("); strcat(def, symbol); free(symbol); strcat(def, ", "); strcat(def, fixity); strcat(def, ", "); strcat(def, prec); strcat(def, ", "); strcat(def, refFalse); strcat(def, ", "); strcat(def, refFalse); strcat(def, ", "); strcat(def, refTrue); free(refTrue); /* no defs */ strcat(def, ", "); strcat(def, refFalse); strcat(def, ", "); strcat(def, typrev); strcat(def, ", "); strcat(def, refFalse); free(refFalse); strcat(def, ", "); strcat(def, tyskel); strcat(def, ", "); strcat(def, tyenvsize); strcat(def, ", "); strcat(def, skelneededness); strcat(def, ", "); strcat(def, neededness); strcat(def, ", "); strcat(def, codeinfo); strcat(def, ", "); strcat(def, constcat); strcat(def, ", "); strcat(def, index); free(index); strcat(def, ", "); strcat(def, pos); free(pos); strcat(def, ")"); constVar = OC_mkVarDef(varname, def); free(def); return constVar; } /* Constant variable definition : let = Absyn.Constant(Symbol.symbolAlias "" "", ref , ref , ref false, ref false, ref false, ref false, ref false, ref , ref false, ref , ref , ref (Some ), ref (Some ), ref , ref , ref 0, Errormsg.none) */ char* OC_mkConstVar(char* constName, OP_Fixity fixity, OP_Prec prec, UTIL_Bool typrev, char* tySkel, int tyenvsize, int neededness, OP_Code codeInfo, UTIL_Bool reDef, char* varName, char* offset, char* printName) { char* constVar; char* fixityText = OC_mkFixity(fixity); char* precText = OC_mkPrec(prec); char* typrevText = OC_mkRefBool(typrev); char* tySkelText = OC_mkRef(tySkel); char* tyenvsizeText = OC_mkRefInt(tyenvsize); char* skelneedednessText = OC_mkSkelNeededness(tyenvsize); char* needednessText = OC_mkNeededness(neededness, tyenvsize); char* codeInfoText = OC_mkCodeInfo(codeInfo); char* constCatText = OC_mkConstCat(reDef); constVar = OC_mkConstVarText(constName, fixityText, precText, typrevText, tySkelText, tyenvsizeText, skelneedednessText, needednessText, codeInfoText, constCatText, varName, offset, printName); free(fixityText); free(precText); free(typrevText); free(tySkelText); free(tyenvsizeText); free(skelneedednessText); free(needednessText); free(codeInfoText); free(constCatText); return constVar; } #define GENERICAPPLY "genericApplyConstant" #define OVERLOADUMINUS "overloadUMinusConstant" #define OVERLOADABS "overloadAbsConstant" #define OVERLOADPLUS "overloadPlusConstant" #define OVERLOADMINUS "overloadMinusConstant" #define OVERLOADTIME "overloadTimeConstant" #define OVERLOADLT "overloadLTConstant" #define OVERLOADGT "overloadGTConstant" #define OVERLOADLE "overloadLEConstant" #define OVERLOADGE "overloadGEConstant" static char* OC_mkOverLoadConstVar(char* name, char* fixity, char* prec, char* tyskel, char* varName) { char* constVar; constVar = OC_mkConstVarText(name, fixity, prec, "ref true", tyskel, "ref 0", "ref(Some(Array.make 0 true))", "ref None", "ref None", "ref(Absyn.PervasiveConstant(false))", varName, "0", name); return constVar; } /* generate fixed constants */ char* OC_mkGenericConstVar(char* varList) { char* text; char* constVar; constVar = OC_mkConstVarText(" apply", "ref Absyn.Infixl", "ref (Absyn.maxPrec + 2)", "ref false", "ref(Some(Absyn.Skeleton(Absyn.ErrorType, ref None, ref false)))", "ref 0", "ref(Some(Array.make 0 true))", "ref None", "ref None", "ref(Absyn.PervasiveConstant(false))", GENERICAPPLY, "0", " apply"); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); constVar = OC_mkOverLoadConstVar("~", "ref Absyn.Prefix", "ref (Absyn.maxPrec + 1)", OVERLOADTYSKEL1, OVERLOADUMINUS); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); constVar = OC_mkConstVarText("abs", "ref Absyn.NoFixity", "ref 0", "ref true", OVERLOADTYSKEL1, "ref 0", "ref(Some(Array.make 0 true))", "ref None", "ref None", "ref(Absyn.PervasiveConstant(true))", OVERLOADABS, "0", "abs"); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); constVar = OC_mkOverLoadConstVar("+", "ref Absyn.Infixl", "ref 150", OVERLOADTYSKEL2, OVERLOADPLUS); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); constVar = OC_mkOverLoadConstVar("-", "ref Absyn.Infixl", "ref 150", OVERLOADTYSKEL2, OVERLOADMINUS); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); constVar = OC_mkOverLoadConstVar("*", "ref Absyn.Infixl", "ref 160", OVERLOADTYSKEL2, OVERLOADTIME); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); constVar = OC_mkOverLoadConstVar("<", "ref Absyn.Infix", "ref 130", OVERLOADTYSKEL3, OVERLOADLT); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); constVar = OC_mkOverLoadConstVar(">", "ref Absyn.Infix", "ref 130", OVERLOADTYSKEL3, OVERLOADGT); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); constVar = OC_mkOverLoadConstVar("<", "ref Absyn.Infix", "ref 130", OVERLOADTYSKEL3, OVERLOADLE); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); constVar = OC_mkOverLoadConstVar(">=", "ref Absyn.Infix", "ref 130", OVERLOADTYSKEL3, OVERLOADGE); text = UTIL_appendStr(varList, constVar); free(constVar); varList = UTIL_appendStr(text, "\n\n"); free(text); return varList; } /* generate fixed constants decs */ char* OC_mkGenericConstVarDec(char* decList) { char* text; char* dec; dec = OC_mkConstVarDec(GENERICAPPLY); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; dec = OC_mkConstVarDec(OVERLOADUMINUS); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; dec = OC_mkConstVarDec(OVERLOADABS); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; dec = OC_mkConstVarDec(OVERLOADPLUS); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; dec = OC_mkConstVarDec(OVERLOADMINUS); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; dec = OC_mkConstVarDec(OVERLOADTIME); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; dec = OC_mkConstVarDec(OVERLOADLT); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; dec = OC_mkConstVarDec(OVERLOADGT); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; dec = OC_mkConstVarDec(OVERLOADLE); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; dec = OC_mkConstVarDec(OVERLOADGE); text = UTIL_appendStr(decList, dec); free(decList); free(dec); decList = text; return decList; } /* generate fixed constants entry in buildConstant function */ char* OC_mkGenericConstTabEntry(char* entries) { char* text; char* tabEntry; tabEntry = OC_mkTabEntry("~", OVERLOADUMINUS); text = UTIL_appendStr(entries, tabEntry); free(tabEntry); free(entries); entries = text; tabEntry = OC_mkTabEntry("abs", OVERLOADABS); text = UTIL_appendStr(entries, tabEntry); free(tabEntry); free(entries); entries = text; tabEntry = OC_mkTabEntry("+", OVERLOADPLUS); text = UTIL_appendStr(entries, tabEntry); free(tabEntry); free(entries); entries = text; tabEntry = OC_mkTabEntry("-", OVERLOADMINUS); text = UTIL_appendStr(entries, tabEntry); free(tabEntry); free(entries); entries = text; tabEntry = OC_mkTabEntry("*", OVERLOADTIME); text = UTIL_appendStr(entries, tabEntry); free(tabEntry); free(entries); entries = text; tabEntry = OC_mkTabEntry("<", OVERLOADLT); text = UTIL_appendStr(entries, tabEntry); free(tabEntry); free(entries); entries = text; tabEntry = OC_mkTabEntry(">", OVERLOADGT); text = UTIL_appendStr(entries, tabEntry); free(tabEntry); free(entries); entries = text; tabEntry = OC_mkTabEntry("<=", OVERLOADLE); text = UTIL_appendStr(entries, tabEntry); free(tabEntry); free(entries); entries = text; tabEntry = OC_mkTabEntry(">=", OVERLOADGE); text = UTIL_appendStr(entries, tabEntry); free(tabEntry); free(entries); entries = text; return entries; } /* let buildPervasiveKinds = function () ->\n \n \n\n */ char* OC_mkBuildCTabFunc(char* entries) { return OC_mkBuildTabFunc(BUILDPERVCONST, entries); } /* make generaic const is function decs */ char* OC_mkGenericConstFuncDecs(char* funcDefs) { char* funcName; char* def; char* text; funcName = OC_mkIsConstFuncName(GENERICAPPLY); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; funcName = OC_mkIsConstFuncName(OVERLOADUMINUS); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; funcName = OC_mkIsConstFuncName(OVERLOADABS); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; funcName = OC_mkIsConstFuncName(OVERLOADPLUS); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; funcName = OC_mkIsConstFuncName(OVERLOADMINUS); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; funcName = OC_mkIsConstFuncName(OVERLOADTIME); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; funcName = OC_mkIsConstFuncName(OVERLOADLT); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; funcName = OC_mkIsConstFuncName(OVERLOADGT); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; funcName = OC_mkIsConstFuncName(OVERLOADLE); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; funcName = OC_mkIsConstFuncName(OVERLOADGE); def = OC_mkIsConstFuncDec(funcName); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = text; return funcDefs; } /* make generaic const is function defs */ char* OC_mkGenericConstFuncDefs(char* funcDefs) { char* funcName; char* def; char* text; funcName = OC_mkIsConstFuncName(GENERICAPPLY); def = OC_mkIsConstFuncDef(funcName, GENERICAPPLY); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); funcName = OC_mkIsConstFuncName(OVERLOADUMINUS); def = OC_mkIsConstFuncDef(funcName, OVERLOADUMINUS); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); funcName = OC_mkIsConstFuncName(OVERLOADABS); def = OC_mkIsConstFuncDef(funcName, OVERLOADABS); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); funcName = OC_mkIsConstFuncName(OVERLOADPLUS); def = OC_mkIsConstFuncDef(funcName, OVERLOADPLUS); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); funcName = OC_mkIsConstFuncName(OVERLOADMINUS); def = OC_mkIsConstFuncDef(funcName, OVERLOADMINUS); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); funcName = OC_mkIsConstFuncName(OVERLOADTIME); def = OC_mkIsConstFuncDef(funcName, OVERLOADTIME); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); funcName = OC_mkIsConstFuncName(OVERLOADLT); def = OC_mkIsConstFuncDef(funcName, OVERLOADLT); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); funcName = OC_mkIsConstFuncName(OVERLOADGT); def = OC_mkIsConstFuncDef(funcName, OVERLOADGT); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); funcName = OC_mkIsConstFuncName(OVERLOADLE); def = OC_mkIsConstFuncDef(funcName, OVERLOADLE); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); funcName = OC_mkIsConstFuncName(OVERLOADGE); def = OC_mkIsConstFuncDef(funcName, OVERLOADGE); free(funcName); text = UTIL_appendStr(funcDefs, def); free(def); free(funcDefs); funcDefs = UTIL_appendStr(text, "\n\n"); free(text); return funcDefs; } char* OC_mkCompare(char* name) { char* text = UTIL_mallocStr(strlen(name) + 15); strcpy(text, "(const == "); strcat(text, name); strcat(text, ")"); return text; } char* OC_mkOr(char* operandl, char* operandr) { char* text = UTIL_mallocStr(strlen(operandl) + strlen(operandr) + 5); strcpy(text, operandl); strcat(text, " || "); strcat(text, operandr); return text; } #define PERV_REGCLOB_DEF_BEG "let regClobberingPerv const = \n if (" #define PERV_REGCLOB_DEF_END ") then true else false \n\n" char* OC_mkRegClobFunc(char* body) { char* text = UTIL_mallocStr(strlen(PERV_REGCLOB_DEF_BEG) + strlen(body) + strlen(PERV_REGCLOB_DEF_END)); strcpy(text, PERV_REGCLOB_DEF_BEG); strcat(text, body); strcat(text, PERV_REGCLOB_DEF_END); return text; } #define PERV_BCK_DEF_BEG "let backtrackablePerv const = \n if (" #define PERV_BCK_DEF_END ") then true else false \n\n" char* OC_mkBackTrackFunc(char* body) { char* text = UTIL_mallocStr(strlen(PERV_BCK_DEF_BEG) + strlen(body) + strlen(PERV_BCK_DEF_END)); strcpy(text, PERV_BCK_DEF_BEG); strcat(text, body); strcat(text, PERV_BCK_DEF_END); return text; } /*****************************************************************************/ /* functions for making the fixed part of pervasive.mli */ /*****************************************************************************/ #define TERM_DECS \ "val implicationTerm : Absyn.aterm\nval andTerm : Absyn.aterm\n" #define PERV_FUNC_DECS \ "val isPerv : Absyn.aconstant -> bool \nval regClobberingPerv : Absyn.aconstant -> bool \nval backtrackablePerv : Absyn.aconstant -> bool\n" /* val pervasiveKinds : Absyn.akind Table.SymbolTable.t val pervasiveConstants : Absyn.aconstant Table.SymbolTable.t val pervasiveTypeAbbrevs : Absyn.atypeabbrev Table.SymbolTable.t */ char* OC_mkFixedMLI() { char* kindDec = OC_mkTabDec(PERVKIND, TY_KIND); char* constDec = OC_mkTabDec(PERVCONST, TY_CONST); char* tyabbrDec = OC_mkTabDec(PERVTYABBR, TY_TYABBREV); size_t length = strlen(kindDec) + strlen(constDec) + strlen(tyabbrDec) + strlen(TERM_DECS) + strlen(PERV_FUNC_DECS) + 10; char* decs = UTIL_mallocStr(length + 1); strcpy(decs, kindDec); free(kindDec); strcat(decs, constDec); free(constDec); strcat(decs, tyabbrDec); free(tyabbrDec); strcat(decs, "\n"); strcat(decs, TERM_DECS); strcat(decs, "\n"); strcat(decs, PERV_FUNC_DECS); strcat(decs, "\n"); return decs; } /*****************************************************************************/ /* functions for making the fixed part of pervasive.ml */ /*****************************************************************************/ #define TERM_DEFS \ "let andTerm = Absyn.ConstantTerm(andConstant, [], false, Errormsg.none) \nlet implicationTerm = Absyn.ConstantTerm(implConstant, [], false, Errormsg.none)\n" #define PERV_ISPERV_DEF \ "let isPerv const = \n let constCat = Absyn.getConstantType(const) in \n match constCat with \n Absyn.PervasiveConstant(_) -> true \n | _ -> false \n" /* let pervasiveKinds = buildPervasiveKinds () let pervasiveConstants = buildPervasiveConstants () let pervasiveTypeAbbrevs = Table.SymbolTable.empty */ char* OC_mkFixedML() { char* kindDef = OC_mkTab(PERVKIND, BUILDPERVKIND); char* constDef = OC_mkTab(PERVCONST, BUILDPERVCONST); char* emptyTab = OC_mkDotStr(TABLE, VCTR_EMPTYTAB); char* tyabbrDef = OC_mkVarDef(PERVTYABBR, emptyTab); size_t length = strlen(kindDef) + strlen(constDef) + strlen(tyabbrDef) + strlen(TERM_DEFS) + strlen(PERV_ISPERV_DEF) + 10; char* defs = UTIL_mallocStr(length + 1); free(emptyTab); strcpy(defs, kindDef); free(kindDef); strcat(defs, constDef); free(constDef); strcat(defs, tyabbrDef); free(tyabbrDef); strcat(defs, "\n\n"); strcat(defs, TERM_DEFS); strcat(defs, "\n"); strcat(defs, PERV_ISPERV_DEF); strcat(defs, "\n"); return defs; }