Skip to content

Commit

Permalink
Add String.ToLower() and String.ToUpper()
Browse files Browse the repository at this point in the history
  • Loading branch information
caesay committed Feb 16, 2024
1 parent 853653d commit 0516754
Show file tree
Hide file tree
Showing 12 changed files with 210 additions and 0 deletions.
4 changes: 4 additions & 0 deletions AST.fu
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ public enum FuId
StringReplace,
StringStartsWith,
StringSubstring,
StringToLower,
StringToUpper,
ArrayBinarySearchAll,
ArrayBinarySearchPart,
ArrayContains,
Expand Down Expand Up @@ -1529,6 +1531,8 @@ public class FuSystem : FuScope
StringClass.AddMethod(StringStorageType, FuId.StringReplace, "Replace", false, FuVar.New(StringPtrType, "oldValue"), FuVar.New(StringPtrType, "newValue"));
StringClass.AddMethod(BoolType, FuId.StringStartsWith, "StartsWith", false, FuVar.New(StringPtrType, "value"));
StringClass.AddMethod(StringStorageType, FuId.StringSubstring, "Substring", false, FuVar.New(IntType, "offset"), FuVar.New(IntType, "length", NewLiteralLong(-1))); // TODO: UIntType
StringClass.AddMethod(StringStorageType, FuId.StringToLower, "ToLower", false);
StringClass.AddMethod(StringStorageType, FuId.StringToUpper, "ToUpper", false);
StringPtrType.Class = StringClass;
Add(StringPtrType);
StringNullablePtrType.Class = StringClass;
Expand Down
40 changes: 40 additions & 0 deletions GenC.fu
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public class GenC : GenCCpp
bool StringEndsWith;
bool StringReplace;
bool StringFormat;
bool StringToLower;
bool StringToUpper;
bool MatchFind;
bool MatchPos;
bool PtrConstruct;
Expand Down Expand Up @@ -2057,6 +2059,18 @@ public class GenC : GenCCpp
case FuId.StringSubstring:
WriteStringSubstring(obj, args, parent);
break;
case FuId.StringToLower:
Include("string.h");
Include("ctype.h");
this.StringToLower = true;
WriteCall("FuString_ToLower", obj, args[0], args[1]);
break;
case FuId.StringToUpper:
Include("string.h");
Include("ctype.h");
this.StringToUpper = true;
WriteCall("FuString_ToUpper", obj, args[0], args[1]);
break;
case FuId.ArrayBinarySearchAll:
case FuId.ArrayBinarySearchPart:
if (parent > FuPriority.Add)
Expand Down Expand Up @@ -3414,6 +3428,32 @@ public class GenC : GenCCpp
WriteLine("return p;");
CloseBlock();
}
if (this.StringToLower) {
WriteNewLine();
WriteLine("static char *FuString_ToLower(const char *str)");
OpenBlock();
WriteLine("char *lowercaseStr = strdup(str); // Duplicate the string to avoid modifying the original");
WriteLine("if (lowercaseStr == NULL) return NULL; // Check for allocation failure");
WriteLine("for (char *p = lowercaseStr; *p; p++)");
OpenBlock();
WriteLine("*p = tolower((unsigned char)*p); // Convert each character to lowercase");
CloseBlock();
WriteLine("return lowercaseStr; // Return the new lowercase string");
CloseBlock();
}
if (this.StringToUpper) {
WriteNewLine();
WriteLine("static char *FuString_ToUpper(const char *str)");
OpenBlock();
WriteLine("char *uppercaseStr = strdup(str); // Duplicate the string to avoid modifying the original");
WriteLine("if (uppercaseStr == NULL) return NULL; // Check for allocation failure");
WriteLine("for (char *p = uppercaseStr; *p; p++)");
OpenBlock();
WriteLine("*p = toupper((unsigned char)*p); // Convert each character to uppercase");
CloseBlock();
WriteLine("return uppercaseStr; // Return the new uppercase string");
CloseBlock();
}
if (this.StringAppend) {
WriteNewLine();
WriteLine("static void FuString_AppendSubstring(char **str, const char *suffix, size_t suffixLen)");
Expand Down
20 changes: 20 additions & 0 deletions GenCpp.fu
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,26 @@ public class GenCpp : GenCCpp
case FuId.StringSubstring:
WriteStringMethod(obj, "substr", method, args);
break;
case FuId.StringToLower:
Include("algorithm");
Include("cctype");
Write("[&] { std::string data = ");
obj.Accept(this, FuPriority.Argument);
Write("; ");
Write("std::transform(data.begin(), data.end(), data.begin(), ");
Write("[](unsigned char c) { return std::tolower(c); }); ");
Write("return data; }()");
break;
case FuId.StringToUpper:
Include("algorithm");
Include("cctype");
Write("[&] { std::string data = ");
obj.Accept(this, FuPriority.Argument);
Write("; ");
Write("std::transform(data.begin(), data.end(), data.begin(), ");
Write("[](unsigned char c) { return std::toupper(c); }); ");
Write("return data; }()");
break;
case FuId.ArrayBinarySearchAll:
case FuId.ArrayBinarySearchPart:
Include("algorithm");
Expand Down
8 changes: 8 additions & 0 deletions GenD.fu
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,14 @@ public class GenD : GenCCppD
case FuId.StringSubstring:
WriteSlice(obj, args[0], args.Count == 2 ? args[1] : null);
break;
case FuId.StringToLower:
Include("std.uni");
WritePostfix(obj, ".toLower()");
break;
case FuId.StringToUpper:
Include("std.uni");
WritePostfix(obj, ".toUpper()");
break;
case FuId.ArrayBinarySearchAll:
case FuId.ArrayBinarySearchPart:
Include("std.range");
Expand Down
6 changes: 6 additions & 0 deletions GenJava.fu
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,12 @@ public class GenJava : GenTyped
}
WriteChar(')');
break;
case FuId.StringToLower:
WritePostfix(obj, ".toLowerCase()");
break;
case FuId.StringToUpper:
WritePostfix(obj, ".toUpperCase()");
break;
case FuId.ArrayBinarySearchAll:
case FuId.ArrayBinarySearchPart:
WriteArrayBinarySearchFill(obj, "binarySearch", args);
Expand Down
6 changes: 6 additions & 0 deletions GenJs.fu
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,12 @@ public class GenJsNoModule : GenBase
}
WriteChar(')');
break;
case FuId.StringToLower:
WritePostfix(obj, ".toLowerCase()");
break;
case FuId.StringToUpper:
WritePostfix(obj, ".toUpperCase()");
break;
case FuId.ArrayFillAll:
case FuId.ArrayFillPart:
WritePostfix(obj, ".fill(");
Expand Down
6 changes: 6 additions & 0 deletions GenPy.fu
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,12 @@ public class GenPy : GenPySwift
obj.Accept(this, FuPriority.Primary);
WriteSlice(args[0], args.Count == 2 ? args[1] : null);
break;
case FuId.StringToLower:
WritePostfix(obj, ".lower()");
break;
case FuId.StringToUpper:
WritePostfix(obj, ".upper()");
break;
case FuId.ArrayBinarySearchAll:
Include("bisect");
WriteCall("bisect.bisect_left", obj, args[0]);
Expand Down
6 changes: 6 additions & 0 deletions GenSwift.fu
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,12 @@ public class GenSwift : GenPySwift
WriteChar(')');
}
break;
case FuId.StringToLower:
WritePostfix(obj, ".lowercased()");
break;
case FuId.StringToUpper:
WritePostfix(obj, ".uppercased()");
break;
case FuId.ArrayCopyTo:
case FuId.ListCopyTo:
OpenIndexing(args[1]);
Expand Down
92 changes: 92 additions & 0 deletions libfut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2462,6 +2462,8 @@ FuSystem::FuSystem()
this->stringClass->addMethod(this->stringStorageType, FuId::stringReplace, "Replace", false, FuVar::new_(this->stringPtrType, "oldValue"), FuVar::new_(this->stringPtrType, "newValue"));
this->stringClass->addMethod(this->boolType, FuId::stringStartsWith, "StartsWith", false, FuVar::new_(this->stringPtrType, "value"));
this->stringClass->addMethod(this->stringStorageType, FuId::stringSubstring, "Substring", false, FuVar::new_(this->intType, "offset"), FuVar::new_(this->intType, "length", newLiteralLong(-1)));
this->stringClass->addMethod(this->stringStorageType, FuId::stringToLower, "ToLower", false);
this->stringClass->addMethod(this->stringStorageType, FuId::stringToUpper, "ToUpper", false);
this->stringPtrType->class_ = this->stringClass.get();
add(this->stringPtrType);
this->stringNullablePtrType->class_ = this->stringClass.get();
Expand Down Expand Up @@ -10928,6 +10930,18 @@ void GenC::writeCallExpr(const FuExpr * obj, const FuMethod * method, const std:
case FuId::stringSubstring:
writeStringSubstring(obj, args, parent);
break;
case FuId::stringToLower:
include("string.h");
include("ctype.h");
this->stringToLower = true;
writeCall("FuString_ToLower", obj, (*args)[0].get(), (*args)[1].get());
break;
case FuId::stringToUpper:
include("string.h");
include("ctype.h");
this->stringToUpper = true;
writeCall("FuString_ToUpper", obj, (*args)[0].get(), (*args)[1].get());
break;
case FuId::arrayBinarySearchAll:
case FuId::arrayBinarySearchPart:
if (parent > FuPriority::add)
Expand Down Expand Up @@ -12301,6 +12315,32 @@ void GenC::writeLibrary()
writeLine("return p;");
closeBlock();
}
if (this->stringToLower) {
writeNewLine();
writeLine("static char *FuString_ToLower(const char *str)");
openBlock();
writeLine("char *lowercaseStr = strdup(str); // Duplicate the string to avoid modifying the original");
writeLine("if (lowercaseStr == NULL) return NULL; // Check for allocation failure");
writeLine("for (char *p = lowercaseStr; *p; p++)");
openBlock();
writeLine("*p = tolower((unsigned char)*p); // Convert each character to lowercase");
closeBlock();
writeLine("return lowercaseStr; // Return the new lowercase string");
closeBlock();
}
if (this->stringToUpper) {
writeNewLine();
writeLine("static char *FuString_ToUpper(const char *str)");
openBlock();
writeLine("char *uppercaseStr = strdup(str); // Duplicate the string to avoid modifying the original");
writeLine("if (uppercaseStr == NULL) return NULL; // Check for allocation failure");
writeLine("for (char *p = uppercaseStr; *p; p++)");
openBlock();
writeLine("*p = toupper((unsigned char)*p); // Convert each character to uppercase");
closeBlock();
writeLine("return uppercaseStr; // Return the new uppercase string");
closeBlock();
}
if (this->stringAppend) {
writeNewLine();
writeLine("static void FuString_AppendSubstring(char **str, const char *suffix, size_t suffixLen)");
Expand Down Expand Up @@ -13696,6 +13736,26 @@ void GenCpp::writeCallExpr(const FuExpr * obj, const FuMethod * method, const st
case FuId::stringSubstring:
writeStringMethod(obj, "substr", method, args);
break;
case FuId::stringToLower:
include("algorithm");
include("cctype");
write("[&] { std::string data = ");
obj->accept(this, FuPriority::argument);
write("; ");
write("std::transform(data.begin(), data.end(), data.begin(), ");
write("[](unsigned char c) { return std::tolower(c); }); ");
write("return data; }()");
break;
case FuId::stringToUpper:
include("algorithm");
include("cctype");
write("[&] { std::string data = ");
obj->accept(this, FuPriority::argument);
write("; ");
write("std::transform(data.begin(), data.end(), data.begin(), ");
write("[](unsigned char c) { return std::toupper(c); }); ");
write("return data; }()");
break;
case FuId::arrayBinarySearchAll:
case FuId::arrayBinarySearchPart:
include("algorithm");
Expand Down Expand Up @@ -16378,6 +16438,14 @@ void GenD::writeCallExpr(const FuExpr * obj, const FuMethod * method, const std:
case FuId::stringSubstring:
writeSlice(obj, (*args)[0].get(), std::ssize(*args) == 2 ? (*args)[1].get() : nullptr);
break;
case FuId::stringToLower:
include("std.uni");
writePostfix(obj, ".toLower()");
break;
case FuId::stringToUpper:
include("std.uni");
writePostfix(obj, ".toUpper()");
break;
case FuId::arrayBinarySearchAll:
case FuId::arrayBinarySearchPart:
include("std.range");
Expand Down Expand Up @@ -17709,6 +17777,12 @@ void GenJava::writeCallExpr(const FuExpr * obj, const FuMethod * method, const s
}
writeChar(')');
break;
case FuId::stringToLower:
writePostfix(obj, ".toLowerCase()");
break;
case FuId::stringToUpper:
writePostfix(obj, ".toUpperCase()");
break;
case FuId::arrayBinarySearchAll:
case FuId::arrayBinarySearchPart:
writeArrayBinarySearchFill(obj, "binarySearch", args);
Expand Down Expand Up @@ -19015,6 +19089,12 @@ void GenJsNoModule::writeCallExpr(const FuExpr * obj, const FuMethod * method, c
}
writeChar(')');
break;
case FuId::stringToLower:
writePostfix(obj, ".toLowerCase()");
break;
case FuId::stringToUpper:
writePostfix(obj, ".toUpperCase()");
break;
case FuId::arrayFillAll:
case FuId::arrayFillPart:
writePostfix(obj, ".fill(");
Expand Down Expand Up @@ -20859,6 +20939,12 @@ void GenSwift::writeCallExpr(const FuExpr * obj, const FuMethod * method, const
writeChar(')');
}
break;
case FuId::stringToLower:
writePostfix(obj, ".lowercased()");
break;
case FuId::stringToUpper:
writePostfix(obj, ".uppercased()");
break;
case FuId::arrayCopyTo:
case FuId::listCopyTo:
openIndexing((*args)[1].get());
Expand Down Expand Up @@ -22868,6 +22954,12 @@ void GenPy::writeCallExpr(const FuExpr * obj, const FuMethod * method, const std
obj->accept(this, FuPriority::primary);
writeSlice((*args)[0].get(), std::ssize(*args) == 2 ? (*args)[1].get() : nullptr);
break;
case FuId::stringToLower:
writePostfix(obj, ".lower()");
break;
case FuId::stringToUpper:
writePostfix(obj, ".upper()");
break;
case FuId::arrayBinarySearchAll:
include("bisect");
writeCall("bisect.bisect_left", obj, (*args)[0].get());
Expand Down
4 changes: 4 additions & 0 deletions libfut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ enum class FuId
stringReplace,
stringStartsWith,
stringSubstring,
stringToLower,
stringToUpper,
arrayBinarySearchAll,
arrayBinarySearchPart,
arrayContains,
Expand Down Expand Up @@ -2108,6 +2110,8 @@ class GenC : public GenCCpp
bool stringEndsWith;
bool stringReplace;
bool stringFormat;
bool stringToLower;
bool stringToUpper;
bool matchFind;
bool matchPos;
bool ptrConstruct;
Expand Down
9 changes: 9 additions & 0 deletions test/StringLower.fu
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
public class Test
{
public static bool Run()
{
string() s = "MiXeD cAsE";
string() n = s.ToLower();
return n == "mixed case" && s == "MiXeD cAsE";
}
}
9 changes: 9 additions & 0 deletions test/StringUpper.fu
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
public class Test
{
public static bool Run()
{
string() s = "MiXeD cAsE";
string() n = s.ToUpper();
return n == "MIXED CASE" && s == "MiXeD cAsE";
}
}

0 comments on commit 0516754

Please sign in to comment.