Skip to content

Commit 2c852d0

Browse files
authored
Merge pull request #151 from fennecJ/Supporting_octal_literals
Support octal literals
2 parents 1586eb1 + 710ae29 commit 2c852d0

File tree

2 files changed

+76
-16
lines changed

2 files changed

+76
-16
lines changed

src/parser.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,10 @@ int read_numeric_constant(char buffer[])
175175
}
176176
return value;
177177
}
178-
value = value * 10 + buffer[i++] - '0';
178+
if (buffer[0] == '0') /* octal */
179+
value = value * 8 + buffer[i++] - '0';
180+
else
181+
value = value * 10 + buffer[i++] - '0';
179182
}
180183
return value;
181184
}
@@ -612,22 +615,29 @@ void read_numeric_param(block_t *parent, basic_block_t *bb, int is_neg)
612615
is_neg = 1 - is_neg;
613616
i++;
614617
}
615-
if ((token[0] == '0') && (token[1] == 'x')) { /* hexadecimal */
616-
i = 2;
617-
do {
618-
c = token[i++];
619-
if (is_digit(c))
620-
c -= '0';
621-
else {
622-
c |= 32; /* convert to lower case */
623-
if (c >= 'a' && c <= 'f')
624-
c = (c - 'a') + 10;
625-
else
626-
error("Invalid numeric constant");
627-
}
618+
if (token[0] == '0') {
619+
if (token[1] == 'x') { /* hexdecimal */
620+
i = 2;
621+
do {
622+
c = token[i++];
623+
if (is_digit(c))
624+
c -= '0';
625+
else {
626+
c |= 32; /* convert to lower case */
627+
if (c >= 'a' && c <= 'f')
628+
c = (c - 'a') + 10;
629+
else
630+
error("Invalid numeric constant");
631+
}
628632

629-
value = (value * 16) + c;
630-
} while (is_hex(token[i]));
633+
value = (value * 16) + c;
634+
} while (is_hex(token[i]));
635+
} else { /* octal */
636+
do {
637+
c = token[i++] - '0';
638+
value = (value * 8) + c;
639+
} while (is_digit(token[i]));
640+
}
631641
} else {
632642
do {
633643
c = token[i++] - '0';

tests/driver.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ function expr() {
7878
expr 0 0
7979
expr 42 42
8080

81+
# octal constant (satisfying re(0[0-7]+))
82+
expr 10 012
83+
expr 65 0101
84+
8185
# arithmetic
8286
expr 42 "24 + 18"
8387
expr 30 "58 - 28"
@@ -95,6 +99,9 @@ expr 55 "((((((((1 + 2) + 3) + 4) + 5) + 6) + 7) + 8) + 9) + 10"
9599
expr 55 "1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + 10))))))))"
96100
expr 210 "1 + (2 + (3 + (4 + (5 + (6 + (7 + (8 + (9 + (10 + (11 + (12 + (13 + (14 + (15 + (16 + (17 + (18 + (19 + 20))))))))))))))))))"
97101

102+
expr 11 "1 + 012" # oct(012) = dec(10)
103+
expr 25 "017 + 012" # oct(017) = dec(15), oct(012) = dec(10)
104+
98105
# expr 21 "+1+20"
99106
# expr 10 "-15+(+35-10)"
100107

@@ -108,6 +115,16 @@ expr 0 "5 >= 10"
108115
expr 1 "5 >= 5"
109116
expr 1 "30 != 20"
110117

118+
# value satisfying re(0[0-7]+) should be parsed as octal
119+
expr 1 "010 == 8"
120+
expr 1 "011 < 11"
121+
expr 0 "021 >= 21"
122+
expr 1 "(012 - 5) == 5"
123+
expr 16 "0100 >> 2"
124+
125+
# oct(355) = bin(1110_1101), oct(~355) = bin(0001_0010) = dec(18)
126+
expr 18 "~0355"
127+
111128
expr 0 "!237"
112129
expr 18 "~237"
113130

@@ -139,12 +156,21 @@ items 10 "int var; var = 10; return var;"
139156
items 42 "int va; int vb; va = 11; vb = 31; int vc; vc = va + vb; return vc;"
140157
items 50 "int v; v = 30; v = 50; return v;"
141158

159+
# variable with octal literals
160+
items 10 "int var; var = 012; return var;"
161+
items 100 "int var; var = 10 * 012; return var;"
162+
items 32 "int var; var = 0100 / 2; return var;"
163+
items 65 "int var; var = 010 << 3; var += 1; return var;"
164+
142165
# if
143166
items 5 "if (1) return 5; else return 20;"
144167
items 10 "if (0) return 5; else if (0) return 20; else return 10;"
145168
items 10 "int a; a = 0; int b; b = 0; if (a) b = 10; else if (0) return a; else if (a) return b; else return 10;"
146169
items 27 "int a; a = 15; int b; b = 2; if(a - 15) b = 10; else if (b) return a + b + 10; else if (a) return b; else return 10;"
147170

171+
items 8 "if (1) return 010; else return 11;"
172+
items 10 "int a; a = 012 - 10; int b; b = 0100 - 64; if (a) b = 10; else if (0) return a; else if (a) return b; else return 10;"
173+
148174
# compound
149175
items 5 "{ return 5; }"
150176
items 10 "{ int a; a = 5; { a = 5 + a; } return a; }"
@@ -197,6 +223,21 @@ int main() {
197223
}
198224
EOF
199225

226+
try_ 55 << EOF
227+
int fib(int n, int a, int b)
228+
{
229+
if (n == 0)
230+
return a;
231+
else if (n == 1)
232+
return b;
233+
return fib(n - 1, b, a + b);
234+
}
235+
236+
int main() {
237+
return fib(012, 0, 1); /* octal(12) = dec(10) */
238+
}
239+
EOF
240+
200241
try_ 1 << EOF
201242
int is_odd(int x);
202243
@@ -656,6 +697,15 @@ int main()
656697
}
657698
EOF
658699

700+
# octal(155) = dec(109), expect same output with above test suite
701+
try_output 0 "12 -1" << EOF
702+
int main()
703+
{
704+
printf("%d %d", -0155 / -9, -0155 % -9);
705+
return 0;
706+
}
707+
EOF
708+
659709
try_output 0 "1365 0" << EOF
660710
int main()
661711
{

0 commit comments

Comments
 (0)