view modules/symbols.tp @ 302:aea99b93cf2f

More fleshed out implementation of symbol tables
author Michael Pavone <pavone@retrodev.com>
date Fri, 25 Jul 2014 13:46:43 -0700
parents 98147071baf6
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
				}
			}
		}
	}
}