Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use native byte/char arrays in Go #2818

Merged
merged 90 commits into from
Jan 25, 2023
Merged
Show file tree
Hide file tree
Changes from 86 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
fd573f8
chore: Improve formatting
RustanLeino Sep 24, 2022
0593726
Change Array from a struct to an interface in Go
RustanLeino Sep 24, 2022
d398d89
fix: Cast to non-box type after let in Java
RustanLeino Sep 24, 2022
310fca6
fix: Comparison of arrays in JavaScript
RustanLeino Sep 24, 2022
9a5da01
fix: Add needed casts in C#
RustanLeino Sep 26, 2022
ed1c1d6
Add tests
RustanLeino Sep 24, 2022
06232a3
Improve EqualsGeneric for ArrayStruct
RustanLeino Sep 26, 2022
6dc48fc
Further improve NewValue…
RustanLeino Sep 26, 2022
37e7c2e
Add more tests
RustanLeino Sep 26, 2022
b7160e1
Improve NewArray… methods further
RustanLeino Sep 26, 2022
7e1adf7
Change “interface{}” to its alias “any” in Go
RustanLeino Sep 26, 2022
ca2205d
chore: Remove unused method
RustanLeino Sep 26, 2022
e6cb5b5
Remove a use of EmitArraySelectAsLvalue
RustanLeino Sep 26, 2022
91b44b3
Remove another use of EmitArraySelectAsLvalue
RustanLeino Sep 26, 2022
c3f810a
Make EmitArrayUpdate return RHS wr rather than take RHS as parameter
RustanLeino Sep 26, 2022
8fb3c25
Replace EmitArraySelectAsLvalue by ArrayLvalueImpl
RustanLeino Sep 26, 2022
a15454a
Replace ArrayIndex pointers with Set/Get
RustanLeino Sep 27, 2022
4b841ae
Remove unused runtime routines
RustanLeino Sep 27, 2022
254100f
Change dims() into dimensionCount()/dimensionLength()
RustanLeino Sep 27, 2022
3b9086c
Move Get1/Set1 into Array interface
RustanLeino Sep 27, 2022
af8c60d
Use ArraySet1 instead of ArrayUpdate
RustanLeino Sep 27, 2022
6bb4e63
Remove contents() from Array interface
RustanLeino Sep 27, 2022
e792511
fix: Print array-display size as given in program
RustanLeino Sep 28, 2022
bf6eeeb
Improve C# array-size run-time checking
RustanLeino Sep 28, 2022
a883bd8
Add exampleElement parameter to EmitNewArray
RustanLeino Sep 28, 2022
c12c102
Create Go arrays using example element
RustanLeino Sep 28, 2022
d8940f6
Add start parameter to CreateForLoop
RustanLeino Sep 28, 2022
8246df6
Change virtual EmitNewArray to take strings instead of Expressions
RustanLeino Sep 28, 2022
1482bfd
Rework new-array with init-funciton to support example
RustanLeino Sep 28, 2022
5bda65d
Add tests for more array types
RustanLeino Sep 28, 2022
7fbf35c
Add tests for 2-dimensional arrays
RustanLeino Sep 28, 2022
7cf4641
fix: Select tightest integer bound among IntBoundedPool’s
RustanLeino Sep 28, 2022
c1b5563
Clean up Array interface
RustanLeino Sep 28, 2022
de94752
Specialize array representation for byte and char
RustanLeino Sep 28, 2022
aebdbef
fix: Fix enumerations of long Java values
RustanLeino Sep 29, 2022
fe341f0
chore: Rename EmitExprAsInt to EmitExprAsNativeInt
RustanLeino Sep 30, 2022
669d189
chore: Add Type parameter to CreateIntLiteral/CreateDecrement
RustanLeino Sep 30, 2022
1631b31
Remove Type parameter from ArrayIndexToInt method
RustanLeino Sep 30, 2022
9e6655d
Add virtual ArrayIndexLiteral method
RustanLeino Sep 30, 2022
2a6b744
Add/improve comments
RustanLeino Sep 30, 2022
5007e25
Add virtual ExprToInt method
RustanLeino Sep 30, 2022
453aba3
fix: Don’t share inner arrays in arrays with 3 or more dimensions
RustanLeino Sep 30, 2022
fb1265d
Tidy up target types of array indices
RustanLeino Sep 30, 2022
452feb0
Reduce boxing across array Get/Set for byte/char
RustanLeino Sep 30, 2022
449eb02
Merge branch 'master' into go-array-refresh
RustanLeino Sep 30, 2022
2975fa8
Fix merge
RustanLeino Sep 30, 2022
df0536f
Add release notes
RustanLeino Sep 30, 2022
7529154
chore: Code improvements
RustanLeino Sep 30, 2022
1756f9a
Follow up on Python support from PR #2742
RustanLeino Sep 30, 2022
4d40379
Add other targets to test
RustanLeino Sep 30, 2022
5e4d38a
Merge branch 'master' into go-array-refresh
RustanLeino Sep 30, 2022
b389f2a
Update Source/DafnyCore/Compilers/Compiler-python.cs
RustanLeino Oct 10, 2022
57c77a3
Update Source/DafnyRuntime/DafnyRuntime.py
RustanLeino Oct 10, 2022
e947e0b
Update Source/DafnyRuntime/DafnyRuntime.py
RustanLeino Oct 10, 2022
a9f57b8
Update Source/DafnyRuntime/DafnyRuntime.py
RustanLeino Oct 10, 2022
83c200d
Update Source/DafnyRuntime/DafnyRuntime.py
RustanLeino Oct 10, 2022
23c6040
Act on reviewer comments for Python
RustanLeino Oct 10, 2022
dea64da
Merge branch 'master' into go-array-refresh
RustanLeino Oct 10, 2022
8b34ea0
Fix code formatting
RustanLeino Oct 10, 2022
723dd86
Reverse use of “any” to the older “interface{}” in Go
RustanLeino Oct 26, 2022
a4acb70
Merge branch 'master' into go-array-refresh
RustanLeino Oct 26, 2022
5aa8360
Merge branch 'master' into go-array-refresh
RustanLeino Nov 24, 2022
43947ed
Merge branch 'master' into go-array-refresh
RustanLeino Nov 29, 2022
f341c12
Merge branch 'master' into go-array-refresh
RustanLeino Nov 29, 2022
855627f
Change a last occurrence of “any” to “interface{}” for Go
RustanLeino Nov 29, 2022
71e791a
Merge branch 'master' into go-array-refresh
RustanLeino Dec 15, 2022
82399d9
Mention a fixed issue
RustanLeino Dec 16, 2022
e96af9b
Add tests for another fixed issue
RustanLeino Dec 16, 2022
84137fb
Point out file issue in a test file
RustanLeino Dec 16, 2022
9015d2f
Merge branch 'master' into go-array-refresh
RustanLeino Dec 16, 2022
362dbe9
Act on PR comments
RustanLeino Dec 16, 2022
a5d2c22
Merge branch 'master' into go-array-refresh
RustanLeino Dec 16, 2022
f9349af
Optimize Go arrays for CodePoint
RustanLeino Dec 16, 2022
a2d8340
fix: Type descriptors and default values of Unicode char for C#
RustanLeino Dec 17, 2022
e842bfc
fix: Default value of unicode char for JavaScript
RustanLeino Dec 17, 2022
e5ee2aa
Big cop-out: Java unicode boxing/unboxing not yet working
RustanLeino Dec 17, 2022
b9b7831
Some unicode fixes, and giving up on Java and Python
RustanLeino Dec 17, 2022
5069cee
Merge branch 'master' into go-array-refresh
RustanLeino Dec 17, 2022
027e17c
Export only Array, not ArrayStruct, ArrayForByte, …
RustanLeino Dec 19, 2022
8cc0b87
Merge branch 'master' into go-array-refresh
RustanLeino Dec 19, 2022
3a8c6fe
Merge branch 'master' into go-array-refresh
robin-aws Jan 6, 2023
6835539
Ensure isStr inference is disabled in more cases for —unicode-char in…
robin-aws Jan 8, 2023
93720cc
Merge branch 'go-array-refresh' of github.com:RustanLeino/dafny into …
robin-aws Jan 8, 2023
3522080
Merge branch 'master' into go-array-refresh
atomb Jan 17, 2023
bcd2f04
Enabling Python in —unicode-char versino of Arrays.dfy
robin-aws Jan 19, 2023
0353ee3
Merge branch 'master' into go-array-refresh
robin-aws Jan 19, 2023
57b80d0
Overload + and - on CodePoint instead
robin-aws Jan 20, 2023
ec525c9
None and None == None
robin-aws Jan 20, 2023
d332ca3
Apply suggestions from code review
robin-aws Jan 20, 2023
41bad87
Merge branch 'master' into go-array-refresh
robin-aws Jan 25, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion Source/DafnyCore/AST/Expressions/ComprehensionExpr.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Linq;
using JetBrains.Annotations;

namespace Microsoft.Dafny;

Expand Down Expand Up @@ -89,13 +91,32 @@ public static BoundedPool GetBest(List<BoundedPool> bounds, PoolVirtues required
BoundedPool best = null;
foreach (var bound in bounds) {
if ((bound.Virtues & requiredVirtues) == requiredVirtues) {
if (best == null || bound.Preference() > best.Preference()) {
if (best is IntBoundedPool ibp0 && bound is IntBoundedPool ibp1) {
best = new IntBoundedPool(
ChooseBestIntegerBound(ibp0.LowerBound, ibp1.LowerBound, true),
ChooseBestIntegerBound(ibp0.UpperBound, ibp1.UpperBound, false));
} else if (best == null || bound.Preference() > best.Preference()) {
best = bound;
}
}
}
return best;
}

[CanBeNull]
static Expression ChooseBestIntegerBound([CanBeNull] Expression a, [CanBeNull] Expression b, bool pickMax) {
if (a == null || b == null) {
return a ?? b;
}

if (Expression.IsIntLiteral(Expression.StripParensAndCasts(a), out var aa) &&
Expression.IsIntLiteral(Expression.StripParensAndCasts(b), out var bb)) {
var x = pickMax ? BigInteger.Max(aa, bb) : BigInteger.Min(aa, bb);
return new LiteralExpr(a.tok, x) { Type = a.Type };
}
return a; // we don't know how to determine which of "a" or "b" is better, so we'll just return "a"
}

public static List<VT> MissingBounds<VT>(List<VT> vars, List<BoundedPool> bounds, PoolVirtues requiredVirtues = PoolVirtues.None) where VT : IVariable {
Contract.Requires(vars != null);
Contract.Requires(bounds == null || vars.Count == bounds.Count);
Expand Down
54 changes: 45 additions & 9 deletions Source/DafnyCore/AST/Expressions/Expressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void ObjectInvariant() {
Contract.Invariant(tok != null);
}

[Pure]
[System.Diagnostics.Contracts.Pure]
public bool WasResolved() {
return Type != null;
}
Expand Down Expand Up @@ -343,30 +343,30 @@ public static Expression CreateIncrement(Expression e, int n) {
/// <summary>
/// Create a resolved expression of the form "e - n"
/// </summary>
public static Expression CreateDecrement(Expression e, int n) {
public static Expression CreateDecrement(Expression e, int n, Type ty = null) {
Contract.Requires(e != null);
Contract.Requires(e.Type.IsNumericBased(Type.NumericPersuasion.Int));
Contract.Requires(0 <= n);
Contract.Ensures(Contract.Result<Expression>() != null);
if (n == 0) {
return e;
}
var nn = CreateIntLiteral(e.tok, n);
var nn = CreateIntLiteral(e.tok, n, ty);
return CreateSubtract(e, nn);
}

/// <summary>
/// Create a resolved expression of the form "n"
/// </summary>
public static Expression CreateIntLiteral(IToken tok, int n) {
public static Expression CreateIntLiteral(IToken tok, int n, Type ty = null) {
Contract.Requires(tok != null);
Contract.Requires(n != int.MinValue);
if (0 <= n) {
var nn = new LiteralExpr(tok, n);
nn.Type = Type.Int;
nn.Type = ty ?? Type.Int;
return nn;
} else {
return CreateDecrement(CreateIntLiteral(tok, 0), -n);
return CreateDecrement(CreateIntLiteral(tok, 0, ty), -n, ty);
}
}

Expand Down Expand Up @@ -427,6 +427,22 @@ public static Expression StripParens(Expression expr) {
}
}

/// <summary>
/// Returns "expr", but with all outer layers of parentheses and casts removed.
/// This method can be called before resolution.
/// </summary>
public static Expression StripParensAndCasts(Expression expr) {
while (true) {
if (expr is ParensExpression parens) {
expr = parens.E;
} else if (expr is ConversionExpr cast) {
expr = cast.E;
} else {
return expr;
}
}
}

public static ThisExpr AsThis(Expression expr) {
Contract.Requires(expr != null);
return StripParens(expr) as ThisExpr;
Expand All @@ -449,6 +465,26 @@ public static bool IsBoolLiteral(Expression expr, out bool value) {
}
}

/// <summary>
/// If "expr" denotes an integer literal "x", then return "true" and set "value" to "x".
/// Otherwise, return "false" (and the value of "value" should not be used by the caller).
/// This method can be called before resolution.
/// </summary>
public static bool IsIntLiteral(Expression expr, out BigInteger value) {
Contract.Requires(expr != null);
var e = StripParens(expr) as LiteralExpr;
if (e != null && e.Value is int x) {
value = new BigInteger(x);
return true;
} else if (e != null && e.Value is BigInteger xx) {
value = xx;
return true;
} else {
value = BigInteger.Zero; // to please compiler
return false;
}
}

/// <summary>
/// Returns "true" if "expr" denotes the empty set (for "iset", "set", or "multiset").
/// This method can be called before resolution.
Expand Down Expand Up @@ -801,7 +837,7 @@ public class LiteralExpr : Expression {
/// </summary>
public readonly object Value;

[Pure]
[System.Diagnostics.Contracts.Pure]
public static bool IsTrue(Expression e) {
Contract.Requires(e != null);
return Expression.IsBoolLiteral(e, out var value) && value;
Expand Down Expand Up @@ -1129,7 +1165,7 @@ public override Type ReplaceTypeArguments(List<Type> arguments) {
}
}
public class ResolverType_Module : ResolverType {
[Pure]
[System.Diagnostics.Contracts.Pure]
public override string TypeName(ModuleDefinition context, bool parseAble) {
Contract.Assert(parseAble == false);
return "#module";
Expand All @@ -1139,7 +1175,7 @@ public override bool Equals(Type that, bool keepConstraints = false) {
}
}
public class ResolverType_Type : ResolverType {
[Pure]
[System.Diagnostics.Contracts.Pure]
public override string TypeName(ModuleDefinition context, bool parseAble) {
Contract.Assert(parseAble == false);
return "#type";
Expand Down
6 changes: 2 additions & 4 deletions Source/DafnyCore/AST/Printer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1835,11 +1835,9 @@ void PrintRhs(AssignmentRhs rhs) {
if (ShowType(t.EType)) {
PrintType(t.EType);
}
var dim0 = t.ArrayDimensions[0] as LiteralExpr;
if (DafnyOptions.O.DafnyPrintResolvedFile == null &&
t.InitDisplay != null &&
t.ArrayDimensions.Count == 1 && dim0.Value is BigInteger &&
(BigInteger)dim0.Value == new BigInteger(t.InitDisplay.Count)) {
t.InitDisplay != null && t.ArrayDimensions.Count == 1 &&
AutoGeneratedToken.Is(t.ArrayDimensions[0].tok)) {
// elide the size
wr.Write("[]");
} else {
Expand Down
60 changes: 27 additions & 33 deletions Source/DafnyCore/Compilers/Compiler-Csharp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,7 @@ internal override string TypeName(Type type, ConcreteSyntaxTree wr, IToken tok,
// To improve readability
private static bool CharIsRune => UnicodeCharEnabled;
private static string CharTypeName => UnicodeCharEnabled ? "Dafny.Rune" : "char";
private static string CharTypeDescriptorName => DafnyHelpersClass + (UnicodeCharEnabled ? ".RUNE" : ".CHAR");

private void ConvertFromChar(Expression e, ConcreteSyntaxTree wr, bool inLetExprBody, ConcreteSyntaxTree wStmts) {
if (e.Type.IsCharType && UnicodeCharEnabled) {
Expand Down Expand Up @@ -1529,7 +1530,7 @@ protected override string TypeInitializationValue(Type type, ConcreteSyntaxTree
if (xType is BoolType) {
return "false";
} else if (xType is CharType) {
return CharType.DefaultValueAsString;
return UnicodeCharEnabled ? $"new {CharTypeName}({CharType.DefaultValueAsString})" : CharType.DefaultValueAsString;
} else if (xType is IntType || xType is BigOrdinalType) {
return "BigInteger.Zero";
} else if (xType is RealType) {
Expand Down Expand Up @@ -1650,7 +1651,7 @@ protected override string TypeDescriptor(Type type, ConcreteSyntaxTree wr, IToke
if (type is BoolType) {
return "Dafny.Helpers.BOOL";
} else if (type is CharType) {
return "Dafny.Helpers.CHAR";
return CharTypeDescriptorName;
} else if (type is IntType || type is BigOrdinalType) {
return "Dafny.Helpers.INT";
} else if (type is RealType) {
Expand Down Expand Up @@ -1930,8 +1931,9 @@ protected override ConcreteSyntaxTree EmitForStmt(IToken tok, IVariable loopInde
return startWr;
}

protected override ConcreteSyntaxTree CreateForLoop(string indexVar, string bound, ConcreteSyntaxTree wr) {
return wr.NewNamedBlock("for (var {0} = 0; {0} < {1}; {0}++)", indexVar, bound);
protected override ConcreteSyntaxTree CreateForLoop(string indexVar, string bound, ConcreteSyntaxTree wr, string start = null) {
start = start ?? "0";
return wr.NewNamedBlock("for (var {0} = {2}; {0} < {1}; {0}++)", indexVar, bound, start);
}

protected override ConcreteSyntaxTree CreateDoublingForLoop(string indexVar, int start, ConcreteSyntaxTree wr) {
Expand Down Expand Up @@ -2000,37 +2002,30 @@ protected override void EmitNew(Type type, IToken tok, CallStmt initCall /*?*/,
arguments.Write(ConstructorArguments(initCall, wStmts, ctor, sep));
}

// if checkRange is false, msg is ignored
// if checkRange is true and msg is null and the value is out of range, a generic message is emitted
// if checkRange is true and msg is not null and the value is out of range, msg is emitted in the error message
protected void TrExprAsInt(Expression expr, ConcreteSyntaxTree wr, bool inLetExprBody, ConcreteSyntaxTree wStmts,
bool checkRange = false, string msg = null) {
wr.Write($"{GetHelperModuleName()}.ToIntChecked(");
TrExpr(expr, wr, inLetExprBody, wStmts);
if (checkRange) {
wr.Write(msg == null ? ", null" : $", \"{msg}\")");
}
}

protected override void EmitNewArray(Type elmtType, IToken tok, List<Expression> dimensions,
bool mustInitialize, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts) {
var wrs = EmitNewArray(elmtType, tok, dimensions.Count, mustInitialize, wr);
protected override void EmitNewArray(Type elementType, IToken tok, List<string> dimensions,
bool mustInitialize, [CanBeNull] string exampleElement, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts) {
var wrs = EmitNewArray(elementType, tok, dimensions.Count, mustInitialize, wr);
for (var i = 0; i < wrs.Count; i++) {
TrExprAsInt(dimensions[i], wrs[i], inLetExprBody: false, wStmts, true, "C# arrays may not be larger than the max 32-bit integer");
wrs[i].Write(dimensions[i]);
}
}

private List<ConcreteSyntaxTree> EmitNewArray(Type elmtType, IToken tok, int dimCount, bool mustInitialize, ConcreteSyntaxTree wr) {
ConcreteSyntaxTree EmitSizeCheckWrapper(ConcreteSyntaxTree w) {
w.Write($"{DafnyHelpersClass}.ToIntChecked(");
var wSize = w.Fork();
w.Write(", \"array size exceeds memory limit\")");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm already happy that we've abstracted away from "C# array size must not be larger than max 32-bit int" to this more general message, but it still implies that we're actually out of memory, or above a configured limit, when that's not actually true. Perhaps "array size exceeds supported maximum" instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make this change consistently for all the compilers. That is, I think we should decide on such a maximum limit for each target (either 31, 32, 63, or 64 bits, or unlimited). Then, the compilers can always use the corresponding native word size for array sizes and indices. I suggest this be done as a separate PR. I filed Issue #3212 to track this.

return wSize;
}

var wrs = new List<ConcreteSyntaxTree>();
if (!mustInitialize || HasSimpleZeroInitializer(elmtType)) {
TypeName_SplitArrayName(elmtType, wr, tok, out string typeNameSansBrackets, out string brackets);
wr.Write("new {0}", typeNameSansBrackets);
string prefix = "[";
for (var d = 0; d < dimCount; d++) {
wr.Write($"{prefix}{DafnyHelpersClass}.ToIntChecked(");
var w = wr.Fork();
wrs.Add(w);
wr.Write(",\"C# array size must not be larger than max 32-bit int\")");
wr.Write(prefix);
wrs.Add(EmitSizeCheckWrapper(wr));
prefix = ", ";
}
wr.Write("]{0}", brackets);
Expand All @@ -2040,8 +2035,7 @@ private List<ConcreteSyntaxTree> EmitNewArray(Type elmtType, IToken tok, int dim
inParens.Write(DefaultValue(elmtType, inParens, tok, true));
for (var d = 0; d < dimCount; d++) {
inParens.Write(", ");
var w = inParens.Fork();
wrs.Add(w);
wrs.Add(EmitSizeCheckWrapper(inParens));
}
}
return wrs;
Expand Down Expand Up @@ -2109,9 +2103,10 @@ protected override void EmitLiteralExpr(ConcreteSyntaxTree wr, LiteralExpr e) {
} else if (e is StringLiteralExpr str) {
wr.Format($"{DafnySeqClass}<{CharTypeName}>.{CharMethodQualifier}FromString({StringLiteral(str)})");
} else if (AsNativeType(e.Type) != null) {
string nativeName = null, literalSuffix = null;
bool needsCastAfterArithmetic = false;
GetNativeInfo(AsNativeType(e.Type).Sel, out nativeName, out literalSuffix, out needsCastAfterArithmetic);
GetNativeInfo(AsNativeType(e.Type).Sel, out var nativeName, out var literalSuffix, out var needsCastAfterArithmetic);
if (needsCastAfterArithmetic) {
wr = wr.Write($"({nativeName})").ForkInParens();
}
wr.Write((BigInteger)e.Value + literalSuffix);
} else if (e.Value is BigInteger bigInteger) {
EmitIntegerLiteral(bigInteger, wr);
Expand Down Expand Up @@ -2159,9 +2154,8 @@ protected override void EmitStringLiteral(string str, bool isVerbatim, ConcreteS

protected override ConcreteSyntaxTree EmitBitvectorTruncation(BitvectorType bvType, bool surroundByUnchecked, ConcreteSyntaxTree wr) {
string nativeName = null, literalSuffix = null;
bool needsCastAfterArithmetic = false;
if (bvType.NativeType != null) {
GetNativeInfo(bvType.NativeType.Sel, out nativeName, out literalSuffix, out needsCastAfterArithmetic);
GetNativeInfo(bvType.NativeType.Sel, out nativeName, out literalSuffix, out var needsCastAfterArithmetic);
}

// --- Before
Expand Down Expand Up @@ -2597,7 +2591,7 @@ protected override ConcreteSyntaxTree EmitArraySelect(List<Expression> indices,
return w;
}

protected override void EmitExprAsInt(Expression expr, bool inLetExprBody, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts) {
protected override void EmitExprAsNativeInt(Expression expr, bool inLetExprBody, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts) {
TrParenExpr("(int)", expr, wr, inLetExprBody, wStmts);
}

Expand Down Expand Up @@ -2710,7 +2704,7 @@ private void EmitSeqConstructionExprFromLambda(Expression lengthExpr, BoundVar b
ixVar, TypeName(indexType, wrLoopBody, body.tok), intIxVar);
var wrArrName = EmitArrayUpdate(new List<string> { ixVar }, body, wrLoopBody);
wrArrName.Write(arrVar);
wrLoopBody.WriteLine(";");
EndStmt(wrLoopBody);

wrLamBody.WriteLine("return {0}<{1}>.FromArray({2});", DafnySeqClass, TypeName(body.Type, wr, body.tok), arrVar);
}
Expand Down
21 changes: 8 additions & 13 deletions Source/DafnyCore/Compilers/Compiler-cpp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1346,8 +1346,9 @@ protected override ConcreteSyntaxTree EmitForStmt(IToken tok, IVariable loopInde
throw new UnsupportedFeatureException(tok, Feature.ForLoops, "for loops have not yet been implemented");
}

protected override ConcreteSyntaxTree CreateForLoop(string indexVar, string bound, ConcreteSyntaxTree wr) {
return wr.NewNamedBlock("for (auto {0} = 0; {0} < {1}; {0}++)", indexVar, bound);
protected override ConcreteSyntaxTree CreateForLoop(string indexVar, string bound, ConcreteSyntaxTree wr, string start = null) {
start = start ?? "0";
return wr.NewNamedBlock("for (auto {0} = {2}; {0} < {1}; {0}++)", indexVar, bound, start);
}

protected override ConcreteSyntaxTree CreateDoublingForLoop(string indexVar, int start, ConcreteSyntaxTree wr) {
Expand Down Expand Up @@ -1439,15 +1440,13 @@ protected override void EmitNew(Type type, IToken tok, CallStmt initCall /*?*/,
}
}

protected override void EmitNewArray(Type elmtType, IToken tok, List<Expression> dimensions,
bool mustInitialize, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts) {
var initValue = mustInitialize ? DefaultValue(elmtType, wr, tok) : null;
protected override void EmitNewArray(Type elementType, IToken tok, List<string> dimensions,
bool mustInitialize, [CanBeNull] string exampleElement, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts) {
var initValue = mustInitialize ? DefaultValue(elementType, wr, tok) : null;
// TODO: Handle initValue
if (dimensions.Count == 1) {
// handle the common case of 1-dimensional arrays separately
wr.Write("DafnyArray<{0}>::New(", TypeName(elmtType, wr, tok));
TrExpr(dimensions[0], wr, false, wStmts);
wr.Write(")");
wr.Write($"DafnyArray<{TypeName(elementType, wr, tok)}>::New({dimensions[0]})");
} else {
throw new UnsupportedFeatureException(tok, Feature.MultiDimensionalArrays);
}
Expand Down Expand Up @@ -1855,11 +1854,7 @@ protected override ConcreteSyntaxTree EmitArraySelect(List<Expression> indices,
return w;
}

protected override string ArrayIndexToInt(string arrayIndex, Type fromType) {
return arrayIndex;
}

protected override void EmitExprAsInt(Expression expr, bool inLetExprBody, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts) {
protected override void EmitExprAsNativeInt(Expression expr, bool inLetExprBody, ConcreteSyntaxTree wr, ConcreteSyntaxTree wStmts) {
TrParenExpr(expr, wr, inLetExprBody, wStmts);
if (AsNativeType(expr.Type) == null) {
wr.Write(".toNumber()");
Expand Down
Loading