first version of commonType
This commit is contained in:
parent
f7c7d95d89
commit
adc75d0201
3 changed files with 57 additions and 0 deletions
|
|
@ -58,6 +58,37 @@ proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
|
||||||
result = copyNode(arg)
|
result = copyNode(arg)
|
||||||
result.typ = formal
|
result.typ = formal
|
||||||
|
|
||||||
|
proc commonType*(x, y: PType): PType =
|
||||||
|
# new type relation that is used for array constructors,
|
||||||
|
# if expressions, etc.:
|
||||||
|
if x == nil: return y
|
||||||
|
var a = skipTypes(x, {tyGenericInst})
|
||||||
|
var b = skipTypes(y, {tyGenericInst})
|
||||||
|
result = x
|
||||||
|
if a.kind in {tyExpr, tyNil}: return y
|
||||||
|
elif b.kind in {tyExpr, tyNil}: return x
|
||||||
|
elif b.kind in {tyArray, tyArrayConstr, tySet, tySequence} and
|
||||||
|
a.kind == b.kind:
|
||||||
|
# check for seq[empty] vs. seq[int]
|
||||||
|
let idx = ord(b.kind in {tyArray, tyArrayConstr})
|
||||||
|
if a.sons[idx].kind == tyEmpty: return y
|
||||||
|
#elif b.sons[idx].kind == tyEmpty: return x
|
||||||
|
else:
|
||||||
|
var k = tyNone
|
||||||
|
if a.kind in {tyRef, tyPtr}:
|
||||||
|
k = a.kind
|
||||||
|
if b.kind != a.kind: return x
|
||||||
|
a = a.sons[0]
|
||||||
|
b = b.sons[0]
|
||||||
|
if a.kind == tyObject and b.kind == tyObject:
|
||||||
|
result = commonSuperclass(a, b)
|
||||||
|
# this will trigger an error later:
|
||||||
|
if result.isNil: return x
|
||||||
|
if k != tyNone:
|
||||||
|
let r = result
|
||||||
|
result = NewType(k, r.owner)
|
||||||
|
result.addSonSkipIntLit(r)
|
||||||
|
|
||||||
proc isTopLevel(c: PContext): bool {.inline.} =
|
proc isTopLevel(c: PContext): bool {.inline.} =
|
||||||
result = c.tab.tos <= 2
|
result = c.tab.tos <= 2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -904,6 +904,26 @@ proc inheritanceDiff*(a, b: PType): int =
|
||||||
inc(result)
|
inc(result)
|
||||||
result = high(int)
|
result = high(int)
|
||||||
|
|
||||||
|
proc commonSuperclass*(a, b: PType): PType =
|
||||||
|
# quick check: are they the same?
|
||||||
|
if sameObjectTypes(a, b): return a
|
||||||
|
|
||||||
|
# simple algorithm: we store all ancestors of 'a' in a ID-set and walk 'b'
|
||||||
|
# up until the ID is found:
|
||||||
|
assert a.kind == tyObject
|
||||||
|
assert b.kind == tyObject
|
||||||
|
var x = a
|
||||||
|
var ancestors = initIntSet()
|
||||||
|
while x != nil:
|
||||||
|
x = skipTypes(x, skipPtrs)
|
||||||
|
ancestors.incl(x.id)
|
||||||
|
x = x.sons[0]
|
||||||
|
var y = b
|
||||||
|
while y != nil:
|
||||||
|
y = skipTypes(y, skipPtrs)
|
||||||
|
if ancestors.contains(y.id): return y
|
||||||
|
y = y.sons[0]
|
||||||
|
|
||||||
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool
|
proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool
|
||||||
proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool =
|
proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind): bool =
|
||||||
result = true
|
result = true
|
||||||
|
|
|
||||||
6
todo.txt
6
todo.txt
|
|
@ -12,6 +12,12 @@ version 0.9.2
|
||||||
allow 'of (var x = 23; nkIdent)'
|
allow 'of (var x = 23; nkIdent)'
|
||||||
* allow (var x = 12; for i in ... ; x) construct
|
* allow (var x = 12; for i in ... ; x) construct
|
||||||
* try except as an expression
|
* try except as an expression
|
||||||
|
- make use of commonType relation in expressions
|
||||||
|
- further expr/stmt unification:
|
||||||
|
- nkIfStmt vs nkIfExpr
|
||||||
|
- start with JS backend and support exprs everywhere
|
||||||
|
- then enhance C backend
|
||||||
|
- OR: do the temp stuff in transf
|
||||||
|
|
||||||
Bugs
|
Bugs
|
||||||
====
|
====
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue