Skip to content

Commit

Permalink
Merge pull request #145 from franklinsch/structs-in-arrays
Browse files Browse the repository at this point in the history
Support arrays and dictionaries of struct elements
  • Loading branch information
franklinsch authored Feb 27, 2018
2 parents 23bc6de + 2e84c60 commit 8497d2f
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 9 deletions.
18 changes: 9 additions & 9 deletions Sources/IRGen/IULIAFunction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ extension IULIAFunction {
case .identifier(let identifier): return render(identifier, asLValue: asLValue)
case .variableDeclaration(let variableDeclaration): return render(variableDeclaration)
case .literal(let literal): return render(literalToken: literal)
case .self(let `self`): return render(selfToken: self)
case .self(let `self`): return render(selfToken: self, asLValue: asLValue)
case .subscriptExpression(let subscriptExpression): return render(subscriptExpression, asLValue: asLValue)
}
}
Expand Down Expand Up @@ -210,19 +210,19 @@ extension IULIAFunction {
}

func renderPropertyAccess(lhs: Expression, rhs: Expression, asLValue: Bool) -> String {
let lhsOffset: Int
let lhsOffset: String

if case .identifier(let lhsIdentifier) = lhs {
if let enclosingType = lhs.enclosingType, let offset = environment.propertyOffset(for: lhsIdentifier.name, enclosingType: enclosingType) {
lhsOffset = offset
lhsOffset = "\(offset)"
} else {
lhsOffset = environment.propertyOffset(for: lhsIdentifier.name, enclosingType: typeIdentifier.name)!
lhsOffset = "\(environment.propertyOffset(for: lhsIdentifier.name, enclosingType: typeIdentifier.name)!)"
}
} else if case .self(_) = lhs {
lhsOffset = 0
} else {
fatalError()
lhsOffset = render(lhs, asLValue: true)
}


let lhsType = environment.type(of: lhs, enclosingType: typeIdentifier.name, scopeContext: scopeContext)
let rhsOffset = propertyOffset(for: rhs, in: lhsType)

Expand Down Expand Up @@ -305,11 +305,11 @@ extension IULIAFunction {
}
}

func render(selfToken: Token) -> String {
func render(selfToken: Token, asLValue: Bool) -> String {
guard case .self = selfToken.kind else {
fatalError("Unexpected token \(selfToken.kind)")
}
return ""
return asLValue ? "0" : ""
}

func render(_ subscriptExpression: SubscriptExpression, asLValue: Bool = false) -> String {
Expand Down
30 changes: 30 additions & 0 deletions Tests/BehaviorTests/tests/array/array.flint
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ contract Array {
var arr: Int[4]
var arr2: Int[10]
var numWrites: Int

var arr3: [S]
}

Array :: (any) {
Expand Down Expand Up @@ -34,4 +36,32 @@ Array :: (any) {
public func numWrites() -> Int {
return numWrites
}

public mutating func write3(index: Int, a: Int, b: Bool, cA: Int) {
arr3[index].a = a
arr3[index].b = b
arr3[index].c.a = cA
}

public func value3a(index: Int) -> Int {
return arr3[index].a
}

public func value3b(index: Int) -> Bool {
return arr3[index].b
}

public func value3cA(index: Int) -> Int {
return arr3[index].c.a
}
}

struct S {
var a: Int
var b: Bool
var c: T
}

struct T {
var a: Int
}
27 changes: 27 additions & 0 deletions Tests/BehaviorTests/tests/array/test/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,33 @@ contract(config.contractName, function(accounts) {

assert.fail()
});

it("should correctly write to arrays of structs", async function() {
const instance = await Contract.deployed();
let t;

await instance.write3(0, 25, 0, 30);
await instance.write3(1, 25, 0, 30);
await instance.write3(0, 12, 1, 31);

t = await instance.value3a.call(0)
assert.equal(t.valueOf(), 12);

t = await instance.value3b.call(0)
assert.equal(t.valueOf(), 1);

t = await instance.value3cA.call(0)
assert.equal(t.valueOf(), 31);

t = await instance.value3a.call(1)
assert.equal(t.valueOf(), 25);

t = await instance.value3b.call(1)
assert.equal(t.valueOf(), 0);

t = await instance.value3cA.call(1)
assert.equal(t.valueOf(), 30);
});
});

contract(config.contractName, function(accounts) {
Expand Down
30 changes: 30 additions & 0 deletions Tests/BehaviorTests/tests/dictionary/dictionary.flint
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ contract Dictionary {
var foo: Int
var storage2: [Address: Int]
var bar: Int

var storage3: [Int: S]
}

struct S {
var a: Int
var b: Bool
var c: T
}

struct T {
var a: Int
}

Dictionary :: (any) {
Expand Down Expand Up @@ -37,4 +49,22 @@ Dictionary :: (any) {
public mutating func setBar(val: Int) {
bar = val
}

public mutating func write3(index: Int, a: Int, b: Bool, cA: Int) {
storage3[index].a = a
storage3[index].b = b
storage3[index].c.a = cA
}

public func value3a(index: Int) -> Int {
return storage3[index].a
}

public func value3b(index: Int) -> Bool {
return storage3[index].b
}

public func value3cA(index: Int) -> Int {
return storage3[index].c.a
}
}
27 changes: 27 additions & 0 deletions Tests/BehaviorTests/tests/dictionary/test/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,31 @@ contract(config.contractName, function(accounts) {
t = await instance.get2.call(0x51);
assert.equal(t.valueOf(), 12);
});

it("should correctly write to dictionaries of struct value types", async function() {
const instance = await Contract.deployed();
let t;

await instance.write3(0, 25, 0, 30);
await instance.write3(1, 25, 0, 30);
await instance.write3(0, 12, 1, 31);

t = await instance.value3a.call(0)
assert.equal(t.valueOf(), 12);

t = await instance.value3b.call(0)
assert.equal(t.valueOf(), 1);

t = await instance.value3cA.call(0)
assert.equal(t.valueOf(), 31);

t = await instance.value3a.call(1)
assert.equal(t.valueOf(), 25);

t = await instance.value3b.call(1)
assert.equal(t.valueOf(), 0);

t = await instance.value3cA.call(1)
assert.equal(t.valueOf(), 30);
});
});

0 comments on commit 8497d2f

Please sign in to comment.