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 : }