/* EXPR1.C */ #include "stdafx.h" #include #include "inp.h" #include "out.h" #include "lex.h" #include "code1.h" #include "expr1.h" /******************************* EXPRESSION *******************************/ void primary (void) { switch (sy) { case IDENT: send_ext ("push variable", IdentVal); break; case NUM: send_ext ("push number", NumVal); break; case FLT: /* neimplementovano */ break; case STR: /* neimplementovano */ break; case CHR: /* neimplementovano */ break; default: Error ("Syntax error in expression"); } NextSymbol (); } void primary_expr (void) { if (sy==IDENT || sy==NUM || sy==FLT || sy==STR || sy==CHR) { primary (); } else if (sy==LPAR) { NextSymbol (); expression (); CheckSymbol (RPAR); /* neni treba generovat zadny kod */ } else Error ("Syntax error in expression"); } void postfix_expr (void) { primary_expr (); /* generovani kodu zatim neimplementovano */ for (;;) if (sy==LBRACK) /* [ ] */ { NextSymbol (); expression (); CheckSymbol (RBRACK); } else if (sy==LPAR) /* ( ) */ { NextSymbol (); /* argument-expression-list */ if (sy!=RPAR) expression (); CheckSymbol (RPAR); } else if (sy==PERIOD) /* . */ { NextSymbol (); /* skip period */ if (sy!=IDENT) Error ("Identifier expected"); NextSymbol (); /* skip identifier */ } else if (sy==ARROW) /* -> */ { NextSymbol (); if (sy!=IDENT) Error ("Identifier expected"); NextSymbol (); } else if (sy==DPLUS || sy==DMINUS) /* ++ -- */ { NextSymbol (); } else break; } void cast_expr (void); void unary_expr (void) { SYMBOL tmp; /* generovani kodu zatim neimplementovano */ if (sy==DPLUS || sy==DMINUS) { tmp = sy; NextSymbol (); unary_expr (); } else if (sy==PLUS || sy==MINUS || sy==NOT) { tmp = sy; NextSymbol (); cast_expr (); } else if (sy==LOGNOT) { tmp = sy; NextSymbol (); cast_expr (); } else if (sy==AND) { NextSymbol (); cast_expr (); } else if (sy==ASTERISK) { NextSymbol (); cast_expr (); } else if (sy==SIZEOF_) { NextSymbol (); unary_expr (); /* if (sy==LPAR) { NextSymbol (); !!! CheckSymbol (RPAR); } */ } else postfix_expr (); } void cast_expr (void) { /* if (sy==LPAR) { NextSymbol (); !!! CheckSymbol (RPAR); } */ unary_expr (); } Expr * mul_expr (void) { Expr * result = NULL; SYMBOL tmp; cast_expr (); while (sy==ASTERISK || sy==SLASH || sy==MOD) { tmp = sy; NextSymbol (); cast_expr (); switch (tmp) { case ASTERISK: send ("mul"); break; case SLASH: send ("div"); break; case MOD: send ("mod"); break; } } return NULL; } Expr * add_expr (void) { Expr * result = mul_expr (); SYMBOL tmp; while (sy==PLUS || sy==MINUS) { tmp = sy; NextSymbol (); Expr * e1 = result; Expr * e2 = mul_expr (); result = new Expr; result->tag = (tmp == PLUS) ? AddExpr : SubExpr; result->left = e1; result->right = e2; } return result; } void shift_expr (void) { SYMBOL tmp; add_expr (); while (sy==SHL || sy==SHR) { tmp = sy; NextSymbol (); add_expr (); switch (tmp) { case SHL: send ("shl"); break; case SHR: send ("shr"); break; } } } void rel_expr (void) { SYMBOL tmp; shift_expr (); while (sy==LESS || sy==GREATER || sy==LESSEQUAL || sy==GREATEREQUAL) { tmp = sy; NextSymbol (); shift_expr (); switch (tmp) { case LESS: send ("cmp less"); break; case GREATER: send ("cmp greater"); break; case LESSEQUAL: send ("cmp less or equal "); break; case GREATEREQUAL: send ("cmp greater or equal"); break; } } } void equ_expr (void) { SYMBOL tmp; rel_expr (); while (sy==EQUAL || sy==UNEQUAL) { tmp = sy; NextSymbol (); rel_expr (); switch (tmp) { case EQUAL: send ("cmp equal"); break; case UNEQUAL: send ("cmp not equal"); break; } } } void and_expr (void) { equ_expr (); while (sy==AND) { NextSymbol (); equ_expr (); send ("and"); } } void xor_expr (void) { and_expr (); while (sy==XOR) { NextSymbol (); and_expr (); send ("xor"); } } void or_expr (void) { xor_expr (); while (sy==OR) { NextSymbol (); xor_expr (); send ("or"); } } void land_expr (void) { or_expr (); while (sy==LOGAND) { NextSymbol (); or_expr (); } } void lor_expr (void) { land_expr (); while (sy==LOGOR) { NextSymbol (); land_expr (); } } void cond_expr (void) { lor_expr (); if (sy==QUESTION) { expression (); CheckSymbol (COLON); cond_expr (); } } void assignment_expr (void) { SYMBOL tmp; cond_expr (); while (sy==ASSIGN || sy==MULASSIGN || sy==DIVASSIGN || sy==MODASSIGN || sy==ADDASSIGN || sy==SUBASSIGN || sy==SHLASSIGN || sy==SHRASSIGN || sy==ANDASSIGN || sy==XORASSIGN || sy==ORASSIGN) { tmp = sy; NextSymbol (); cond_expr (); /* pro spravne generovani kodu potrebuji na zasobniku adresu promenne, nikoliv hodnotu - neimplementovano */ switch (tmp) { case ASSIGN: send ("assign"); break; /* ... */ } } } Expr * expression (void) { Expr * result = NULL; Indent (); PutStr ("/* expression */"); PutEol (); Indent (); assignment_expr (); if (sy==COMMA) { NextSymbol (); send ("pop"); /* odstran predchazejici vysledek */ expression (); } Unindent (); PutStr ("/* end of expression */"); PutEol (); Unindent (); return result; } /* switch (tmp) { case : send (""); break; case : send (""); break; case : send (""); break; case : send (""); break; } */