Merge pull request #5 from ThakeeNathees/string-format

string format method implemented
This commit is contained in:
Thakee Nathees 2021-04-29 20:50:38 +05:30 committed by GitHub
commit 8f52c6d54e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 6 deletions

View File

@ -298,7 +298,7 @@ Var varAdd(MSVM* vm, Var v1, Var v2) {
case OBJ_STRING:
{
if (o2->type == OBJ_STRING) {
TODO; // Implement String.format('@@', s1, s2);
return stringFormat(vm, "@@", v1, v2);
}
} break;

View File

@ -96,16 +96,21 @@ double varToDouble(Var value) {
#endif // VAR_NAN_TAGGING
}
static String* allocateString(MSVM* vm, size_t length) {
String* string = ALLOCATE_DYNAMIC(vm, String, length + 1, char);
varInitObject(&string->_super, vm, OBJ_STRING);
string->length = length;
string->data[length] = '\0';
return string;
}
String* newString(MSVM* vm, const char* text, uint32_t length) {
ASSERT(length == 0 || text != NULL, "Unexpected NULL string.");
String* string = ALLOCATE_DYNAMIC(vm, String, length + 1, char);
varInitObject(&string->_super, vm, OBJ_STRING);
string->length = length;
String* string = allocateString(vm, length);
if (length != 0) memcpy(string->data, text, length);
string->data[length] = '\0';
if (length != 0 && text != NULL) memcpy(string->data, text, length);
return string;
}
@ -363,3 +368,58 @@ bool toBool(Var v) {
return true;
}
Var stringFormat(MSVM* vm, const char* fmt, ...) {
va_list arg_list;
// Calculate the total length of the resulting string. This is required to
// determine the final string size to allocate.
va_start(arg_list, fmt);
size_t total_length = 0;
for (const char* c = fmt; *c != '\0'; c++) {
switch (*c) {
case '$':
total_length += strlen(va_arg(arg_list, const char*));
break;
case '@':
total_length += AS_STRING(va_arg(arg_list, Var))->length;
break;
default:
total_length++;
}
}
va_end(arg_list);
// Now build the new string.
String* result = allocateString(vm, total_length);
va_start(arg_list, fmt);
char* buff = result->data;
for (const char* c = fmt; *c != '\0'; c++) {
switch (*c) {
case '$':
{
const char* string = va_arg(arg_list, const char*);
size_t length = strlen(string);
memcpy(buff, string, length);
buff += length;
} break;
case '@':
{
String* string = AS_STRING(va_arg(arg_list, Var));
memcpy(buff, string->data, string->length);
buff += string->length;
} break;
default:
{
*buff++ = *c;
} break;
}
}
va_end(arg_list);
return VAR_OBJ(result);
}

View File

@ -378,4 +378,10 @@ String* toString(MSVM* vm, Var v, bool _recursive);
// Returns the truthy value of the var.
bool toBool(Var v);
// Creates a new string from the arguments. This is intented to used internal
// usage and it has 2 formated characters (just like wren does).
// $ - a C string
// @ - a String object
Var stringFormat(MSVM* vm, const char* fmt, ...);
#endif // VAR_H