summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-02-03 19:19:12 -0500
committerpommicket <pommicket@gmail.com>2022-02-03 19:19:12 -0500
commit3e6cacfb7c57fc8b6969c5939e88ba75089c0161 (patch)
treef2e31adcdd50fce6fad3dddac1ea1b98e4f7aab0
parent04c5e1af8a03cb943acbebcb7460193c8bd37a26 (diff)
parsing C is annoying
-rw-r--r--05/main.c107
-rw-r--r--05/parse.b18
2 files changed, 70 insertions, 55 deletions
diff --git a/05/main.c b/05/main.c
index 34be337..6a9af7f 100644
--- a/05/main.c
+++ b/05/main.c
@@ -1,54 +1,57 @@
-/*typedef struct {
+typedef struct {
int i[41];
long double d;
-} (*x)(void);
-
-/* typedef enum X { */
-/* R,S,T */
-/* } *Foo[sizeof(unsigned long)]; */
-/* typedef int A[T]; */
-/* */
-/* typedef struct A { */
-/* int x, y; */
-/* long double c; */
-/* unsigned long d; */
-/* char e[3]; */
-/* long f; */
-/* } A; */
-/* */
-/* typedef union B{ */
-/* int x; */
-/* struct { */
-/* int y; */
-/* struct {long z; } c; */
-/* } c; */
-/* }B; */
-/* */
-/* typedef int x[sizeof(A)+sizeof"hello"]; */
-/* typedef int y[sizeof(struct B)]; */
-/* */
-/* static unsigned int x={55}; */
-/* static char *s = "hello"; */
-/* static char *t = "goodbye"; */
-/* static char u[8] = "hellothe"; */
-/* static char v[100] = "re my"; */
-/* static char w[] = "friendly"; */
-/* static char x_[] = "hi"; */
-/* typedef int A[sizeof x_ + sizeof u]; */
-/* */
-/* static int a[5] = {1,2,3}; */
-/* static char b[6][7] = {{'a'},{'b'},{'c'},{'d'},{'e'}}; */
-/* static char __b[][7] = {{'a'},"hello",'r'}; */
-/* static int _u = sizeof __b; */
-
-/* struct { */
-/* int a; */
-/* long b; */
-/* } x1[] = {0x1234567890, 1ul<<60|1ul<<3, 77}; */
-/* int y1 = 0x12345678; */
-typedef int R[sizeof *(int*)"hello"];
-
-/* struct { */
-/* int x[2], y; */
-/* } test = {3, 5}; */
-/* unsigned marker = 0xdeadbeef; */
+} (*x___)(void);
+
+typedef enum X {
+ R,S,T
+ } *Foo[sizeof(unsigned long)];
+typedef int A___[T];
+
+typedef struct A {
+ int x, y;
+ long double c;
+ unsigned long d;
+ char e[3];
+ long f;
+} A;
+
+typedef union B{
+ int x;
+ struct {
+ int y;
+ struct {long z; } c;
+ } c;
+}B;
+
+typedef int QQQ[sizeof(A)+sizeof"hello"];
+typedef int RRR[sizeof(struct B)];
+
+static unsigned int x={55};
+static char *s = "hello";
+static char *t = "goodbye";
+static char u[8] = "hellothe";
+static char v[100] = "re my";
+static char w[] = "friendly";
+static char x_[] = "hi";
+typedef int A_[sizeof x_ + sizeof u];
+
+static int a[5] = {1,2,3};
+static char b[6][7] = {{'a'},{'b'},{'c'},{'d'},{'e'}};
+static char __b[][7] = {{'a'},"hello",'r'};
+static int _u = sizeof __b;
+
+struct {
+ int a;
+ long b;
+} x1[] = {0x1234567890, 1ul<<60|1ul<<3, 77};
+int y1 = 0x12345678;
+
+struct {
+ int x[2], y;
+} test[] = {3, 5,0x1234,0x4321};
+typedef int Blah[sizeof((B *)0)->c.y];
+unsigned marker = 0xdeadbeef;
+
+
+/* typedef int X[sizeof(int)+4]; */
diff --git a/05/parse.b b/05/parse.b
index 18dbcb6..60dc73d 100644
--- a/05/parse.b
+++ b/05/parse.b
@@ -1329,7 +1329,7 @@ function parse_expression
local first_token
:parse_expression_top
- print_tokens(tokens, tokens_end)
+ ;print_tokens(tokens, tokens_end)
type = out + 4
@@ -1676,8 +1676,15 @@ function parse_expression
parse_type_declarators(sizeof_prefix, sizeof_suffix, sizeof_suffix, sizeof_suffix_end)
parse_base_type(sizeof_base_type)
if *1p != SYMBOL_RPAREN goto bad_expression ; e.g. sizeof(int ,)
+ p += 16
+ if p != tokens_end goto stuff_after_sizeof_type
*8out = type_sizeof(a)
goto parse_sizeof_finish
+ :stuff_after_sizeof_type
+ token_error(sizeof_suffix_end, .str_stuff_after_sizeof_type)
+ :str_stuff_after_sizeof_type
+ string Unrecognized stuff after sizeof(T).
+ byte 0
:parse_sizeof_expr
; it's an expression, e.g. sizeof(x+3)
local temp
@@ -2575,15 +2582,20 @@ function operator_precedence
:figre_out_rparen_arity
; given that the token before this one is a right-parenthesis, figure out if
; this is a unary or binary operator. this is (annoyingly) necessary, because:
- ; (int)-x; /* cast processed first */
; (y)-x; /* subtraction processed first */
+ ; (int)-x; /* cast processed first */
+ ; sizeof(int)-x; /* subtraction processed first */
local p
p = token - 16
token_reverse_to_matching_lparen(&p)
p += 16
b = token_is_type(p)
- if b != 0 goto operator_precedence_unary ; e.g. (int)-x;
+ if b != 0 goto rparen_might_be_cast
goto operator_precedence_binary ; e.g. (y)-x;
+ :rparen_might_be_cast
+ p -= 32
+ if *1p != KEYWORD_SIZEOF goto operator_precedence_unary ; e.g. (int)-x
+ goto operator_precedence_binary ; e.g. sizeof(int)-x
function unary_op_to_expression_type
argument op