summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Thompson <ken@golang.org>2010-02-17 22:08:30 -0800
committerKen Thompson <ken@golang.org>2010-02-17 22:08:30 -0800
commit81bc925915b7fec2cc9cb892b9fde11e97d8967a (patch)
tree39a9c351b752d112e768ce40cda37857b7249f25
parenta205da88991d60e03496f9d25bea0fedf054294c (diff)
downloadgolang-81bc925915b7fec2cc9cb892b9fde11e97d8967a.tar.gz
new types complex, complex64 and complex128
only front-end compiler work. best to do thin in 3 steps 1. frontend 2. backend 3. lib R=rsc CC=golang-dev http://codereview.appspot.com/214042
-rw-r--r--src/cmd/6g/galign.c1
-rw-r--r--src/cmd/gc/align.c24
-rw-r--r--src/cmd/gc/const.c211
-rw-r--r--src/cmd/gc/go.h28
-rw-r--r--src/cmd/gc/lex.c27
-rw-r--r--src/cmd/gc/print.c5
-rw-r--r--src/cmd/gc/reflect.c13
-rw-r--r--src/cmd/gc/subr.c23
-rw-r--r--src/pkg/runtime/type.go9
9 files changed, 285 insertions, 56 deletions
diff --git a/src/cmd/6g/galign.c b/src/cmd/6g/galign.c
index fa7315057..68647e21b 100644
--- a/src/cmd/6g/galign.c
+++ b/src/cmd/6g/galign.c
@@ -18,6 +18,7 @@ Typedef typedefs[] =
"uint", TUINT, TUINT32,
"uintptr", TUINTPTR, TUINT64,
"float", TFLOAT, TFLOAT32,
+ "complex", TCOMPLEX, TCOMPLEX64,
0
};
diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c
index dfb9f9e89..095645955 100644
--- a/src/cmd/gc/align.c
+++ b/src/cmd/gc/align.c
@@ -166,8 +166,12 @@ dowidth(Type *t)
case TINT64:
case TUINT64:
case TFLOAT64:
+ case TCOMPLEX64:
w = 8;
break;
+ case TCOMPLEX128:
+ w = 16;
+ break;
case TPTR32:
w = 4;
checkwidth(t->type);
@@ -385,10 +389,14 @@ typeinit(void)
isint[TUINT] = 1;
isint[TUINTPTR] = 1;
- for(i=TFLOAT32; i<=TFLOAT64; i++)
- isfloat[i] = 1;
+ isfloat[TFLOAT32] = 1;
+ isfloat[TFLOAT64] = 1;
isfloat[TFLOAT] = 1;
+ iscomplex[TCOMPLEX64] = 1;
+ iscomplex[TCOMPLEX128] = 1;
+ iscomplex[TCOMPLEX] = 1;
+
isptr[TPTR32] = 1;
isptr[TPTR64] = 1;
@@ -425,6 +433,13 @@ typeinit(void)
minfltval[i] = mal(sizeof(*minfltval[i]));
maxfltval[i] = mal(sizeof(*maxfltval[i]));
}
+ if(iscomplex[i]) {
+ okforeq[i] = 1;
+ okforadd[i] = 1;
+ okforarith[i] = 1;
+ okforconst[i] = 1;
+// issimple[i] = 1;
+ }
}
issimple[TBOOL] = 1;
@@ -518,6 +533,11 @@ typeinit(void)
mpatoflt(maxfltval[TFLOAT64], "18014398509481983p970"); /* 2^53-1 p (1023-52) + 1/2 ulp */
mpatoflt(minfltval[TFLOAT64], "-18014398509481983p970");
+ maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32];
+ minfltval[TCOMPLEX64] = minfltval[TFLOAT32];
+ maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64];
+ minfltval[TCOMPLEX128] = minfltval[TFLOAT64];
+
/* for walk to use in error messages */
types[TFUNC] = functype(N, nil, nil);
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
index d541c60c5..fed3b1476 100644
--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -5,6 +5,7 @@
#include "go.h"
#define TUP(x,y) (((x)<<16)|(y))
+static Val tocplx(Val);
static Val toflt(Val);
static Val tostr(Val);
static Val copyval(Val);
@@ -165,24 +166,51 @@ convlit1(Node **np, Type *t, int explicit)
case CTINT:
case CTFLT:
+ case CTCPLX:
ct = n->val.ctype;
if(isint[et]) {
- if(ct == CTFLT)
+ switch(ct) {
+ default:
+ case CTCPLX:
+ case CTFLT:
n->val = toint(n->val);
- else if(ct != CTINT)
- goto bad;
- overflow(n->val, t);
- } else if(isfloat[et]) {
- if(ct == CTINT)
+ // flowthrough
+ case CTINT:
+ overflow(n->val, t);
+ break;
+ }
+ } else
+ if(isfloat[et]) {
+ switch(ct) {
+ default:
+ case CTCPLX:
+ case CTINT:
n->val = toflt(n->val);
- else if(ct != CTFLT)
+ // flowthrough
+ case CTFLT:
+ overflow(n->val, t);
+ n->val.u.fval = truncfltlit(n->val.u.fval, t);
+ break;
+ }
+ } else
+ if(iscomplex[et]) {
+ switch(ct) {
+ default:
goto bad;
- overflow(n->val, t);
- n->val.u.fval = truncfltlit(n->val.u.fval, t);
- } else if(et == TSTRING && ct == CTINT && explicit)
+ case CTFLT:
+ case CTINT:
+ n->val = tocplx(n->val);
+ break;
+ case CTCPLX:
+ overflow(n->val, t);
+ break;
+ }
+ } else
+ if(et == TSTRING && ct == CTINT && explicit)
n->val = tostr(n->val);
else
goto bad;
+ break;
}
n->type = t;
return;
@@ -204,6 +232,7 @@ copyval(Val v)
{
Mpint *i;
Mpflt *f;
+ Mpcplx *c;
switch(v.ctype) {
case CTINT:
@@ -216,6 +245,36 @@ copyval(Val v)
mpmovefltflt(f, v.u.fval);
v.u.fval = f;
break;
+ case CTCPLX:
+ c = mal(sizeof(*c));
+ mpmovefltflt(&c->real, &v.u.cval->real);
+ mpmovefltflt(&c->imag, &v.u.cval->imag);
+ v.u.cval = c;
+ break;
+ }
+ return v;
+}
+
+static Val
+tocplx(Val v)
+{
+ Mpcplx *c;
+
+ switch(v.ctype) {
+ case CTINT:
+ c = mal(sizeof(*c));
+ mpmovefixflt(&c->real, v.u.xval);
+ mpmovecflt(&c->imag, 0.0);
+ v.ctype = CTCPLX;
+ v.u.cval = c;
+ break;
+ case CTFLT:
+ c = mal(sizeof(*c));
+ mpmovefltflt(&c->real, v.u.fval);
+ mpmovecflt(&c->imag, 0.0);
+ v.ctype = CTCPLX;
+ v.u.cval = c;
+ break;
}
return v;
}
@@ -225,11 +284,21 @@ toflt(Val v)
{
Mpflt *f;
- if(v.ctype == CTINT) {
+ switch(v.ctype) {
+ case CTINT:
f = mal(sizeof(*f));
mpmovefixflt(f, v.u.xval);
v.ctype = CTFLT;
v.u.fval = f;
+ break;
+ case CTCPLX:
+ f = mal(sizeof(*f));
+ mpmovefltflt(f, &v.u.cval->real);
+ if(mpcmpfltc(&v.u.cval->imag, 0) != 0)
+ yyerror("constant %#F truncated to real", v.u.fval);
+ v.ctype = CTFLT;
+ v.u.fval = f;
+ break;
}
return v;
}
@@ -239,12 +308,23 @@ toint(Val v)
{
Mpint *i;
- if(v.ctype == CTFLT) {
+ switch(v.ctype) {
+ case CTFLT:
i = mal(sizeof(*i));
if(mpmovefltfix(i, v.u.fval) < 0)
yyerror("constant %#F truncated to integer", v.u.fval);
v.ctype = CTINT;
v.u.xval = i;
+ break;
+ case CTCPLX:
+ i = mal(sizeof(*i));
+ if(mpmovefltfix(i, &v.u.cval->real) < 0)
+ yyerror("constant %#F truncated to integer", v.u.fval);
+ if(mpcmpfltc(&v.u.cval->imag, 0) != 0)
+ yyerror("constant %#F truncated to real", v.u.fval);
+ v.ctype = CTINT;
+ v.u.xval = i;
+ break;
}
return v;
}
@@ -260,15 +340,24 @@ overflow(Val v, Type *t)
case CTINT:
if(!isint[t->etype])
fatal("overflow: %T integer constant", t);
- if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0
- || mpcmpfixfix(v.u.xval, maxintval[t->etype]) > 0)
+ if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0 ||
+ mpcmpfixfix(v.u.xval, maxintval[t->etype]) > 0)
yyerror("constant %B overflows %T", v.u.xval, t);
break;
case CTFLT:
if(!isfloat[t->etype])
fatal("overflow: %T floating-point constant", t);
- if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) <= 0
- || mpcmpfltflt(v.u.fval, maxfltval[t->etype]) >= 0)
+ if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) <= 0 ||
+ mpcmpfltflt(v.u.fval, maxfltval[t->etype]) >= 0)
+ yyerror("constant %#F overflows %T", v.u.fval, t);
+ break;
+ case CTCPLX:
+ if(!iscomplex[t->etype])
+ fatal("overflow: %T complex constant", t);
+ if(mpcmpfltflt(&v.u.cval->real, minfltval[t->etype]) <= 0 ||
+ mpcmpfltflt(&v.u.cval->real, maxfltval[t->etype]) >= 0 ||
+ mpcmpfltflt(&v.u.cval->imag, minfltval[t->etype]) <= 0 ||
+ mpcmpfltflt(&v.u.cval->imag, maxfltval[t->etype]) >= 0)
yyerror("constant %#F overflows %T", v.u.fval, t);
break;
}
@@ -283,8 +372,8 @@ tostr(Val v)
switch(v.ctype) {
case CTINT:
- if(mpcmpfixfix(v.u.xval, minintval[TINT]) < 0
- || mpcmpfixfix(v.u.xval, maxintval[TINT]) > 0)
+ if(mpcmpfixfix(v.u.xval, minintval[TINT]) < 0 ||
+ mpcmpfixfix(v.u.xval, maxintval[TINT]) > 0)
yyerror("overflow in int -> string");
rune = mpgetfix(v.u.xval);
l = runelen(rune);
@@ -380,7 +469,7 @@ evconst(Node *n)
if(consttype(nl) < 0)
return;
wl = nl->type->etype;
- if(isint[wl] || isfloat[wl])
+ if(isint[wl] || isfloat[wl] || iscomplex[wl])
wl = TIDEAL;
nr = n->right;
@@ -391,7 +480,7 @@ evconst(Node *n)
if(consttype(nr) < 0)
return;
wr = nr->type->etype;
- if(isint[wr] || isfloat[wr])
+ if(isint[wr] || isfloat[wr] || iscomplex[wr])
wr = TIDEAL;
// check for compatible general types (numeric, string, etc)
@@ -433,11 +522,12 @@ evconst(Node *n)
rv = nr->val;
- // since wl == wr,
- // the only way v.ctype != nr->val.ctype
- // is when one is CTINT and the other CTFLT.
- // make both CTFLT.
- if(v.ctype != nr->val.ctype) {
+ // convert to common ideal
+ if(v.ctype == CTCPLX || rv.ctype == CTCPLX) {
+ v = tocplx(v);
+ rv = tocplx(rv);
+ }
+ if(v.ctype == CTFLT || rv.ctype == CTFLT) {
v = toflt(v);
rv = toflt(rv);
}
@@ -515,6 +605,20 @@ evconst(Node *n)
mpdivfltflt(v.u.fval, rv.u.fval);
break;
+ case TUP(OADD, CTCPLX):
+ mpaddfltflt(&v.u.cval->real, &rv.u.cval->real);
+ mpaddfltflt(&v.u.cval->imag, &rv.u.cval->imag);
+ break;
+ case TUP(OSUB, CTCPLX):
+ mpsubfltflt(&v.u.cval->real, &rv.u.cval->real);
+ mpsubfltflt(&v.u.cval->imag, &rv.u.cval->imag);
+ break;
+ case TUP(OMUL, CTCPLX):
+ goto illegal; // TODO
+ case TUP(ODIV, CTCPLX):
+ goto illegal; // TODO
+ break;
+
case TUP(OEQ, CTNIL):
goto settrue;
case TUP(ONE, CTNIL):
@@ -737,6 +841,7 @@ nodlit(Val v)
break;
case CTINT:
case CTFLT:
+ case CTCPLX:
n->type = types[TIDEAL];
break;
case CTNIL:
@@ -815,7 +920,8 @@ defaultlit(Node **np, Type *t)
if(t != T) {
if(isint[t->etype])
n->type = t;
- else if(isfloat[t->etype]) {
+ else
+ if(isfloat[t->etype]) {
n->type = t;
n->val = toflt(n->val);
}
@@ -827,7 +933,25 @@ defaultlit(Node **np, Type *t)
if(t != T) {
if(isfloat[t->etype])
n->type = t;
- else if(isint[t->etype]) {
+ else
+ if(isint[t->etype]) {
+ n->type = t;
+ n->val = toint(n->val);
+ }
+ }
+ overflow(n->val, n->type);
+ break;
+ case CTCPLX:
+ n->type = types[TCOMPLEX];
+ if(t != T) {
+ if(iscomplex[t->etype])
+ n->type = t;
+ else
+ if(isfloat[t->etype]) {
+ n->type = t;
+ n->val = toflt(n->val);
+ } else
+ if(isint[t->etype]) {
n->type = t;
n->val = toint(n->val);
}
@@ -862,6 +986,11 @@ defaultlit2(Node **lp, Node **rp, int force)
}
if(!force)
return;
+ if(isconst(l, CTCPLX) || isconst(r, CTCPLX)) {
+ convlit(lp, types[TCOMPLEX]);
+ convlit(rp, types[TCOMPLEX]);
+ return;
+ }
if(isconst(l, CTFLT) || isconst(r, CTFLT)) {
convlit(lp, types[TFLOAT]);
convlit(rp, types[TFLOAT]);
@@ -1013,22 +1142,28 @@ convconst(Node *con, Type *t, Val *val)
}
if(isfloat[tt]) {
- if(con->val.ctype == CTINT) {
- con->val.ctype = CTFLT;
- con->val.u.fval = mal(sizeof *con->val.u.fval);
- mpmovefixflt(con->val.u.fval, val->u.xval);
- }
- if(con->val.ctype != CTFLT)
- fatal("convconst ctype=%d %T", con->val.ctype, t);
- if(!isfloat[tt]) {
- // easy to handle, but can it happen?
- fatal("convconst CTINT %T", t);
- }
+ con->val = toflt(con->val);
+// if(con->val.ctype == CTINT) {
+// con->val.ctype = CTFLT;
+// con->val.u.fval = mal(sizeof *con->val.u.fval);
+// mpmovefixflt(con->val.u.fval, val->u.xval);
+// }
+// if(con->val.ctype != CTFLT)
+// fatal("convconst ctype=%d %T", con->val.ctype, t);
if(tt == TFLOAT32)
con->val.u.fval = truncfltlit(con->val.u.fval, t);
return;
}
+ if(iscomplex[tt]) {
+ con->val = tocplx(con->val);
+ if(tt == TCOMPLEX64) {
+ con->val.u.cval->real = *truncfltlit(&con->val.u.cval->real, types[TFLOAT32]);
+ con->val.u.cval->imag = *truncfltlit(&con->val.u.cval->imag, types[TFLOAT32]);
+ }
+ return;
+ }
+
fatal("convconst %lT constant", t);
}
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index f3bab1355..b9d87070c 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -113,6 +113,13 @@ struct Mpflt
short exp;
};
+typedef struct Mpcplx Mpcplx;
+struct Mpcplx
+{
+ Mpflt real;
+ Mpflt imag;
+};
+
typedef struct Val Val;
struct Val
{
@@ -123,6 +130,7 @@ struct Val
short bval; // bool value CTBOOL
Mpint* xval; // int CTINT
Mpflt* fval; // float CTFLT
+ Mpcplx* cval; // float CTCPLX
Strlit* sval; // string CTSTR
} u;
};
@@ -422,28 +430,32 @@ enum
TINT64, TUINT64,
TINT, TUINT, TUINTPTR,
- TFLOAT32, // 12
+ TCOMPLEX64, // 12
+ TCOMPLEX128,
+ TCOMPLEX,
+
+ TFLOAT32, // 15
TFLOAT64,
TFLOAT,
- TBOOL, // 15
+ TBOOL, // 18
- TPTR32, TPTR64, // 16
+ TPTR32, TPTR64, // 19
- TFUNC, // 18
+ TFUNC, // 21
TARRAY,
T_old_DARRAY,
- TSTRUCT, // 21
+ TSTRUCT, // 24
TCHAN,
TMAP,
- TINTER, // 24
+ TINTER, // 27
TFORW,
TFIELD,
TANY,
TSTRING,
// pseudo-types for literals
- TIDEAL, // 29
+ TIDEAL, // 32
TNIL,
TBLANK,
@@ -459,6 +471,7 @@ enum
CTINT,
CTFLT,
+ CTCPLX,
CTSTR,
CTBOOL,
CTNIL,
@@ -668,6 +681,7 @@ EXTERN uchar isptr[NTYPE];
EXTERN uchar isforw[NTYPE];
EXTERN uchar isint[NTYPE];
EXTERN uchar isfloat[NTYPE];
+EXTERN uchar iscomplex[NTYPE];
EXTERN uchar issigned[NTYPE];
EXTERN uchar issimple[NTYPE];
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 686277425..e6db4e7a7 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -900,6 +900,8 @@ tnum:
goto casedot;
if(c == 'e' || c == 'E')
goto casee;
+ if(c == 'i')
+ goto casei;
if(c1)
yyerror("malformed octal constant");
goto ncu;
@@ -911,6 +913,8 @@ dc:
goto casee;
if(c == 'p' || c == 'P')
goto casep;
+ if(c == 'i')
+ goto casei;
ncu:
*cp = 0;
@@ -933,6 +937,8 @@ casedot:
if(!isdigit(c))
break;
}
+ if(c == 'i')
+ goto casei;
if(c != 'e' && c != 'E')
goto caseout;
@@ -949,6 +955,8 @@ casee:
*cp++ = c;
c = getc();
}
+ if(c == 'i')
+ goto casei;
goto caseout;
casep:
@@ -964,8 +972,24 @@ casep:
*cp++ = c;
c = getc();
}
+ if(c == 'i')
+ goto casei;
goto caseout;
+casei:
+ // imaginary constant
+ *cp = 0;
+ yylval.val.u.cval = mal(sizeof(*yylval.val.u.cval));
+ mpmovecflt(&yylval.val.u.cval->real, 0.0);
+ mpatoflt(&yylval.val.u.cval->imag, lexbuf);
+ if(yylval.val.u.cval->imag.val.ovf) {
+ yyerror("overflow in imaginary constant");
+ mpmovecflt(&yylval.val.u.cval->real, 0.0);
+ }
+ yylval.val.ctype = CTCPLX;
+ DBG("lex: imaginary literal\n");
+ return LLITERAL;
+
caseout:
*cp = 0;
ungetc(c);
@@ -1235,6 +1259,9 @@ static struct
"float32", LNAME, TFLOAT32, OXXX,
"float64", LNAME, TFLOAT64, OXXX,
+ "complex64", LNAME, TCOMPLEX64, OXXX,
+ "complex128", LNAME, TCOMPLEX128, OXXX,
+
"bool", LNAME, TBOOL, OXXX,
"byte", LNAME, TUINT8, OXXX,
"string", LNAME, TSTRING, OXXX,
diff --git a/src/cmd/gc/print.c b/src/cmd/gc/print.c
index 57ebe3f1c..b460953a2 100644
--- a/src/cmd/gc/print.c
+++ b/src/cmd/gc/print.c
@@ -129,6 +129,11 @@ exprfmt(Fmt *f, Node *n, int prec)
else
fmtprint(f, "false");
break;
+ case CTCPLX:
+ fmtprint(f, "%.17g+%.17gi",
+ mpgetflt(&n->val.u.cval->real),
+ mpgetflt(&n->val.u.cval->imag));
+ break;
case CTFLT:
fmtprint(f, "%.17g", mpgetflt(n->val.u.fval));
break;
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index 12d27aa88..2217b582c 100644
--- a/src/cmd/gc/reflect.c
+++ b/src/cmd/gc/reflect.c
@@ -447,19 +447,22 @@ structnames[] =
[TINT64] = "*runtime.Int64Type",
[TUINT64] = "*runtime.Uint64Type",
[TUINTPTR] = "*runtime.UintptrType",
+ [TCOMPLEX] = "*runtime.ComplexType",
+ [TCOMPLEX64] = "*runtime.Complex64Type",
+ [TCOMPLEX128] = "*runtime.Complex128Type",
[TFLOAT] = "*runtime.FloatType",
[TFLOAT32] = "*runtime.Float32Type",
[TFLOAT64] = "*runtime.Float64Type",
[TBOOL] = "*runtime.BoolType",
- [TSTRING] = "*runtime.StringType",
+ [TSTRING] = "*runtime.StringType",
- [TPTR32] = "*runtime.PtrType",
- [TPTR64] = "*runtime.PtrType",
+ [TPTR32] = "*runtime.PtrType",
+ [TPTR64] = "*runtime.PtrType",
[TSTRUCT] = "*runtime.StructType",
- [TINTER] = "*runtime.InterfaceType",
+ [TINTER] = "*runtime.InterfaceType",
[TCHAN] = "*runtime.ChanType",
[TMAP] = "*runtime.MapType",
- [TARRAY] = "*runtime.ArrayType",
+ [TARRAY] = "*runtime.ArrayType",
[TFUNC] = "*runtime.FuncType",
};
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 8b0ce600b..8af57bdf7 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -954,6 +954,9 @@ etnames[] =
[TFLOAT] = "FLOAT",
[TFLOAT32] = "FLOAT32",
[TFLOAT64] = "FLOAT64",
+ [TCOMPLEX] = "COMPLEX",
+ [TCOMPLEX64] = "COMPLEX64",
+ [TCOMPLEX128] = "COMPLEX128",
[TBOOL] = "BOOL",
[TPTR32] = "PTR32",
[TPTR64] = "PTR64",
@@ -1106,10 +1109,10 @@ basicnames[] =
[TFLOAT64] = "float64",
[TBOOL] = "bool",
[TANY] = "any",
- [TSTRING] = "string",
+ [TSTRING] = "string",
[TNIL] = "nil",
- [TIDEAL] = "ideal",
- [TBLANK] = "blank",
+ [TIDEAL] = "ideal",
+ [TBLANK] = "blank",
};
int
@@ -1453,6 +1456,11 @@ Nconv(Fmt *fp)
case CTFLT:
snprint(buf1, sizeof(buf1), "F%g", mpgetflt(n->val.u.fval));
break;
+ case CTCPLX:
+ snprint(buf1, sizeof(buf1), "(F%g+F%gi)",
+ mpgetflt(&n->val.u.cval->real),
+ mpgetflt(&n->val.u.cval->imag));
+ break;
case CTSTR:
snprint(buf1, sizeof(buf1), "S\"%Z\"", n->val.u.sval);
break;
@@ -1665,7 +1673,14 @@ isideal(Type *t)
{
if(t == T)
return 0;
- return t == idealstring || t == idealbool || t->etype == TNIL || t->etype == TIDEAL;
+ if(t == idealstring || t == idealbool)
+ return 1;
+ switch(t->etype) {
+ case TNIL:
+ case TIDEAL:
+ return 1;
+ }
+ return 0;
}
/*
diff --git a/src/pkg/runtime/type.go b/src/pkg/runtime/type.go
index d76edeba4..7227904ac 100644
--- a/src/pkg/runtime/type.go
+++ b/src/pkg/runtime/type.go
@@ -99,6 +99,15 @@ type Float64Type commonType
// FloatType represents a float type.
type FloatType commonType
+// Complex64Type represents a complex64 type.
+type Complex64Type commonType
+
+// Complex128Type represents a complex32 type.
+type Complex128Type commonType
+
+// ComplexType represents a complex type.
+type ComplexType commonType
+
// Int16Type represents an int16 type.
type Int16Type commonType