OSDN Git Service

fix StrLiteral and BytesLiteral to support constant (#11)
authoroysheng <33340252+oysheng@users.noreply.github.com>
Fri, 28 Sep 2018 11:25:26 +0000 (19:25 +0800)
committerPaladz <yzhu101@uottawa.ca>
Fri, 28 Sep 2018 11:25:26 +0000 (19:25 +0800)
* modify to support BytesLiteral

* optimise

* fix string literal and add escape character

* add unit test for constant

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

index a55dc02..3e0b791 100644 (file)
@@ -86,6 +86,11 @@ func TestCompile(t *testing.T) {
                        equitytest.TestIfNesting,
                        "7b644400000054795279879169765579a00087643500000052795479a000876429000000765379a06952795579879169633a000000765479a06953797b8791635c0000007654798791695279a000876459000000527978a0697d8791",
                },
+               {
+                       "TestConstantMath",
+                       equitytest.TestConstantMath,
+                       "547a547a935a93880431323330aa8806737472696e67aa87",
+               },
        }
        for _, c := range cases {
                t.Run(c.name, func(t *testing.T) {
index e362da2..0aae952 100644 (file)
@@ -167,3 +167,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) {
+    verify result == left + right + 10
+    verify hashByte == sha3(0x31323330)
+    verify hashStr == sha3('string')
+    unlock valueAmount of valueAsset
+  }
+}
+`
index 3dcb4bb..e66e5c0 100644 (file)
@@ -468,6 +468,10 @@ func scanIntLiteral(buf []byte, offset int) (integerLiteral, int) {
        }
        i := offset
        for ; i < len(buf) && unicode.IsDigit(rune(buf[i])); i++ {
+               // the literal is BytesLiteral when it starts with 0x/0X
+               if buf[i] == '0' && i < len(buf)-1 && (buf[i+1] == 'x' || buf[i+1] == 'X') {
+                       return 0, -1
+               }
        }
        if i > offset {
                n, err := strconv.ParseInt(string(buf[start:i]), 10, 64)
@@ -484,13 +488,19 @@ func scanStrLiteral(buf []byte, offset int) (bytesLiteral, int) {
        if offset >= len(buf) || buf[offset] != '\'' {
                return bytesLiteral{}, -1
        }
+       var byteBuf bytesLiteral
        for i := offset + 1; i < len(buf); i++ {
                if buf[i] == '\'' {
-                       return bytesLiteral(buf[offset : i+1]), i + 1
+                       return byteBuf, i + 1
                }
-               if buf[i] == '\\' {
-                       i++
+               if buf[i] == '\\' && i < len(buf)-1 {
+                       if c, ok := scanEscape(buf[i+1]); ok {
+                               byteBuf = append(byteBuf, c)
+                               i++
+                               continue
+                       }
                }
+               byteBuf = append(byteBuf, buf[i])
        }
        panic(parseErr(buf, offset, "unterminated string literal"))
 }
@@ -593,3 +603,25 @@ func (p parserErr) Error() string {
        args = append(args, p.args...)
        return fmt.Sprintf("line %d, col %d: "+p.format, args...)
 }
+
+func scanEscape(c byte) (byte, bool) {
+       escapeFlag := true
+       switch c {
+       case '\'', '"', '\\':
+       case 'b':
+               c = '\b'
+       case 'f':
+               c = '\f'
+       case 'n':
+               c = '\n'
+       case 'r':
+               c = '\r'
+       case 't':
+               c = '\t'
+       case 'v':
+               c = '\v'
+       default:
+               escapeFlag = false
+       }
+       return c, escapeFlag
+}