mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 11:54:11 +00:00
implemented AST based overloading
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
21
tests/run/tastoverload1.nim
Normal file
21
tests/run/tastoverload1.nim
Normal 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)
|
||||
Reference in New Issue
Block a user