implemented AST based overloading
This commit is contained in:
parent
1d842e8b75
commit
a1f6779802
5 changed files with 41 additions and 7 deletions
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
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)
|
||||||
1
todo.txt
1
todo.txt
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue