changeset 889:6a92d3e8a4b5

expr14 reorganization
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 06 Apr 2014 11:54:08 +0900
parents 2466ac7c1287
children 9d5da127f462
files mc-inline.c mc-parse.c test/strinit.c
diffstat 3 files changed, 180 insertions(+), 166 deletions(-) [+]
line wrap: on
line diff
--- a/mc-inline.c	Sun Apr 06 04:50:34 2014 +0900
+++ b/mc-inline.c	Sun Apr 06 11:54:08 2014 +0900
@@ -885,7 +885,10 @@
                 error(-1);
         }
         e = caddr(init);
-        if (!e) continue; // {...,} case
+        if (!e) {  // {...,} case, zerofill
+            offset = passign_data(var,EMPTY,list2(CONST,size(target_type)),EMPTY,offset);
+            continue;
+        }
         e = pexpr(e);
         offset = pdecl_data(var,car(type0),e,offset);
     }
@@ -901,9 +904,6 @@
     target_type = type_value(target_type);
 
     if (init==0) {
-        // empty declaration     
-        //   it can happen like a = (struct hoge){};
-        // offset = passign_data(var,EMPTY,list2(CONST,size(target_type)),EMPTY,offset);
         return offset;
     }
     e = cadr(init);
--- a/mc-parse.c	Sun Apr 06 04:50:34 2014 +0900
+++ b/mc-parse.c	Sun Apr 06 11:54:08 2014 +0900
@@ -1675,7 +1675,7 @@
     // local var init cannot postponed because of assign_expr0/type
     //  if initialization contains expressions,
     //  we cannot do it in STADECL, but we can assign later in this mode
-    if (local_nptr || mode==SFDINIT)  {
+    if (local_nptr || mode==SFDINIT || inmode )  {
         decl_data_field(type,v,local_struct_offset);
         return;
     }
@@ -4057,75 +4057,183 @@
 /* term */
 
 static int
+expr_identifier()
+{
+    int e1;
+    conv->id_(sym,nptr);
+    switch(nptr->sc) {
+    case EXTRN: case EXTRN1: 
+        extrn_use(nptr);
+    case STATIC:
+        if(is_code(nptr)||is_function(nptr)) {
+            return fname(nptr);
+        }
+    case GVAR:
+        e1=list3n(GVAR,0,nptr);
+        type=nptr->ty;
+        getsym(0);
+        extrn_use(nptr);
+        break;
+    case FLABEL: case BLABEL:
+        return fname(nptr);
+    case LVAR:
+    case IVAR:
+    case LREGISTER:
+    case DREGISTER:
+    case FREGISTER:
+    case REGISTER:
+        e1=list3n(nptr->sc,nptr->dsp,nptr);
+        type=nptr->ty;
+        getsym(0);
+        break;
+    case ENUM:
+        e1=list2(CONST,nptr->dsp);
+        type=INT;
+        getsym(0);
+        break;
+    case EMPTY:
+        if(getsym(0)==LPAR) {
+            type= glist3(stmode==GOTO?CODE:FUNCTION,INT,0);
+            nptr->sc = EXTRN1;
+            nptr->ty= type;
+            extrn_use(nptr);
+            e1=expr15(list3n(FNAME,0,nptr));
+            break;
+        } else if (in_macro_if) {
+            type = INT;
+            e1= list2(CONST,0);
+            break;
+        } else {
+            if (stmode!=GOTO) // undefined on goto statement is OK
+                error(UDERR);
+            int smode = mode; mode = GDECL;
+            // type = nptr->ty= glist3(FUNCTION,INT,0);
+            type = INT;
+            def(nptr,0);
+            nptr->sc = EXTRN1;
+            mode = smode;
+            e1=list3n(FNAME,0,nptr);
+            // type=list3(nptr->sc,nptr->ty,nptr->dsp);
+            break;
+        }
+    default:error(UDERR); e1 = 0;
+    }
+    return expr16(e1);
+}
+
+static int 
+typecast() 
+{
+    int e1;
+    NMTBL *nptr0;
+    int t=typename();
+    conv->type_(t,0,0);
+    conv->rpar_();
+    checksym(RPAR);
+    if (sym==LC && (t>0 && (car(t)==STRUCT||car(t)==UNION))) {
+        //    initializer
+        //             q->lock = (spinlock_t) { };
+        conv->lc_();
+        nptr0 = get_nptr(); // should be freed in a scope?
+                            // in case of inline, we cannot
+        nptr0->nm = "";
+        nptr0->sc = EMPTY;
+        nptr0->attr = 0;
+        type = nptr0->ty = t;
+        def(nptr0,0);
+        if (mode==GDECL||inmode) {
+            int e2,e3;
+            e1 = size(type);
+            e2 = list3n(GVAR,0,nptr0);
+            e3 = decl_data_field(type,e2,0);
+            if (!inmode) {
+                e1 = list3(RSTRUCT,e2,e1);
+            } else {
+                e1 = reverse0(e3);
+                e1 = list3(DECL_DATA,e1,t);
+                e1 = list4(CAST,e1,t,t); // only for cast syntax
+            }
+        } else {
+            e1 = list3n(nptr0->sc,nptr0->dsp,nptr0);
+#if LOCAL_STRUCT_INIT_STATIC 
+            local_struct_static(e1); 
+#else
+            decl_data_field(type,e1,0);
+#endif
+        }
+        if (init_vars && mode!=LDECL) {
+            emit_init_vars();
+        }
+        conv->rc_();
+        checksym(RC);
+        type = t;
+        return e1;
+    }
+    e1=expr13();     //  (type) expr
+    if (inmode) { 
+        e1 = list4(CAST,e1,t,type);
+        type = t;
+        return e1;
+    } else {
+        if (integral(t) || t==DOUBLE || t==FLOAT || t==LONGLONG || t==ULONGLONG)
+            e1 = rvalue(e1);    // left value should not be rvalued
+        e1 =  correct_type(e1,t);
+        type = t;
+        return e1;
+    }
+}
+
+static int
+statement_expression()
+{
+    // statement in expression  (GNU extension)
+    //    a = {hoge(); 1;}
+    // In docomp, last expression is kept in lastexp.
+    //
+    int e1;
+    if (inmode) {
+        int sparse = parse; parse=0;
+        docomp(1);
+        // wrong parse tree fix me!
+        e1 = list3(COMMA,reverse0(parse),lastexp);
+        parse = sparse;
+        lastexp = 0;
+    } else {
+        int l,b,l2,cntl=control;
+        // if COMMA expr is not gexpred by !control, 
+        // l2 is not defined and generates undefined error.
+        // cntl prevents this. 
+        if (cntl) {
+            gen_jmp(l=fwdlabel());
+        } else l = 0;
+        b = backdef(); // control=1
+        docomp(1);
+        if (cntl) {
+            gen_jmp(l2=fwdlabel());
+        } else l2 = 0;
+        // make it a simple call (by jmp)
+        // register stack save now
+        e1 = list3(COMMA,list3(LCALL,b,l2),lastexp);
+        lastexp = 0;
+        if (l) fwddef(l);
+        control=cntl;
+    }
+    conv->rpar_();
+    checksym(RPAR);
+    return expr16(e1);
+}
+
+/**
+ *  basic term
+ */
+static int
 expr14(void)
 {
-    int e1=0,t,t1,smode;
-    NMTBL *nptr0;
+    int e1=0,t,t1;
 
     switch(sym) {
     case IDENT:
-        conv->id_(sym,nptr);
-        switch(nptr->sc) {
-        case EXTRN: case EXTRN1: 
-            extrn_use(nptr);
-        case STATIC:
-            if(is_code(nptr)||is_function(nptr)) {
-                return fname(nptr);
-            }
-        case GVAR:
-            e1=list3n(GVAR,0,nptr);
-            type=nptr->ty;
-            getsym(0);
-            extrn_use(nptr);
-            break;
-        case FLABEL: case BLABEL:
-            return fname(nptr);
-        case FUNCTION: case CODE:
-            error(-1);          // FNAME have to be used
-            break;
-        case LVAR:
-        case IVAR:
-        case LREGISTER:
-        case DREGISTER:
-        case FREGISTER:
-        case REGISTER:
-            e1=list3n(nptr->sc,nptr->dsp,nptr);
-            type=nptr->ty;
-            getsym(0);
-            break;
-        case ENUM:
-            e1=list2(CONST,nptr->dsp);
-            type=INT;
-            getsym(0);
-            break;
-        case EMPTY:
-            if(getsym(0)==LPAR) {
-                type= glist3(stmode==GOTO?CODE:FUNCTION,INT,0);
-                nptr->sc = EXTRN1;
-                nptr->ty= type;
-                extrn_use(nptr);
-                e1=expr15(list3n(FNAME,0,nptr));
-                break;
-            } else if (in_macro_if) {
-                type = INT;
-                e1= list2(CONST,0);
-                break;
-            } else {
-                if (stmode!=GOTO) // undefined on goto statement is OK
-                    error(UDERR);
-                smode = mode; mode = GDECL;
-                // type = nptr->ty= glist3(FUNCTION,INT,0);
-                type = INT;
-                def(nptr,0);
-                nptr->sc = EXTRN1;
-                mode = smode;
-                e1=list3n(FNAME,0,nptr);
-                // type=list3(nptr->sc,nptr->ty,nptr->dsp);
-                break;
-            }
-        default:error(UDERR);
-        }
-        break;
+        return expr_identifier();
     case STRINGS:
         e1=list3n(STRINGS,nptr->dsp,nptr);
         type=list3(ARRAY,CHAR,symval);
@@ -4216,108 +4324,15 @@
         e1=list2(CONST,lineno);
         getsym(0);
         break;
-
     case LPAR:
         conv->lpar_();
         getsym(0);
         qualifiers();
 
-        /* type cast */
-
         if(typeid(sym)) {
-            t=typename();
-            conv->type_(t,0,0);
-            conv->rpar_();
-            checksym(RPAR);
-            if (sym==LC && (t>0 && (car(t)==STRUCT||car(t)==UNION))) {
-                //    initializer
-                //             q->lock = (spinlock_t) { };
-                conv->lc_();
-                if (mode==GDECL||inmode) {
-                    int e2,e3;
-                    smode = mode;
-                    type = t;
-                    nptr0=new_static_name("__lstruct",'_');
-                    mode=STADECL;
-                    def(nptr0,0);
-                    e1 = size(type);
-                    mode = smode;
-                    e2 = list3n(GVAR,0,nptr0);
-                    e3 = decl_data_field(type,e2,0);
-                    if (!inmode) {
-                        e1 = list3(RSTRUCT,e2,e1);
-                    } else {
-                        e1 = reverse0(e3);
-                        e1 = list3(DECL_DATA,e1,t);
-                        e1 = list4(CAST,e1,t,t); // only for cast syntax
-                    }
-                } else {
-                    nptr0 = get_nptr(); // should be freed in a scope?
-                                        // in case of inline, we cannot
-                    nptr0->nm = "";
-                    nptr0->sc = EMPTY;
-                    nptr0->attr = 0;
-                    type = nptr0->ty = t;
-                    def(nptr0,0);
-                    e1 = list3n(nptr0->sc,nptr0->dsp,nptr0);
-#if LOCAL_STRUCT_INIT_STATIC 
-                    local_struct_static(e1); 
-#else
-                    decl_data_field(type,e1,0);
-#endif
-                }
-                if (init_vars && mode!=LDECL) {
-                    emit_init_vars();
-                }
-                conv->rc_();
-                checksym(RC);
-                type = t;
-                return e1;
-            }
-            e1=expr13();     //  (type) expr
-            if (inmode) { 
-                e1 = list4(CAST,e1,t,type);
-                type = t;
-                return e1;
-            } else {
-                if (integral(t) || t==DOUBLE || t==FLOAT || t==LONGLONG || t==ULONGLONG)
-                    e1 = rvalue(e1);    // left value should not be rvalued
-                e1 =  correct_type(e1,t);
-                type = t;
-                return e1;
-            }
+            return typecast();
         } else if (sym==LC) {
-            // statement in expression  (GNU extension)
-            //    a = {hoge(); 1;}
-            // In docomp, last expression is kept in lastexp.
-            //
-            if (inmode) {
-                int sparse = parse; parse=0;
-                docomp(1);
-                // wrong parse tree fix me!
-                e1 = list3(COMMA,reverse0(parse),lastexp);
-                parse = sparse;
-                lastexp = 0;
-            } else {
-                int l,b,l2,cntl=control;
-                // if COMMA expr is not gexpred by !control, 
-                // l2 is not defined and generates undefined error.
-                // cntl prevents this. 
-                if (cntl) {
-                    gen_jmp(l=fwdlabel());
-                } else l = 0;
-                b = backdef(); // control=1
-                docomp(1);
-                if (cntl) {
-                    gen_jmp(l2=fwdlabel());
-                } else l2 = 0;
-                // make it a simple call (by jmp)
-                // register stack save now
-                e1 = list3(COMMA,list3(LCALL,b,l2),lastexp);
-                lastexp = 0;
-                if (l) fwddef(l);
-                control=cntl;
-            }
+            return statement_expression();
         } else {
             e1=expr0();
         }
@@ -4410,7 +4425,6 @@
 
 /*
     function call
-
  */
 static int
 expr15(int e1)
--- a/test/strinit.c	Sun Apr 06 04:50:34 2014 +0900
+++ b/test/strinit.c	Sun Apr 06 11:54:08 2014 +0900
@@ -230,7 +230,7 @@
      struct arg e = (struct arg){};
      f(0,a);
      f(1,b);
-     f(2,c);
+     // f(2,c);    indeterminate output
      f(3,d);
      f(4,e);
      f(5,(struct arg){.fuga = 3,.aho=5});