code generator supports constant sequences; more consistent compile time evaluation

This commit is contained in:
Araq 2011-10-07 09:02:08 +02:00
commit 42516c0086
18 changed files with 180 additions and 137 deletions

View file

@ -280,22 +280,33 @@ proc semConst(c: PContext, n: PNode): PNode =
var typ: PType = nil
if a.sons[1].kind != nkEmpty: typ = semTypeNode(c, a.sons[1], nil)
var e = semExprWithType(c, a.sons[2])
if e == nil: GlobalError(a.sons[2].info, errConstExprExpected)
var def = getConstExpr(c.module, e)
if def == nil:
v.flags.incl(sfFakeConst)
def = evalConstExpr(c.module, e)
if def == nil or def.kind == nkEmpty: def = e
# check type compatibility between def.typ and typ:
if typ != nil:
def = fitRemoveHiddenConv(c, typ, def)
else:
typ = def.typ
if not typeAllowed(typ, skConst):
v.flags.incl(sfFakeConst)
if not typeAllowed(typ, skVar):
when true:
var def = semConstExpr(c, a.sons[2])
if def == nil: GlobalError(a.sons[2].info, errConstExprExpected)
# check type compatibility between def.typ and typ:
if typ != nil:
def = fitRemoveHiddenConv(c, typ, def)
else:
typ = def.typ
if not typeAllowed(typ, skConst):
GlobalError(a.info, errXisNoType, typeToString(typ))
else:
var e = semExprWithType(c, a.sons[2])
if e == nil: GlobalError(a.sons[2].info, errConstExprExpected)
var def = getConstExpr(c.module, e)
if def == nil:
v.flags.incl(sfFakeConst)
def = evalConstExpr(c.module, e)
if def == nil or def.kind == nkEmpty: def = e
# check type compatibility between def.typ and typ:
if typ != nil:
def = fitRemoveHiddenConv(c, typ, def)
else:
typ = def.typ
if not typeAllowed(typ, skConst):
v.flags.incl(sfFakeConst)
if not typeAllowed(typ, skVar):
GlobalError(a.info, errXisNoType, typeToString(typ))
v.typ = typ
v.ast = def # no need to copy
addInterfaceDecl(c, v)