summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPiotr Fusik <piotr@fusion-lang.org>2024-02-28 15:10:23 +0100
committerPiotr Fusik <piotr@fusion-lang.org>2024-02-28 15:10:23 +0100
commitce08f8b765b1f18863ce3a478ba9c15842a0c285 (patch)
tree4a825070e6c3354927f504a221bf6b6bdd294057
parenteddb25e7de0704eb6110d7244f00b071d3dc85f5 (diff)
[c] StringWriter.
-rw-r--r--GenC.fu86
-rw-r--r--libfut.cpp86
-rw-r--r--libfut.cs86
-rw-r--r--libfut.js86
-rw-r--r--test/StringWriter.fu10
5 files changed, 296 insertions, 58 deletions
diff --git a/GenC.fu b/GenC.fu
index 48b70ce..f00dff2 100644
--- a/GenC.fu
+++ b/GenC.fu
@@ -486,6 +486,9 @@ public class GenC : GenCCpp
Include("stdio.h");
Write("FILE *");
break;
+ case FuId.StringWriterClass:
+ WriteGlib("GString *");
+ break;
case FuId.RegexClass:
if (!(klass is FuReadWriteClassType))
Write("const ");
@@ -626,6 +629,7 @@ public class GenC : GenCCpp
case FuId.SortedSetClass:
case FuId.DictionaryClass:
case FuId.SortedDictionaryClass:
+ case FuId.StringWriterClass:
case FuId.MatchClass:
case FuId.LockClass:
return true;
@@ -732,6 +736,9 @@ public class GenC : GenCCpp
case FuId.SortedDictionaryClass:
AddListFree(FuId.SortedDictionaryClass);
break;
+ case FuId.StringWriterClass:
+ AddListFree(FuId.StringWriterClass);
+ break;
case FuId.RegexClass:
AddListFree(FuId.RegexClass);
break;
@@ -838,6 +845,9 @@ public class GenC : GenCCpp
case FuId.SortedDictionaryClass:
Write("g_tree_unref");
return false;
+ case FuId.StringWriterClass:
+ Write("g_string_free");
+ return false;
case FuId.RegexClass:
Write("g_regex_unref");
return false;
@@ -961,6 +971,9 @@ public class GenC : GenCCpp
case FuId.SortedDictionaryClass:
WriteNewTree(klass.GetKeyType(), klass.GetValueType());
break;
+ case FuId.StringWriterClass:
+ Write("g_string_new(NULL)");
+ break;
default:
this.SharedMake = true;
if (parent > FuPriority.Mul)
@@ -987,6 +1000,7 @@ public class GenC : GenCCpp
case FuId.SortedSetClass:
case FuId.DictionaryClass:
case FuId.SortedDictionaryClass:
+ case FuId.StringWriterClass:
return true;
default:
return false;
@@ -1370,6 +1384,8 @@ public class GenC : GenCCpp
Write(", ");
WriteDictionaryDestroy(klass.GetElementType());
}
+ else if (klass.Class.Id == FuId.StringWriterClass)
+ Write(", TRUE");
WriteLine(");");
this.Indent -= nesting;
}
@@ -1768,38 +1784,61 @@ public class GenC : GenCCpp
void WriteTextWriterWrite!(FuExpr obj, List<FuExpr#> args, bool newLine)
{
if (args.Count == 0) {
- Write("putc('\\n', ");
- obj.Accept(this, FuPriority.Argument);
+ if (obj.Type.AsClassType().Class.Id == FuId.StringWriterClass) {
+ Write("g_string_append_c(");
+ obj.Accept(this, FuPriority.Argument);
+ Write(", '\\n'");
+ }
+ else {
+ Write("putc('\\n', ");
+ obj.Accept(this, FuPriority.Argument);
+ }
WriteChar(')');
}
else if (args[0] is FuInterpolatedString interpolated) {
- Write("fprintf(");
+ Write(obj.Type.AsClassType().Class.Id == FuId.StringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj.Accept(this, FuPriority.Argument);
Write(", ");
WritePrintf(interpolated, newLine);
}
else if (args[0].Type is FuNumericType) {
- Write("fprintf(");
+ Write(obj.Type.AsClassType().Class.Id == FuId.StringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj.Accept(this, FuPriority.Argument);
Write(", ");
WritePrintfNotInterpolated(args, newLine);
}
else if (!newLine) {
- Write("fputs(");
- args[0].Accept(this, FuPriority.Argument);
- Write(", ");
- obj.Accept(this, FuPriority.Argument);
+ if (obj.Type.AsClassType().Class.Id == FuId.StringWriterClass) {
+ Write("g_string_append(");
+ obj.Accept(this, FuPriority.Argument);
+ Write(", ");
+ args[0].Accept(this, FuPriority.Argument);
+ }
+ else {
+ Write("fputs(");
+ args[0].Accept(this, FuPriority.Argument);
+ Write(", ");
+ obj.Accept(this, FuPriority.Argument);
+ }
WriteChar(')');
}
else if (args[0] is FuLiteralString literal) {
- Write("fputs(");
- WriteStringLiteralWithNewLine(literal.Value);
- Write(", ");
- obj.Accept(this, FuPriority.Argument);
+ if (obj.Type.AsClassType().Class.Id == FuId.StringWriterClass) {
+ Write("g_string_append(");
+ obj.Accept(this, FuPriority.Argument);
+ Write(", ");
+ WriteStringLiteralWithNewLine(literal.Value);
+ }
+ else {
+ Write("fputs(");
+ WriteStringLiteralWithNewLine(literal.Value);
+ Write(", ");
+ obj.Accept(this, FuPriority.Argument);
+ }
WriteChar(')');
}
else {
- Write("fprintf(");
+ Write(obj.Type.AsClassType().Class.Id == FuId.StringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj.Accept(this, FuPriority.Argument);
Write(", \"%s\\n\", ");
args[0].Accept(this, FuPriority.Argument);
@@ -2324,7 +2363,16 @@ public class GenC : GenCCpp
WriteTextWriterWrite(obj, args, false);
break;
case FuId.TextWriterWriteChar:
- WriteCall("putc", args[0], obj);
+ if (obj.Type.AsClassType().Class.Id == FuId.StringWriterClass)
+ WriteCall("g_string_append_c", obj, args[0]);
+ else
+ WriteCall("putc", args[0], obj);
+ break;
+ case FuId.TextWriterWriteCodePoint:
+ if (obj.Type.AsClassType().Class.Id != FuId.StringWriterClass)
+ NotSupported(obj, method.Name);
+ else
+ WriteCall("g_string_append_unichar", obj, args[0]);
break;
case FuId.TextWriterWriteLine:
WriteTextWriterWrite(obj, args, true);
@@ -2335,6 +2383,14 @@ public class GenC : GenCCpp
case FuId.ConsoleWriteLine:
WriteConsoleWrite(args, true);
break;
+ case FuId.StringWriterClear:
+ Write("g_string_truncate(");
+ obj.Accept(this, FuPriority.Argument);
+ Write(", 0)");
+ break;
+ case FuId.StringWriterToString:
+ WritePostfix(obj, "->str");
+ break;
case FuId.ConvertToBase64String:
WriteGlib("g_base64_encode(");
WriteArrayPtrAdd(args[0], args[1]);
@@ -2676,6 +2732,8 @@ public class GenC : GenCCpp
WriteDestructMethodName(owning);
WriteChar('(');
statement.Accept(this, FuPriority.Argument);
+ if (owning.Class.Id == FuId.StringWriterClass)
+ Write(", TRUE");
WriteLine(");");
CleanupTemporaries();
}
diff --git a/libfut.cpp b/libfut.cpp
index 099f962..6a1756c 100644
--- a/libfut.cpp
+++ b/libfut.cpp
@@ -9388,6 +9388,9 @@ void GenC::writeClassType(const FuClassType * klass, bool space)
include("stdio.h");
write("FILE *");
break;
+ case FuId::stringWriterClass:
+ writeGlib("GString *");
+ break;
case FuId::regexClass:
if (!dynamic_cast<const FuReadWriteClassType *>(klass))
write("const ");
@@ -9531,6 +9534,7 @@ bool GenC::needToDestructType(const FuType * type)
case FuId::sortedSetClass:
case FuId::dictionaryClass:
case FuId::sortedDictionaryClass:
+ case FuId::stringWriterClass:
case FuId::matchClass:
case FuId::lockClass:
return true;
@@ -9639,6 +9643,9 @@ void GenC::writeListFree(const FuClassType * elementType)
case FuId::sortedDictionaryClass:
addListFree(FuId::sortedDictionaryClass);
break;
+ case FuId::stringWriterClass:
+ addListFree(FuId::stringWriterClass);
+ break;
case FuId::regexClass:
addListFree(FuId::regexClass);
break;
@@ -9743,6 +9750,9 @@ bool GenC::writeDestructMethodName(const FuClassType * klass)
case FuId::sortedDictionaryClass:
write("g_tree_unref");
return false;
+ case FuId::stringWriterClass:
+ write("g_string_free");
+ return false;
case FuId::regexClass:
write("g_regex_unref");
return false;
@@ -9862,6 +9872,9 @@ void GenC::writeNew(const FuReadWriteClassType * klass, FuPriority parent)
case FuId::sortedDictionaryClass:
writeNewTree(klass->getKeyType(), klass->getValueType().get());
break;
+ case FuId::stringWriterClass:
+ write("g_string_new(NULL)");
+ break;
default:
this->sharedMake = true;
if (parent > FuPriority::mul)
@@ -9888,6 +9901,7 @@ bool GenC::isCollection(const FuClass * klass)
case FuId::sortedSetClass:
case FuId::dictionaryClass:
case FuId::sortedDictionaryClass:
+ case FuId::stringWriterClass:
return true;
default:
return false;
@@ -10252,6 +10266,8 @@ void GenC::writeDestruct(const FuSymbol * symbol)
write(", ");
writeDictionaryDestroy(klass->getElementType().get());
}
+ else if (klass->class_->id == FuId::stringWriterClass)
+ write(", TRUE");
writeLine(");");
this->indent -= nesting;
}
@@ -10652,38 +10668,61 @@ void GenC::writePrintfNotInterpolated(const std::vector<std::shared_ptr<FuExpr>>
void GenC::writeTextWriterWrite(const FuExpr * obj, const std::vector<std::shared_ptr<FuExpr>> * args, bool newLine)
{
if (std::ssize(*args) == 0) {
- write("putc('\\n', ");
- obj->accept(this, FuPriority::argument);
+ if (obj->type->asClassType()->class_->id == FuId::stringWriterClass) {
+ write("g_string_append_c(");
+ obj->accept(this, FuPriority::argument);
+ write(", '\\n'");
+ }
+ else {
+ write("putc('\\n', ");
+ obj->accept(this, FuPriority::argument);
+ }
writeChar(')');
}
else if (const FuInterpolatedString *interpolated = dynamic_cast<const FuInterpolatedString *>((*args)[0].get())) {
- write("fprintf(");
+ write(obj->type->asClassType()->class_->id == FuId::stringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj->accept(this, FuPriority::argument);
write(", ");
writePrintf(interpolated, newLine);
}
else if (dynamic_cast<const FuNumericType *>((*args)[0]->type.get())) {
- write("fprintf(");
+ write(obj->type->asClassType()->class_->id == FuId::stringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj->accept(this, FuPriority::argument);
write(", ");
writePrintfNotInterpolated(args, newLine);
}
else if (!newLine) {
- write("fputs(");
- (*args)[0]->accept(this, FuPriority::argument);
- write(", ");
- obj->accept(this, FuPriority::argument);
+ if (obj->type->asClassType()->class_->id == FuId::stringWriterClass) {
+ write("g_string_append(");
+ obj->accept(this, FuPriority::argument);
+ write(", ");
+ (*args)[0]->accept(this, FuPriority::argument);
+ }
+ else {
+ write("fputs(");
+ (*args)[0]->accept(this, FuPriority::argument);
+ write(", ");
+ obj->accept(this, FuPriority::argument);
+ }
writeChar(')');
}
else if (const FuLiteralString *literal = dynamic_cast<const FuLiteralString *>((*args)[0].get())) {
- write("fputs(");
- writeStringLiteralWithNewLine(literal->value);
- write(", ");
- obj->accept(this, FuPriority::argument);
+ if (obj->type->asClassType()->class_->id == FuId::stringWriterClass) {
+ write("g_string_append(");
+ obj->accept(this, FuPriority::argument);
+ write(", ");
+ writeStringLiteralWithNewLine(literal->value);
+ }
+ else {
+ write("fputs(");
+ writeStringLiteralWithNewLine(literal->value);
+ write(", ");
+ obj->accept(this, FuPriority::argument);
+ }
writeChar(')');
}
else {
- write("fprintf(");
+ write(obj->type->asClassType()->class_->id == FuId::stringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj->accept(this, FuPriority::argument);
write(", \"%s\\n\", ");
(*args)[0]->accept(this, FuPriority::argument);
@@ -11227,7 +11266,16 @@ void GenC::writeCallExpr(const FuExpr * obj, const FuMethod * method, const std:
writeTextWriterWrite(obj, args, false);
break;
case FuId::textWriterWriteChar:
- writeCall("putc", (*args)[0].get(), obj);
+ if (obj->type->asClassType()->class_->id == FuId::stringWriterClass)
+ writeCall("g_string_append_c", obj, (*args)[0].get());
+ else
+ writeCall("putc", (*args)[0].get(), obj);
+ break;
+ case FuId::textWriterWriteCodePoint:
+ if (obj->type->asClassType()->class_->id != FuId::stringWriterClass)
+ notSupported(obj, method->name);
+ else
+ writeCall("g_string_append_unichar", obj, (*args)[0].get());
break;
case FuId::textWriterWriteLine:
writeTextWriterWrite(obj, args, true);
@@ -11238,6 +11286,14 @@ void GenC::writeCallExpr(const FuExpr * obj, const FuMethod * method, const std:
case FuId::consoleWriteLine:
writeConsoleWrite(args, true);
break;
+ case FuId::stringWriterClear:
+ write("g_string_truncate(");
+ obj->accept(this, FuPriority::argument);
+ write(", 0)");
+ break;
+ case FuId::stringWriterToString:
+ writePostfix(obj, "->str");
+ break;
case FuId::convertToBase64String:
writeGlib("g_base64_encode(");
writeArrayPtrAdd((*args)[0].get(), (*args)[1].get());
@@ -11584,6 +11640,8 @@ void GenC::visitExpr(const FuExpr * statement)
writeDestructMethodName(owning);
writeChar('(');
statement->accept(this, FuPriority::argument);
+ if (owning->class_->id == FuId::stringWriterClass)
+ write(", TRUE");
writeLine(");");
cleanupTemporaries();
}
diff --git a/libfut.cs b/libfut.cs
index 858c6d2..762deab 100644
--- a/libfut.cs
+++ b/libfut.cs
@@ -9689,6 +9689,9 @@ namespace Fusion
Include("stdio.h");
Write("FILE *");
break;
+ case FuId.StringWriterClass:
+ WriteGlib("GString *");
+ break;
case FuId.RegexClass:
if (!(klass is FuReadWriteClassType))
Write("const ");
@@ -9829,6 +9832,7 @@ namespace Fusion
case FuId.SortedSetClass:
case FuId.DictionaryClass:
case FuId.SortedDictionaryClass:
+ case FuId.StringWriterClass:
case FuId.MatchClass:
case FuId.LockClass:
return true;
@@ -9935,6 +9939,9 @@ namespace Fusion
case FuId.SortedDictionaryClass:
AddListFree(FuId.SortedDictionaryClass);
break;
+ case FuId.StringWriterClass:
+ AddListFree(FuId.StringWriterClass);
+ break;
case FuId.RegexClass:
AddListFree(FuId.RegexClass);
break;
@@ -10041,6 +10048,9 @@ namespace Fusion
case FuId.SortedDictionaryClass:
Write("g_tree_unref");
return false;
+ case FuId.StringWriterClass:
+ Write("g_string_free");
+ return false;
case FuId.RegexClass:
Write("g_regex_unref");
return false;
@@ -10164,6 +10174,9 @@ namespace Fusion
case FuId.SortedDictionaryClass:
WriteNewTree(klass.GetKeyType(), klass.GetValueType());
break;
+ case FuId.StringWriterClass:
+ Write("g_string_new(NULL)");
+ break;
default:
this.SharedMake = true;
if (parent > FuPriority.Mul)
@@ -10190,6 +10203,7 @@ namespace Fusion
case FuId.SortedSetClass:
case FuId.DictionaryClass:
case FuId.SortedDictionaryClass:
+ case FuId.StringWriterClass:
return true;
default:
return false;
@@ -10558,6 +10572,8 @@ namespace Fusion
Write(", ");
WriteDictionaryDestroy(klass.GetElementType());
}
+ else if (klass.Class.Id == FuId.StringWriterClass)
+ Write(", TRUE");
WriteLine(");");
this.Indent -= nesting;
}
@@ -10955,38 +10971,61 @@ namespace Fusion
void WriteTextWriterWrite(FuExpr obj, List<FuExpr> args, bool newLine)
{
if (args.Count == 0) {
- Write("putc('\\n', ");
- obj.Accept(this, FuPriority.Argument);
+ if (obj.Type.AsClassType().Class.Id == FuId.StringWriterClass) {
+ Write("g_string_append_c(");
+ obj.Accept(this, FuPriority.Argument);
+ Write(", '\\n'");
+ }
+ else {
+ Write("putc('\\n', ");
+ obj.Accept(this, FuPriority.Argument);
+ }
WriteChar(')');
}
else if (args[0] is FuInterpolatedString interpolated) {
- Write("fprintf(");
+ Write(obj.Type.AsClassType().Class.Id == FuId.StringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj.Accept(this, FuPriority.Argument);
Write(", ");
WritePrintf(interpolated, newLine);
}
else if (args[0].Type is FuNumericType) {
- Write("fprintf(");
+ Write(obj.Type.AsClassType().Class.Id == FuId.StringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj.Accept(this, FuPriority.Argument);
Write(", ");
WritePrintfNotInterpolated(args, newLine);
}
else if (!newLine) {
- Write("fputs(");
- args[0].Accept(this, FuPriority.Argument);
- Write(", ");
- obj.Accept(this, FuPriority.Argument);
+ if (obj.Type.AsClassType().Class.Id == FuId.StringWriterClass) {
+ Write("g_string_append(");
+ obj.Accept(this, FuPriority.Argument);
+ Write(", ");
+ args[0].Accept(this, FuPriority.Argument);
+ }
+ else {
+ Write("fputs(");
+ args[0].Accept(this, FuPriority.Argument);
+ Write(", ");
+ obj.Accept(this, FuPriority.Argument);
+ }
WriteChar(')');
}
else if (args[0] is FuLiteralString literal) {
- Write("fputs(");
- WriteStringLiteralWithNewLine(literal.Value);
- Write(", ");
- obj.Accept(this, FuPriority.Argument);
+ if (obj.Type.AsClassType().Class.Id == FuId.StringWriterClass) {
+ Write("g_string_append(");
+ obj.Accept(this, FuPriority.Argument);
+ Write(", ");
+ WriteStringLiteralWithNewLine(literal.Value);
+ }
+ else {
+ Write("fputs(");
+ WriteStringLiteralWithNewLine(literal.Value);
+ Write(", ");
+ obj.Accept(this, FuPriority.Argument);
+ }
WriteChar(')');
}
else {
- Write("fprintf(");
+ Write(obj.Type.AsClassType().Class.Id == FuId.StringWriterClass ? "g_string_append_printf(" : "fprintf(");
obj.Accept(this, FuPriority.Argument);
Write(", \"%s\\n\", ");
args[0].Accept(this, FuPriority.Argument);
@@ -11507,7 +11546,16 @@ namespace Fusion
WriteTextWriterWrite(obj, args, false);
break;
case FuId.TextWriterWriteChar:
- WriteCall("putc", args[0], obj);
+ if (obj.Type.AsClassType().Class.Id == FuId.StringWriterClass)
+ WriteCall("g_string_append_c", obj, args[0]);
+ else
+ WriteCall("putc", args[0], obj);
+ break;
+ case FuId.TextWriterWriteCodePoint:
+ if (obj.Type.AsClassType().Class.Id != FuId.StringWriterClass)
+ NotSupported(obj, method.Name);
+ else
+ WriteCall("g_string_append_unichar", obj, args[0]);
break;
case FuId.TextWriterWriteLine:
WriteTextWriterWrite(obj, args, true);
@@ -11518,6 +11566,14 @@ namespace Fusion
case FuId.ConsoleWriteLine:
WriteConsoleWrite(args, true);
break;
+ case FuId.StringWriterClear:
+ Write("g_string_truncate(");
+ obj.Accept(this, FuPriority.Argument);
+ Write(", 0)");
+ break;
+ case FuId.StringWriterToString:
+ WritePostfix(obj, "->str");
+ break;
case FuId.ConvertToBase64String:
WriteGlib("g_base64_encode(");
WriteArrayPtrAdd(args[0], args[1]);
@@ -11859,6 +11915,8 @@ namespace Fusion
WriteDestructMethodName(owning);
WriteChar('(');
statement.Accept(this, FuPriority.Argument);
+ if (owning.Class.Id == FuId.StringWriterClass)
+ Write(", TRUE");
WriteLine(");");
CleanupTemporaries();
}
diff --git a/libfut.js b/libfut.js
index d7e2ab9..6bb23b1 100644
--- a/libfut.js
+++ b/libfut.js
@@ -10023,6 +10023,9 @@ export class GenC extends GenCCpp
this.include("stdio.h");
this.write("FILE *");
break;
+ case FuId.STRING_WRITER_CLASS:
+ this.#writeGlib("GString *");
+ break;
case FuId.REGEX_CLASS:
if (!(klass instanceof FuReadWriteClassType))
this.write("const ");
@@ -10170,6 +10173,7 @@ export class GenC extends GenCCpp
case FuId.SORTED_SET_CLASS:
case FuId.DICTIONARY_CLASS:
case FuId.SORTED_DICTIONARY_CLASS:
+ case FuId.STRING_WRITER_CLASS:
case FuId.MATCH_CLASS:
case FuId.LOCK_CLASS:
return true;
@@ -10279,6 +10283,9 @@ export class GenC extends GenCCpp
case FuId.SORTED_DICTIONARY_CLASS:
this.#addListFree(FuId.SORTED_DICTIONARY_CLASS);
break;
+ case FuId.STRING_WRITER_CLASS:
+ this.#addListFree(FuId.STRING_WRITER_CLASS);
+ break;
case FuId.REGEX_CLASS:
this.#addListFree(FuId.REGEX_CLASS);
break;
@@ -10386,6 +10393,9 @@ export class GenC extends GenCCpp
case FuId.SORTED_DICTIONARY_CLASS:
this.write("g_tree_unref");
return false;
+ case FuId.STRING_WRITER_CLASS:
+ this.write("g_string_free");
+ return false;
case FuId.REGEX_CLASS:
this.write("g_regex_unref");
return false;
@@ -10506,6 +10516,9 @@ export class GenC extends GenCCpp
case FuId.SORTED_DICTIONARY_CLASS:
this.#writeNewTree(klass.getKeyType(), klass.getValueType());
break;
+ case FuId.STRING_WRITER_CLASS:
+ this.write("g_string_new(NULL)");
+ break;
default:
this.#sharedMake = true;
if (parent > FuPriority.MUL)
@@ -10532,6 +10545,7 @@ export class GenC extends GenCCpp
case FuId.SORTED_SET_CLASS:
case FuId.DICTIONARY_CLASS:
case FuId.SORTED_DICTIONARY_CLASS:
+ case FuId.STRING_WRITER_CLASS:
return true;
default:
return false;
@@ -10926,6 +10940,8 @@ export class GenC extends GenCCpp
this.write(", ");
this.#writeDictionaryDestroy(klass.getElementType());
}
+ else if (klass.class.id == FuId.STRING_WRITER_CLASS)
+ this.write(", TRUE");
this.writeLine(");");
this.indent -= nesting;
}
@@ -11331,42 +11347,65 @@ export class GenC extends GenCCpp
#writeTextWriterWrite(obj, args, newLine)
{
if (args.length == 0) {
- this.write("putc('\\n', ");
- obj.accept(this, FuPriority.ARGUMENT);
+ if (obj.type.asClassType().class.id == FuId.STRING_WRITER_CLASS) {
+ this.write("g_string_append_c(");
+ obj.accept(this, FuPriority.ARGUMENT);
+ this.write(", '\\n'");
+ }
+ else {
+ this.write("putc('\\n', ");
+ obj.accept(this, FuPriority.ARGUMENT);
+ }
this.writeChar(41);
}
else {
let interpolated;
if ((interpolated = args[0]) instanceof FuInterpolatedString) {
- this.write("fprintf(");
+ this.write(obj.type.asClassType().class.id == FuId.STRING_WRITER_CLASS ? "g_string_append_printf(" : "fprintf(");
obj.accept(this, FuPriority.ARGUMENT);
this.write(", ");
this.writePrintf(interpolated, newLine);
}
else if (args[0].type instanceof FuNumericType) {
- this.write("fprintf(");
+ this.write(obj.type.asClassType().class.id == FuId.STRING_WRITER_CLASS ? "g_string_append_printf(" : "fprintf(");
obj.accept(this, FuPriority.ARGUMENT);
this.write(", ");
this.writePrintfNotInterpolated(args, newLine);
}
else if (!newLine) {
- this.write("fputs(");
- args[0].accept(this, FuPriority.ARGUMENT);
- this.write(", ");
- obj.accept(this, FuPriority.ARGUMENT);
+ if (obj.type.asClassType().class.id == FuId.STRING_WRITER_CLASS) {
+ this.write("g_string_append(");
+ obj.accept(this, FuPriority.ARGUMENT);
+ this.write(", ");
+ args[0].accept(this, FuPriority.ARGUMENT);
+ }
+ else {
+ this.write("fputs(");
+ args[0].accept(this, FuPriority.ARGUMENT);
+ this.write(", ");
+ obj.accept(this, FuPriority.ARGUMENT);
+ }
this.writeChar(41);
}
else {
let literal;
if ((literal = args[0]) instanceof FuLiteralString) {
- this.write("fputs(");
- this.writeStringLiteralWithNewLine(literal.value);
- this.write(", ");
- obj.accept(this, FuPriority.ARGUMENT);
+ if (obj.type.asClassType().class.id == FuId.STRING_WRITER_CLASS) {
+ this.write("g_string_append(");
+ obj.accept(this, FuPriority.ARGUMENT);
+ this.write(", ");
+ this.writeStringLiteralWithNewLine(literal.value);
+ }
+ else {
+ this.write("fputs(");
+ this.writeStringLiteralWithNewLine(literal.value);
+ this.write(", ");
+ obj.accept(this, FuPriority.ARGUMENT);
+ }
this.writeChar(41);
}
else {
- this.write("fprintf(");
+ this.write(obj.type.asClassType().class.id == FuId.STRING_WRITER_CLASS ? "g_string_append_printf(" : "fprintf(");
obj.accept(this, FuPriority.ARGUMENT);
this.write(", \"%s\\n\", ");
args[0].accept(this, FuPriority.ARGUMENT);
@@ -11895,7 +11934,16 @@ export class GenC extends GenCCpp
this.#writeTextWriterWrite(obj, args, false);
break;
case FuId.TEXT_WRITER_WRITE_CHAR:
- this.writeCall("putc", args[0], obj);
+ if (obj.type.asClassType().class.id == FuId.STRING_WRITER_CLASS)
+ this.writeCall("g_string_append_c", obj, args[0]);
+ else
+ this.writeCall("putc", args[0], obj);
+ break;
+ case FuId.TEXT_WRITER_WRITE_CODE_POINT:
+ if (obj.type.asClassType().class.id != FuId.STRING_WRITER_CLASS)
+ this.notSupported(obj, method.name);
+ else
+ this.writeCall("g_string_append_unichar", obj, args[0]);
break;
case FuId.TEXT_WRITER_WRITE_LINE:
this.#writeTextWriterWrite(obj, args, true);
@@ -11906,6 +11954,14 @@ export class GenC extends GenCCpp
case FuId.CONSOLE_WRITE_LINE:
this.#writeConsoleWrite(args, true);
break;
+ case FuId.STRING_WRITER_CLEAR:
+ this.write("g_string_truncate(");
+ obj.accept(this, FuPriority.ARGUMENT);
+ this.write(", 0)");
+ break;
+ case FuId.STRING_WRITER_TO_STRING:
+ this.writePostfix(obj, "->str");
+ break;
case FuId.CONVERT_TO_BASE64_STRING:
this.#writeGlib("g_base64_encode(");
this.writeArrayPtrAdd(args[0], args[1]);
@@ -12252,6 +12308,8 @@ export class GenC extends GenCCpp
this.#writeDestructMethodName(owning);
this.writeChar(40);
statement.accept(this, FuPriority.ARGUMENT);
+ if (owning.class.id == FuId.STRING_WRITER_CLASS)
+ this.write(", TRUE");
this.writeLine(");");
this.cleanupTemporaries();
}
diff --git a/test/StringWriter.fu b/test/StringWriter.fu
index 3cc2872..8fc4b8e 100644
--- a/test/StringWriter.fu
+++ b/test/StringWriter.fu
@@ -2,17 +2,23 @@ public static class Test
{
public static bool Run()
{
- StringWriter() w; //FAIL: c d swift TODO; cl
+ StringWriter() w; //FAIL: d swift TODO; cl
w.Write("kill me");
w.Clear();
w.Write("Hello");
string s = "World";
w.Write(s);
+ long l = 5;
+#if C
+ w.Write(42);
+ w.Write(l);
+ w.Write('c');
+#else
TextWriter! tw = w; //FAIL: ts
tw.Write(42);
- long l = 5;
w.Write(l);
tw.Write('c');
+#endif
w.WriteChar('c');
return w.ToString() == "HelloWorld42599c";
}