implemented AST based overloading

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

View file

@ -12,18 +12,18 @@
import import
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst, intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
magicsys, condsyms, idents, lexer, options magicsys, condsyms, idents, lexer, options, parampatterns
type type
TCandidateState* = enum TCandidateState* = enum
csEmpty, csMatch, csNoMatch csEmpty, csMatch, csNoMatch
TCandidate* {.final.} = object TCandidate* {.final.} = object
exactMatches*: int exactMatches*: int # also misused to prefer iters over procs
genericMatches: int # also misused to prefer constraints
subtypeMatches: int subtypeMatches: int
intConvMatches: int # conversions to int are not as expensive intConvMatches: int # conversions to int are not as expensive
convMatches: int convMatches: int
genericMatches: int
state*: TCandidateState state*: TCandidateState
callee*: PType # may not be nil! callee*: PType # may not be nil!
calleeSym*: PSym # may 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, proc matchesAux*(c: PContext, n, nOrig: PNode,
m: var TCandidate, marker: var TIntSet) = 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 f = 1 # iterates over formal parameters
var a = 1 # iterates over the actual given arguments var a = 1 # iterates over the actual given arguments
m.state = csMatch # until proven otherwise m.state = csMatch # until proven otherwise
@ -806,6 +815,7 @@ proc matchesAux*(c: PContext, n, nOrig: PNode,
if arg == nil: if arg == nil:
m.state = csNoMatch m.state = csNoMatch
return return
checkConstraint(n.sons[a].sons[1])
if m.baseTypeMatch: if m.baseTypeMatch:
assert(container == nil) assert(container == nil)
container = newNodeI(nkBracket, n.sons[a].info) container = newNodeI(nkBracket, n.sons[a].info)
@ -862,6 +872,7 @@ proc matchesAux*(c: PContext, n, nOrig: PNode,
if f != formalLen - 1: container = nil if f != formalLen - 1: container = nil
else: else:
setSon(m.call, formal.position + 1, arg) setSon(m.call, formal.position + 1, arg)
checkConstraint(n.sons[a])
inc(a) inc(a)
inc(f) inc(f)

View file

@ -632,7 +632,8 @@ proc SameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool =
result = SameTypeAux(a, b, c) result = SameTypeAux(a, b, c)
proc equalParam(a, b: PSym): TParamsEquality = 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: if a.ast == b.ast:
result = paramsEqual result = paramsEqual
elif a.ast != nil and b.ast != nil: 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 overloading
- ``hoist`` pragma for loop hoisting: can be easily done with - ``hoist`` pragma for loop hoisting: can be easily done with
AST overloading + global AST overloading + global
- document overloading based on ASTs
- test&finish first class iterators: - test&finish first class iterators:
* nested iterators * nested iterators