2009-09-01 18:21:44 -06:00
|
|
|
// 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 (
|
|
|
|
"bignum";
|
|
|
|
"testing";
|
|
|
|
)
|
|
|
|
|
|
|
|
var undefined = "undefined"
|
|
|
|
var typeAsExpr = "type .* used as expression"
|
|
|
|
var badCharLit = "character literal"
|
|
|
|
var illegalEscape = "illegal char escape"
|
|
|
|
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 = bignum.Int(1).Shl(64);
|
|
|
|
|
|
|
|
var exprTests = []test {
|
|
|
|
Val("i", 1),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("zzz", undefined),
|
2009-09-01 18:21:44 -06:00
|
|
|
// TODO(austin) Test variable in constant context
|
2009-09-03 17:20:49 -06:00
|
|
|
//CErr("t", typeAsExpr),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("'a'", bignum.Int('a')),
|
|
|
|
Val("'\\uffff'", bignum.Int('\uffff')),
|
|
|
|
Val("'\\n'", bignum.Int('\n')),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("''+x", badCharLit),
|
2009-09-01 18:21:44 -06:00
|
|
|
// Produces two parse errors
|
2009-09-03 17:20:49 -06:00
|
|
|
//CErr("'''", ""),
|
|
|
|
CErr("'\n'", badCharLit),
|
|
|
|
CErr("'\\z'", illegalEscape),
|
|
|
|
CErr("'ab'", badCharLit),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("1.0", bignum.Rat(1, 1)),
|
|
|
|
Val("1.", bignum.Rat(1, 1)),
|
|
|
|
Val(".1", bignum.Rat(1, 10)),
|
|
|
|
Val("1e2", bignum.Rat(100, 1)),
|
|
|
|
|
|
|
|
Val("\"abc\"", "abc"),
|
|
|
|
Val("\"\"", ""),
|
|
|
|
Val("\"\\n\\\"\"", "\n\""),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("\"\\z\"", illegalEscape),
|
|
|
|
CErr("\"abc", "string not terminated"),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("\"abc\" \"def\"", "abcdef"),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("\"abc\" \"\\z\"", illegalEscape),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("(i)", 1),
|
|
|
|
|
|
|
|
Val("ai[0]", 1),
|
|
|
|
Val("(&ai)[0]", 1),
|
|
|
|
Val("ai[1]", 2),
|
|
|
|
Val("ai[i]", 2),
|
|
|
|
Val("ai[u]", 2),
|
2009-09-03 17:20:49 -06:00
|
|
|
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),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("aai[0][0]", 1),
|
|
|
|
Val("aai[1][1]", 4),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("aai[2][0]", "index 2 exceeds"),
|
|
|
|
CErr("aai[0][2]", "index 2 exceeds"),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("sli[0]", 1),
|
|
|
|
Val("sli[1]", 2),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("sli[-1]", "negative index"),
|
|
|
|
RErr("sli[-i]", "negative index"),
|
|
|
|
RErr("sli[2]", "index 2 exceeds"),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("s[0]", uint8('a')),
|
|
|
|
Val("s[1]", uint8('b')),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("s[-1]", "negative index"),
|
|
|
|
RErr("s[-i]", "negative index"),
|
|
|
|
RErr("s[3]", "index 3 exceeds"),
|
|
|
|
|
|
|
|
CErr("1(2)", "cannot call"),
|
|
|
|
CErr("fn(1,2)", "too many"),
|
|
|
|
CErr("fn()", "not enough"),
|
|
|
|
CErr("fn(true)", opTypes),
|
|
|
|
CErr("fn(true)", "function call"),
|
2009-09-01 18:21:44 -06:00
|
|
|
// Single argument functions don't say which argument.
|
2009-09-03 17:20:49 -06:00
|
|
|
//CErr("fn(true)", "argument 1"),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("fn(1)", 2),
|
|
|
|
Val("fn(1.0)", 2),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("fn(1.5)", constantTruncated),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("fn(i)", 2),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("fn(u)", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("void()+2", opTypes),
|
|
|
|
CErr("oneTwo()+2", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("cap(ai)", 2),
|
|
|
|
Val("cap(&ai)", 2),
|
|
|
|
Val("cap(aai)", 2),
|
|
|
|
Val("cap(sli)", 3),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("cap(0)", opTypes),
|
|
|
|
CErr("cap(i)", opTypes),
|
|
|
|
CErr("cap(s)", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("len(s)", 3),
|
|
|
|
Val("len(ai)", 2),
|
|
|
|
Val("len(&ai)", 2),
|
|
|
|
Val("len(aai)", 2),
|
|
|
|
Val("len(sli)", 2),
|
|
|
|
// TODO(austin) Test len of map
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("len(0)", opTypes),
|
|
|
|
CErr("len(i)", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("*i", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("*&i", 1),
|
|
|
|
Val("*&(i)", 1),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("&1", badAddrOf),
|
|
|
|
CErr("&c", badAddrOf),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("*(&ai[0])", 1),
|
|
|
|
|
|
|
|
Val("+1", bignum.Int(+1)),
|
|
|
|
Val("+1.0", bignum.Rat(1, 1)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("+\"x\"", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("-42", bignum.Int(-42)),
|
|
|
|
Val("-i", -1),
|
|
|
|
Val("-f", -1.0),
|
|
|
|
// 6g bug?
|
|
|
|
//Val("-(f-1)", -0.0),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("-\"x\"", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
// TODO(austin) Test unary !
|
|
|
|
|
|
|
|
Val("^2", bignum.Int(^2)),
|
|
|
|
Val("^(-2)", bignum.Int(^(-2))),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("^2.0", opTypes),
|
|
|
|
CErr("^2.5", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("^i", ^1),
|
|
|
|
Val("^u", ^uint(1)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("^f", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("1+i", 2),
|
|
|
|
Val("1+u", uint(2)),
|
|
|
|
Val("3.0+i", 4),
|
|
|
|
Val("1+1", bignum.Int(2)),
|
|
|
|
Val("f+f", 2.0),
|
|
|
|
Val("1+f", 2.0),
|
|
|
|
Val("1.0+1", bignum.Rat(2, 1)),
|
|
|
|
Val("\"abc\" + \"def\"", "abcdef"),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("i+u", opTypes),
|
|
|
|
CErr("-1+u", constantUnderflows),
|
2009-09-01 18:21:44 -06:00
|
|
|
// TODO(austin) Test named types
|
|
|
|
|
|
|
|
Val("2-1", bignum.Int(1)),
|
|
|
|
Val("2.0-1", bignum.Rat(1, 1)),
|
|
|
|
Val("f-2", -1.0),
|
|
|
|
// TOOD(austin) bignum can't do negative 0?
|
|
|
|
//Val("-0.0", XXX),
|
|
|
|
Val("2*2", bignum.Int(4)),
|
|
|
|
Val("2*i", 2),
|
|
|
|
Val("3/2", bignum.Int(1)),
|
|
|
|
Val("3/i", 3),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("1/0", divByZero),
|
|
|
|
CErr("1.0/0", divByZero),
|
|
|
|
RErr("i/0", divByZero),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("3%2", bignum.Int(1)),
|
|
|
|
Val("i%2", 1),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("3%0", divByZero),
|
|
|
|
CErr("3.0%0", opTypes),
|
|
|
|
RErr("i%0", divByZero),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
// Examples from "Arithmetic operators"
|
|
|
|
Val("5/3", bignum.Int(1)),
|
|
|
|
Val("(i+4)/(i+2)", 1),
|
|
|
|
Val("5%3", bignum.Int(2)),
|
|
|
|
Val("(i+4)%(i+2)", 2),
|
|
|
|
Val("-5/3", bignum.Int(-1)),
|
|
|
|
Val("(i-6)/(i+2)", -1),
|
|
|
|
Val("-5%3", bignum.Int(-2)),
|
|
|
|
Val("(i-6)%(i+2)", -2),
|
|
|
|
Val("5/-3", bignum.Int(-1)),
|
|
|
|
Val("(i+4)/(i-4)", -1),
|
|
|
|
Val("5%-3", bignum.Int(2)),
|
|
|
|
Val("(i+4)%(i-4)", 2),
|
|
|
|
Val("-5/-3", bignum.Int(1)),
|
|
|
|
Val("(i-6)/(i-4)", 1),
|
|
|
|
Val("-5%-3", bignum.Int(-2)),
|
|
|
|
Val("(i-6)%(i-4)", -2),
|
|
|
|
|
|
|
|
// Examples from "Arithmetic operators"
|
|
|
|
Val("11/4", bignum.Int(2)),
|
|
|
|
Val("(i+10)/4", 2),
|
|
|
|
Val("11%4", bignum.Int(3)),
|
|
|
|
Val("(i+10)%4", 3),
|
|
|
|
Val("11>>2", bignum.Int(2)),
|
|
|
|
Val("(i+10)>>2", 2),
|
|
|
|
Val("11&3", bignum.Int(3)),
|
|
|
|
Val("(i+10)&3", 3),
|
|
|
|
Val("-11/4", bignum.Int(-2)),
|
|
|
|
Val("(i-12)/4", -2),
|
|
|
|
Val("-11%4", bignum.Int(-3)),
|
|
|
|
Val("(i-12)%4", -3),
|
|
|
|
Val("-11>>2", bignum.Int(-3)),
|
|
|
|
Val("(i-12)>>2", -3),
|
|
|
|
Val("-11&3", bignum.Int(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", bignum.Int(2<<2)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("2<<(-1)", constantUnderflows),
|
|
|
|
CErr("2<<0x10000000000000000", constantOverflows),
|
|
|
|
CErr("2<<2.5", constantTruncated),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("2<<2.0", bignum.Int(2<<2.0)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("2<<i", mustBeUnsigned),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("2<<u", 2<<1),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("2<<f", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("-2<<2", bignum.Int(-2<<2)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("-2<<(-1)", constantUnderflows),
|
|
|
|
CErr("-2<<0x10000000000000000", constantOverflows),
|
|
|
|
CErr("-2<<2.5", constantTruncated),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("-2<<2.0", bignum.Int(-2<<2.0)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("-2<<i", mustBeUnsigned),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("-2<<u", -2<<1),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("-2<<f", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("0x10000000000000000<<2", hugeInteger.Shl(2)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("0x10000000000000000<<(-1)", constantUnderflows),
|
|
|
|
CErr("0x10000000000000000<<0x10000000000000000", constantOverflows),
|
|
|
|
CErr("0x10000000000000000<<2.5", constantTruncated),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("0x10000000000000000<<2.0", hugeInteger.Shl(2)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("0x10000000000000000<<i", mustBeUnsigned),
|
|
|
|
CErr("0x10000000000000000<<u", constantOverflows),
|
|
|
|
CErr("0x10000000000000000<<f", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("2.5<<2", opTypes),
|
|
|
|
CErr("2.0<<2", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
Val("i<<2", 1<<2),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("i<<(-1)", constantUnderflows),
|
|
|
|
CErr("i<<0x10000000000000000", constantOverflows),
|
|
|
|
CErr("i<<2.5", constantTruncated),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("i<<2.0", 1<<2),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("i<<i", mustBeUnsigned),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("i<<u", 1<<1),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("i<<f", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("i<<u", 1<<1),
|
|
|
|
|
|
|
|
Val("u<<2", uint(1<<2)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("u<<(-1)", constantUnderflows),
|
|
|
|
CErr("u<<0x10000000000000000", constantOverflows),
|
|
|
|
CErr("u<<2.5", constantTruncated),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("u<<2.0", uint(1<<2)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("u<<i", mustBeUnsigned),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("u<<u", uint(1<<1)),
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("u<<f", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
Val("u<<u", uint(1<<1)),
|
|
|
|
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("f<<2", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
// <, <=, >, >=
|
|
|
|
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),
|
|
|
|
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("i<u", opTypes),
|
|
|
|
CErr("i<f", opTypes),
|
|
|
|
CErr("i<s", opTypes),
|
|
|
|
CErr("&i<&i", opTypes),
|
|
|
|
CErr("ai<ai", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
|
|
|
|
// ==, !=
|
|
|
|
Val("1==1", true),
|
|
|
|
Val("1!=1", false),
|
|
|
|
Val("1==2", false),
|
|
|
|
Val("1!=2", true),
|
|
|
|
|
|
|
|
Val("1.0==1", true),
|
|
|
|
Val("1.5==1", false),
|
|
|
|
|
|
|
|
Val("i==1", true),
|
|
|
|
Val("i!=1", false),
|
|
|
|
Val("i==2", false),
|
|
|
|
Val("i!=2", true),
|
|
|
|
|
|
|
|
Val("u==1", true),
|
|
|
|
Val("f==1", true),
|
|
|
|
|
|
|
|
Val("s==\"abc\"", true),
|
|
|
|
Val("s!=\"abc\"", false),
|
|
|
|
Val("s==\"abcd\"", false),
|
|
|
|
Val("s!=\"abcd\"", true),
|
|
|
|
|
|
|
|
Val("&i==&i", true),
|
|
|
|
Val("&i==&i2", false),
|
|
|
|
|
|
|
|
Val("fn==fn", true),
|
|
|
|
Val("fn==func(int)int{return 0}", false),
|
|
|
|
|
2009-09-03 17:20:49 -06:00
|
|
|
CErr("i==u", opTypes),
|
|
|
|
CErr("i==f", opTypes),
|
|
|
|
CErr("&i==&f", opTypes),
|
|
|
|
CErr("ai==ai", opTypes),
|
|
|
|
CErr("t==t", opTypes),
|
|
|
|
CErr("fn==oneTwo", opTypes),
|
2009-09-01 18:21:44 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestExpr(t *testing.T) {
|
|
|
|
runTests(t, "exprTests", exprTests);
|
|
|
|
}
|