diff --git a/Sources/AST/Token.swift b/Sources/AST/Token.swift index 15a0b18b..a2c81b9c 100644 --- a/Sources/AST/Token.swift +++ b/Sources/AST/Token.swift @@ -52,11 +52,13 @@ extension Token { case minusEqual = "-=" case timesEqual = "*=" case divideEqual = "/=" - + + case doubleEqual = "==" + case notEqual = "!=" case lessThanOrEqual = "<=" case greaterThanOrEqual = ">=" - static var allBinaryOperators: [Punctuation] { return [.plus, .minus, .times, .divide, .equal, .plusEqual, .minusEqual, .timesEqual, .divideEqual, .dot, .closeAngledBracket, .lessThanOrEqual, .openAngledBracket, .greaterThanOrEqual] } + static var allBinaryOperators: [Punctuation] { return [.plus, .minus, .times, .divide, .equal, .plusEqual, .minusEqual, .timesEqual, .divideEqual, .dot, .closeAngledBracket, .lessThanOrEqual, .openAngledBracket, .greaterThanOrEqual, .doubleEqual, .notEqual] } public static var allBinaryOperatorsByIncreasingPrecedence: [Punctuation] { return allBinaryOperators.sorted { $0.precedence < $1.precedence } } @@ -68,7 +70,7 @@ extension Token { var precedence: Int { switch self { case .equal, .plusEqual, .minusEqual, .timesEqual, .divideEqual: return 10 - case .closeAngledBracket, .lessThanOrEqual, .openAngledBracket, .greaterThanOrEqual: return 15 + case .closeAngledBracket, .lessThanOrEqual, .openAngledBracket, .greaterThanOrEqual, .doubleEqual, .notEqual: return 15 case .plus: return 20 case .minus: return 20 case .times: return 30 diff --git a/Sources/IRGen/IULIAFunction.swift b/Sources/IRGen/IULIAFunction.swift index b4419677..2cf87922 100644 --- a/Sources/IRGen/IULIAFunction.swift +++ b/Sources/IRGen/IULIAFunction.swift @@ -45,7 +45,11 @@ struct IULIAFunction { } var scopeContext: ScopeContext { - return ScopeContext(localVariables: functionDeclaration.parametersAsVariableDeclarations) + var localVariables = functionDeclaration.parametersAsVariableDeclarations + if let capabilityBinding = capabilityBinding { + localVariables.append(VariableDeclaration(varToken: nil, identifier: capabilityBinding, type: Type(inferredType: .builtInType(.address), identifier: capabilityBinding))) + } + return ScopeContext(localVariables: localVariables) } var parameterCanonicalTypes: [CanonicalType] { @@ -191,6 +195,8 @@ extension IULIAFunction { case .lessThanOrEqual: return "le(\(lhs), \(rhs))" case .openAngledBracket: return "lt(\(lhs), \(rhs))" case .greaterThanOrEqual: return "ge(\(lhs), \(rhs))" + case .doubleEqual: return "eq(\(lhs), \(rhs))" + case .notEqual: return "iszero(eq(\(lhs), \(rhs)))" default: fatalError() } } diff --git a/Sources/Parser/Tokenizer.swift b/Sources/Parser/Tokenizer.swift index b390e8ff..8d095530 100644 --- a/Sources/Parser/Tokenizer.swift +++ b/Sources/Parser/Tokenizer.swift @@ -78,6 +78,8 @@ public struct Tokenizer { "<=": .punctuation(.lessThanOrEqual), ">": .punctuation(.closeAngledBracket), ">=": .punctuation(.greaterThanOrEqual), + "==": .punctuation(.doubleEqual), + "!=": .punctuation(.notEqual), "{": .punctuation(.openBrace), "}": .punctuation(.closeBrace), "[": .punctuation(.openSquareBracket), diff --git a/Tests/BehaviorTests/tests/string/string.flint b/Tests/BehaviorTests/tests/string/string.flint index d7351a1c..65e57f92 100644 --- a/Tests/BehaviorTests/tests/string/string.flint +++ b/Tests/BehaviorTests/tests/string/string.flint @@ -10,5 +10,21 @@ StringContract :: (any) { public func get() -> String { return s } + + public func isEqual(other: String) -> Bool { + if s == other { + return true + } + + return false + } + + public func isNotEqual(other: String) -> Bool { + if s != other { + return true + } + + return false + } } diff --git a/Tests/BehaviorTests/tests/string/test/test/test.js b/Tests/BehaviorTests/tests/string/test/test/test.js index 0a64d32f..1aa439c8 100644 --- a/Tests/BehaviorTests/tests/string/test/test/test.js +++ b/Tests/BehaviorTests/tests/string/test/test/test.js @@ -13,6 +13,24 @@ contract(config.contractName, function(accounts) { assert.equal(web3.toUtf8(t.valueOf()), "hello"); }); + + it("should be possible to compare strings", async function() { + const instance = await Contract.deployed(); + + await instance.set("hello"); + + let t = await instance.isEqual("hello"); + assert.equal(t.valueOf(), 1); + + t = await instance.isEqual("hell"); + assert.equal(t.valueOf(), 0); + + t = await instance.isNotEqual("hello"); + assert.equal(t.valueOf(), 0); + + t = await instance.isNotEqual("hell"); + assert.equal(t.valueOf(), 1); + }); });