Add: string concatenation#963
Conversation
|
@bocchino Can you review the plan and share feedback, please? Also do we need to add |
| _ <- e.op match { | ||
| case Ast.Binop.Add => t match { | ||
| case _: Type.String => Right(t) | ||
| case _ => convertToNumeric(loc, t) |
There was a problem hiding this comment.
We may need a new function convertToNumericOrString here. Otherwise the error message could be misleading. For example, if you try to add two things that are not numbers or strings, it will suggest that you can only add numbers.
I think we should extend the definition of value addition here: https://github.com/nasa/fpp/blob/main/compiler/lib/src/main/scala/analysis/Semantics/Value.scala. And test it here: https://github.com/nasa/fpp/blob/main/compiler/lib/src/test/scala/semantics/ValueSpec.scala. I think that may be enough functional testing on the FPP side. We could also add a functional test to FppTest in nasa/fprime. |
The plan looks good so far, but it is not complete. The plan should include the following high-level steps (from the new features wiki):
|
|
I understand, thanks for your review; Work to do 🚀 |
|
@bocchino
I have identified the following changes in spec:
Not necessary here since syntax was not modified.
I reviewed the analysis on the wiki and discovered no need to update it.
Implemented at compiler/lib/src/main/scala/analysis/Semantics/Value.scala and tested at compiler/lib/src/test/scala/semantics/ValueSpec.scala
I'm a little confused about this one; one solution is to update and extend section 3.3.2 to provide a guide to the updated semantics. Another option is to create a new section 3.3.3 -> String Concatenation, which would necessitate changes to the subsequent sections. I do not believe this could be implemented in Section 3.3.8 Value Arithmetic Expressions. |
Updated with clean function definition @@ -159,7 +159,10 @@ object CheckExprTypes extends UseAnalyzer {
for {
a <- super.exprBinopNode(a, node, e)
t <- a.commonType(e.e1.id, e.e2.id, loc)
- _ <- convertToNumeric(loc, t)
+ _ <- e.op match {
+ case Ast.Binop.Add => convertToNumericOrString(loc, t)
+ case _ => convertToNumeric(loc, t)
+ }
} yield a.assignType(node -> t)
}
@@ -469,5 +472,13 @@ object CheckExprTypes extends UseAnalyzer {
Left(error)
}
}
-
+
+ private def convertToNumericOrString(loc: Location, t: Type): Result.Result[Type] = {
+ t match {
+ case _: Type.String => Right(t)
+ case _ if t.isNumeric => Right(t)
+ case _ if t.isConvertibleTo(Type.Integer) => Right(Type.Integer)
+ case _ => Left(SemanticError.InvalidType(loc, s"cannot convert $t to a numeric or string type"))
+ }
+ }
} |
…ort string additions
…sages when adding with string
|
Forced push since had to rebase to keep latest docs |
To resolve docs conflicts, generally you should regenerate the docs. That way the updated docs will include your changes and the upstream changes. |
It looks like we may still need fpp-check tests to cover the error case(s). |
I agree this isn't value arithmetic. Can we add a new section 3.3.9. String Concatenation? It looks a lot like value arithmetic, so it makes sense to have that section follow section 3.3.8. I think it shouldn't go 3.3.2, because that section just covers literal string values. If you add the new section and regenerate the docs, then the current 3.3.9 will automatically be renumbered to 3.3.10. |
|
Hey @bocchino, I have implemented the changes you asked for. Could you please review them? |
|
I have noticed that in final def +(v: Value) = {
def intOp(v1: BigInt, v2: BigInt) = v1 + v2
def doubleOp(v1: Double, v2: Double) = v1 + v2
binop(Value.Binop(intOp, doubleOp))(v)
}And Value.String.binop is: override def binop(op: Binop)(v: Value) = v match {
case String(value2) => Some(String(value + value2))
case _ => None
}This would mean String.binop would work for any operator like
|
Based on the discussions in #954
Added:
String concatenation
Stringtype.Concatenation Tests:
fpp-check.Spec Tasks
+means string concatenation+sign on strings+operator.defs.shto includeString-Concatenation-Expression.adocRevised Tasks:
convertToNumericOrString. This will fix misleading error messages when adding to strings.lib/src/main/scala/analysis/Semantics/Value.scalaand tested inlib/src/test/scala/semantics/ValueSpec.scala