ref: 2d30362df693b46f67f1515e9d23e56e237410a5
parent: 08c42cdfaea4d0cc3bf0bc00ee3e7cf2e5a9664a
author: Roberto E. Vargas Caballero <[email protected]>
date: Thu Apr 10 03:29:53 EDT 2014
Add shift operators
--- a/cc.h
+++ b/cc.h
@@ -219,7 +219,8 @@
enum {
OCAST, OPTR, OADD, OARY, OSIZE, OMUL, OSUB,
- OINC, ODEC, OPINC, OPDEC, ODIV, OMOD
+ OINC, ODEC, OPINC, OPDEC, ODIV, OMOD, OSHL,
+ OSHR
};
extern void
--- a/code.c
+++ b/code.c
@@ -15,7 +15,9 @@
[OSIZE] = "#",
[OPTR] = "@",
[OMOD] = "*",
- [ODIV] = "/'"
+ [ODIV] = "/'",
+ [OSHL] = "l",
+ [OSHR] = "r"
};
Node *
--- a/expr.c
+++ b/expr.c
@@ -49,6 +49,7 @@
static Node *
arithmetic(char op, Node *np1, Node *np2)
{
+ char *err;
Node *naux;
Type *tp1, *tp2, *tp3;
uint8_t t1, t2, taux, lvalue = 0;
@@ -56,6 +57,9 @@
tp1 = UNQUAL(np1->type), tp2 = UNQUAL(np2->type);
t1 = tp1->op, t2 = tp2->op;
+ if ((op == OSHL || op == OSHR) && (t1 != INT || t2 != INT))
+ goto bad_shift;
+
switch (t1) {
case INT:
switch (t2) {
@@ -112,10 +116,16 @@
np1->b.lvalue = lvalue;
return np1;
+bad_shift:
+ err = "invalid operands to shift operator";
+ goto error;
nocomplete:
- error("invalid use of indefined type");
+ err = "invalid use of indefined type";
+ goto error;
incorrect:
- error("incorrect arithmetic operands");
+ err = "incorrect arithmetic operands";
+error:
+ error(err);
}
static Node *
@@ -283,6 +293,24 @@
}
}
+static struct node *
+shift(void)
+{
+ register char op;
+ register Node *np;
+
+ np = add();
+ for (;;) {
+ switch (yytoken) {
+ case SHL: op = OSHL; break;
+ case SHR: op = OSHR; break;
+ default: return np;
+ }
+ next();
+ np = arithmetic(op, np, add());
+ }
+}
+
Node *
expr(void)
{
@@ -289,7 +317,7 @@
register Node *np;
do
- np = add();
+ np = shift();
while (yytoken == ',');
return np;
}