summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr Fusik <piotr@fusion-lang.org>2024-02-26 18:47:12 +0100
committerPiotr Fusik <piotr@fusion-lang.org>2024-02-26 19:55:14 +0100
commit6ab069f177ebcbfd067940be42349bd03a2ceb26 (patch)
treefe916c6613d3958a1bc1e07cbf63569628da3f15
parent99c95da914860466196c997fe6b932ca722c45d3 (diff)
[c] Refactor string.Substring.
-rw-r--r--GenC.fu62
-rw-r--r--GenCl.fu5
-rw-r--r--libfut.cpp67
-rw-r--r--libfut.cs67
-rw-r--r--libfut.hpp4
-rw-r--r--libfut.js67
6 files changed, 154 insertions, 118 deletions
diff --git a/GenC.fu b/GenC.fu
index 5753c7c..13a6f03 100644
--- a/GenC.fu
+++ b/GenC.fu
@@ -118,15 +118,15 @@ public class GenC : GenCCpp
WriteTemporaryOrExpr(expr, FuPriority.Argument);
}
- void WriteStringPtrAdd!(FuExpr? obj, bool utf8GetString, List<FuExpr#> args, bool cast)
+ void WriteStringPtrAdd!(FuCallExpr call, bool cast)
{
- if (utf8GetString) {
+ if (IsUTF8GetString(call)) {
if (cast)
Write("(const char *) ");
- WriteArrayPtrAdd(args[0], args[1]);
+ WriteArrayPtrAdd(call.Arguments[0], call.Arguments[1]);
}
else
- WriteArrayPtrAdd(obj, args[0]);
+ WriteArrayPtrAdd(call.Method.Left, call.Arguments[0]);
}
static bool IsDictionaryClassStgIndexing(FuExpr expr)
@@ -184,7 +184,7 @@ public class GenC : GenCCpp
if (call != null) {
GetStringSubstringLength(call).Accept(this, FuPriority.Argument);
Write(", ");
- WriteStringPtrAdd(call.Method.Left, IsUTF8GetString(call), call.Arguments, true);
+ WriteStringPtrAdd(call, true);
}
else if (expr.Type is FuClassType klass && klass.Class.Id != FuId.StringClass) {
// TODO: abstract, virtual, override
@@ -781,17 +781,7 @@ public class GenC : GenCCpp
void WriteStringStorageValue!(FuExpr expr)
{
- FuCallExpr? call = IsStringSubstring(expr);
- if (call != null) {
- Include("string.h");
- this.StringSubstring = true;
- Write("FuString_Substring(");
- WriteStringPtrAdd(call.Method.Left, IsUTF8GetString(call), call.Arguments, true);
- Write(", ");
- GetStringSubstringLength(call).Accept(this, FuPriority.Argument);
- WriteChar(')');
- }
- else if (expr.IsNewString(false))
+ if (expr.IsNewString(false))
expr.Accept(this, FuPriority.Argument);
else {
Include("string.h");
@@ -1578,7 +1568,7 @@ public class GenC : GenCCpp
WriteChar('(');
Include("string.h");
Write("memcmp(");
- WriteStringPtrAdd(call.Method.Left, IsUTF8GetString(call), call.Arguments, false);
+ WriteStringPtrAdd(call, false);
Write(", ");
VisitLiteralString(literal);
Write(", ");
@@ -1929,17 +1919,14 @@ public class GenC : GenCCpp
WriteChar(')');
}
- protected void WriteStringSubstring!(FuExpr obj, List<FuExpr#> args, FuPriority parent)
+ protected void WriteStringSubstringStart!(FuExpr obj, List<FuExpr#> args, FuPriority parent)
{
- if (args.Count == 1) {
- if (parent > FuPriority.Add)
- WriteChar('(');
- WriteAdd(obj, args[0]);
- if (parent > FuPriority.Add)
- WriteChar(')');
- }
- else
- NotSupported(obj, "Substring");
+ assert args.Count == 1;
+ if (parent > FuPriority.Add)
+ WriteChar('(');
+ WriteAdd(obj, args[0]);
+ if (parent > FuPriority.Add)
+ WriteChar(')');
}
void StartArrayContains!(FuExpr obj)
@@ -2061,7 +2048,17 @@ public class GenC : GenCCpp
WriteChar(')');
break;
case FuId.StringSubstring:
- WriteStringSubstring(obj, args, parent);
+ if (args.Count == 1)
+ WriteStringSubstringStart(obj, args, parent);
+ else {
+ Include("string.h");
+ this.StringSubstring = true;
+ Write("FuString_Substring(");
+ WriteArrayPtrAdd(obj, args[0]);
+ Write(", ");
+ args[1].Accept(this, FuPriority.Argument);
+ WriteChar(')');
+ }
break;
case FuId.StringToLower:
WriteGlib("g_utf8_strdown(");
@@ -2357,6 +2354,15 @@ public class GenC : GenCCpp
args[0].Accept(this, FuPriority.Argument); // FIXME: side effect
Write("))");
break;
+ case FuId.UTF8GetString:
+ Include("string.h");
+ this.StringSubstring = true;
+ Write("FuString_Substring((const char *) ");
+ WriteArrayPtrAdd(args[0], args[1]);
+ Write(", ");
+ args[2].Accept(this, FuPriority.Argument);
+ WriteChar(')');
+ break;
case FuId.EnvironmentGetEnvironmentVariable:
WriteCall("getenv", args[0]);
break;
diff --git a/GenCl.fu b/GenCl.fu
index 123905a..02f2bac 100644
--- a/GenCl.fu
+++ b/GenCl.fu
@@ -199,7 +199,10 @@ public class GenCl : GenC
}
break;
case FuId.StringSubstring:
- WriteStringSubstring(obj, args, parent);
+ if (args.Count == 1)
+ WriteStringSubstringStart(obj, args, parent);
+ else
+ NotSupported(obj, "Substring");
break;
case FuId.ArrayCopyTo:
Write("for (size_t _i = 0; _i < ");
diff --git a/libfut.cpp b/libfut.cpp
index ab92efe..0e9e81e 100644
--- a/libfut.cpp
+++ b/libfut.cpp
@@ -9119,15 +9119,15 @@ void GenC::writeInterpolatedStringArgBase(const FuExpr * expr)
writeTemporaryOrExpr(expr, FuPriority::argument);
}
-void GenC::writeStringPtrAdd(const FuExpr * obj, bool utf8GetString, const std::vector<std::shared_ptr<FuExpr>> * args, bool cast)
+void GenC::writeStringPtrAdd(const FuCallExpr * call, bool cast)
{
- if (utf8GetString) {
+ if (isUTF8GetString(call)) {
if (cast)
write("(const char *) ");
- writeArrayPtrAdd((*args)[0].get(), (*args)[1].get());
+ writeArrayPtrAdd(call->arguments[0].get(), call->arguments[1].get());
}
else
- writeArrayPtrAdd(obj, (*args)[0].get());
+ writeArrayPtrAdd(call->method->left.get(), call->arguments[0].get());
}
bool GenC::isDictionaryClassStgIndexing(const FuExpr * expr)
@@ -9181,7 +9181,7 @@ void GenC::writeInterpolatedStringArg(const FuExpr * expr)
if (call != nullptr) {
getStringSubstringLength(call)->accept(this, FuPriority::argument);
write(", ");
- writeStringPtrAdd(call->method->left.get(), isUTF8GetString(call), &call->arguments, true);
+ writeStringPtrAdd(call, true);
}
else {
const FuClassType * klass;
@@ -9723,17 +9723,7 @@ const FuExpr * GenC::getStringSubstringLength(const FuCallExpr * call)
void GenC::writeStringStorageValue(const FuExpr * expr)
{
- const FuCallExpr * call = isStringSubstring(expr);
- if (call != nullptr) {
- include("string.h");
- this->stringSubstring = true;
- write("FuString_Substring(");
- writeStringPtrAdd(call->method->left.get(), isUTF8GetString(call), &call->arguments, true);
- write(", ");
- getStringSubstringLength(call)->accept(this, FuPriority::argument);
- writeChar(')');
- }
- else if (expr->isNewString(false))
+ if (expr->isNewString(false))
expr->accept(this, FuPriority::argument);
else {
include("string.h");
@@ -10501,7 +10491,7 @@ void GenC::writeSubstringEqual(const FuCallExpr * call, std::string_view literal
writeChar('(');
include("string.h");
write("memcmp(");
- writeStringPtrAdd(call->method->left.get(), isUTF8GetString(call), &call->arguments, false);
+ writeStringPtrAdd(call, false);
write(", ");
visitLiteralString(literal);
write(", ");
@@ -10852,17 +10842,14 @@ void GenC::writeTryParse(const FuExpr * obj, const std::vector<std::shared_ptr<F
writeChar(')');
}
-void GenC::writeStringSubstring(const FuExpr * obj, const std::vector<std::shared_ptr<FuExpr>> * args, FuPriority parent)
+void GenC::writeStringSubstringStart(const FuExpr * obj, const std::vector<std::shared_ptr<FuExpr>> * args, FuPriority parent)
{
- if (std::ssize(*args) == 1) {
- if (parent > FuPriority::add)
- writeChar('(');
- writeAdd(obj, (*args)[0].get());
- if (parent > FuPriority::add)
- writeChar(')');
- }
- else
- notSupported(obj, "Substring");
+ assert(std::ssize(*args) == 1);
+ if (parent > FuPriority::add)
+ writeChar('(');
+ writeAdd(obj, (*args)[0].get());
+ if (parent > FuPriority::add)
+ writeChar(')');
}
void GenC::startArrayContains(const FuExpr * obj)
@@ -10988,7 +10975,17 @@ void GenC::writeCallExpr(const FuExpr * obj, const FuMethod * method, const std:
break;
}
case FuId::stringSubstring:
- writeStringSubstring(obj, args, parent);
+ if (std::ssize(*args) == 1)
+ writeStringSubstringStart(obj, args, parent);
+ else {
+ include("string.h");
+ this->stringSubstring = true;
+ write("FuString_Substring(");
+ writeArrayPtrAdd(obj, (*args)[0].get());
+ write(", ");
+ (*args)[1]->accept(this, FuPriority::argument);
+ writeChar(')');
+ }
break;
case FuId::stringToLower:
writeGlib("g_utf8_strdown(");
@@ -11296,6 +11293,15 @@ void GenC::writeCallExpr(const FuExpr * obj, const FuMethod * method, const std:
(*args)[0]->accept(this, FuPriority::argument);
write("))");
break;
+ case FuId::uTF8GetString:
+ include("string.h");
+ this->stringSubstring = true;
+ write("FuString_Substring((const char *) ");
+ writeArrayPtrAdd((*args)[0].get(), (*args)[1].get());
+ write(", ");
+ (*args)[2]->accept(this, FuPriority::argument);
+ writeChar(')');
+ break;
case FuId::environmentGetEnvironmentVariable:
writeCall("getenv", (*args)[0].get());
break;
@@ -12913,7 +12919,10 @@ void GenCl::writeCallExpr(const FuExpr * obj, const FuMethod * method, const std
break;
}
case FuId::stringSubstring:
- writeStringSubstring(obj, args, parent);
+ if (std::ssize(*args) == 1)
+ writeStringSubstringStart(obj, args, parent);
+ else
+ notSupported(obj, "Substring");
break;
case FuId::arrayCopyTo:
write("for (size_t _i = 0; _i < ");
diff --git a/libfut.cs b/libfut.cs
index 82138a7..dd5e201 100644
--- a/libfut.cs
+++ b/libfut.cs
@@ -9344,15 +9344,15 @@ namespace Fusion
WriteTemporaryOrExpr(expr, FuPriority.Argument);
}
- void WriteStringPtrAdd(FuExpr obj, bool utf8GetString, List<FuExpr> args, bool cast)
+ void WriteStringPtrAdd(FuCallExpr call, bool cast)
{
- if (utf8GetString) {
+ if (IsUTF8GetString(call)) {
if (cast)
Write("(const char *) ");
- WriteArrayPtrAdd(args[0], args[1]);
+ WriteArrayPtrAdd(call.Arguments[0], call.Arguments[1]);
}
else
- WriteArrayPtrAdd(obj, args[0]);
+ WriteArrayPtrAdd(call.Method.Left, call.Arguments[0]);
}
static bool IsDictionaryClassStgIndexing(FuExpr expr)
@@ -9405,7 +9405,7 @@ namespace Fusion
if (call != null) {
GetStringSubstringLength(call).Accept(this, FuPriority.Argument);
Write(", ");
- WriteStringPtrAdd(call.Method.Left, IsUTF8GetString(call), call.Arguments, true);
+ WriteStringPtrAdd(call, true);
}
else if (expr.Type is FuClassType klass && klass.Class.Id != FuId.StringClass) {
Write(this.Namespace);
@@ -10000,17 +10000,7 @@ namespace Fusion
void WriteStringStorageValue(FuExpr expr)
{
- FuCallExpr call = IsStringSubstring(expr);
- if (call != null) {
- Include("string.h");
- this.StringSubstring = true;
- Write("FuString_Substring(");
- WriteStringPtrAdd(call.Method.Left, IsUTF8GetString(call), call.Arguments, true);
- Write(", ");
- GetStringSubstringLength(call).Accept(this, FuPriority.Argument);
- WriteChar(')');
- }
- else if (expr.IsNewString(false))
+ if (expr.IsNewString(false))
expr.Accept(this, FuPriority.Argument);
else {
Include("string.h");
@@ -10782,7 +10772,7 @@ namespace Fusion
WriteChar('(');
Include("string.h");
Write("memcmp(");
- WriteStringPtrAdd(call.Method.Left, IsUTF8GetString(call), call.Arguments, false);
+ WriteStringPtrAdd(call, false);
Write(", ");
VisitLiteralString(literal);
Write(", ");
@@ -11132,17 +11122,14 @@ namespace Fusion
WriteChar(')');
}
- protected void WriteStringSubstring(FuExpr obj, List<FuExpr> args, FuPriority parent)
+ protected void WriteStringSubstringStart(FuExpr obj, List<FuExpr> args, FuPriority parent)
{
- if (args.Count == 1) {
- if (parent > FuPriority.Add)
- WriteChar('(');
- WriteAdd(obj, args[0]);
- if (parent > FuPriority.Add)
- WriteChar(')');
- }
- else
- NotSupported(obj, "Substring");
+ Debug.Assert(args.Count == 1);
+ if (parent > FuPriority.Add)
+ WriteChar('(');
+ WriteAdd(obj, args[0]);
+ if (parent > FuPriority.Add)
+ WriteChar(')');
}
void StartArrayContains(FuExpr obj)
@@ -11264,7 +11251,17 @@ namespace Fusion
WriteChar(')');
break;
case FuId.StringSubstring:
- WriteStringSubstring(obj, args, parent);
+ if (args.Count == 1)
+ WriteStringSubstringStart(obj, args, parent);
+ else {
+ Include("string.h");
+ this.StringSubstring = true;
+ Write("FuString_Substring(");
+ WriteArrayPtrAdd(obj, args[0]);
+ Write(", ");
+ args[1].Accept(this, FuPriority.Argument);
+ WriteChar(')');
+ }
break;
case FuId.StringToLower:
WriteGlib("g_utf8_strdown(");
@@ -11556,6 +11553,15 @@ namespace Fusion
args[0].Accept(this, FuPriority.Argument);
Write("))");
break;
+ case FuId.UTF8GetString:
+ Include("string.h");
+ this.StringSubstring = true;
+ Write("FuString_Substring((const char *) ");
+ WriteArrayPtrAdd(args[0], args[1]);
+ Write(", ");
+ args[2].Accept(this, FuPriority.Argument);
+ WriteChar(')');
+ break;
case FuId.EnvironmentGetEnvironmentVariable:
WriteCall("getenv", args[0]);
break;
@@ -13171,7 +13177,10 @@ namespace Fusion
}
break;
case FuId.StringSubstring:
- WriteStringSubstring(obj, args, parent);
+ if (args.Count == 1)
+ WriteStringSubstringStart(obj, args, parent);
+ else
+ NotSupported(obj, "Substring");
break;
case FuId.ArrayCopyTo:
Write("for (size_t _i = 0; _i < ");
diff --git a/libfut.hpp b/libfut.hpp
index 1605e6e..a2f3a0f 100644
--- a/libfut.hpp
+++ b/libfut.hpp
@@ -2079,7 +2079,7 @@ protected:
void writeArrayFill(const FuExpr * obj, const std::vector<std::shared_ptr<FuExpr>> * args);
void writePrintfNotInterpolated(const std::vector<std::shared_ptr<FuExpr>> * args, bool newLine);
void writeCCall(const FuExpr * obj, const FuMethod * method, const std::vector<std::shared_ptr<FuExpr>> * args);
- void writeStringSubstring(const FuExpr * obj, const std::vector<std::shared_ptr<FuExpr>> * args, FuPriority parent);
+ void writeStringSubstringStart(const FuExpr * obj, const std::vector<std::shared_ptr<FuExpr>> * args, FuPriority parent);
void writeCallExpr(const FuExpr * obj, const FuMethod * method, const std::vector<std::shared_ptr<FuExpr>> * args, FuPriority parent) override;
void writeIndexingExpr(const FuBinaryExpr * expr, FuPriority parent) override;
void writeResource(std::string_view name, int length) override;
@@ -2137,7 +2137,7 @@ private:
std::set<FuId> compares;
std::set<FuId> contains;
std::vector<const FuVar *> varsToDestruct;
- void writeStringPtrAdd(const FuExpr * obj, bool utf8GetString, const std::vector<std::shared_ptr<FuExpr>> * args, bool cast);
+ void writeStringPtrAdd(const FuCallExpr * call, bool cast);
static bool isDictionaryClassStgIndexing(const FuExpr * expr);
void writeTemporaryOrExpr(const FuExpr * expr, FuPriority parent);
void writeUpcast(const FuClass * resultClass, const FuSymbol * klass);
diff --git a/libfut.js b/libfut.js
index 6e15337..1a5faf7 100644
--- a/libfut.js
+++ b/libfut.js
@@ -9670,15 +9670,15 @@ export class GenC extends GenCCpp
this.#writeTemporaryOrExpr(expr, FuPriority.ARGUMENT);
}
- #writeStringPtrAdd(obj, utf8GetString, args, cast)
+ #writeStringPtrAdd(call, cast)
{
- if (utf8GetString) {
+ if (GenC.isUTF8GetString(call)) {
if (cast)
this.write("(const char *) ");
- this.writeArrayPtrAdd(args[0], args[1]);
+ this.writeArrayPtrAdd(call.arguments_[0], call.arguments_[1]);
}
else
- this.writeArrayPtrAdd(obj, args[0]);
+ this.writeArrayPtrAdd(call.method.left, call.arguments_[0]);
}
static #isDictionaryClassStgIndexing(expr)
@@ -9732,7 +9732,7 @@ export class GenC extends GenCCpp
if (call != null) {
GenC.#getStringSubstringLength(call).accept(this, FuPriority.ARGUMENT);
this.write(", ");
- this.#writeStringPtrAdd(call.method.left, GenC.isUTF8GetString(call), call.arguments_, true);
+ this.#writeStringPtrAdd(call, true);
}
else {
let klass;
@@ -10345,17 +10345,7 @@ export class GenC extends GenCCpp
#writeStringStorageValue(expr)
{
- let call = GenC.isStringSubstring(expr);
- if (call != null) {
- this.include("string.h");
- this.#stringSubstring = true;
- this.write("FuString_Substring(");
- this.#writeStringPtrAdd(call.method.left, GenC.isUTF8GetString(call), call.arguments_, true);
- this.write(", ");
- GenC.#getStringSubstringLength(call).accept(this, FuPriority.ARGUMENT);
- this.writeChar(41);
- }
- else if (expr.isNewString(false))
+ if (expr.isNewString(false))
expr.accept(this, FuPriority.ARGUMENT);
else {
this.include("string.h");
@@ -11157,7 +11147,7 @@ export class GenC extends GenCCpp
this.writeChar(40);
this.include("string.h");
this.write("memcmp(");
- this.#writeStringPtrAdd(call.method.left, GenC.isUTF8GetString(call), call.arguments_, false);
+ this.#writeStringPtrAdd(call, false);
this.write(", ");
this.visitLiteralString(literal);
this.write(", ");
@@ -11517,17 +11507,14 @@ export class GenC extends GenCCpp
this.writeChar(41);
}
- writeStringSubstring(obj, args, parent)
+ writeStringSubstringStart(obj, args, parent)
{
- if (args.length == 1) {
- if (parent > FuPriority.ADD)
- this.writeChar(40);
- this.writeAdd(obj, args[0]);
- if (parent > FuPriority.ADD)
- this.writeChar(41);
- }
- else
- this.notSupported(obj, "Substring");
+ console.assert(args.length == 1);
+ if (parent > FuPriority.ADD)
+ this.writeChar(40);
+ this.writeAdd(obj, args[0]);
+ if (parent > FuPriority.ADD)
+ this.writeChar(41);
}
#startArrayContains(obj)
@@ -11649,7 +11636,17 @@ export class GenC extends GenCCpp
this.writeChar(41);
break;
case FuId.STRING_SUBSTRING:
- this.writeStringSubstring(obj, args, parent);
+ if (args.length == 1)
+ this.writeStringSubstringStart(obj, args, parent);
+ else {
+ this.include("string.h");
+ this.#stringSubstring = true;
+ this.write("FuString_Substring(");
+ this.writeArrayPtrAdd(obj, args[0]);
+ this.write(", ");
+ args[1].accept(this, FuPriority.ARGUMENT);
+ this.writeChar(41);
+ }
break;
case FuId.STRING_TO_LOWER:
this.#writeGlib("g_utf8_strdown(");
@@ -11943,6 +11940,15 @@ export class GenC extends GenCCpp
args[0].accept(this, FuPriority.ARGUMENT);
this.write("))");
break;
+ case FuId.U_T_F8_GET_STRING:
+ this.include("string.h");
+ this.#stringSubstring = true;
+ this.write("FuString_Substring((const char *) ");
+ this.writeArrayPtrAdd(args[0], args[1]);
+ this.write(", ");
+ args[2].accept(this, FuPriority.ARGUMENT);
+ this.writeChar(41);
+ break;
case FuId.ENVIRONMENT_GET_ENVIRONMENT_VARIABLE:
this.writeCall("getenv", args[0]);
break;
@@ -13592,7 +13598,10 @@ export class GenCl extends GenC
}
break;
case FuId.STRING_SUBSTRING:
- this.writeStringSubstring(obj, args, parent);
+ if (args.length == 1)
+ this.writeStringSubstringStart(obj, args, parent);
+ else
+ this.notSupported(obj, "Substring");
break;
case FuId.ARRAY_COPY_TO:
this.write("for (size_t _i = 0; _i < ");