<?php namespace eMacros;
class Scope implements \ArrayAccess, \IteratorAggregate { /** * Symboil table * @var array */ public $symbols = array(); /** * Macros list * @var array */ public $macros = array(); protected static function symbol($symbol) { if ($symbol instanceof Symbol) { return $symbol->symbol; } elseif (is_string($symbol)) { return $symbol; } throw new \UnexpectedValueException(sprintf("Unexpected value of type '%s'.", is_object($symbol) ? get_class($symbol) : gettype($symbol))); } /** * Obtains a symbol from table * (non-PHPdoc) * @see ArrayAccess::offsetGet() */ public function offsetGet($symbol) { $sym = self::symbol($symbol);
//is symbol defined on this scope? if (array_key_exists($sym, $this->symbols)) { return $this->symbols[$sym]; } else { foreach ($this->macros as $regex => $callback) { if (preg_match($regex, $sym, $matches)) { $this->symbols[$sym] = $callback->__invoke($matches); return $this->symbols[$sym]; } } } return null; } public function offsetExists($symbol) { return true; } /** * Stores a symbol * Used when setting up a Scope/Package * Ex: $this['.'] = new Concatenation(); * (non-PHPdoc) * @see ArrayAccess::offsetSet() */ public function offsetSet($symbol, $value) { $symbol = Symbol::validateSymbol($symbol); $this->symbols[$symbol] = $value; } /** * Removes a symbol from table * (non-PHPdoc) * @see ArrayAccess::offsetUnset() */ public function offsetUnset($symbol) { unset($this->symbols[$symbol]); } /** * Obtains a symbol iterator * (non-PHPdoc) * @see IteratorAggregate::getIterator() */ public function getIterator() { $symbols = array(); foreach ($this->listSymbols() as $name) { $symbols[$name] = $this[$name]; } return new \ArrayIterator($symbols); } /** * Obtains all defined symbols * @return array */ public function listSymbols() { return array_keys($this->symbols); } /** * Adds a new macro * @param string $regex * @param \Closure $handler */ public function macro($regex, \Closure $handler) { $this->macros[$regex] = $handler; } } ?>
|