implemented AST based overloading

This commit is contained in:
Araq
2012-12-06 08:45:18 +01:00
parent 1d842e8b75
commit a1f6779802
5 changed files with 41 additions and 7 deletions

View File

@@ -29,7 +29,7 @@ proc equalGenericParams(procA, procB: PNode): bool =
a = procA.sons[i].sym
b = procB.sons[i].sym
if (a.name.id != b.name.id) or
not sameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): return
not sameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): return
if (a.ast != nil) and (b.ast != nil):
if not ExprStructuralEquivalent(a.ast, b.ast): return
result = true
@@ -44,7 +44,7 @@ proc SearchForProc*(c: PContext, fn: PSym, tos: int): PSym =
if equalGenericParams(result.ast.sons[genericParamsPos],
fn.ast.sons[genericParamsPos]):
case equalParams(result.typ.n, fn.typ.n)
of paramsEqual:
of paramsEqual:
return
of paramsIncompatible:
LocalError(fn.info, errNotOverloadable, fn.name.s)

View File

@@ -12,18 +12,18 @@
import
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
magicsys, condsyms, idents, lexer, options
magicsys, condsyms, idents, lexer, options, parampatterns
type
TCandidateState* = enum
csEmpty, csMatch, csNoMatch
TCandidate* {.final.} = object
exactMatches*: int
exactMatches*: int # also misused to prefer iters over procs
genericMatches: int # also misused to prefer constraints
subtypeMatches: int
intConvMatches: int # conversions to int are not as expensive
convMatches: int
genericMatches: int
state*: TCandidateState
callee*: PType # may not be nil!
calleeSym*: PSym # may be nil
@@ -773,6 +773,15 @@ proc setSon(father: PNode, at: int, son: PNode) =
proc matchesAux*(c: PContext, n, nOrig: PNode,
m: var TCandidate, marker: var TIntSet) =
template checkConstraint(n: expr) {.immediate, dirty.} =
if not formal.constraint.isNil:
if matchNodeKinds(formal.constraint, n):
# better match over other routines with no such restriction:
inc(m.genericMatches, 100)
else:
m.state = csNoMatch
return
var f = 1 # iterates over formal parameters
var a = 1 # iterates over the actual given arguments
m.state = csMatch # until proven otherwise
@@ -805,7 +814,8 @@ proc matchesAux*(c: PContext, n, nOrig: PNode,
n.sons[a].sons[1], nOrig.sons[a].sons[1])
if arg == nil:
m.state = csNoMatch
return
return
checkConstraint(n.sons[a].sons[1])
if m.baseTypeMatch:
assert(container == nil)
container = newNodeI(nkBracket, n.sons[a].info)
@@ -862,6 +872,7 @@ proc matchesAux*(c: PContext, n, nOrig: PNode,
if f != formalLen - 1: container = nil
else:
setSon(m.call, formal.position + 1, arg)
checkConstraint(n.sons[a])
inc(a)
inc(f)

View File

@@ -632,7 +632,8 @@ proc SameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool =
result = SameTypeAux(a, b, c)
proc equalParam(a, b: PSym): TParamsEquality =
if SameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}):
if SameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}) and
ExprStructuralEquivalent(a.constraint, b.constraint):
if a.ast == b.ast:
result = paramsEqual
elif a.ast != nil and b.ast != nil:

View File

@@ -0,0 +1,21 @@
discard """
output: '''string literal
no string literal
no string literal'''
"""
proc optLit(a: string{lit}) =
echo "string literal"
proc optLit(a: string) =
echo "no string literal"
const
constant = "abc"
var
variable = "xyz"
optLit("literal")
optLit(constant)
optLit(variable)

View File

@@ -6,6 +6,7 @@ version 0.9.2
overloading
- ``hoist`` pragma for loop hoisting: can be easily done with
AST overloading + global
- document overloading based on ASTs
- test&finish first class iterators:
* nested iterators