Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / loglan96 / loglan93 / expr.cc
1 #include <String.h>
2 #include <iostream.h>
3 #include "Objects.h"
4
5 #include "Expr.h"
6
7 //**************************************
8 //**                                  **
9 //**  Objects decribing an expression **
10 //**  inside an abstract tree.        **
11 //**                                  **
12 //**************************************
13
14 ostream& operator <<( ostream& stream, ExprType type )
15 {
16   switch(type)
17   {
18     case Ident:
19       return stream << "Identifier";
20     case IntegerConst:
21       return stream << "Integer Constant";
22     case IntegerExpr:
23       return stream << "Integer expression";
24     case RealConst:
25       return stream << "Real Constant";
26     case RealExpr:
27       return stream << "Real expression";
28     case BoolConst:
29       return stream << "Boolean Constant";
30     case BoolExpr:
31       return stream << "Boolean expression";
32     case ObjExpr:
33       return stream << "Object expression";
34     case ObjConst:
35       return stream << "Object Constant";
36     case Other:
37       return stream << "Other";
38     case ExprError:
39       return stream << "Error Type";
40     default:
41       return stream << "Unknown value";
42   }
43 }
44
45 ostream& operator <<( ostream& stream, ArithOpType type )
46 {
47   switch(type)
48   {
49     case Plus:
50       return stream << " Plus ";
51     case Minus:
52       return stream << " Minus ";
53     case Multiply:
54       return stream << " Multiply ";
55     case Divide:
56       return stream << " Divide ";
57     case IntDivide:
58       return stream << " Integer Divide";
59     case Modulo:
60       return stream << " Modulo ";
61     default:
62       return stream << "Unknown value";
63   }
64 }
65
66 ostream& operator <<( ostream& stream, BoolOpType type )
67 {
68   switch(type)
69   {
70     case Less:
71       return stream << " Less ";
72     case LessOrEqual:
73       return stream << " Less Or Equal ";
74     case Equal:
75       return stream << " Equal ";
76     case NotEqual:
77       return stream << " Not Equal ";
78     case Greater:
79       return stream << " Greater ";
80     case GreaterOrEqual:
81       return stream << " Greater Or Equal ";
82     case Or:
83       return stream << " Or ";
84     case And:
85       return stream << " And ";
86     case AndIf:
87       return stream << " AndIf ";
88     case OrIf:
89       return stream << " OrIf ";
90     default:
91       return stream << "Unknown value";
92   }
93 }
94
95 ostream& operator <<( ostream& stream, ObjOpType type )
96 {
97   switch(type)
98   {
99     case Qua:
100       return stream << " Qua ";
101     case Is:
102       return stream << " Is ";
103     case In:
104       return stream << " In ";
105     default:
106       return stream << "Unknown value";
107   }
108 }
109
110 Expression::Expression( ExprType rettype , Location *objloc )
111 {
112   kind       = "NullObject";
113   returntype = rettype;
114   place      = objloc;
115 }
116
117 ostream& operator << ( ostream& stream , Expression ThisExp )
118 {
119 #ifdef VERBOSE_PRINT_EXPR_TREE
120   stream << "\nExpression :";
121 #endif
122   ThisExp.Print( stream );
123   return stream;
124 }
125
126 void Expression::Print( ostream& stream )
127 {
128 #ifdef VERBOSE_PRINT_EXPR_TREE
129   stream << "\nkind     :" << kind  << \
130             "\ntype     :" << type  << \
131             "\nlocation :" << *place << \
132             "\nReturnType :" << returntype;
133 #endif
134 }
135
136 IntegerConstant::IntegerConstant( int value, Location *TheLoc ) :
137        Expression( IntegerConst,TheLoc ),rvalue(value)
138 {
139   kind   = "IntegerConstant";
140 }
141
142 void IntegerConstant::Print( ostream& stream )
143 {
144   Expression::Print(stream);
145 #ifdef VERBOSE_PRINT_EXPR_TREE
146   stream = stream << "\nRValue  :" << rvalue;
147 #else
148   stream << rvalue;
149 #endif
150 }
151
152 RealConstant::RealConstant( double value, Location *TheLoc ) :
153        Expression( RealConst,TheLoc ),rvalue(value)
154 {
155   kind   = "RealConstant";
156 }
157
158 void RealConstant::Print( ostream& stream )
159 {
160   Expression::Print(stream);
161 #ifdef VERBOSE_PRINT_EXPR_TREE
162   stream = stream << "\nRValue  :" << rvalue;
163 #else
164   stream << rvalue;
165 #endif
166 }
167
168 BoolConstant::BoolConstant( int value, Location *TheLoc ) :
169        Expression( BoolConst, TheLoc ),rvalue(value)
170 {
171   kind   = "RealConst";
172 }
173
174 void BoolConstant::Print( ostream& stream )
175 {
176   Expression::Print(stream);
177 #ifdef VERBOSE_PRINT_EXPR_TREE
178   stream << "\nRValue  :" << rvalue;
179 #else
180   stream << rvalue;
181 #endif
182 }
183
184 StringConstant::StringConstant( String *value, Location *TheLoc ) :
185        Expression( StringConst,TheLoc ),rvalue(value)
186 {
187   kind   = "StringConstant";
188 }
189
190 void StringConstant::Print( ostream& stream )
191 {
192   Expression::Print(stream);
193 #ifdef VERBOSE_PRINT_EXPR_TREE
194   stream << "\nRValue  :" << *rvalue;
195 #else
196   stream << *rvalue;
197 #endif
198 }
199
200 CharConstant::CharConstant( char value, Location *TheLoc ) :
201        Expression( CharConst, TheLoc ),rvalue(value)
202 {
203   kind   = "CharConstant";
204 }
205
206 void CharConstant::Print( ostream& stream )
207 {
208   Expression::Print(stream);
209 #ifdef VERBOSE_PRINT_EXPR_TREE
210   stream << "\nRValue  :" << rvalue;
211 #else
212   stream << rvalue;
213 #endif
214 }
215
216 Identifier::Identifier( String * TheName, Location *TheLoc ) :
217             Expression( Ident, TheLoc )
218 {
219   kind  = "Identifier";
220   Title = TheName;
221 }
222
223 Identifier::Identifier( Entry ThisEntry, Location *TheLoc ) :
224             Expression( Ident, TheLoc )
225 {
226   kind  = "Identifier";
227   Title = NULL;
228   Where = ThisEntry;
229 }
230
231 void Identifier::Print( ostream& stream )
232 {
233   Expression::Print(stream);
234 #ifdef VERBOSE_PRINT_EXPR_TREE
235   stream << "\nTitle :" << *Title;
236 #else
237   stream << *Title ;
238 #endif
239 }
240
241 NoneObject::NoneObject( Location *TheLoc ) : Expression( ObjConst, TheLoc )
242 {
243   kind = "None";
244 }
245
246 Result::Result( Location *TheLoc ) : Expression( ObjConst, TheLoc )
247 {
248   kind = "Result";
249 }
250
251 UnaryOperator::UnaryOperator( Expression * ThisExp, ExprType ret, Location *TheLoc ) :
252            Expression( ret, TheLoc )
253 {
254   kind = "UnaryOperator";
255   Argument = ThisExp;
256   place = new Location(*(ThisExp->place) + *TheLoc);
257 }
258
259 void UnaryOperator::Print ( ostream& stream )
260 {
261   Expression::Print(stream);
262 #ifdef VERBOSE_PRINT_EXPR_TREE
263   stream << "\n((";
264   Argument->Print(stream);
265   stream << "\n))";
266 #else
267   stream << '(';
268   Argument->Print(stream);
269   stream << ')';
270 #endif
271 }
272
273 BinaryOperator::BinaryOperator( Expression *LeftExpr, Expression *RightExpr,
274                                 ExprType ret        , Location *TheLoc ) :
275                 Expression( ret, TheLoc )
276 {
277   kind = "BinaryOperator";
278   LeftMember  = LeftExpr;
279   RightMember = RightExpr;
280   place = new Location(*(LeftMember->place) + *TheLoc + *(RightMember->place));
281 }
282
283 virtual void BinaryOperator::Print( ostream& stream )
284 {
285   Expression::Print( stream );
286 #ifdef VERBOSE_PRINT_EXPR_TREE
287   stream << "\n(\nLeft Member :\n";
288   LeftMember->Print( stream );
289   stream << "  ,  ";
290   RightMember->Print( stream );
291   stream << "\n)";
292 #else
293   stream << " ( ";
294   LeftMember->Print(stream);
295   stream << ' ' << kind << ' ';
296   RightMember->Print(stream);
297   stream << " ) ";
298   
299 #endif
300 }
301
302 BoolOperator::BoolOperator( Expression *LeftExpr, Expression *RightExpr,
303                             BoolOpType  TheOp   , Location   *TheLoc ) :
304               BinaryOperator( LeftExpr, RightExpr, Other,TheLoc )
305 {
306   kind   = "Boolean Operator";
307   OpKind = TheOp;
308
309   if ( (TheOp == Or) || (TheOp == And) )
310     switch( LeftExpr->returntype)
311     {
312       case BoolExpr:
313       case BoolConst:
314       case Ident:
315         switch( RightExpr->returntype )
316         {
317           case BoolExpr:
318           case BoolConst:
319           case Ident:
320             returntype = BoolExpr;
321             break;
322
323           default:
324             returntype = ExprError;
325             cout << "Operand 2 of Operator " << TheOp << "  : \"";
326             RightExpr->Print( cout );
327             cout << "\" is not a boolean expression.\n";
328             break;
329         }
330         break;
331
332       default:
333         cout << "Operand 1 of Operator " << TheOp << "  : \"";
334         LeftExpr->Print( cout );
335         cout << "\" is not a boolean expression.\n";
336         switch( RightExpr->returntype )
337         {
338           case BoolExpr:
339           case BoolConst:
340           case Ident:
341             break;
342
343           default:
344             cout << "Operand 2 of Operator " << TheOp << "  : \"";
345             RightExpr->Print( cout );
346             cout << "\" is not a boolan expression.\n";
347             break;
348         }
349         returntype = ExprError;
350     }
351   else
352     switch( LeftExpr->returntype )
353     {
354       case IntegerConst:
355       case IntegerExpr:
356         switch( RightExpr->returntype )
357         {
358           case IntegerConst:
359           case IntegerExpr:
360           case Ident:
361             returntype = BoolExpr;
362             break;
363
364           default:
365             returntype = ExprError;
366             cout << "As operand 1 of operator " << TheOp << " is "
367                  << LeftExpr->returntype << ", operand 2 that is \"";
368             RightExpr->Print( cout );
369             cout << "\" is expected to be an Integer Expression too.\n";
370         }
371         break;
372
373       case RealConst:
374       case RealExpr:
375         switch( RightExpr->returntype )
376         {
377           case RealConst:
378           case RealExpr:
379           case Ident:
380             returntype = BoolExpr;
381             break;
382
383           default:
384             returntype = ExprError;
385             cout << "As operand 1 of operator " << TheOp << " is "
386                  << LeftExpr->returntype << ", operand 2 that is \"";
387             RightExpr->Print( cout );
388             cout << "\" is expected to be a Real Expression too.\n";
389         }
390         break;
391
392       case CharConst:
393       case CharExpr:
394         switch( RightExpr->returntype )
395         {
396           case CharConst:
397           case CharExpr:
398           case Ident:
399             returntype = BoolExpr;
400             break;
401
402           default:
403             returntype = ExprError;
404             cout << "As operand 1 of operator " << TheOp << " is "
405                  << LeftExpr->returntype << ", operand 2 that is \"";
406             RightExpr->Print( cout );
407             cout << "\" is expected to be a Character Expression too.\n";
408         }
409         break;
410
411       case StringConst:
412       case StringExpr:
413         switch( RightExpr->returntype )
414         {
415           case StringConst:
416           case StringExpr:
417           case Ident:
418             returntype = BoolExpr;
419             break;
420
421           default:
422             returntype = ExprError;
423             cout << "As operand 1 of operator " << TheOp << " is "
424                  << LeftExpr->returntype << ", operand 2 that is \"";
425             RightExpr->Print( cout );
426             cout << "\" is expected to be a String Expression too.\n";
427         }
428         break;
429
430       case ObjConst:
431       case ObjExpr:
432         if ( (TheOp == Equal) || (TheOp == NotEqual) )
433           switch( RightExpr->returntype )
434           {
435             case ObjConst:
436             case ObjExpr:
437             case Ident:
438               returntype = BoolExpr;
439               break;
440
441             default:
442               returntype = ExprError;
443               cout << "As operand 1 of operator " << TheOp << " is "
444                    << LeftExpr->returntype << ", operand 2 that is \"";
445               RightExpr->Print( cout );
446               cout << "\" is expected to be an Object Expression too.\n";
447           }
448         else
449         {
450           cout << " Only = and <> can be applied onto objects.\n";
451           returntype = ExprError;
452         }
453         break;
454
455       case BoolConst:
456       case BoolExpr:
457         if ( (TheOp == Equal) || (TheOp == NotEqual) )
458           switch( RightExpr->returntype )
459           {
460             case BoolConst:
461             case BoolExpr:
462             case Ident:
463               returntype = BoolExpr;
464               break;
465
466             default:
467               returntype = ExprError;
468               cout << "As operand 1 of operator " << TheOp << " is "
469                    << LeftExpr->returntype << ", operand 2 that is \"";
470               RightExpr->Print( cout );
471               cout << "\" is expected to be a Boolean Expression too.\n";
472           }
473         else
474         {
475           cout << " Only = and <> can be applied onto booleans.\n";
476           returntype = ExprError;
477         }
478         break;
479
480       case Ident:
481         switch( RightExpr->returntype )
482         {
483           case IntegerConst:
484           case IntegerExpr:
485           case RealConst:
486           case RealExpr:
487           case CharConst:
488           case CharExpr:
489           case StringConst:
490           case StringExpr:
491             returntype = BoolExpr;
492             break;
493
494           case ObjConst:
495           case ObjExpr:
496             if ( (TheOp == Equal) || (TheOp == NotEqual) )
497               returntype = BoolExpr;
498             else
499             {
500               cout << " You can only apply Equal and NotEqual onto objects.\n";
501               returntype = ExprError;
502             }
503             break;
504
505           case BoolConst:
506           case BoolExpr:
507             if ( (TheOp == Equal) || (TheOp == NotEqual) )
508               returntype = BoolExpr;
509             else
510             {
511               cout << " You can only apply Equal and NotEqual onto booleans.\n";
512               returntype = ExprError;
513             }
514             break;
515
516           case Ident:
517             returntype = BoolExpr;
518             break;
519
520           default:
521             returntype = ExprError;
522             cout << " Type of Operand 2 \"";
523             RightExpr->Print( cout );
524             cout << "\" of operand " << TheOp << " is wrong.\n";
525         }
526         break;
527
528       case ExprError:
529         returntype = ExprError;
530         break;
531
532       default:
533         returntype = ExprError;
534         cout << " The type of Operand 1 \"";
535         LeftExpr->Print( cout );
536         cout << "\" of operator " << TheOp << " is wrong.\n";
537     }
538 }
539
540 virtual void BoolOperator::Print( ostream& stream )
541 {
542 #ifdef VERBOSE_PRINT_EXPR_TREE
543   BinaryOperator::Print( stream );
544   stream << "\nKind of Boolean Operator : " << OpKind;
545 #else
546   stream << " ( ";
547   LeftMember->Print( stream );
548   stream << ' ' << OpKind << ' ';
549   RightMember->Print( stream );
550   stream << " ) ";
551 #endif
552 }
553
554 ArithOperator::ArithOperator( Expression  *LeftExpr, Expression *RightExpr,
555                               ArithOpType  TheOp   , Location   *TheLoc ) :
556                BinaryOperator( LeftExpr, RightExpr, Other, TheLoc )
557 {
558   kind   = "Arithmetic Operator";
559   OpKind = TheOp;
560
561   switch( LeftExpr->returntype)
562   {
563     case IntegerConst:
564     case IntegerExpr:
565
566       switch( RightExpr->returntype )
567       {
568         case IntegerConst:
569         case IntegerExpr:
570           returntype = IntegerExpr;
571           break;
572
573         case RealConst:
574         case RealExpr:
575           returntype = RealExpr;
576           break;
577
578         case Ident:
579           returntype = IntegerExpr;
580           break;
581
582         case ExprError:
583           returntype = ExprError;
584           break;
585
586         default:
587           returntype = ExprError;
588           cout << "Operand 2 of Operator " << TheOp << "  : \"";
589           RightExpr->Print( cout );
590           cout << "\" is not an arithmetic expression.\n";
591           break;
592       }
593       break;
594
595     case RealConst:
596     case RealExpr:
597       switch( RightExpr->returntype )
598       {
599
600         case IntegerConst:
601         case IntegerExpr:
602         case RealConst:
603         case RealExpr:
604         case Ident:
605           returntype = RealExpr;
606           break;
607
608         case ExprError:
609           returntype = ExprError;
610           break;
611
612         default:
613           returntype = ExprError;
614           cout << "Operand 2 of Operator " << TheOp << "  : \"";
615           RightExpr->Print( cout );
616           cout << "\" is not an arithmetic expression.\n";
617
618       }
619       break;
620
621     case Ident:
622       switch( RightExpr->returntype )
623       {
624         case IntegerConst:
625         case IntegerExpr:
626           returntype = IntegerExpr;
627           break;
628
629         case RealConst:
630         case RealExpr:
631           returntype = RealExpr;
632           break;
633
634         case Ident:
635           returntype = Ident;
636           break;
637
638         case ExprError:
639           returntype = ExprError;
640           break;
641
642         default:
643           returntype = ExprError;
644           cout << "Operand 2 of Operator " << TheOp << "  : \"";
645           RightExpr->Print( cout );
646           cout << "\" is not an arithmetic expression.\n";
647       }
648       break;
649
650     case ExprError:
651       returntype = ExprError;
652       break;
653
654     default:
655       returntype = ExprError;
656       cout << "Operand 1 of Operator " << TheOp << "  : \"";
657       LeftExpr->Print( cout );
658       cout << "\" is not an arithmetic expression.\n";
659       switch( RightExpr->returntype )
660       {
661         case IntegerConst:
662         case IntegerExpr:
663         case RealConst:
664         case RealExpr:
665         case Ident:
666           break;
667
668         default:
669           cout << "Operand 2 of Operator " << TheOp << "  : \"";
670           RightExpr->Print( cout );
671           cout << "\" is not an arithmetic expression.\n";
672       }
673
674   }
675 }
676
677 virtual void ArithOperator::Print( ostream& stream)
678 {
679 #ifdef VERBOSE_PRINT_EXPR_TREE
680   BinaryOperator::Print( stream );
681   stream << "\nKind of Arithmetic Operator : " << OpKind;
682 #else
683   stream << " ( ";
684   LeftMember->Print( stream );
685   stream << ' ' << OpKind << ' ';
686   RightMember->Print( stream );
687   stream << " ) ";
688 #endif
689 }
690
691 ObjOperator::ObjOperator( Expression *LeftExpr, Expression  *RightExpr,
692                           ObjOpType   TheOp   , Location    *TheLoc ) :
693               BinaryOperator( LeftExpr, RightExpr, Other, TheLoc )
694 {
695   kind   = "Object Operator";
696   OpKind = TheOp;
697
698   switch(LeftExpr->returntype)
699   {
700     case Ident:
701       switch ( RightExpr->returntype )
702       {
703         case Ident:
704           if (TheOp == Qua)
705             returntype = ObjExpr;
706           else
707             returntype = BoolExpr;
708           break;
709
710         case ExprError:
711           returntype = ExprError;
712           break;
713
714         default:
715           returntype = ExprError;
716           cout << "Operand 2 of Operator " << TheOp << "  : \"";
717           RightExpr->Print( cout );
718           cout << "\" is not an Identifier.\n";
719       }
720       break;
721
722     case ExprError:
723       returntype = ExprError;
724       break;
725
726     default:
727       cout << "Operand 1 of Operator " << TheOp << "  : \"";
728       LeftExpr->Print( cout );
729       cout << "\" is not an Identifier.\n";
730
731   }
732 }
733
734 virtual void ObjOperator::Print( ostream& stream )
735 {
736 #ifdef VERBOSE_PRINT_EXPR_TREE
737   BinaryOperator::Print( stream );
738   stream << "\nKind of Object Operator : " << OpKind;
739 #else
740   stream << " ( ";
741   LeftMember->Print( stream );
742   stream << ' ' << OpKind << ' ';
743   RightMember->Print( stream );
744   stream << " ) ";
745 #endif
746 }
747
748 Not::Not( Expression *TheExpr, Location *TheLoc ) :
749      UnaryOperator( TheExpr , Other, TheLoc )
750 {
751   kind = "Not";
752
753   switch( TheExpr->returntype )
754   {
755     case BoolExpr:
756     case BoolConst:
757     case Ident:
758       returntype = BoolExpr;
759       break;
760
761     case ExprError:
762       returntype = ExprError;
763       break;
764
765     default:
766       returntype = ExprError;
767       cout << "Operand of Operator Not  : \"";
768       TheExpr->Print( cout );
769       cout << "\" is not a Boolean Expression.\n";
770   }
771 }
772
773 This::This( Expression *TheExpr, Location *TheLoc ) :
774       UnaryOperator( TheExpr, Other, TheLoc )
775 {
776   kind = "This";
777
778   if ( TheExpr )
779     switch ( TheExpr->returntype )
780     {
781       case Ident:
782         returntype = ObjExpr;
783         break;
784
785       default:
786         returntype = ExprError;
787         cout << "Operand is of operator 'This' is not an Identifier.\n";
788     }
789   else
790     returntype = ObjExpr;
791 }
792
793 void This::Print( ostream& stream )
794 {
795   cout << " This ";
796   if ( Argument )
797     UnaryOperator::Print( stream );
798 }
799
800 New::New( Expression *TheExpr, Location *TheLoc ) :
801      UnaryOperator( TheExpr , Other, TheLoc )
802 {
803   kind = "New";
804
805   switch( TheExpr->returntype )
806   {
807     case Ident:
808       returntype = ObjExpr;
809       break;
810
811     case ExprError:
812       returntype = ExprError;
813       break;
814
815     default:
816       returntype = ExprError;
817       cout << "Operand \"";
818       TheExpr->Print(cout);
819       cout << "\"type of New operator is wrong.\n";
820   }
821 }
822
823 Copy::Copy( Expression *TheExpr, Location *TheLoc ) :
824       UnaryOperator( TheExpr, Other, TheLoc )
825 {
826   kind = "Copy";
827   switch(TheExpr->returntype)
828   {
829     case Ident:
830     case ObjExpr:
831       returntype = ObjExpr;
832       break;
833
834     case ExprError:
835       returntype = ExprError;
836       break;
837
838     default:
839       returntype = ExprError;
840       cout << "Wrong operand type for operand \"";
841       TheExpr->Print(cout);
842       cout << "\" of Copy.\n";
843       break;
844   }
845 }
846
847 ArrayOf::ArrayOf( Expression *TheExpr, ExprType ret, Location *TheLoc ) :
848          UnaryOperator( TheExpr, ret, TheLoc )
849 {
850   kind = "ArrayOf";
851 }
852
853 Error::Error( ) : Expression( ExprError, NULL )
854 {
855   kind = "Error into Expression";
856 }