| 
<?phpnamespace eMacros\Environment;
 
 use eMacros\Scope;
 use eMacros\Package\Package;
 use eMacros\Symbol;
 
 class Environment extends Scope {
 /**
 * Imported packages
 * @var array
 */
 public $packages = array();
 
 /**
 * Program arguments
 * @var array
 */
 public $arguments = array();
 
 /**
 * Validates a aymbol
 * @param \eMacros\Symbol $symbol
 * @throws \UnexpectedValueException
 * @return array
 */
 protected static function symbol($symbol) {
 if ($symbol instanceof Symbol) {
 return array($symbol->symbol, $symbol->package);
 }
 
 throw new \UnexpectedValueException(sprintf("Unexpected value of type '%s'.", is_object($symbol) ? get_class($symbol) : gettype($symbol)));
 }
 
 /**
 * Imports a package to current symbol table
 * @param Package $package
 * @param string $id
 */
 public function import(Package $package, $id = null) {
 $id = is_null($id) ? $package->id : $id;
 
 //load symbols
 $this->symbols = array_merge($package->symbols, $this->symbols);
 
 //load macros
 $this->macros = array_merge($package->macros, $this->macros);
 
 //store package
 $this->packages[$id] = $package;
 }
 
 /**
 * Determines if a given package has been imported
 * @param string $packageId
 * @return boolean
 */
 public function hasPackage($packageId) {
 return in_array($packageId, array_keys($this->packages));
 }
 
 /**
 * Obtains a symbol from environment table
 * (non-PHPdoc)
 * @see \eMacros\Scope::offsetGet()
 */
 public function offsetGet($symbol) {
 list($sym, $pck) = self::symbol($symbol);
 
 if (!is_null($pck)) {
 //check package
 if (!array_key_exists($pck, $this->packages)) {
 throw new \UnexpectedValueException(sprintf("Package '%s' not found.", $pck));
 }
 
 return $this->packages[$pck]->offsetGet($sym);
 }
 
 //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];
 }
 }
 }
 }
 }
 ?>
 |