public function __construct($scanner, $_symTable, $array) { $arrayType = $array->variable->symType; if (!is_a($arrayType, 'vendor\\SemanticParser\\Nodes\\SymArrayType')) { SemanticException::varAccessTypeMismatch($scanner, $arrayType, 'array'); } $this->array = $array; $this->indexes = []; $continue = true; $idx = 0; while (!$scanner->get()->isOperator(']')) { if (!$continue) { parent::simpleException($scanner, ["<OPERATOR ']'>"]); } $this->indexes[$idx] = new Expression($scanner, $_symTable); if (!$arrayType->checkIndex($this->indexes[$idx], $idx, $_symTable)) { SemanticException::raw($scanner, "Array index type mismatch"); } $idx++; $continue = $scanner->get()->isOperator(','); if ($scanner->get()->isOperator(']')) { break; } $scanner->next(); } if ($idx != count($arrayType->dimensions)) { SemanticException::raw($scanner, "Array should be dereferenced completely"); } $this->symType = $arrayType->type; if ($continue) { parent::simpleException($scanner, ['<INDEX-EXPRESSION>']); } $scanner->next(); }
public function checkIndex($expression, $idx, $_symTable) { if (count($this->dimensions) <= $idx) { SemanticException::raw('Array has already completely dereferenced'); } return SymSimpleType::equal($expression->symType, $_symTable->findRecursive('integer')); }
public function __construct($scanner, $_symTable) { parent::requireKeyword($scanner, 'for'); $scanner->next(); $this->counter = VariableAccess::parse($scanner, $_symTable); if (!SymSimpleType::equal($this->counter->symType, Globals::getSimpleType('integer'))) { SemanticException::raw($scanner, 'Counter must be integer'); } parent::requireOperator($scanner, ':='); $scanner->next(); $this->from = new Expression($scanner, $_symTable); $this->from = TypeCast::tryTypeCast($this->from, 'integer'); switch ($scanner->get()->getValue()) { case 'to': $this->direction = self::DIRECTION_ASC; break; case 'downto': $this->direction = self::DIRECTION_DESC; break; default: parent::simpleException($scanner, ['<KEYWORD \'to\'>', '<KEYWORD \'downto\'>']); } $scanner->next(); $this->to = new Expression($scanner, $_symTable); $this->to = TypeCast::tryTypeCast($this->to, 'integer'); parent::requireKeyword($scanner, 'do'); $scanner->next(); Globals::$loopDepth++; $this->statements = CompoundStatement::smartParse($scanner, $_symTable); Globals::$loopDepth--; }
public function __construct($scanner, $_symTable, $identifier) { $this->identifier = $identifier; $this->from = self::getRangeValue($scanner, $_symTable); $dots = $scanner->nget(); if (!$dots->isOperator('..')) { Node::simpleException($scanner, ['<OPERATOR \'..\'>']); } $scanner->next(); $this->to = self::getRangeValue($scanner, $_symTable); if ($this->from > $this->to) { SemanticException::raw($scanner, 'Found Subrange type, but FROM > TO'); } $scanner->next(); }
public function appendForwardable($forwardable) { $pretendent = $this->findRecursive($forwardable->identifier); if (!is_a($forwardable, 'vendor\\SemanticParser\\Nodes\\SymProc')) { SemanticException::raw(null, '{$forwardable->identifier} is not forwardable!'); } $pretendent = $this->find($forwardable->identifier); if ($pretendent == null) { $this->append($forwardable); return; } if (is_a($pretendent, 'vendor\\SemanticParser\\Nodes\\SymProc') && $pretendent->isDefined()) { SemanticException::raw(null, "<{$forwardable->identifier}> has been already defined!"); } if (get_class($forwardable) != get_class($pretendent)) { SemanticException::raw(null, "<{$forwardable->identifier}> definition and declaration are different!"); } $class = get_class($forwardable); if (!$class::cmpSignature($forwardable, $pretendent)) { SemanticException::raw(null, "<{$forwardable->identifier}> definition and declaration are different!"); } $pretendent->mergeWith($forwardable); }