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 __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 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) { if (!$scanner->get()->isKeyword()) { parent::simpleException($scanner, ['<KEYWORD>']); } $identifier = $scanner->get(); $scanner->next(); $valid = false; switch ($identifier->getValue()) { case 'break': $valid = Globals::$switchDepth > 0; case 'continue': $valid |= Globals::$loopDepth > 0; break; case 'exit': $valid |= Globals::$funcDepth > 0; break; default: throw new \Exception("Control keyword " . $identifier->getValue() . " not implemented yet"); } if (!$valid) { SemanticException::illegalControlStatement($scanner, $identifier->getValue()); } $this->identifier = $identifier; }
public function __construct($scanner, $_symTable, $identifier) { $this->symTable = new SymTable($_symTable); $this->identifier = $identifier; while ($scanner->get()->isIdentifier()) { //variable declaration parse $identifier = $scanner->get(); if (!$scanner->nget()->isOperator(':')) { Node::simpleException($scanner, ['<OPERATOR \':\'>']); } $scanner->next(); $type = SymType::parse($scanner, $_symTable, null); if ($type->isAnonim()) { $this->symTable->append($type); } $this->symTable->append(new SymVar($identifier->getValue(), $type)); // $scanner->next(); Node::semicolonPass($scanner); } if (!$scanner->get()->isKeyword('end')) { Node::simpleException($scanner, ['<KEYWORD \'end\'']); } $scanner->next(); if ($this->symTable->count() == 0) { SemanticException::expected($scanner, ['<VAR DECLARATIONS>']); } }
public static function parseFixed($scanner, $_symTable) { if ($scanner->get()->isIdentifier()) { $aliased = $_symTable->findRecursive($scanner->get()->getValue()); if (is_a($aliased, 'vendor\\SemanticParser\\Nodes\\SymType')) { $scanner->next(); return $aliased; } SemanticException::expected($scanner, ['<TYPE IDENTIFIER>']); } else { if ($scanner->get()->isOperator('^')) { return new SymPointerAnonimType($scanner, $_symTable); } else { if ($scanner->get()->isKeyword('array')) { $type = new SymArrayAnonimType($scanner, $_symTable); if (!$type->isDynamic()) { SemanticException::expected($scanner, ['<FIXED TYPE>']); } return $type; } else { SemanticException::expected($scanner, ['<TYPE>']); } } } }
public function __construct($identifier, $paramList, $_symTable, $isFunc = true) { $symFunc = $_symTable->findRecursive($identifier->getValue()); if ($isFunc) { if ($symFunc == null || !is_a($symFunc, 'vendor\\SemanticParser\\Nodes\\SymFunc')) { //TODO: Throw exceptions like identifier <$identifier> is not a function SemanticException::undeclared(null, $identifier->getValue()); } } $symFuncArgs = $symFunc->getArgs(); if (count($paramList->params) != count($symFuncArgs)) { SemanticException::invalidArgCount($identifier->getValue()); } for ($i = 0; $i < count($paramList->params); $i++) { $class = get_class($symFuncArgs[$i]->type); if (!$class::equal($symFuncArgs[$i]->type, $paramList->params[$i]->symType)) { $paramList->params[$i] = new TypeCast($paramList->params[$i], $symFuncArgs[$i]->type); } } if ($isFunc) { $this->symType = $symFunc->returnType; } $this->symbol = $symFunc; $this->identifier = $identifier; $this->paramList = $paramList; }
public function __construct($node, $symType) { if (!$node->symType->isConvertableTo($symType)) { SemanticException::invalidTypeCast($node->symType, $symType); } $this->node = $node; $this->symType = $symType; }
public function __construct($operand, $operator, $_symTable) { if (!SymSimpleType::equal($operand->symType, Globals::getSimpleType('integer')) && !SymSimpleType::equal($operand->symType, Globals::getSimpleType('real'))) { SemanticException::invalidTypeCast($operand->symType, Globals::getSimpleType('real')); } $this->symType = $operand->symType; $this->operand = $operand; $this->operator = $operator; }
public function __construct($scanner, $_symTable, $identifier) { $symbol = $_symTable->findRecursive($identifier->getValue()); if ($symbol == null || !is_a($symbol, 'vendor\\SemanticParser\\Nodes\\SymVar')) { SemanticException::undeclared($scanner, $identifier->getValue()); } $this->symbol = $symbol; $this->symType = $symbol->type; $this->identifier = $identifier; }
public function __construct($scanner, $_symTable, $identifier) { $this->identifier = $identifier; $type = $scanner->nget(); if (!$type->isIdentifier()) { Node::simpleException($scanner, ['<TYPE IDENTIFIER>']); } $type = $_symTable->findRecursive($type->getValue()); if ($type == null || !is_a($type, 'vendor\\SemanticParser\\Nodes\\SymType')) { SemanticException::expected($scanner, ['<TYPE IDENTIFIER>']); } $this->type = $type; $scanner->next(); }
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 __construct($scanner, $_symTable, $record) { $recType = $record->variable->symType; if (is_a($recType, 'vendor\\SemanticParser\\Nodes\\SymAliasType')) { $recType = $recType->getBase(); } if (!is_a($recType, 'vendor\\SemanticParser\\Nodes\\SymRecordType')) { SemanticException::varAccessTypeMismatch($scanner, $recType, 'record'); } if (!$scanner->get()->isIdentifier()) { parent::simpleException($scanner, ['<FIELD-DESIGNATOR>']); } $identifier = $scanner->get()->getValue(); $designatorType = $recType->getFieldType($identifier); if ($designatorType == null) { SemanticException::undeclared($scanner, $identifier->getValue()); } $this->symType = $designatorType; $this->record = $record; $this->designator = $scanner->get(); $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); }