public override TranslationResult Translate(TranslationContext context) { var left = this.Left.Translate(new TranslationContext(context) { LValueNeeded = true }); var right = this.Right.Translate(context.ChangePurityContext(PurityContext.Purifiable)); List <Error> errors = CommonUtils.CombineErrors(left, right).ToList(); StatementsSequenceSilvernode sequence; if (left.ArraysContainer != null) { errors.AddRange(left.ArraysContainer.Errors); errors.AddRange(left.ArraysIndex.Errors); var arrayWrite = context.Process.ArraysTranslator.ArrayWrite(this.OriginalNode, left.ArraysContainer.Silvernode, left.ArraysIndex.Silvernode, right.Silvernode); sequence = new StatementsSequenceSilvernode(null, right.PrependTheseSilvernodes.Concat(new[] { arrayWrite }).ToArray()); } else { var assignment = new AssignmentSilvernode(left.Silvernode, right.Silvernode, this.OriginalNode); sequence = new StatementsSequenceSilvernode(null, right.PrependTheseSilvernodes.Concat(new[] { assignment }).ToArray()); } return(TranslationResult.FromSilvernode(sequence, errors)); }
public override TranslationResult Translate(TranslationContext context) { var symbol = context.Semantics.GetDeclaredSymbol(this.variable); var identifier = context.Process.IdentifierTranslator.RegisterAndGetIdentifier(symbol); Error err; List <Error> errors = new List <Error>(); VarStatementSilvernode intro = new VarStatementSilvernode(identifier, TypeTranslator.TranslateType( context.Semantics.GetSymbolInfo(this.typeSyntax).Symbol as ITypeSymbol, this.typeSyntax, out err), this.OriginalNode); if (err != null) { errors.Add(err); } if (this.initialValue == null) { return(TranslationResult.FromSilvernode(intro, errors)); } // Add assignment if there is an initial value. var res = this.initialValue.Translate(context.ChangePurityContext(PurityContext.Purifiable)); AssignmentSilvernode assignmentSilvernode = new AssignmentSilvernode(new IdentifierSilvernode(identifier), res.Silvernode, this.OriginalNode); errors.AddRange(res.Errors); return(TranslationResult.FromSilvernode(new StatementsSequenceSilvernode(this.OriginalNode, intro, new StatementsSequenceSilvernode(null, res.PrependTheseSilvernodes.ToArray()), assignmentSilvernode), errors)); }
/// <summary> /// This is called when an invocation sharpnode determines that this silvernode must be a statement in Viper code; this method /// then, if in <see cref="PurityContext.PureOrFail"/> context, changes this result into an error; or, if in <see cref="PurityContext.Purifiable"/> /// context, moves this result's <see cref="Silvernode"/> to <see cref="PrependTheseSilvernodes"/> and performs the prepending. /// </summary> /// <param name="context">The context.</param> /// <param name="type">The Silver type of this silvernode.</param> /// <param name="impurityReason">The reason why this silvernode must be a statement.</param> internal void AsImpureAssertion(TranslationContext context, SilverType type, string impurityReason) { switch (context.PurityContext) { case PurityContext.PureOrFail: this.Errors.Add(new Error(Diagnostics.SSIL114_NotPureContext, this.Silvernode.OriginalNode, impurityReason)); break; case PurityContext.Purifiable: var newTempVar = context.Process.IdentifierTranslator.RegisterNewUniqueIdentifier(); VarStatementSilvernode v = new VarStatementSilvernode(newTempVar, type, null); AssignmentSilvernode a = new AssignmentSilvernode(new IdentifierSilvernode(newTempVar), this.Silvernode, null); this.PrependTheseSilvernodes.Add(v); this.PrependTheseSilvernodes.Add(a); this.Silvernode = new IdentifierSilvernode(newTempVar); break; case PurityContext.PurityNotRequired: break; } }