mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-11 13:37:57 +03:00
core & templates: fixed size of stringification buffers
This commit is contained in:
parent
1eb8ae27bf
commit
8cb5f5311b
76
core/core.h
76
core/core.h
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {"
|
||||
|
@ -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; }"
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user