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();
 }
Exemple #2
0
 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--;
 }
Exemple #3
0
 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;
 }
Exemple #5
0
 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>']);
     }
 }
Exemple #6
0
 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;
 }
Exemple #8
0
 public function __construct($node, $symType)
 {
     if (!$node->symType->isConvertableTo($symType)) {
         SemanticException::invalidTypeCast($node->symType, $symType);
     }
     $this->node = $node;
     $this->symType = $symType;
 }
Exemple #9
0
 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;
 }
Exemple #10
0
 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;
 }
Exemple #11
0
 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();
 }
Exemple #12
0
 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();
 }
Exemple #14
0
 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);
 }