public function createProperties(TES4VariableDeclarationList $variableList, TES5GlobalScope $globalScope) { /** * @var TES4VariableDeclaration[] $alreadyDefinedVariables */ $alreadyDefinedVariables = []; foreach ($variableList->getVariableList() as $variable) { $theVariableName = strtolower($variable->getVariableName()); if (isset($alreadyDefinedVariables[$theVariableName])) { if ($variable->getVariableType() == $alreadyDefinedVariables[$theVariableName]->getVariableType()) { continue; //Same variable defined twice, smack the original script developer and fallthrough silently. } throw new ConversionException("Double definition of variable named " . $variable->getVariableName() . " with different types ( " . $alreadyDefinedVariables[$theVariableName]->getVariableType()->value() . " and " . $variable->getVariableType()->value() . " )"); } switch ($variable->getVariableType()) { case TES4Type::T_FLOAT(): $property = new TES5Property($variable->getVariableName(), TES5BasicType::T_FLOAT(), null); break; case TES4Type::T_INT(): case TES4Type::T_SHORT(): case TES4Type::T_LONG(): $property = new TES5Property($variable->getVariableName(), TES5BasicType::T_INT(), null); break; case TES4Type::T_REF(): $property = $this->createPropertyFromReference($variable); break; default: throw new ConversionException("Unknown variable declaration type."); } $globalScope->add($property); $alreadyDefinedVariables[$theVariableName] = $variable; } }
public function getType() { if ($this->leftValue->getType() == TES5BasicType::T_FLOAT() || $this->rightValue->getType() == TES5BasicType::T_FLOAT()) { return TES5BasicType::T_FLOAT(); } return TES5BasicType::T_INT(); }
public function createGlobalScopes() { $globalScopes = []; $globalScope = new TES5GlobalScope(new TES5ScriptHeader("TES4TimerHelper", "TES4TimerHelper", TES5BasicType::T_QUEST(), "")); $globalScopes[] = $globalScope; $globalScope = new TES5GlobalScope(new TES5ScriptHeader("TES4Container", "TES4Container", TES5BasicType::T_QUEST(), "")); $globalScope->add(new TES5Property("isInJail", TES5BasicType::T_BOOL(), "isInJail")); $globalScope->add(new TES5Property("isMurderer", TES5BasicType::T_BOOL(), "isMurderer")); $globalScopes[] = $globalScope; return $globalScopes; }
public function createFromFragmentType(TES5FragmentType $fragmentType) { $localScope = new TES5LocalScope(); switch ($fragmentType) { case TES5FragmentType::T_TIF(): $localScope->addVariable(new TES5LocalVariable("akSpeakerRef", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); break; case TES5FragmentType::T_PF(): $localScope->addVariable(new TES5LocalVariable("akActor", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); break; case TES5FragmentType::T_QF(): break; } return $localScope; }
/** * @param $memberByValue string Type to be created. * @param $basicType TES5BasicType You might override the basic type for this custom type created. * @return \Eloquent\Enumeration\ValueMultitonInterface|TES5CustomType|TES5VoidType */ public static function memberByValue($memberByValue, TES5BasicType $basicType = null) { if ($memberByValue == "void") { return new TES5VoidType(); } try { return TES5BasicType::memberByValue(ucwords($memberByValue)); } catch (\Exception $e) { //Ugly - todo: REFACTOR THIS TO NON-STATIC CLASS AND MOVE THIS TO DI if ($basicType === null) { $analyzer = ESMAnalyzer::instance(); $basicType = $analyzer->getScriptType($memberByValue); } return new TES5CustomType(TES5NameTransformer::transform($memberByValue, self::$scriptsPrefix), self::$scriptsPrefix, $basicType); } }
/** * @param string $scriptName * @param TES4VariableDeclarationList $variableList * @param TES4CodeChunks $script * @return TES5Script * @throws ConversionException */ public function convert($scriptName, TES4VariableDeclarationList $variableList, TES4CodeChunks $script) { //Create the header. $scriptHeader = new TES5ScriptHeader($this->nameTransformer->transform($scriptName, ''), $scriptName, TES5BasicType::T_TOPICINFO(), '', true); $globalScope = new TES5GlobalScope($scriptHeader); foreach ($this->esmAnalyzer->getGlobalVariables() as $globalVariable) { $globalScope->addGlobalVariable($globalVariable); } if ($variableList !== null) { //Converting the variables to the properties. $this->propertiesFactory->createProperties($variableList, $globalScope); } $fragment = $this->fragmentFactory->createFragment(TES5FragmentType::T_TIF(), "Fragment_0", $globalScope, new TES5MultipleScriptsScope([$globalScope]), $script); $blockList = new TES5BlockList(); $blockList->add($fragment); return new TES5Script($scriptHeader, $globalScope, $blockList); }
private function inferenceTypeOfMethodArguments(TES5ObjectCall $objectCall, TES5MultipleScriptsScope $multipleScriptsScope) { /** * Inference the arguments */ $arguments = $objectCall->getArguments(); $argumentNumber = 0; $calledOnType = $objectCall->getAccessedObject()->getType()->getNativeType(); foreach ($arguments->getArguments() as $argument) { /** * Get the argument type according to TES5Inheritance graph. */ $argumentTargetType = TES5InheritanceGraphAnalyzer::findTypeByMethodParameter($calledOnType, $objectCall->getFunctionName(), $argumentNumber); if ($argument->getType() == $argumentTargetType) { ++$argumentNumber; continue; //Same type matched. We do not need to do anything :) } /** * todo - maybe we should move getReferencesTo() to TES5Value and make all of the rest TES5Values just have null references as they do not reference anything? :) */ if (TES5InheritanceGraphAnalyzer::isExtending($argumentTargetType, $argument->getType()->getNativeType()) && $argument instanceof TES5Referencer) { //HACKY! $this->inferenceType($argument->getReferencesTo(), $argumentTargetType, $multipleScriptsScope); } else { //So there's one , one special case where we actually have to cast a var from one to another even though they are not ,,inheriting" from themselves, because they are primitives. //Scenario: there's an T_INT argument, and we feed it with a T_FLOAT variable reference. It won't work :( //We need to cast it on call level ( NOT inference it ) to make it work and not break other possible scenarios ( more specifically, when a float would be inferenced to int and there's a //float assigment somewhere in the code ) if ($argumentTargetType == TES5BasicType::T_INT() && $argument->getType() == TES5BasicType::T_FLOAT()) { if ($argument instanceof TES5Reference) { //HACKY! When we'll clean up this interface, it will dissapear :) $argument->setManualCastTo(TES5BasicType::T_INT()); } } } ++$argumentNumber; } }
public function createCodeChunk(TES4VariableDeclarationList $chunk, TES5CodeScope $codeScope) { foreach ($chunk->getVariableList() as $variable) { switch ($variable->getVariableType()) { case TES4Type::T_FLOAT(): $property = new TES5LocalVariable($variable->getVariableName(), TES5BasicType::T_FLOAT()); break; case TES4Type::T_INT(): case TES4Type::T_SHORT(): case TES4Type::T_LONG(): $property = new TES5LocalVariable($variable->getVariableName(), TES5BasicType::T_INT()); break; case TES4Type::T_REF(): //most basic one, if something from inherited class is used, we will set to the inheriting class $property = new TES5LocalVariable($variable->getVariableName(), TES5BasicType::T_FORM()); break; default: throw new ConversionException("Unknown local variable declaration type."); } $codeScope->getLocalScope()->addVariable($property); } return null; }
public function createFromBlockType($blockType, TES5GlobalScope $globalScope) { $localScope = new TES5LocalScope(); switch ($blockType) { case 'OnUpdate': break; case 'OnActivate': $localScope->addVariable(new TES5LocalVariable("akActivateRef", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); break; case 'OnInit': break; case 'OnSell': $localScope->addVariable(new TES5LocalVariable("akSeller", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); break; case 'OnDeath': $localScope->addVariable(new TES5LocalVariable("akKiller", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); break; case 'OnLoad': break; case 'OnObjectEquipped': $localScope->addVariable(new TES5LocalVariable("akBaseObject", TES5BasicType::T_FORM(), [TES5LocalVariableParameterMeaning::CONTAINER()])); $localScope->addVariable(new TES5LocalVariable("akReference", TES5BasicType::T_OBJECTREFERENCE())); break; case 'OnTriggerEnter': $localScope->addVariable(new TES5LocalVariable("akActivateRef", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR(), TES5LocalVariableParameterMeaning::CONTAINER()])); break; case 'OnEquipped': $localScope->addVariable(new TES5LocalVariable("akActor", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR(), TES5LocalVariableParameterMeaning::CONTAINER()])); break; case 'OnUnequipped': $localScope->addVariable(new TES5LocalVariable("akActor", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); break; case 'OnContainerChanged': $localScope->addVariable(new TES5LocalVariable("akNewContainer", TES5BasicType::T_OBJECTREFERENCE())); $localScope->addVariable(new TES5LocalVariable("akOldContainer", TES5BasicType::T_OBJECTREFERENCE())); break; case 'OnTrigger': $localScope->addVariable(new TES5LocalVariable("akActivateRef", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); break; case 'OnHit': $localScope->addVariable(new TES5LocalVariable("akAggressor", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); $localScope->addVariable(new TES5LocalVariable("akSource", TES5BasicType::T_FORM())); $localScope->addVariable(new TES5LocalVariable("akProjectile", TES5BasicType::T_PROJECTILE())); $localScope->addVariable(new TES5LocalVariable("abPowerAttack", TES5BasicType::T_BOOL())); $localScope->addVariable(new TES5LocalVariable("abSneakAttack", TES5BasicType::T_BOOL())); $localScope->addVariable(new TES5LocalVariable("abBashAttack", TES5BasicType::T_BOOL())); $localScope->addVariable(new TES5LocalVariable("abHitBlocked", TES5BasicType::T_BOOL())); break; case 'OnCombatStateChanged': $localScope->addVariable(new TES5LocalVariable("akTarget", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); $localScope->addVariable(new TES5LocalVariable("aeCombatState", TES5BasicType::T_INT())); break; case 'OnPackageStart': $localScope->addVariable(new TES5LocalVariable("akNewPackage", TES5BasicType::T_PACKAGE())); break; case 'OnPackageDone': $localScope->addVariable(new TES5LocalVariable("akDonePackage", TES5BasicType::T_PACKAGE())); break; case 'OnPackageEnd': $localScope->addVariable(new TES5LocalVariable("akOldPackage", TES5BasicType::T_PACKAGE())); break; case 'OnPackageChange': $localScope->addVariable(new TES5LocalVariable("akOldPackage", TES5BasicType::T_PACKAGE())); break; case 'OnMagicEffectApply': $localScope->addVariable(new TES5LocalVariable("akCaster", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); $localScope->addVariable(new TES5LocalVariable("akMagicEffect", TES5BasicType::T_MAGICEFFECT())); break; case 'OnReset': break; case 'OnEffectStart': $localScope->addVariable(new TES5LocalVariable("akTarget", TES5BasicType::T_ACTOR())); $localScope->addVariable(new TES5LocalVariable("akCaster", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); break; case 'OnEffectFinish': $localScope->addVariable(new TES5LocalVariable("akTarget", TES5BasicType::T_ACTOR())); $localScope->addVariable(new TES5LocalVariable("akCaster", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()])); break; default: throw new ConversionException("Cannot find new block type local scope variables out of " . $blockType); } return $localScope; }
public function getType() { return TES5BasicType::T_BOOL(); }
/** * Extracts implicit reference from calls. * Returns a reference from calls like: * Enable * Disable * Activate * GetInFaction whatsoever * @param TES5GlobalScope $globalScope * @param TES5MultipleScriptsScope $multipleScriptsScope * @param TES5LocalScope $localScope * @return TES5Referencer * @throws \Ormin\OBSLexicalParser\TES5\Exception\ConversionException */ private function extractImplicitReference(TES5GlobalScope $globalScope, TES5MultipleScriptsScope $multipleScriptsScope, TES5LocalScope $localScope) { switch ($globalScope->getScriptHeader()->getBasicScriptType()) { case TES5BasicType::T_OBJECTREFERENCE(): return $this->referenceFactory->createReferenceToSelf($globalScope); case TES5BasicType::T_ACTIVEMAGICEFFECT(): $self = $this->referenceFactory->createReferenceToSelf($globalScope); return $this->createObjectCall($self, "GetTargetActor", $multipleScriptsScope); case TES5BasicType::T_QUEST(): //todo - this should not be done like this //we should actually not try to extract the implicit reference on the non-reference oblivion functions like "stopQuest" //think of this line as a hacky way to just get code forward. return $this->referenceFactory->createReferenceToSelf($globalScope); /** * TIF Fragments */ /** * TIF Fragments */ case TES5BasicType::T_TOPICINFO(): return $this->createReadReference('akSpeakerRef', $globalScope, $multipleScriptsScope, $localScope); default: throw new ConversionException("Cannot extract implicit reference - unknown basic script type."); } }
/** * @param string $EDID * @return TES5Type * @throws ConversionException */ public function getFormTypeByEDID($EDID) { $len = strlen($EDID); $len = $len + 1; $hex = dechex($len); if (strlen($hex) == 1) { $hex = '0' . $hex; } preg_match("#EDID\\x{" . $hex . "}." . $EDID . "\\x{00}#i", $this->esm, $matches, PREG_OFFSET_CAPTURE); if (isset($matches[0])) { $offset = $matches[0][1] - 20; $type = substr($this->esm, $offset, 4); return TypeMapper::map($type); } else { $npc = $this->getNpcByEDID($EDID); if ($npc === null) { throw new ConversionException("Cannot find type for EDID " . $EDID); } return TES5BasicType::T_ACTOR(); } }
/** * @param TES4CodeBlock $block * @param TES5EventBlockList $blockList * @param TES5EventCodeBlock $newBlock * @param TES5MultipleScriptsScope $multipleScriptsScope * @param TES5GlobalScope $globalScope */ public function modify(TES4CodeBlock $block, TES5EventBlockList $blockList, TES5EventCodeBlock $newBlock, TES5GlobalScope $globalScope, TES5MultipleScriptsScope $multipleScriptsScope) { $blockLocalScope = $newBlock->getLocalScope(); switch (strtolower($block->getBlockType())) { case "gamemode": case 'scripteffectupdate': $onInitLocalScope = $this->blockLocalScopeFactory->createFromBlockType("OnInit", $globalScope); $newInitBlock = new TES5EventCodeBlock("OnInit", $onInitLocalScope, $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($onInitLocalScope))); $args = new TES5ObjectCallArguments(); $args->add(new TES5Float(self::ON_UPDATE_TICK)); $function = $this->valueFactory->createObjectCall($this->referenceFactory->createReferenceToSelf($globalScope), "RegisterForUpdate", $multipleScriptsScope, $args); $newInitBlock->addChunk($function); $blockList->add($newInitBlock); break; case "onactivate": $onInitLocalScope = $this->blockLocalScopeFactory->createFromBlockType("OnInit", $globalScope); $newInitBlock = new TES5EventCodeBlock("OnInit", $onInitLocalScope, $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($onInitLocalScope))); $function = $this->valueFactory->createObjectCall($this->referenceFactory->createReferenceToSelf($globalScope), "BlockActivation", $multipleScriptsScope); $newInitBlock->addChunk($function); $blockList->add($newInitBlock); break; case 'onactorequip': $parameterList = $block->getBlockParameterList(); if ($parameterList == null) { break; } $parameterList = $parameterList->getVariableList(); $tesEquippedTarget = $parameterList[0]; $localScope = $newBlock->getCodeScope()->getLocalScope(); $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope); $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->findVariableWithMeaning(TES5LocalVariableParameterMeaning::CONTAINER())), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer); $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope)); $outerBranchCode = unserialize(serialize($newBlock->getCodeScope())); $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope()); $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode))); $newBlock->setCodeScope($newCodeScope); break; case "ontriggeractor": $parameterList = $block->getBlockParameterList(); $localScope = $newBlock->getCodeScope()->getLocalScope(); $activator = $localScope->findVariableWithMeaning(TES5LocalVariableParameterMeaning::ACTIVATOR()); $castedToActor = new TES5LocalVariable("akAsActor", TES5BasicType::T_ACTOR()); $referenceToCastedVariable = $this->referenceFactory->createReferenceToVariable($castedToActor); $referenceToNonCastedVariable = $this->referenceFactory->createReferenceToVariable($activator); $expression = $this->expressionFactory->createArithmeticExpression($referenceToCastedVariable, TES5ArithmeticExpressionOperator::OPERATOR_NOT_EQUAL(), new TES5None()); $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope)); $newCodeScope->getLocalScope()->addVariable($castedToActor); $newCodeScope->add($this->assignationFactory->createAssignation($referenceToCastedVariable, $referenceToNonCastedVariable)); if ($parameterList !== null) { //NOT TESTED $parameterList = $parameterList->getVariableList(); $targetActor = $this->valueFactory->createReadReference($parameterList[0]->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope); $interExpression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($activator), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $targetActor); $interBranchCode = unserialize(serialize($newBlock->getCodeScope())); $outerBranchCode = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($newCodeScope->getLocalScope())); $interBranchCode->getLocalScope()->setParentScope($outerBranchCode->getLocalScope()); $outerBranchCode->add(new TES5Branch(new TES5SubBranch($interExpression, $interBranchCode))); } else { $outerBranchCode = unserialize(serialize($newBlock->getCodeScope())); $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope()); } $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode))); $newBlock->setCodeScope($newCodeScope); break; case 'onadd': $parameterList = $block->getBlockParameterList(); if ($parameterList == null) { break; } $parameterList = $parameterList->getVariableList(); $tesEquippedTarget = $parameterList[0]; $localScope = $newBlock->getCodeScope()->getLocalScope(); $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope); $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akNewContainer")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer); $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope)); $outerBranchCode = unserialize(serialize($newBlock->getCodeScope())); $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope()); $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode))); $newBlock->setCodeScope($newCodeScope); break; case 'ondrop': $parameterList = $block->getBlockParameterList(); if ($parameterList == null) { break; } $parameterList = $parameterList->getVariableList(); $tesEquippedTarget = $parameterList[0]; $localScope = $newBlock->getCodeScope()->getLocalScope(); $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope); $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akOldContainer")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer); $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope)); $outerBranchCode = unserialize(serialize($newBlock->getCodeScope())); $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope()); $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode))); $newBlock->setCodeScope($newCodeScope); break; case 'onpackagestart': $parameterList = $block->getBlockParameterList(); if ($parameterList == null) { break; } $parameterList = $parameterList->getVariableList(); $tesEquippedTarget = $parameterList[0]; $localScope = $newBlock->getCodeScope()->getLocalScope(); $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope); $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akNewPackage")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer); $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope)); $outerBranchCode = unserialize(serialize($newBlock->getCodeScope())); $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope()); $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode))); $newBlock->setCodeScope($newCodeScope); break; case 'onpackagedone': case 'onpackagechange': case 'onpackageend': $parameterList = $block->getBlockParameterList()->getVariableList(); $tesEquippedTarget = $parameterList[0]; $localScope = $newBlock->getCodeScope()->getLocalScope(); $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope); $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akOldPackage")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer); $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope)); $outerBranchCode = unserialize(serialize($newBlock->getCodeScope())); $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope()); $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode))); $newBlock->setCodeScope($newCodeScope); break; case 'onalarm': //@INCONSISTENCE - We don't account for alarm type. $expression = $this->expressionFactory->createArithmeticExpression($this->valueFactory->createObjectCall($this->referenceFactory->createReferenceToSelf($globalScope), "IsAlarmed", $multipleScriptsScope), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), new TES5Bool(true)); $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope)); $outerBranchCode = unserialize(serialize($newBlock->getCodeScope())); $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope()); $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode))); $newBlock->setCodeScope($newCodeScope); break; /** case 'onalarm': { $this->skyrimGroupEventName = 'onhit'; if ($this->eventArgs[1] != 3) { //Nothing eelse is supported really.. $this->omit = true; break; } $branch = new TES4ConditionalBranch(); $expression = new TES4Expression(); $leftConstant = new TES4Constant("akAggressor", "ObjectReference"); // $actionConstant = new TES4Constant($this->eventArgs[1],"Package"); $actionConstant = TES4Factories::createReference($this->eventArgs[2], $this); $expression->left_side = $leftConstant; $expression->right_side = $actionConstant; $expression->comparision_operator = TES4Expression::COMPARISION_OPERATOR_EQUAL; $codeBlock = new TES4CodeBlock(); $codeBlock->chunks = $this->chunks; $branch->ifs[] = array( 'rawExpression' => 'SCRIPT_GENERATED', 'expression' => $expression, 'codeBlock' => $codeBlock ); $this->chunks = new TES4ChunkContainer(); $this->chunks->parent = $this; $this->chunks->addChunk($branch); break; } */ } }
public function getType() { return TES5BasicType::T_FORM(); }
/** * Create a generic-purpose reference. * @param $referenceName * @param TES5GlobalScope $globalScope * @param TES5MultipleScriptsScope $multipleScriptsScope * @param TES5LocalScope $localScope * @return \Ormin\OBSLexicalParser\TES5\AST\Object\TES5ObjectProperty|TES5PlayerReference|TES5Reference */ public function createReference($referenceName, TES5GlobalScope $globalScope, TES5MultipleScriptsScope $multipleScriptsScope, TES5LocalScope $localScope) { //Papyrus compiler somehow treats properties with ,,temp" in them in a special way, so we change them to tmp to accomodate that. if (preg_match('#temp#', $referenceName)) { $referenceName = preg_replace("#temp#i", "tmp", $referenceName); } if (strtolower($referenceName) == "player") { return $this->createReferenceToPlayer(); } if (preg_match("#([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)#i", $referenceName, $matches)) { $mainReference = $this->createReference($matches[1], $globalScope, $multipleScriptsScope, $localScope); $propertyReference = $this->objectPropertyFactory->createObjectProperty($multipleScriptsScope, $mainReference, $matches[2]); //Todo rethink the prefix adding return $propertyReference; } $property = $localScope->getVariableByName($referenceName); if ($property === null) { $property = $globalScope->getPropertyByName($referenceName); //todo rethink how to unify the prefix searching if ($property === null) { foreach ($this->special_conversions as $special_conversion_name => $special_type) { if ($special_conversion_name == $referenceName) { $property = new TES5Property($referenceName, $special_type, $referenceName); break; } } if ($property === null) { if (!$globalScope->hasGlobalVariable($referenceName)) { $property = new TES5Property($referenceName, TES5BasicType::T_FORM(), $referenceName); } else { $property = new TES5Property($referenceName, TES5BasicType::T_GLOBALVARIABLE(), $referenceName); } } $globalScope->add($property); } } return new TES5Reference($property); }
public function getType() { return TES5BasicType::T_STRING(); }
protected function execute(InputInterface $input, OutputInterface $output) { set_time_limit(10800); $target = 'Standalone'; $errorLog = fopen("graph_error_log", "w+"); $log = fopen("graph_debug_log", "w+"); $buildTarget = BuildTargetFactory::get($target); if (count(array_slice(scandir($buildTarget->getWorkspacePath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getTranspiledPath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getArtifactsPath()), 2)) > 0) { $output->writeln("Target " . $target . " current build dir not clean, archive it manually."); return; } $sourceFiles = array_slice(scandir($buildTarget->getSourcePath()), 2); $inferencer = new TES5TypeInferencer(new ESMAnalyzer(new TypeMapper()), $buildTarget->getSourcePath()); $dependencyGraph = []; $usageGraph = []; $progressBar = new CliProgressBar(count($sourceFiles)); $progressBar->display(); foreach ($sourceFiles as $sourceFile) { try { $scriptName = substr($sourceFile, 0, -4); $AST = $buildTarget->getAST($buildTarget->getSourceFromPath($scriptName)); /** * @var TES4ObjectProperty[] $propertiesAccesses */ $propertiesAccesses = []; $AST->filter(function ($data) use(&$propertiesAccesses) { if ($data instanceof TES4ObjectProperty) { $propertiesAccesses[] = $data; } }); /** * @var TES5Property[] $preparedProperties */ $preparedProperties = []; /** * @var TES5Type[] $preparedPropertiesTypes */ $preparedPropertiesTypes = []; foreach ($propertiesAccesses as $property) { preg_match("#([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)#i", $property->getData(), $matches); $propertyName = $matches[1]; $propertyKeyName = strtolower($propertyName); if (!isset($preparedProperties[$propertyKeyName])) { $preparedProperty = new TES5Property($propertyName, TES5BasicType::T_FORM(), $matches[1]); $preparedProperties[$propertyKeyName] = $preparedProperty; $inferencingType = $inferencer->resolveInferenceTypeByReferenceEdid($preparedProperty); $preparedPropertiesTypes[$propertyKeyName] = $inferencingType; } else { $preparedProperty = $preparedProperties[$propertyKeyName]; $inferencingType = $inferencer->resolveInferenceTypeByReferenceEdid($preparedProperty); if ($inferencingType != $preparedPropertiesTypes[$propertyKeyName]) { throw new ConversionException("Cannot settle up the properties types - conflict."); } } } fwrite($log, $scriptName . " - " . count($preparedProperties) . " prepared" . PHP_EOL); foreach ($preparedProperties as $preparedPropertyKey => $preparedProperty) { //Only keys are lowercased. $lowerPropertyType = strtolower($preparedPropertiesTypes[$preparedPropertyKey]->value()); $lowerScriptType = strtolower($scriptName); if (!isset($dependencyGraph[$lowerPropertyType])) { $dependencyGraph[$lowerPropertyType] = []; } $dependencyGraph[$lowerPropertyType][] = $lowerScriptType; if (!isset($usageGraph[$lowerScriptType])) { $usageGraph[$lowerScriptType] = []; } $usageGraph[$lowerScriptType][] = $lowerPropertyType; fwrite($log, 'Registering a dependency from ' . $scriptName . ' to ' . $preparedPropertiesTypes[$preparedPropertyKey]->value() . PHP_EOL); } $progressBar->progress(); } catch (\Exception $e) { fwrite($errorLog, $sourceFile . PHP_EOL . $e->getMessage()); continue; } } $progressBar->end(); $graph = new TES5ScriptDependencyGraph($dependencyGraph, $usageGraph); file_put_contents('app/graph', serialize($graph)); fclose($errorLog); fclose($log); }
public function getType() { return TES5BasicType::T_STRING(); //concatenated value is always a string ( what else.. :) ) }
public function getType() { return TES5BasicType::T_ACTOR(); }