Mercurial > repos > tabletprog
view modules/symbols.tp @ 331:61f5b794d939
Breaking change: method call syntax now always uses the syntactic receiver as the actual receiver. This makes its behavior different from function call syntax, but solves some problems with methods being shadowed by local variables and the like.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 28 Mar 2015 14:21:04 -0700 |
parents | aea99b93cf2f |
children |
line wrap: on
line source
{ _null <- #{ find:else <- :_ :else { else: } ifDefined:else <- :name ifdef :else { else: } } _local <- 0 _closedover <- 1 _upvar <- 2 _method <- 3 _self <- 4 _parent <- 5 _nextMethodId <- 0 _method <- :_name { _id <- _nextMethodId _nextMethodId <- _id + 1 #{ name <- { _name } id <- { _id } string <- { "method " . _name . "(" . _id . ")" } isMethod? <- { true } isLocal? <- { false } } } _local <- :_name _def { #{ name <- { _name } string <- { "local " . _name } def <- { _def } isMethod? <- { false } closedOver? <- false isLocal? <- { true } } } _upvar <- :parent { if: (parent isLocal?) { parent closedOver?!: true #{ name <- { parent name } def <- { parent def } closedOver? <- { parent closedOver? } isMethod? <- { parent isMethod? } string <- { "upvar " . name} isLocal? <- { false } depth <- 1 } } else: { parent depth!: (parent depth) + 1 } } #{ nullTable <- { _null } tableWithParent <- :_parent { _symbols <- dict hash #{ ifDefined:else <- :name ifdef :else { _symbols ifget: name :sym { ifdef: sym } else: { _parent ifDefined: name :sym { ifdef: (_upvar: sym) } else: else } } find:else <- :name :else { _symbols get: name else: { _parent ifDefined: name :sym { if: (sym isMethod?) { //TODO: methods on parent objects sym } else: { _upvar: sym } } else: { else: } } } defineMethod <- :name { _symbols get: name else: { _symbols set: name (_method: name) } self } define <- :name def { s <- (_local: name def) _symbols set: name s s } find:elseDefine <- :name :def { find: name else: { define: name def } } print <- { foreach: _symbols :name info { print: name . ": " . info . "\n" } } } } table <- { tableWithParent: _null } buildMethodTable <- :tree { _object <- ast obj _assignment <- ast assignment _call <- ast call tree fold: table with: :acc el { if: (el nodeType) = _object { (el messages) fold: acc with: :acc msg { if: (msg nodeType) = _assignment { acc defineMethod: ((msg to) name) } else: { if: (msg nodeType) = _call && (msg llMessage?) { acc defineMethod: (((msg args) value) name) } } acc } } else: { acc } } } } }