From c39c29bf4c52a85d7c83cc8b66ae45e265f9e078 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 28 Apr 2025 11:42:22 -0700 Subject: Add Slang Byte Code generation and interpreter. (#6896) * Add Slang Byte Code generation and interpreter. * Fix compile issues. * format code * More compile fix. * Fix clang issue. * Fix more clang issues. * Another clang fix. * Fix clang issues. * Fix another clang issue. * Fix wasm build. * Update building.md * Fix test-server. * Fix compile error. * Fix bug. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> --- source/core/slang-string-util.cpp | 153 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) (limited to 'source/core/slang-string-util.cpp') diff --git a/source/core/slang-string-util.cpp b/source/core/slang-string-util.cpp index ba234e30b..65758fd14 100644 --- a/source/core/slang-string-util.cpp +++ b/source/core/slang-string-util.cpp @@ -390,6 +390,159 @@ UnownedStringSlice StringUtil::getAtInSplit( return builder; } +template +static T readValue(ArrayView ptrToArgs, Count& argIndex) +{ + if (argIndex < ptrToArgs.getCount()) + { + T value; + memcpy(&value, ptrToArgs[argIndex], sizeof(T)); + argIndex++; + return value; + } + return T(); +} + +String StringUtil::makeStringWithFormatFromArgArray( + const char* format, + ArrayView ptrToArgs) +{ + if (!format) + { + return String(); + } + StringBuilder builder; + const char* ptr = format; + Count argIndex = 0; + auto consumeString = [&]() + { + if (argIndex < ptrToArgs.getCount()) + { + const char* strPtr = *(const char**)ptrToArgs[argIndex]; + argIndex++; + if (strPtr) + { + // Append the string to the builder + builder.append(strPtr); + } + } + }; +#define ADVANCE_PTR \ + ptr++; \ + if (!*ptr) \ + { \ + return builder.produceString(); \ + } + + while (*ptr) + { + if (*ptr == '%') + { + const char* formatStart = ptr; + ADVANCE_PTR; + if (*ptr == 's') + { + // If we have a %s, then we want to append the data + consumeString(); + // Move past the 's' + ADVANCE_PTR; + continue; + } + if (*ptr == '-') + { + // If we have a %- then we want to continue parsing format string. + ADVANCE_PTR; + } + while (CharUtil::isDigit(*ptr)) + { + // Skip the digits after the '.' + ADVANCE_PTR; + } + if (*ptr == '.') + { + ADVANCE_PTR; + while (CharUtil::isDigit(*ptr)) + { + // Skip the digits after the '.' + ADVANCE_PTR; + } + } + int isLong = 0; + if (*ptr == 'l' || *ptr == 'L') + { + // If we have a 'l' or 'L', then we want to skip it. + ADVANCE_PTR; + isLong = 1; + if (*ptr == 'l' || *ptr == 'L') + { + // If we have another 'l' or 'L', then we want to skip it too. + ADVANCE_PTR; + isLong = 2; + } + } + const char typeChar = *ptr; + ADVANCE_PTR; + String formatStr = UnownedStringSlice(formatStart, ptr); + switch (CharUtil::toLower(typeChar)) + { + case 'd': + case 'x': + case 'i': + case 'u': + case 'o': + case 'c': + if (isLong == 2) + { + StringUtil::appendFormat( + builder, + formatStr.getBuffer(), + readValue(ptrToArgs, argIndex)); + } + else + { + StringUtil::appendFormat( + builder, + formatStr.getBuffer(), + readValue(ptrToArgs, argIndex)); + } + break; + case 'e': + case 'f': + case 'g': + if (isLong != 0) + { + StringUtil::appendFormat( + builder, + formatStr.getBuffer(), + readValue(ptrToArgs, argIndex)); + } + else + { + StringUtil::appendFormat( + builder, + formatStr.getBuffer(), + readValue(ptrToArgs, argIndex)); + } + break; + case 'n': + break; + case '%': + // If we have a '%%' then we want to append a single '%' + builder.appendChar('%'); + continue; + } + } + else + { + // Just append the character + builder.appendChar(*ptr); + ptr++; + } + } + return builder.produceString(); +} + + /* static */ UnownedStringSlice StringUtil::getSlice(ISlangBlob* blob) { if (blob) -- cgit v1.2.3