From: oysheng <33340252+oysheng@users.noreply.github.com> Date: Fri, 28 Sep 2018 11:25:26 +0000 (+0800) Subject: fix StrLiteral and BytesLiteral to support constant (#11) X-Git-Tag: v0.1.1~22 X-Git-Url: http://git.osdn.net/view?p=bytom%2Fequity.git;a=commitdiff_plain;h=38a476b9a5bed09fef310a89216e5da4c5e1e956 fix StrLiteral and BytesLiteral to support constant (#11) * modify to support BytesLiteral * optimise * fix string literal and add escape character * add unit test for constant --- diff --git a/compiler/compile_test.go b/compiler/compile_test.go index a55dc02..3e0b791 100644 --- a/compiler/compile_test.go +++ b/compiler/compile_test.go @@ -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) { diff --git a/compiler/equitytest/equitytest.go b/compiler/equitytest/equitytest.go index e362da2..0aae952 100644 --- a/compiler/equitytest/equitytest.go +++ b/compiler/equitytest/equitytest.go @@ -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 + } +} +` diff --git a/compiler/parse.go b/compiler/parse.go index 3dcb4bb..e66e5c0 100644 --- a/compiler/parse.go +++ b/compiler/parse.go @@ -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 +}