LCOV - code coverage report
Current view: top level - src/common - exprtype.cpp (source / functions) Hit Total Coverage
Test: flower-f.info Lines: 133 260 51.2 %
Date: 2022-06-10 00:44:15 Functions: 5 8 62.5 %

          Line data    Source code
       1             : #include <iostream>
       2             : #include "common/obstacle.hpp"
       3             : #include "common/exprtype.hpp"
       4             : 
       5           0 : void debugOp(operation_t op) {
       6           0 :     switch (op) {
       7           0 :         case INV: std::cout << "INV "; break;
       8           0 :         case PLUS: std::cout << "PLUS "; break;
       9           0 :         case MINUS: std::cout << "MINUS "; break;
      10           0 :         case MUL: std::cout << "MUL "; break;
      11           0 :         case DIV: std::cout << "DIV "; break;
      12           0 :         case LOR: std::cout << "LOR "; break;
      13           0 :         case LAND: std::cout << "LAND "; break;
      14           0 :         case LNOT: std::cout << "LNOT "; break;
      15           0 :         case MOD: std::cout << "MOD "; break;
      16           0 :         case LESS: std::cout << "LESS "; break;
      17           0 :         case GRTR: std::cout << "GRTR "; break;
      18           0 :         case LESSEQ: std::cout << "LESSEQ "; break;
      19           0 :         case GRTREQ: std::cout << "GRTREQ "; break;
      20           0 :         case EQ: std::cout << "EQ "; break;
      21           0 :         case NEQ: std::cout << "NEQ "; break;
      22           0 :         case ASSIGN: std::cout << "ASSIGN "; break;
      23           0 :         case STOP: std::cout << "STOP "; break;
      24           0 :         case WRITE: std::cout << "WRITE "; break;
      25           0 :         case ENDL: std::cout << "ENDL "; break;
      26           0 :         case READ: std::cout << "READ "; break;
      27           0 :         case JIT: std::cout << "JIT "; break;
      28           0 :         case JMP: std::cout << "JMP "; break;
      29           0 :         case RET: std::cout << "RET "; break;
      30           0 :         case CALL: std::cout << "CALL "; break;
      31           0 :         case LOAD: std::cout << "LOAD "; break;
      32           0 :         case SHARE: std::cout << "SHARE "; break;
      33           0 :         case FORK: std::cout << "FORK "; break;
      34           0 :         case LOCK: std::cout << "LOCK "; break;
      35           0 :         case NONE: std::cout << "NONE "; break;
      36           0 :         case UNPACK: std::cout << "UNPACK "; break;
      37           0 :         default: throw Obstacle(PANIC);
      38             :     }
      39           0 : }
      40             : 
      41        1049 : type_t expressionType(type_t t1, type_t t2, operation_t o) {
      42        1049 :     type_t r = _NONE_;
      43             : 
      44             :     #ifdef DEBUG
      45             :     std::cout << "Проверка " << typetostr(t1) << " " << typetostr(t2) << std::endl;
      46             :     #endif
      47             : 
      48        1049 :     switch (o) {
      49          65 :         case PLUS:
      50          65 :             switch (t1) {
      51             :                 // INT PLUS INT  = INT
      52             :                 // INT PLUS REAL = REAL
      53          32 :                 case _INT_:
      54          32 :                     r = t2;
      55          32 :                     if ((t2 != _INT_) && (t2 != _REAL_) && (t2 != _STRUCT_)) 
      56           0 :                         throw Obstacle(EXPR_BAD_TYPE);
      57          32 :                     break;
      58             : 
      59             :                 // REAL PLUS INT  = REAL
      60             :                 // REAL PLUS REAL = REAL
      61          19 :                 case _REAL_:
      62          19 :                     r = _REAL_;
      63          19 :                     if ((t2 != _INT_) && (t2 != _REAL_))
      64           0 :                         throw Obstacle(EXPR_BAD_TYPE);
      65          19 :                     break;
      66             : 
      67             :                 // STRING PLUS STRING = STRING
      68          12 :                 case _STRING_:
      69          12 :                     r = _STRING_;
      70          12 :                     if (t2 != _STRING_) 
      71           0 :                         throw Obstacle(EXPR_BAD_TYPE);
      72          12 :                     break;
      73             :                 
      74             :                 // STRUCT PLUS STRUCT = STRUCT
      75             :                 // STRUCT PLUS INT    = STRUCT
      76             :                 // STRUCT PLUS REAL   = STRUCT
      77             :                 // STRUCT PLUS STRING = STRUCT
      78           2 :                 case _STRUCT_:
      79           2 :                     r = _STRUCT_;
      80           2 :                     if ((t2 == _BOOLEAN_) || (t2 == _LABEL_) || (t2 == _NONE_))
      81           0 :                         throw Obstacle(EXPR_BAD_TYPE);
      82           2 :                     break;
      83             : 
      84             :                 // _ PLUS INT    = INT
      85             :                 // _ PLUS REAL   = REAL
      86             :                 // _ PLUS STRUCT = STRUCT
      87           0 :                 case _NONE_:
      88           0 :                     r = t2;
      89           0 :                     if ((t2 != _INT_) && (t2 != _REAL_) && (t2 != _STRUCT_))
      90           0 :                         throw Obstacle(EXPR_BAD_TYPE);
      91           0 :                     break;
      92             : 
      93           0 :                 default:
      94           0 :                     throw Obstacle(EXPR_BAD_TYPE);
      95             :             }
      96             : 
      97             :             // STRUCT PLUS STRUCT = STRUCT
      98             :             // INT    PLUS STRUCT = STRUCT
      99             :             // REAL   PLUS STRUCT = STRUCT
     100             :             // STRING PLUS STRUCT = STRUCT
     101             :             // _      PLUS STRUCT = STRUCT
     102          65 :             if (t2 == _STRUCT_) {
     103           0 :                 r = _STRUCT_;
     104           0 :                 if ((t1 == _BOOLEAN_) || (t1 == _LABEL_))
     105           0 :                     throw Obstacle(EXPR_BAD_TYPE);
     106             :             }
     107             : 
     108          65 :             break;
     109             : 
     110          14 :         case MINUS:
     111          14 :             switch (t1) {
     112             :                 // INT MINUS INT  = INT
     113             :                 // INT MINUS REAL = REAL
     114           8 :                 case _INT_:
     115           8 :                     r = t2;
     116           8 :                     if ((t2 != _INT_) && (t2 != _REAL_) && (t2 != _STRUCT_))
     117           0 :                         throw Obstacle(EXPR_BAD_TYPE);
     118           8 :                     break;
     119             : 
     120             :                 // REAL MINUS INT  = REAL
     121             :                 // REAL MINUS REAL = REAL
     122           6 :                 case _REAL_:
     123           6 :                     r = _REAL_;
     124           6 :                     if ((t2 != _INT_) && (t2 != _REAL_)) 
     125           0 :                         throw Obstacle(EXPR_BAD_TYPE);
     126           6 :                     break;
     127             : 
     128             :                 // _ MINUS INT  = REAL
     129             :                 // _ MINUS REAL = REAL
     130             :                 // _ MINUS STRUCT = STRUCT
     131           0 :                 case _NONE_:
     132           0 :                     r = t2;
     133           0 :                     if ((t2 != _INT_) && (t2 != _REAL_) && (t2 != _STRUCT_)) 
     134           0 :                         throw Obstacle(EXPR_BAD_TYPE);
     135           0 :                     break;
     136             : 
     137             :                 // STRUCT MINUS STRUCT = STRUCT
     138             :                 // STRUCT MINUS INT    = STRUCT
     139             :                 // STRUCT MINUS REAL   = STRUCT
     140           0 :                 case _STRUCT_:
     141           0 :                     r = _STRUCT_;
     142           0 :                     if ((t2 != _INT_) && (t2 != _REAL_) && (t2 != _STRUCT_)) 
     143           0 :                         throw Obstacle(EXPR_BAD_TYPE);
     144           0 :                     break;
     145           0 :                 default:
     146           0 :                     throw Obstacle(EXPR_BAD_TYPE);
     147             :             }
     148             : 
     149             :             // STRUCT MINUS STRUCT = STRUCT
     150             :             // INT    MINUS STRUCT = STRUCT
     151             :             // REAL   MINUS STRUCT = STRUCT
     152             :             // STRING MINUS STRUCT = STRUCT
     153             :             // _      MINUS STRUCT = STRUCT
     154          14 :             if (t2 == _STRUCT_) {
     155           0 :                 r = _STRUCT_;
     156           0 :                 if ((t1 == _BOOLEAN_) || (t1 == _LABEL_)) 
     157           0 :                     throw Obstacle(EXPR_BAD_TYPE);
     158             :             }
     159             : 
     160          14 :             break;
     161             :         
     162          68 :         case MUL: case DIV:
     163          68 :             switch (t1) {
     164             :                 // INT MUL INT  = INT
     165             :                 // INT MUL REAL = REAL
     166             :                 // INT DIV INT  = INT
     167             :                 // INT DIV REAL = REAL
     168          38 :                 case _INT_:
     169          38 :                     r = t2;
     170          38 :                     if ((t2 != _INT_) && (t2 != _REAL_) && (t2 != _STRUCT_))
     171           0 :                         throw Obstacle(EXPR_BAD_TYPE);
     172          38 :                     break;
     173             : 
     174             :                 // REAL MUL INT  = REAL
     175             :                 // REAL MUL REAL = REAL
     176             :                 // REAL DIV INT  = REAL
     177             :                 // REAL DIV REAL = REAL
     178          30 :                 case _REAL_:
     179          30 :                     r = _REAL_;
     180          30 :                     if ((t2 != _INT_) && (t2 != _REAL_)) 
     181           0 :                         throw Obstacle(EXPR_BAD_TYPE);
     182          30 :                     break;
     183             : 
     184           0 :                 case _STRUCT_:
     185           0 :                     r = _STRUCT_;
     186           0 :                     if ((t2 != _INT_) && (t2 != _REAL_) && (t2 != _STRUCT_)) 
     187           0 :                         throw Obstacle(EXPR_BAD_TYPE);
     188           0 :                     break;
     189           0 :                 default:
     190           0 :                     throw Obstacle(EXPR_BAD_TYPE);
     191             :             }
     192             : 
     193          68 :             if (t2 == _STRUCT_) {
     194           1 :                 r = _STRUCT_;
     195           1 :                 if ((t1 != _INT_) && (t1 != _REAL_) && (t1 != _STRUCT_)) 
     196           0 :                         throw Obstacle(EXPR_BAD_TYPE);
     197             :             }
     198             :             
     199          68 :             break;
     200             : 
     201             :         // INT MOD INT = INT
     202             :         // INT MOD STRUCT = STRUCT
     203           4 :         case MOD:
     204           4 :             if ((t1 != _INT_) && (t1 != _STRUCT_))
     205           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     206             :             
     207           4 :             if ((t2 != _INT_) && (t2 != _STRUCT_))
     208           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     209             : 
     210           4 :             if ((t1 == _STRUCT_) || (t2 == _STRUCT_))
     211           0 :                 r = _STRUCT_;
     212           4 :             else r = _INT_;
     213             : 
     214           4 :             break;
     215             : 
     216             :         // _ INV INT     = INT
     217             :         // _ INV REAL    = REAL
     218             :         // _ INV BOOLEAN = BOOLEAN
     219             :         // _ INV STRUCT  = STRUCT
     220           0 :         case INV:
     221           0 :             r = t2;
     222           0 :             if (t1 != _NONE_)
     223           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     224           0 :             if ((t2 == _STRING_) || (t2 == _NONE_) || (t2 == _LABEL_))
     225           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     226             : 
     227           0 :             break;
     228             : 
     229             :         // INT    LESS INT    = BOOLEAN
     230             :         // INT    LESS REAL   = BOOLEAN
     231             :         // REAL   LESS INT    = BOOLEAN
     232             :         // REAL   LESS REAL   = BOOLEAN
     233             :         // INT    GRTR INT    = BOOLEAN
     234             :         // INT    GRTR REAL   = BOOLEAN
     235             :         // REAL   GRTR INT    = BOOLEAN
     236             :         // REAL   GRTR REAL   = BOOLEAN
     237             :         // INT    EQ   INT    = BOOLEAN
     238             :         // INT    EQ   REAL   = BOOLEAN
     239             :         // REAL   EQ   INT    = BOOLEAN
     240             :         // REAL   EQ   REAL   = BOOLEAN
     241             :         // INT    NEQ  INT    = BOOLEAN
     242             :         // INT    NEQ  REAL   = BOOLEAN
     243             :         // REAL   NEQ  INT    = BOOLEAN
     244             :         // REAL   NEQ  REAL   = BOOLEAN
     245             :         // STRING LESS STRING = BOOLEAN
     246             :         // STRING GRTR STRING = BOOLEAN
     247             :         // STRING EQ   STRING = BOOLEAN
     248             :         // STRING NEQ  STRING = BOOLEAN
     249             :         // STRING LESS STRUCT = BOOLEAN
     250             :         // STRING GRTR STRUCT = BOOLEAN
     251             :         // STRING EQ   STRUCT = BOOLEAN
     252             :         // STRING NEQ  STRUCT = BOOLEAN
     253             :         // STRUCT LESS STRING = BOOLEAN
     254             :         // STRUCT GRTR STRING = BOOLEAN
     255             :         // STRUCT EQ   STRING = BOOLEAN
     256             :         // STRUCT NEQ  STRING = BOOLEAN
     257             :         // STRUCT LESS STRUCT = BOOLEAN
     258             :         // STRUCT GRTR STRUCT = BOOLEAN
     259             :         // STRUCT EQ   STRUCT = BOOLEAN
     260             :         // STRUCT NEQ  STRUCT = BOOLEAN
     261          46 :         case LESS: case GRTR: case EQ: case NEQ:
     262          46 :             r = _BOOLEAN_;
     263          46 :             if (((t1 == _INT_) || (t1 == _REAL_)) && 
     264           0 :                     (t2 != _INT_) && (t2 != _REAL_))
     265           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     266             : 
     267          46 :             if (((t1 == _STRING_) || (t1 == _STRUCT_)) && 
     268           0 :                     (t2 != _STRING_) && (t2 != _STRUCT_))
     269           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     270             :             
     271          46 :             if ((t1 == _BOOLEAN_) || (t1 == _LABEL_) || (t1 == _NONE_))
     272           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     273             : 
     274          46 :             if ((t2 == _BOOLEAN_) || (t2 == _LABEL_) || (t2 == _NONE_))
     275           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     276             : 
     277          46 :             break;
     278             : 
     279             :         // INT  LESSEQ INT  = BOOLEAN
     280             :         // INT  LESSEQ REAL = BOOLEAN
     281             :         // REAL LESSEQ INT  = BOOLEAN
     282             :         // REAL LESSEQ REAL = BOOLEAN
     283             :         // INT  GRTREQ INT  = BOOLEAN
     284             :         // INT  GRTREQ REAL = BOOLEAN
     285             :         // REAL GRTREQ INT  = BOOLEAN
     286             :         // REAL GRTREQ REAL = BOOLEAN
     287          12 :         case LESSEQ: case GRTREQ:
     288          12 :             r = _BOOLEAN_;
     289             : 
     290          12 :             if ((t1 != _INT_) && (t1 != _REAL_) && (t1 != _STRUCT_))
     291           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     292             :             
     293          12 :             if ((t2 != _INT_) && (t2 != _REAL_) && (t2 != _STRUCT_))
     294           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     295             : 
     296          12 :             break;
     297             : 
     298             :         // BOOLEAN LOR  BOOLEAN = BOOLEAN
     299             :         // BOOLEAN LAND BOOLEAN = BOOLEAN
     300             :         // STRUCT  LOR  STRUCT  = STRUCT
     301             :         // STRUCT  LAND STRUCT  = STRUCT
     302          12 :         case LOR: case LAND:
     303          12 :             r = t1;
     304          12 :             if ((t1 != _BOOLEAN_) && (t1 != _STRUCT_) && (t1 != t2)) 
     305           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     306             : 
     307          12 :             break;
     308             : 
     309             :         // _ LNOT BOOLEAN = BOOLEAN
     310             :         // _ LNOT STRUCT  = STRUCT
     311          19 :         case LNOT:
     312          19 :             r = t2;
     313          19 :             if ((t1 != _NONE_) || ((t2 != _BOOLEAN_) && (t2 != _STRUCT_)))
     314           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     315             : 
     316          19 :             break;
     317             : 
     318             :         // INT     ASSIGN INT     = INT
     319             :         // INT     ASSIGN REAL    = INT
     320             :         // REAL    ASSIGN INT     = REAL
     321             :         // REAL    ASSIGN REAL    = REAL
     322             :         // STRING  ASSIGN STRING  = STRING
     323             :         // BOOLEAN ASSIGN BOOLEAN = BOOLEAN
     324             :         // STRUCT  ASSIGN STRUCT  = STRUCT
     325         197 :         case ASSIGN:
     326         197 :             r = _NONE_;
     327         197 :             if (((t1 == _INT_) || (t1 == _REAL_)) && (t2 != _INT_) && (t2 != _REAL_))
     328           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     329         197 :             if (((t1 == _STRING_) || (t1 == _BOOLEAN_)) && (t1 != t2))
     330           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     331         197 :             if ((t1 == _NONE_) || (t2 == _NONE_))
     332           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     333         197 :             if ((t2 == _STRUCT_) && (t1 != _STRUCT_))
     334           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     335         197 :             if ((t1 == _LABEL_) || (t2 == _LABEL_))
     336           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     337             : 
     338         197 :             break;
     339             : 
     340             :         // BOOLEAN JIT LABEL = _
     341          61 :         case JIT:
     342          61 :             r = _NONE_;
     343          61 :             if ((t1 != _BOOLEAN_) || (t2 != _LABEL_))
     344           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     345             : 
     346          61 :             break;
     347             : 
     348             :         // _ JMP LABEL = _
     349         147 :         case JMP:
     350         147 :             r = _NONE_;
     351         147 :             if ((t1 != _NONE_) || (t2 != _LABEL_))
     352           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     353             : 
     354         147 :             break;
     355             : 
     356             :         // INT CALL LABEL = _
     357             :         // INT RET  LABEL = _
     358          42 :         case CALL: case RET:
     359          42 :             r = _NONE_;
     360          42 :             if ((t1 != _INT_) || (t2 != _LABEL_))
     361           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     362             : 
     363          42 :             break;
     364             : 
     365             :         // _ READ  INT     = _
     366             :         // _ READ  REAL    = _
     367             :         // _ READ  STRING  = _
     368             :         // _ READ  BOOLEAN = _
     369             :         // _ WRITE INT     = _
     370             :         // _ WRITE REAL    = _
     371             :         // _ WRITE STRING  = _
     372             :         // _ WRITE BOOLEAN = _
     373         191 :         case READ: case WRITE:
     374         191 :             r = _NONE_;
     375         191 :             if ((t1 != _NONE_) || (t2 == _NONE_) || (t2 == _STRUCT_) || (t2 == _LABEL_))
     376           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     377             : 
     378         191 :             break;
     379             : 
     380             :         // _ STOP _ = _
     381             :         // _ LOCK _ = _
     382             :         // _ ENDL _ = _
     383         124 :         case STOP: case LOCK: case ENDL:
     384         124 :             r = _NONE_;
     385         124 :             if ((t1 != _NONE_) || (t2 != _NONE_))
     386           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     387             : 
     388         124 :             break;
     389             : 
     390             :         // _ SHARE  INT = _
     391             :         // _ FORK   INT = _
     392             :         // _ UNPACK INT = _
     393           9 :         case SHARE: case FORK: case UNPACK:
     394           9 :             r = _NONE_;
     395           9 :             if ((t1 != _NONE_) || (t2 != _INT_))
     396           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     397             : 
     398           9 :             break;
     399             : 
     400             :         // _ LOAD INT = *        
     401          38 :         case LOAD:
     402          38 :             r = _NONE_; // Нужна замена на реальный тип
     403          38 :             if ((t1 != _NONE_) || (t2 != _INT_))
     404           0 :                 throw Obstacle(EXPR_BAD_TYPE);
     405             : 
     406          38 :             break;
     407             : 
     408           0 :         default:
     409           0 :             throw Obstacle(PANIC);
     410             :     }
     411             : 
     412        1049 :     return r;
     413             : }
     414             : 
     415           0 : char * typetostr(type_t t) {
     416           0 :     switch(t) {
     417           0 :         case _NONE_: return "NONE"; break;
     418           0 :         case _INT_:  return "INT";  break;
     419           0 :         case _REAL_: return "REAL"; break;
     420           0 :         case _STRING_: return "STRING"; break;
     421           0 :         case _BOOLEAN_: return "BOOLEAN"; break;
     422           0 :         case _LABEL_: return "LABEL"; break;
     423           0 :         case _STRUCT_: return "STRUCT"; break;
     424             :     }
     425             :     #ifdef DEBUG
     426             :     return "???";
     427             :     #else
     428           0 :     throw Obstacle(PANIC);
     429             :     #endif
     430             : }
     431             : 
     432          25 : bool isNullary(operation_t o) {
     433          25 :     bool ret = (o == NONE) || (o == ENDL) || (o == RET) || (o == STOP);
     434          25 :     ret = ret || (o == LOCK);
     435          25 :     return ret;
     436             : }
     437             : 
     438          25 : bool isUnary(operation_t o) {
     439          25 :     bool ret = (o == INV) || (o == LNOT) || (o == LOAD) || (o == READ);
     440          25 :     ret = ret || (o == WRITE) || (o == JMP) || (o == SHARE) || (o == FORK);
     441          25 :     ret = ret || (o == UNPACK);
     442          25 :     return ret;
     443             : }
     444             : 
     445          16 : bool isBinary(operation_t o) {
     446          16 :     bool ret = (o == JIT) || (o == CALL) || (o == PLUS) || (o == MINUS);
     447          16 :     ret = ret || (o == LOR) || (o == MUL) || (o == DIV) || (o == LAND);
     448          16 :     ret = ret || (o == MOD) || (o == LESS) || (o == GRTR) || (o == LESSEQ);
     449          16 :     ret = ret || (o == GRTREQ) || (o == EQ) || (o == NEQ) || (o == ASSIGN);
     450          16 :     return ret;
     451             : }
     452             : 
     453           0 : bool isExpr(operation_t o) {
     454           0 :     bool ret = (o == INV) || (o == PLUS) || (o == MINUS) || (o == LOR);
     455           0 :     ret = ret || (o == MUL) || (o == DIV) || (o == LAND) || (o == LNOT);
     456           0 :     ret = ret || (o == MOD) || (o == LESS) || (o == GRTR) || (o == LESSEQ);
     457           0 :     ret = ret || (o == GRTREQ) || (o == EQ) || (o == NEQ) || (o == LOAD); //|| (o == ASSIGN);
     458           0 :     return ret;
     459             : }
     460             : 
     461          25 : int operands(operation_t o) {
     462          25 :     if (isNullary(o))
     463           0 :         return 0;
     464          25 :     if (isUnary(o))
     465           9 :         return 1;
     466          16 :     if (isBinary(o))
     467          16 :         return 2;
     468           0 :     throw Obstacle(PANIC);
     469             : }

Generated by: LCOV version 1.14