Skip to content

Commit

Permalink
- Atualizado o exemplo de teste TesteUnidade.sl
Browse files Browse the repository at this point in the history
- Corrigido um problema na concatenação de strings com tipos numéricos quando o tipo da string é contado por referência.
  • Loading branch information
sharivan committed Sep 18, 2024
1 parent 10dfe24 commit 760233c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 19 deletions.
51 changes: 40 additions & 11 deletions Comp/Expr/CompilerBinaryExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -941,32 +941,61 @@ private AbstractType CompileBinaryExpression(Context context, Assembler assemble

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

CompileCast(context, rightAssembler, beforeRightAssembler, rightType, leftType, false, rightOperand.Interval, out rightCastTempVar);
}
else if (rightType is not StringType)
CompileCast(context, leftAssembler, beforeLeftAssembler, leftType, StringType.STRING, false, leftOperand.Interval, out var leftCastTempVar);

switch (rightType)
{
throw new CompilerException(rightOperand.Interval, $"Concatenação de strings não pode ser feita com o tipo '{rightType}'.");
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
{
var rightTempVar = context.AcquireTemporaryVariable(StringType.STRING, rightOperand.Interval);
beforeRightAssembler.EmitLoadLocalHostAddress(rightTempVar.Offset);

var func = rp.Primitive switch
{
Primitive.BOOL => unitySystem.FindFunction("BoolParaTexto"),
Primitive.CHAR => unitySystem.FindFunction("CharParaTexto"),
Primitive.BYTE or Primitive.SHORT or Primitive.INT => unitySystem.FindFunction("IntParaTexto"),
Primitive.LONG => unitySystem.FindFunction("LongParaTexto"),
Primitive.FLOAT => unitySystem.FindFunction("FloatParaTexto"),
Primitive.DOUBLE => unitySystem.FindFunction("DoubleParaTexto"),
_ => throw new CompilerException(rightOperand.Interval, "Operando inválido."),
};
int index = GetOrAddExternalFunction(func.Name, func.ParameterSize);
rightAssembler.EmitExternCall(index);
rightAssembler.EmitLoadLocalPtr(rightTempVar.Offset);
break;
}

case PointerType rptr:
{
if (!PrimitiveType.IsPrimitiveChar(rptr.Type))
throw new CompilerException(rightOperand.Interval, $"Concatenação de strings não pode ser feita com um ponteiro do tipo '{rptr.Type}'.");

CompileCast(context, rightAssembler, beforeRightAssembler, rightType, leftType, false, rightOperand.Interval, out rightCastTempVar);
break;
}

default:
throw new CompilerException(rightOperand.Interval, $"Concatenação de strings não pode ser feita com o tipo '{rightType}'.");
}

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

assembler.Emit(beforeLeftAssembler);
assembler.Emit(leftAssembler);
assembler.Emit(beforeRightAssembler);
assembler.Emit(rightAssembler);

rightCastTempVar?.Release();

var func = unitySystem.FindFunction("ConcatenaTextos2");
int index = GetOrAddExternalFunction(func.Name, func.ParameterSize);
assembler.EmitExternCall(index);
var concat = unitySystem.FindFunction("ConcatenaTextos2");
int concatIndex = GetOrAddExternalFunction(concat.Name, concat.ParameterSize);
assembler.EmitExternCall(concatIndex);

assembler.EmitLoadLocalPtr(tempVar.Offset);

Expand Down
15 changes: 7 additions & 8 deletions examples/TesteUnidades.sl
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,21 @@ usando Sorts;
{
// Teste da unidade padrão System:

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

escrevaln "ComprimentoString(\"", str, "\")=", ComprimentoString(str);
escrevaln "Tamanho do texto \"", str, "\" = ", str.tamanho;

var str2:char[16];
var str2:char[16]; // string estática
CopiaString("4567", str2);
var str2Int:int;
StringParaInt(str2, str2Int);
escrevaln "StringParaInt(\"", str2, "\")=", str2Int;

// saída esperada:
// "abcdefgh"+"1234567890"="abcdefgh1234567890"
// ComprimentoString("abcdefgh1234567890")=18;
// "abcdefgh" + "1234567890" = "abcdefgh1234567890"
// Tamanho do texto "abcdefgh1234567890" = 18;
// StringParaInt("4567")=4567

// Teste da unidade Sorts:
Expand Down

0 comments on commit 760233c

Please sign in to comment.