OSDN Git Service

support BytesLiteral true/false and operator && / || / ! (#12)
authoroysheng <33340252+oysheng@users.noreply.github.com>
Sat, 29 Sep 2018 06:04:50 +0000 (14:04 +0800)
committerPaladz <yzhu101@uottawa.ca>
Sat, 29 Sep 2018 06:04:50 +0000 (14:04 +0800)
* modify to support BytesLiteral

* optimise

* fix string literal and add escape character

* add unit test for constant

* add boolean literal true/false

* delete boolean check

* modify keywords

* add unit test

* support ! operator

* support boolean or / and operator

compiler/builtins.go
compiler/compile_test.go
compiler/equitytest/equitytest.go
compiler/parse.go

index cdf4530..f7e3a3e 100644 (file)
@@ -31,11 +31,8 @@ type binaryOp struct {
 }
 
 var binaryOps = []binaryOp{
-       // disjunctions disallowed (for now?)
-       // {"||", 1, "BOOLOR", "Boolean", "Boolean", "Boolean"},
-
-       // and disallow this too
-       // {"&&", 2, "BOOLAND", "Boolean", "Boolean", "Boolean"},
+       {"||", 1, "BOOLOR", "Boolean", "Boolean", "Boolean"},
+       {"&&", 2, "BOOLAND", "Boolean", "Boolean", "Boolean"},
 
        {">", 3, "GREATERTHAN", "Integer", "Integer", "Boolean"},
        {"<", 3, "LESSTHAN", "Integer", "Integer", "Boolean"},
@@ -72,8 +69,7 @@ type unaryOp struct {
 var unaryOps = []unaryOp{
        {"-", "NEGATE", "Integer", "Integer"},
 
-       // not not allowed (for now?)
-       // {"!", "NOT", "Boolean", "Boolean"},
+       {"!", "NOT", "Boolean", "Boolean"},
 
        {"~", "INVERT", "", ""},
 }
index 3e0b791..3fc02d9 100644 (file)
@@ -89,7 +89,7 @@ func TestCompile(t *testing.T) {
                {
                        "TestConstantMath",
                        equitytest.TestConstantMath,
-                       "547a547a935a93880431323330aa8806737472696e67aa87",
+                       "765779577a935a93887c0431323330aa887c06737472696e67aa887c91697b011493879a",
                },
        }
        for _, c := range cases {
index 0aae952..f5906b9 100644 (file)
@@ -168,11 +168,13 @@ contract TestIfNesting(a: Integer, count:Integer) locks valueAmount of valueAsse
 }
 `
 const TestConstantMath = `
-contract TestConstantMath(result: Integer, hashByte: Hash, hashStr: Hash) locks valueAmount of valueAsset {
-  clause calculation(left: Integer, right: Integer) {
+contract TestConstantMath(result: Integer, hashByte: Hash, hashStr: Hash, outcome: Boolean) locks valueAmount of valueAsset {
+  clause calculation(left: Integer, right: Integer, boolResult: Boolean) {
     verify result == left + right + 10
     verify hashByte == sha3(0x31323330)
     verify hashStr == sha3('string')
+    verify !outcome
+    verify boolResult && (result == left + 20)
     unlock valueAmount of valueAsset
   }
 }
index e66e5c0..4848aee 100644 (file)
@@ -348,8 +348,9 @@ func peekTok(p *parser, token string) bool {
 // consume functions
 
 var keywords = []string{
-       "contract", "clause", "verify", "output", "return",
-       "locks", "requires", "of", "lock", "with", "unlock",
+       "contract", "clause", "verify", "locks", "of",
+       "lock", "with", "unlock", "if", "else",
+       "define", "assign", "true", "false",
 }
 
 func consumeKeyword(p *parser, keyword string) {
@@ -426,6 +427,10 @@ func scanLiteralExpr(buf []byte, offset int) (expression, int) {
        if newOffset >= 0 {
                return bytesliteral, newOffset
        }
+       booleanLiteral, newOffset := scanBoolLiteral(buf, offset) // true or false
+       if newOffset >= 0 {
+               return booleanLiteral, newOffset
+       }
        return nil, -1
 }
 
@@ -536,6 +541,22 @@ func scanBytesLiteral(buf []byte, offset int) (bytesLiteral, int) {
        return bytesLiteral(decoded), i
 }
 
+func scanBoolLiteral(buf []byte, offset int) (booleanLiteral, int) {
+       offset = skipWsAndComments(buf, offset)
+       if offset >= len(buf) {
+               return false, -1
+       }
+
+       newOffset := scanKeyword(buf, offset, "true")
+       if newOffset < 0 {
+               if newOffset = scanKeyword(buf, offset, "false"); newOffset < 0 {
+                       return false, -1
+               }
+               return false, newOffset
+       }
+       return true, newOffset
+}
+
 func skipWsAndComments(buf []byte, offset int) int {
        var inComment bool
        for ; offset < len(buf); offset++ {