core & templates: fixed size of stringification buffers

This commit is contained in:
hellerve 2018-01-22 12:47:38 +01:00
parent 1eb8ae27bf
commit 8cb5f5311b
3 changed files with 101 additions and 50 deletions

View File

@ -162,7 +162,7 @@ void IO_print(string *s) { printf("%s", *s); }
string IO_get_MINUS_line() {
size_t size = 1024;
char *buffer = CARP_MALLOC(size);
string buffer = CARP_MALLOC(size);
getline(&buffer, &size, stdin);
return buffer;
}
@ -189,15 +189,16 @@ int Int_random_MINUS_between(int lower, int upper) {
}
string Int_str(int x) {
char *buffer = CARP_MALLOC(64);
snprintf(buffer, 64, "%d", x);
int size = snprintf(NULL, 0, "%d", x)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, "%d", x);
return buffer;
}
string Int_format(string* str, int x) {
int n = strlen(*str) + 32;
char *buffer = CARP_MALLOC(n+1);
snprintf(buffer, n+1, *str, x);
int size = snprintf(NULL, 0, *str, x)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, *str, x);
return buffer;
}
@ -227,15 +228,16 @@ long Long_random_MINUS_between(long lower, long upper) {
}
string Long_str(long x) {
char *buffer = CARP_MALLOC(64);
snprintf(buffer, 64, "%ldl", x);
int size = snprintf(NULL, 0, "%ldl", x)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, "%ldl", x);
return buffer;
}
string Long_format(string* str, long x) {
int n = strlen(*str) + 32;
char *buffer = CARP_MALLOC(n+1);
snprintf(buffer, n+1, *str, x);
int size = snprintf(NULL, 0, *str, x)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, *str, x);
return buffer;
}
@ -257,13 +259,13 @@ void String_delete(string s) {
string String_copy(string *s) {
size_t len = strlen(*s) + 1;
char *ptr = CARP_MALLOC(len);
string ptr = CARP_MALLOC(len);
if (ptr == NULL) {
return NULL;
}
return (char *) memcpy(ptr, *s, len);
return (string) memcpy(ptr, *s, len);
}
bool String__EQ_(string *a, string *b) {
@ -306,9 +308,9 @@ char String_char_MINUS_at(string* s, int i) {
}
string String_format(string *str, string *s) {
int n = strlen(*s) + strlen(*str);
string buffer = CARP_MALLOC(n+1);
snprintf(buffer, n+1, *str, *s);
int size = snprintf(NULL, 0, *str, *s)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, *str, *s);
return buffer;
}
@ -328,7 +330,7 @@ string String_from_MINUS_chars(Array a) {
string String_tail(string* s) {
int len = strlen(*s);
char* news = CARP_MALLOC(len);
string news = CARP_MALLOC(len);
memcpy(news, (*s)+1, len-1);
news[len-1] = '\0';
return news;
@ -345,7 +347,7 @@ bool Char__EQ_(char a, char b) {
}
string Char_str(char c) {
char *buffer = CARP_MALLOC(3);
string buffer = CARP_MALLOC(3);
snprintf(buffer, 3, "\\%c", c);
return buffer;
}
@ -363,9 +365,9 @@ char Char_copy(char *c) {
}
string Char_format(string* str, char b) {
int n = strlen(*str) + 32;
char *buffer = CARP_MALLOC(n+1);
snprintf(buffer, n+1, *str, b);
int size = snprintf(NULL, 0, *str, b)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, *str, b);
return buffer;
}
@ -472,8 +474,9 @@ double Double_mod(double x, double y) {
}
string Double_str(double x) {
char *buffer = CARP_MALLOC(32);
snprintf(buffer, 32, "%g", x);
int size = snprintf(NULL, 0, "%g", x)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, "%g", x);
return buffer;
}
@ -488,9 +491,9 @@ double Double_random_MINUS_between(double lower, double upper) {
}
string Double_format(string* s, double x) {
int n = strlen(*s) + 32;
char *buffer = CARP_MALLOC(n+1);
snprintf(buffer, n+1, *s, x);
int size = snprintf(NULL, 0, *s, x)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, *s, x);
return buffer;
}
@ -597,15 +600,16 @@ float Float_mod(float x, float y) {
}
string Float_str(float x) {
char *buffer = CARP_MALLOC(32);
snprintf(buffer, 32, "%gf", x);
int size = snprintf(NULL, 0, "%gf", x)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, "%gf", x);
return buffer;
}
string Float_format(string* str, float x) {
int n = strlen(*str) + 32;
char *buffer = CARP_MALLOC(n+1);
snprintf(buffer, n+1, *str, x);
int size = snprintf(NULL, 0, *str, x)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, *str, x);
return buffer;
}
@ -623,8 +627,8 @@ bool Bool__DIV__EQ_(bool a, bool b) {
}
string Bool_str(bool b) {
char *true_str = "true";
char *false_str = "false";
string true_str = "true";
string false_str = "false";
if(b) {
return String_copy(&true_str);
} else {
@ -633,9 +637,9 @@ string Bool_str(bool b) {
}
string Bool_format(string* str, bool b) {
int n = strlen(*str) + 32;
char *buffer = CARP_MALLOC(n+1);
snprintf(buffer, n+1, *str, b);
int size = snprintf(NULL, 0, *str, b)+1;
string buffer = CARP_MALLOC(size);
snprintf(buffer, size, *str, b);
return buffer;
}

View File

@ -393,11 +393,12 @@ templateStrArray = defineTypeParameterizedTemplate templateCreator path t
strTy :: TypeEnv -> Env -> Ty -> [Token]
strTy typeEnv env (StructTy "Array" [innerType]) =
[ TokC ""
, TokC " string buffer = CARP_MALLOC(32768); // very arbitrary! TODO: CALCULATE!\n"
, TokC " string bufferPtr = buffer;\n"
, TokC " string temp = NULL;\n"
, TokC $ calculateStrSize typeEnv env innerType
, TokC " string buffer = CARP_MALLOC(size);\n"
, TokC " string bufferPtr = buffer;\n"
, TokC "\n"
, TokC " snprintf(buffer, 32768, \"[\");\n"
, TokC " snprintf(buffer, size, \"[\");\n"
, TokC " bufferPtr += 1;\n"
, TokC "\n"
, TokC " for(int i = 0; i < a->len; i++) {\n"
@ -405,18 +406,40 @@ strTy typeEnv env (StructTy "Array" [innerType]) =
, TokC " }\n"
, TokC "\n"
, TokC " if(a->len > 0) { bufferPtr -= 1; }\n"
, TokC " snprintf(bufferPtr, 32768, \"]\");\n"
, TokC " snprintf(bufferPtr, size, \"]\");\n"
, TokC " return buffer;\n"
]
strTy _ _ _ = []
calculateStrSize :: TypeEnv -> Env -> Ty -> String
calculateStrSize typeEnv env t =
unlines [ " int size = 3; // opening and closing brackets and terminator"
, " for(int i = 0; i < a->len; i++) {"
, arrayMemberSizeCalc
, " }"
]
where arrayMemberSizeCalc =
case findFunctionForMemberIncludePrimitives typeEnv env "str" (typesStrFunctionType typeEnv t) ("Inside array.", t) of
FunctionFound functionFullName ->
let takeAddressOrNot = if isManaged typeEnv t then "&" else ""
in unlines [ " temp = " ++ functionFullName ++ "(" ++ takeAddressOrNot ++ "((" ++ tyToC t ++ "*)a->data)[i]);"
, " size += snprintf(NULL, 0, \"%s \", temp);"
, " if(temp) {"
, " CARP_FREE(temp);"
, " temp = NULL;"
, " }"
]
FunctionNotFound msg -> error msg
FunctionIgnored -> " /* Ignore type inside Array: '" ++ show t ++ "' ??? */\n"
insideArrayStr :: TypeEnv -> Env -> Ty -> String
insideArrayStr typeEnv env t =
case findFunctionForMemberIncludePrimitives typeEnv env "str" (typesStrFunctionType typeEnv t) ("Inside array.", t) of
FunctionFound functionFullName ->
let takeAddressOrNot = if isManaged typeEnv t then "&" else ""
in unlines [ " temp = " ++ functionFullName ++ "(" ++ takeAddressOrNot ++ "((" ++ tyToC t ++ "*)a->data)[i]);"
, " snprintf(bufferPtr, 32768, \"%s \", temp);"
, " snprintf(bufferPtr, size, \"%s \", temp);"
, " bufferPtr += strlen(temp) + 1;"
, " assert((bufferPtr - buffer) < 16000); // out of bounds"
, " if(temp) {"

View File

@ -213,7 +213,6 @@ tyToXObj x = XObj (Sym (SymPath [] (show x)) Symbol) Nothing Nothing
-- | The template for the 'str' function for a deftype.
-- | TODO: Handle all lengths of members, now the string can be at most 1024 characters long.
templateStr :: TypeEnv -> Env -> Ty -> [(String, Ty)] -> Template
templateStr typeEnv env t@(StructTy typeName _) members =
Template
@ -221,15 +220,17 @@ templateStr typeEnv env t@(StructTy typeName _) members =
(\(FuncTy [RefTy structTy] StringTy) -> (toTemplate $ "string $NAME(" ++ tyToC structTy ++ " *p)"))
(\(FuncTy [RefTy structTy] StringTy) -> (toTemplate $ unlines [ "$DECL {"
, " // convert members to string here:"
, " string buffer = CARP_MALLOC(1024); // TODO: dynamic length"
, " string bufferPtr = buffer;"
, " string temp = NULL;"
, " int tempsize = 0;"
, calculateStructStrSize typeEnv env members structTy
, " string buffer = CARP_MALLOC(size);"
, " string bufferPtr = buffer;"
, ""
, " snprintf(bufferPtr, 1024, \"(%s \", \"" ++ tyToC structTy ++ "\");"
, " snprintf(bufferPtr, size, \"(%s \", \"" ++ tyToC structTy ++ "\");"
, " bufferPtr += strlen(\"" ++ tyToC structTy ++ "\") + 2;\n"
, joinWith "\n" (map (memberStr typeEnv env) members)
, " bufferPtr--;"
, " snprintf(bufferPtr, 1024, \")\");"
, " snprintf(bufferPtr, 0, \")\");"
, " return buffer;"
, "}"]))
(\(ft@(FuncTy [RefTy structTy] StringTy)) ->
@ -239,6 +240,28 @@ templateStr typeEnv env t@(StructTy typeName _) members =
(if typeIsGeneric structTy then [] else [defineFunctionTypeAlias ft])
)
calculateStructStrSize :: TypeEnv -> Env -> [(String, Ty)] -> Ty -> String
calculateStructStrSize typeEnv env members structTy =
" int size = snprintf(NULL, 0, \"(%s )\", \"" ++ tyToC structTy ++ "\");\n" ++
unlines (map memberStrSize members)
where memberStrSize (memberName, memberTy) =
let refOrNotRefType = if isManaged typeEnv memberTy then RefTy memberTy else memberTy
maybeTakeAddress = if isManaged typeEnv memberTy then "&" else ""
strFuncType = FuncTy [refOrNotRefType] StringTy
in case nameOfPolymorphicFunction typeEnv env strFuncType "str" of
Just strFunctionPath ->
unlines [" temp = " ++ pathToC strFunctionPath ++ "(" ++ maybeTakeAddress ++ "p->" ++ memberName ++ ");"
, " size += snprintf(NULL, 0, \"%s \", temp);"
, " if(temp) { CARP_FREE(temp); temp = NULL; }"
]
Nothing ->
if isExternalType typeEnv memberTy
then unlines [ " size += snprintf(NULL, 0, \"%p \", p->" ++ memberName ++ ");"
, " if(temp) { CARP_FREE(temp); temp = NULL; }"
]
else " // Failed to find str function for " ++ memberName ++ " : " ++ show memberTy ++ "\n"
-- | Generate C code for converting a member variable to a string and appending it to a buffer.
memberStr :: TypeEnv -> Env -> (String, Ty) -> String
memberStr typeEnv env (memberName, memberTy) =
@ -248,15 +271,16 @@ memberStr typeEnv env (memberName, memberTy) =
in case nameOfPolymorphicFunction typeEnv env strFuncType "str" of
Just strFunctionPath ->
unlines [" temp = " ++ pathToC strFunctionPath ++ "(" ++ maybeTakeAddress ++ "p->" ++ memberName ++ ");"
, " snprintf(bufferPtr, 1024, \"%s \", temp);"
, " snprintf(bufferPtr, size, \"%s \", temp);"
, " bufferPtr += strlen(temp) + 1;"
, " if(temp) { CARP_FREE(temp); temp = NULL; }"
]
Nothing ->
if isExternalType typeEnv memberTy
then unlines [ " temp = malloc(64);"
, " snprintf(temp, 64, \"%p\", p->" ++ memberName ++ ");"
, " snprintf(bufferPtr, 1024, \"%s \", temp);"
then unlines [ " tempsize = snprintf(NULL, 0, \"%p\", p->" ++ memberName ++ ");"
, " temp = malloc(tempsize);"
, " snprintf(temp, tempsize, \"%p\", p->" ++ memberName ++ ");"
, " snprintf(bufferPtr, size, \"%s \", temp);"
, " bufferPtr += strlen(temp) + 1;"
, " if(temp) { CARP_FREE(temp); temp = NULL; }"
]