mirror of
https://github.com/zekexiao/pocketlang.git
synced 2025-02-11 07:00:58 +08:00
string format method implemented
This commit is contained in:
parent
df39d71cf1
commit
8a438b4f7e
@ -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;
|
||||
|
||||
|
70
src/var.c
70
src/var.c
@ -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);
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user