metagen/metagen.inc.php

202 lines
4.4 KiB
PHP

<?php
require_once(__DIR__ . '/type.inc.php');
require_once(__DIR__ . '/scope.inc.php');
require_once(__DIR__ . '/struct.inc.php');
require_once(__DIR__ . '/enum.inc.php');
require_once(__DIR__ . '/func.inc.php');
require_once(__DIR__ . '/interface.inc.php');
require_once(__DIR__ . '/service.inc.php');
require_once(__DIR__ . '/util.inc.php');
class mtgMetaInfo
{
public static $BUILTIN_TYPES = array(
'int8', 'int16', 'int32', 'uint8', 'uint16', 'uint32',
'float', 'double', 'uint64', 'int64', 'bool', 'string', 'blob'
);
private $units = array();
private $factory_types = array();
function addUnit(mtgMetaInfoUnit $unit)
{
if(isset($this->units[$unit->object->getName()]))
throw new Exception("Meta info unit '{$unit->object->getName()}' already defined in file '{$this->units[$unit->object->getName()]->file}'");
$this->units[$unit->object->getName()] = $unit;
if($unit->object instanceof mtgMetaStruct)
$this->_registerFactoryStruct($unit->object);
else if($unit->object instanceof mtgMetaService)
{
foreach($unit->object->getUserTypes() as $user_type)
if($user_type instanceof mtgMetaStruct)
$this->_registerFactoryStruct($user_type);
}
}
function delUnit(mtgMetaInfoUnit $unit)
{
unset($this->units[$unit->object->getName()]);
if($unit->object instanceof mtgMetaStruct)
$this->_unregisterFactoryStruct($unit->object);
else if($unit->object instanceof mtgMetaService)
{
foreach($unit->object->getUserTypes() as $user_type)
if($user_type instanceof mtgMetaStruct)
$this->_unregisterFactoryStruct($user_type);
}
}
function getUnits() : array
{
return $this->units;
}
function findUnit($id) : ?mtgMetaInfoUnit
{
if(isset($this->units[$id]))
return $this->units[$id];
return null;
}
function getUnit($id) : mtgMetaInfoUnit
{
$unit = $this->findUnit($id);
if(!$unit)
throw new Exception("Unit '$id' not found");
return $unit;
}
private function _registerFactoryStruct(mtgMetaStruct $struct)
{
if(isset($this->factory_types[$struct->getClassId()]))
throw new Exception("Factory user type with id '{$struct->getClassId()}' already defined for type '{$this->factory_types[$struct->getClassId()]->getName()}'");
$this->factory_types[$struct->getClassId()] = $struct;
}
private function _unregisterFactoryStruct(mtgMetaStruct $struct)
{
unset($this->factory_types[$struct->getClassId()]);
}
function getFactoryTypes() : array
{
return $this->factory_types;
}
function validate()
{
foreach($this->units as $u)
$u->object->validate($this);
}
}
class mtgMetaInfoUnit
{
public ?mtgMetaParsedModule $module = null;
public string $file;
public mtgMetaUnit $object;
function __construct(mtgMetaParsedModule|string $file_or_module, mtgMetaUnit $obj)
{
if($file_or_module instanceof mtgMetaParsedModule)
{
$this->module = $file_or_module;
$this->file = $file_or_module->file;
}
else
{
$this->module = null;
$this->file = $file_or_module;
}
$this->object = $obj;
}
}
//NOTE: represents a meta symbol
abstract class mtgMetaUnit
{
protected ?mtgScope $scope = null;
protected ?mtgOrigin $origin;
protected $tokens = array();
abstract function getName() : string;
function setScope(mtgScope $scope)
{
$this->scope = $scope;
}
function getScope() : ?mtgScope
{
return $this->scope;
}
function setOrigin(mtgOrigin $origin)
{
$this->origin = $origin;
}
function getOrigin() : ?mtgOrigin
{
return $this->origin;
}
function getTokens() : array
{
return $this->tokens;
}
function setTokens(array $tokens)
{
$this->tokens = $tokens;
}
function setToken(string $name, mixed $val)
{
$this->tokens[$name] = $val;
}
function delToken(string $name)
{
unset($this->tokens[$name]);
}
function getToken(string $name) : mixed
{
return $this->hasToken($name) ? $this->tokens[$name] : null;
}
function hasToken(string $name) : bool
{
return array_key_exists($name, $this->tokens);
}
abstract function validate(mtgMetaInfo $meta);
}
class mtgOrigin
{
public $file;
public $line;
function __construct($file = '', $line = 0)
{
$this->file = $file;
$this->line = $line;
}
function __toString()
{
return "{$this->file}@{$this->line}";
}
}