Skip to content

Commit 760233c

Browse files
committed
- Atualizado o exemplo de teste TesteUnidade.sl
- Corrigido um problema na concatenação de strings com tipos numéricos quando o tipo da string é contado por referência.
1 parent 10dfe24 commit 760233c

File tree

2 files changed

+47
-19
lines changed

2 files changed

+47
-19
lines changed

Comp/Expr/CompilerBinaryExpression.cs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -941,32 +941,61 @@ private AbstractType CompileBinaryExpression(Context context, Assembler assemble
941941

942942
case StringType:
943943
{
944+
Assembler beforeLeftAssembler = new();
944945
Assembler beforeRightAssembler = new();
945946
Variable rightCastTempVar = null;
946-
if (rightType is PointerType rptr)
947-
{
948-
if (!PrimitiveType.IsPrimitiveChar(rptr.Type))
949-
throw new CompilerException(rightOperand.Interval, $"Concatenação de strings não pode ser feita com um ponteiro do tipo '{rptr.Type}'.");
950947

951-
CompileCast(context, rightAssembler, beforeRightAssembler, rightType, leftType, false, rightOperand.Interval, out rightCastTempVar);
952-
}
953-
else if (rightType is not StringType)
948+
CompileCast(context, leftAssembler, beforeLeftAssembler, leftType, StringType.STRING, false, leftOperand.Interval, out var leftCastTempVar);
949+
950+
switch (rightType)
954951
{
955-
throw new CompilerException(rightOperand.Interval, $"Concatenação de strings não pode ser feita com o tipo '{rightType}'.");
952+
case PrimitiveType rp: // Concatenação de uma string com um tipo primitivo, isso exige a conversão do primitivo para string para então realizar a concatenação
953+
{
954+
var rightTempVar = context.AcquireTemporaryVariable(StringType.STRING, rightOperand.Interval);
955+
beforeRightAssembler.EmitLoadLocalHostAddress(rightTempVar.Offset);
956+
957+
var func = rp.Primitive switch
958+
{
959+
Primitive.BOOL => unitySystem.FindFunction("BoolParaTexto"),
960+
Primitive.CHAR => unitySystem.FindFunction("CharParaTexto"),
961+
Primitive.BYTE or Primitive.SHORT or Primitive.INT => unitySystem.FindFunction("IntParaTexto"),
962+
Primitive.LONG => unitySystem.FindFunction("LongParaTexto"),
963+
Primitive.FLOAT => unitySystem.FindFunction("FloatParaTexto"),
964+
Primitive.DOUBLE => unitySystem.FindFunction("DoubleParaTexto"),
965+
_ => throw new CompilerException(rightOperand.Interval, "Operando inválido."),
966+
};
967+
int index = GetOrAddExternalFunction(func.Name, func.ParameterSize);
968+
rightAssembler.EmitExternCall(index);
969+
rightAssembler.EmitLoadLocalPtr(rightTempVar.Offset);
970+
break;
971+
}
972+
973+
case PointerType rptr:
974+
{
975+
if (!PrimitiveType.IsPrimitiveChar(rptr.Type))
976+
throw new CompilerException(rightOperand.Interval, $"Concatenação de strings não pode ser feita com um ponteiro do tipo '{rptr.Type}'.");
977+
978+
CompileCast(context, rightAssembler, beforeRightAssembler, rightType, leftType, false, rightOperand.Interval, out rightCastTempVar);
979+
break;
980+
}
981+
982+
default:
983+
throw new CompilerException(rightOperand.Interval, $"Concatenação de strings não pode ser feita com o tipo '{rightType}'.");
956984
}
957985

958986
tempVar = context.AcquireTemporaryVariable(StringType.STRING, expression.Interval);
959987
assembler.EmitLoadLocalHostAddress(tempVar.Offset);
960988

989+
assembler.Emit(beforeLeftAssembler);
961990
assembler.Emit(leftAssembler);
962991
assembler.Emit(beforeRightAssembler);
963992
assembler.Emit(rightAssembler);
964993

965994
rightCastTempVar?.Release();
966995

967-
var func = unitySystem.FindFunction("ConcatenaTextos2");
968-
int index = GetOrAddExternalFunction(func.Name, func.ParameterSize);
969-
assembler.EmitExternCall(index);
996+
var concat = unitySystem.FindFunction("ConcatenaTextos2");
997+
int concatIndex = GetOrAddExternalFunction(concat.Name, concat.ParameterSize);
998+
assembler.EmitExternCall(concatIndex);
970999

9711000
assembler.EmitLoadLocalPtr(tempVar.Offset);
9721001

examples/TesteUnidades.sl

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,21 @@ usando Sorts;
55
{
66
// Teste da unidade padrão System:
77

8-
var str:char[256];
9-
CopiaString("abcdefgh", str);
10-
ConcatenaStrings(str, str, "1234567890");
11-
escrevaln "\"abcdefgh\"+\"1234567890\"=\"", str, '"';
8+
var str:texto = "abcdefgh"; // string dinâmica contada por referência
9+
str = str + 1234567890; // concatenação de string com tipos numéricos
10+
escrevaln "\"abcdefgh\" + \"1234567890\" = \"", str, '"';
1211

13-
escrevaln "ComprimentoString(\"", str, "\")=", ComprimentoString(str);
12+
escrevaln "Tamanho do texto \"", str, "\" = ", str.tamanho;
1413

15-
var str2:char[16];
14+
var str2:char[16]; // string estática
1615
CopiaString("4567", str2);
1716
var str2Int:int;
1817
StringParaInt(str2, str2Int);
1918
escrevaln "StringParaInt(\"", str2, "\")=", str2Int;
2019

2120
// saída esperada:
22-
// "abcdefgh"+"1234567890"="abcdefgh1234567890"
23-
// ComprimentoString("abcdefgh1234567890")=18;
21+
// "abcdefgh" + "1234567890" = "abcdefgh1234567890"
22+
// Tamanho do texto "abcdefgh1234567890" = 18;
2423
// StringParaInt("4567")=4567
2524

2625
// Teste da unidade Sorts:

0 commit comments

Comments
 (0)