// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package eval import ( "big" "testing" ) var undefined = "undefined" var typeAsExpr = "type .* used as expression" var badCharLit = "character literal" var unknownEscape = "unknown escape sequence" var opTypes = "illegal (operand|argument) type|cannot index into" var badAddrOf = "cannot take the address" var constantTruncated = "constant [^ ]* truncated" var constantUnderflows = "constant [^ ]* underflows" var constantOverflows = "constant [^ ]* overflows" var implLimit = "implementation limit" var mustBeUnsigned = "must be unsigned" var divByZero = "divide by zero" var hugeInteger = new(big.Int).Lsh(idealOne, 64) var exprTests = []test{ Val("i", 1), CErr("zzz", undefined), // TODO(austin) Test variable in constant context //CErr("t", typeAsExpr), Val("'a'", big.NewInt('a')), Val("'\\uffff'", big.NewInt('\uffff')), Val("'\\n'", big.NewInt('\n')), CErr("''+x", badCharLit), // Produces two parse errors //CErr("'''", ""), CErr("'\n'", badCharLit), CErr("'\\z'", unknownEscape), CErr("'ab'", badCharLit), Val("1.0", big.NewRat(1, 1)), Val("1.", big.NewRat(1, 1)), Val(".1", big.NewRat(1, 10)), Val("1e2", big.NewRat(100, 1)), Val("\"abc\"", "abc"), Val("\"\"", ""), Val("\"\\n\\\"\"", "\n\""), CErr("\"\\z\"", unknownEscape), CErr("\"abc", "string not terminated"), Val("(i)", 1), Val("ai[0]", 1), Val("(&ai)[0]", 1), Val("ai[1]", 2), Val("ai[i]", 2), Val("ai[u]", 2), CErr("ai[f]", opTypes), CErr("ai[0][0]", opTypes), CErr("ai[2]", "index 2 exceeds"), CErr("ai[1+1]", "index 2 exceeds"), CErr("ai[-1]", "negative index"), RErr("ai[i+i]", "index 2 exceeds"), RErr("ai[-i]", "negative index"), CErr("i[0]", opTypes), CErr("f[0]", opTypes), Val("aai[0][0]", 1), Val("aai[1][1]", 4), CErr("aai[2][0]", "index 2 exceeds"), CErr("aai[0][2]", "index 2 exceeds"), Val("sli[0]", 1), Val("sli[1]", 2), CErr("sli[-1]", "negative index"), RErr("sli[-i]", "negative index"), RErr("sli[2]", "index 2 exceeds"), Val("s[0]", uint8('a')), Val("s[1]", uint8('b')), CErr("s[-1]", "negative index"), RErr("s[-i]", "negative index"), RErr("s[3]", "index 3 exceeds"), Val("ai[0:2]", vslice{varray{1, 2}, 2, 2}), Val("ai[0:1]", vslice{varray{1, 2}, 1, 2}), Val("ai[0:]", vslice{varray{1, 2}, 2, 2}), Val("ai[i:]", vslice{varray{2}, 1, 1}), Val("sli[0:2]", vslice{varray{1, 2, 3}, 2, 3}), Val("sli[0:i]", vslice{varray{1, 2, 3}, 1, 3}), Val("sli[1:]", vslice{varray{2, 3}, 1, 2}), CErr("1(2)", "cannot call"), CErr("fn(1,2)", "too many"), CErr("fn()", "not enough"), CErr("fn(true)", opTypes), CErr("fn(true)", "function call"), // Single argument functions don't say which argument. //CErr("fn(true)", "argument 1"), Val("fn(1)", 2), Val("fn(1.0)", 2), CErr("fn(1.5)", constantTruncated), Val("fn(i)", 2), CErr("fn(u)", opTypes), CErr("void()+2", opTypes), CErr("oneTwo()+2", opTypes), Val("cap(ai)", 2), Val("cap(&ai)", 2), Val("cap(aai)", 2), Val("cap(sli)", 3), CErr("cap(0)", opTypes), CErr("cap(i)", opTypes), CErr("cap(s)", opTypes), Val("len(s)", 3), Val("len(ai)", 2), Val("len(&ai)", 2), Val("len(ai[0:])", 2), Val("len(ai[1:])", 1), Val("len(ai[2:])", 0), Val("len(aai)", 2), Val("len(sli)", 2), Val("len(sli[0:])", 2), Val("len(sli[1:])", 1), Val("len(sli[2:])", 0), // TODO(austin) Test len of map CErr("len(0)", opTypes), CErr("len(i)", opTypes), CErr("*i", opTypes), Val("*&i", 1), Val("*&(i)", 1), CErr("&1", badAddrOf), CErr("&c", badAddrOf), Val("*(&ai[0])", 1), Val("+1", big.NewInt(+1)), Val("+1.0", big.NewRat(1, 1)), Val("01.5", big.NewRat(15, 10)), CErr("+\"x\"", opTypes), Val("-42", big.NewInt(-42)), Val("-i", -1), Val("-f", -1.0), // 6g bug? //Val("-(f-1)", -0.0), CErr("-\"x\"", opTypes), // TODO(austin) Test unary ! Val("^2", big.NewInt(^2)), Val("^(-2)", big.NewInt(^(-2))), CErr("^2.0", opTypes), CErr("^2.5", opTypes), Val("^i", ^1), Val("^u", ^uint(1)), CErr("^f", opTypes), Val("1+i", 2), Val("1+u", uint(2)), Val("3.0+i", 4), Val("1+1", big.NewInt(2)), Val("f+f", 2.0), Val("1+f", 2.0), Val("1.0+1", big.NewRat(2, 1)), Val("\"abc\" + \"def\"", "abcdef"), CErr("i+u", opTypes), CErr("-1+u", constantUnderflows), // TODO(austin) Test named types Val("2-1", big.NewInt(1)), Val("2.0-1", big.NewRat(1, 1)), Val("f-2", -1.0), Val("-0.0", big.NewRat(0, 1)), Val("2*2", big.NewInt(4)), Val("2*i", 2), Val("3/2", big.NewInt(1)), Val("3/i", 3), CErr("1/0", divByZero), CErr("1.0/0", divByZero), RErr("i/0", divByZero), Val("3%2", big.NewInt(1)), Val("i%2", 1), CErr("3%0", divByZero), CErr("3.0%0", opTypes), RErr("i%0", divByZero), // Examples from "Arithmetic operators" Val("5/3", big.NewInt(1)), Val("(i+4)/(i+2)", 1), Val("5%3", big.NewInt(2)), Val("(i+4)%(i+2)", 2), Val("-5/3", big.NewInt(-1)), Val("(i-6)/(i+2)", -1), Val("-5%3", big.NewInt(-2)), Val("(i-6)%(i+2)", -2), Val("5/-3", big.NewInt(-1)), Val("(i+4)/(i-4)", -1), Val("5%-3", big.NewInt(2)), Val("(i+4)%(i-4)", 2), Val("-5/-3", big.NewInt(1)), Val("(i-6)/(i-4)", 1), Val("-5%-3", big.NewInt(-2)), Val("(i-6)%(i-4)", -2), // Examples from "Arithmetic operators" Val("11/4", big.NewInt(2)), Val("(i+10)/4", 2), Val("11%4", big.NewInt(3)), Val("(i+10)%4", 3), Val("11>>2", big.NewInt(2)), Val("(i+10)>>2", 2), Val("11&3", big.NewInt(3)), Val("(i+10)&3", 3), Val("-11/4", big.NewInt(-2)), Val("(i-12)/4", -2), Val("-11%4", big.NewInt(-3)), Val("(i-12)%4", -3), Val("-11>>2", big.NewInt(-3)), Val("(i-12)>>2", -3), Val("-11&3", big.NewInt(1)), Val("(i-12)&3", 1), // TODO(austin) Test bit ops // For shift, we try nearly every combination of positive // ideal int, negative ideal int, big ideal int, ideal // fractional float, ideal non-fractional float, int, uint, // and float. Val("2<<2", big.NewInt(2<<2)), CErr("2<<(-1)", constantUnderflows), CErr("2<<0x10000000000000000", constantOverflows), CErr("2<<2.5", constantTruncated), Val("2<<2.0", big.NewInt(2<<2.0)), CErr("2<, >= Val("1<2", 1 < 2), Val("1<=2", 1 <= 2), Val("2<=2", 2 <= 2), Val("1>2", 1 > 2), Val("1>=2", 1 >= 2), Val("2>=2", 2 >= 2), Val("i<2", 1 < 2), Val("i<=2", 1 <= 2), Val("i+1<=2", 2 <= 2), Val("i>2", 1 > 2), Val("i>=2", 1 >= 2), Val("i+1>=2", 2 >= 2), Val("u<2", 1 < 2), Val("f<2", 1 < 2), Val("s<\"b\"", true), Val("s<\"a\"", false), Val("s<=\"abc\"", true), Val("s>\"aa\"", true), Val("s>\"ac\"", false), Val("s>=\"abc\"", true), CErr("i