changeset 326:e5d40f8c4cce

bit-field continue.
author kono
date Sun, 20 Jun 2004 20:54:24 +0900
parents b51b87ddf60c
children da2e3f2d127d
files Changes Idea README README.jp mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c mc-parse.c mc-switch.c mc.h
diffstat 11 files changed, 208 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Sat Jun 19 21:45:19 2004 +0900
+++ b/Changes	Sun Jun 20 20:54:24 2004 +0900
@@ -5036,3 +5036,16 @@
 まぁ、
     BASSOP, BPREINC, BPOSTINC.... 
 でもいいんだけど。
+
+Sun Jun 20 20:21:38 JST 2004
+
+どうも、mc-parse に、mc-codegen に相当する部分がかなり入り込んでいる
+みたいだね。これを移すのはめんどくさいが... binop とか、もともと
+mc-codegen にあるべきものなのか。
+
+でも、これをしないと、構文に対応した構文木を取れないわけか。
+inline で、構文木を再評価する場合もあるからなぁ。再評価した
+場合に、構文木レベルで変更するべきなのか、コード生成レベルの
+木でやるべきなのか、という問題もあるわけか。
+
+macro も分割した方が良いね。
--- a/Idea	Sat Jun 19 21:45:19 2004 +0900
+++ b/Idea	Sun Jun 20 20:54:24 2004 +0900
@@ -38,7 +38,7 @@
 
 fp->local1 みたいなことだけするなら、C と同じになる。
 
-call する時のarguemnt も、
+call する時のargument も、
     static な func_state に置く
     stack 上の func_state に置く
 という二通りの選択肢がある。Cと互換なら、当然、後者。
@@ -108,7 +108,7 @@
 
 union の拡張もあわせて議論すると...
 
-Partial evalutator をセマンティクスや実行系にいれておくことは可能か?
+Partial evaluator をセマンティクスや実行系にいれておくことは可能か?
 
 byte code とか仮想マシンだったら可能。そうでない場合は?
 
@@ -152,7 +152,7 @@
 で、構造体に register storage を許す。
 
     func(
-	static struct argment {
+	static struct argument {
 	    register void *stack;
 	    register void *continuation;
 	}
@@ -168,7 +168,7 @@
 すると、caller の方も、構造体を引数とするのが自然。
 
     call caller(
-	static struct argment {
+	static struct argument {
 	    register void *stack;
 	    register void *continuation;
 	} arg = {a,b};
@@ -189,8 +189,8 @@
 
 function には、interface と code と state があることになる。
 
-state にアクセスする時のlockは? protected state? synchonized state かな?
-もちろん、sequential implementatoinでは、そんなものはいらない。
+state にアクセスする時のlockは? protected state? synchronized state かな?
+もちろん、sequential implementationでは、そんなものはいらない。
 
 function {
     interface:
@@ -205,15 +205,15 @@
 
 int にvoid value を定義する。実装は重くなるけど...
 
-serialzed の semantics は?
+serialized の semantics は?
 
 もう少しmicro-Cに近く! 
 
-carring state と static state。
+carrying state と static state。
 
 Mon Dec 13 19:42:41 JST 1999
 
-interface に regsiter keyword を使うのは、あまりに
+interface に register keyword を使うのは、あまりに
 実装よりすぎる。でも、でないと状態にできない?
 そんなことはないか。やっぱりcaller側のstatic 領域に
 直接書き込む?
@@ -223,8 +223,8 @@
 Wed Dec 15 14:09:49 JST 1999
 
 C と互換にする?
-	goto function(argments);
-	goto *continuation(argments);
+	goto function(arguments);
+	goto *continuation(arguments);
 みたいな感じで。
 
 stackの管理は? どうせ、library との互換はとらないと
@@ -235,8 +235,8 @@
 
 return した時の挙動が複雑になる。大域returnするわけだら。
 
-argments をstatic 領域にかきこむ方式だと互換性がとれない。
-stack 上の frmae pointer 上にないとダメだから。
+arguments をstatic 領域にかきこむ方式だと互換性がとれない。
+stack 上の frame pointer 上にないとダメだから。
 
 両立させるのは無理か? つまり、これだと、呼び出された方の
 frame semantics は、C と互換になる。だから、stackの直後に
@@ -246,7 +246,7 @@
 
 つまり、それはだめだったことじゃない? つまり、goto だと、
 frame pointer は、stack の直後とは限らないから。前の
-frmae pointer 相対に引数にアクセスしてくれれば別だけどね。
+frame pointer 相対に引数にアクセスしてくれれば別だけどね。
 
 stack に引数を積むのは容認して、goto の場合は、向こう側で
 stack を畳むってのは?  ということは、普通の関数と定義の
@@ -256,7 +256,7 @@
 方が異なることをする。それは、なんかおかしいな。それに、
 それだと関数呼び出しが軽くならない...
 
-ということは、やはり、C のcall は、call funciton で
+ということは、やはり、C のcall は、call function で
 実現して、その他の呼び出しは、すべて、goto 扱いに
 する方が正しいだろう。
 
@@ -293,7 +293,7 @@
 
 あ、これは良いかも知れない。code が複数かけるから。
 
-state 以外は、consitent state であることを保証しない。ってのは?
+state 以外は、consistent state であることを保証しない。ってのは?
 local 変数は使っても良いけど、call/goto の前後で、値を保証しないか...
 
 うーん、だんだん炸裂してるなぁ。
@@ -333,7 +333,7 @@
 	# register save
 	# set 1st argument in register %eax
 	# set 2nd argument in register %ecx
-	# set extra aguments in save area
+	# set extra arguments in save area
 	# set extra argument pointer in %edx
 	    jmp function
 という形式になるわけね。second を処理するのはめんどくさいから一つ
@@ -341,11 +341,11 @@
 
 えーと、frame pointer はないけど、コンパイルの手順からすると
 あった方が良い。しかし、frame pointer そのものをstatic
-にとるのはまずい。だから、frame pointer がfirst argment
+にとるのはまずい。だから、frame pointer がfirst argument
 ということにする方が正しい。とすると引数は、さらに、その
 後と言うわけか。
-	f(fp,argment)
-fp を渡すのにさらにargment をレジスタで渡すのはおかしい。おかしいけど、
+	f(fp,argument)
+fp を渡すのにさらにargument をレジスタで渡すのはおかしい。おかしいけど、
 ま、良いか。
 
 return しないなら、return type の定義をとるのは変だな。
@@ -382,7 +382,7 @@
     goto name(arg);
 }
  
-ぐらいかな? で、first argment が必ずregisterにのるようにしないと
+ぐらいかな? で、first argument が必ずregisterにのるようにしないと
 いけない。register storage class を入れて、
     register "%ebp" void *arg
 とかするわけね。
@@ -471,7 +471,7 @@
 
 Sat Jan  1 22:40:22 JST 2000
 
-とーにかく、 storage class regisgter を実装しよう。
+とーにかく、 storage class register を実装しよう。
 
     stmode=REGISTER
 
@@ -481,12 +481,12 @@
 symbol table に storage class をたせば? dsp==EXTRN で判定しているから、
 local 変数が36以上あるとおかしくなるぞ?
 
-sc  は GVAR/LVAR だけど、regsiter は LVAR の特殊な奴だから、
+sc  は GVAR/LVAR だけど、register は LVAR の特殊な奴だから、
 sc に入れるほうが正しいか...
 
 Sun Jan  2 01:47:17 JST 2000
 
-register 変数はできました。けど、regsiter を二つ使うと、
+register 変数はできました。けど、register を二つ使うと、
 一杯になってしまうので、REGISTER6 でコンパイルしないと
 結構ひどい。が、register 変数を%esi,%edi に割り当てれば
 いいか。
@@ -565,7 +565,7 @@
 うーん、なんかレジスタにつむ順序が違う
 これは、adecl がreverseにつむから。
 
-code のretrun
+code のreturn
 
 やはりcodeはtypeにしないとだめ。
 
@@ -625,12 +625,12 @@
 かな? call/cc ?
 
 label へのgotoを許すのもいいけど、
-でも、label を許すと、すごくspagettyにならない?
+でも、label を許すと、すごくspaghettiにならない?
 
 
 Tue Jan  4 11:47:24 JST 2000
 
-contiunation じゃなくて、return keyword を使おう。
+continuation じゃなくて、return keyword を使おう。
 (実際、continuation と少し違うし)
 type が少し変になるけど、まあ良い。
 
@@ -650,7 +650,7 @@
 Tue Jan  4 12:21:44 JST 2000
 
 これだとmethodがすべてstatic になってしまう。dynamic なmethod
-呼び出しにするには? dipatcher を自分で作ることになる。かなり
+呼び出しにするには? dispatcher を自分で作ることになる。かなり
 めんどくさいが...
 
 code method(obj,arg)
@@ -662,7 +662,7 @@
 
 Tue Jan  4 14:22:19 JST 2000
 
-main の変数を書き潰すのと、gotgo (*reg)(123) での値は、
+main の変数を書き潰すのと、goto (*reg)(123) での値は、
 register 渡しで、current register にのらないので、
 結局、return label は専用に作る必要がある。
 
@@ -796,7 +796,7 @@
 あるね。
 
 そうじゃなくて、return 側で判断するか? 
-	retrun(ID)
+	return(ID)
 みたいな形でIDで判断する。そうすれば、return 側でID
 を見て判断できる。けど...
 
@@ -806,7 +806,7 @@
 そういうことは起こらない。
 
 continuation 特有の問題を避けるなら、このままでもいいんだが...
-contrinuation や環境は、このシステムでは自分で作ることが
+continuation や環境は、このシステムでは自分で作ることが
 できるからね。
 
 そうなんだけど.... retlabel や retcont は実はオブジェクト
@@ -1353,7 +1353,7 @@
 
 Thu Feb  6 11:47:03 JST 2003
 
-Code Segement を単位として使うときに、大域変数はどういう
+Code Segment を単位として使うときに、大域変数はどういう
 ように分けるの? static なんかは意味ないよね。
 
 もちろん、自然にグループ分けされるわけだけど。
@@ -1507,7 +1507,7 @@
 type に -1 とheapの引数が混在しているやつだけど..
 やっぱまずいんじゃないか?
 
-temproal struct は再利用できるんだけど、dispの変更ができないので
+temporal struct は再利用できるんだけど、dispの変更ができないので
 新しく作るしかない。大きいときだけ新しく作るなんていうセコイ
 技はあるけど。(そうすると、帰って来た値へのポインタを使えなく
 なるが.... 別にいいよね。戻り値それ自身を直接 return する
@@ -1584,7 +1584,7 @@
 
 Tue Feb 18 11:56:10 JST 2003
 
-overraped 用の emit_copy
+overlapped 用の emit_copy
 float/double
 long long
 
@@ -1608,11 +1608,11 @@
 って、きっと return 文がないと、文句を
 言われるよね。むむむ。
 
-post processing する時にoverrapしてないという保証がない。
+post processing する時にoverlapしてないという保証がない。
 
 Wed Feb 19 15:38:55 JST 2003
 
-自分自身とのoverrrapを見てないので、
+自分自身とのoverlapを見てないので、
     struct a a,int i
     int i,struct a a
 みたいな時に自分自身を壊してしまう。なので、emit_copy
--- a/README	Sat Jun 19 21:45:19 2004 +0900
+++ b/README	Sun Jun 20 20:54:24 2004 +0900
@@ -127,15 +127,17 @@
 //    Register float arguments does no accepts assignment operation such as
 //	*=, /=, +=.
 
-No built-in alloca.
+//No built-in alloca.
 
-No varargs.
+// No varargs.
+
+Use stdarg
 
-Switch statements is implemented as series of compare and branch,
-no tables.
+// Switch statements is implemented as series of compare and branch,
+// no tables.
 
-Some operations such as concatenation are not implemented in macro
-processor.
+// Some operations such as concatenation are not implemented in macro
+// processor.
 
 Macro processor is a coroutine in this compiler, slightly different
 from cpp.
--- a/README.jp	Sat Jun 19 21:45:19 2004 +0900
+++ b/README.jp	Sun Jun 20 20:54:24 2004 +0900
@@ -57,7 +57,7 @@
 code は code segment を表す型です。code segment ではreturn
 文を使用することはできません。
 
-Interfaces は引数です。構造体も使うことができます。Inteface
+Interfaces は引数です。構造体も使うことができます。Interface
 の一部はレジスタにマップされるので参照を取ることはできません。
 構造体は常に可能です。
 
--- a/mc-code-ia32.c	Sat Jun 19 21:45:19 2004 +0900
+++ b/mc-code-ia32.c	Sun Jun 20 20:54:24 2004 +0900
@@ -1,4 +1,4 @@
-/* Micro-C Code Generatation Part for intel386 */
+/* Micro-C Code Generation Part for intel386 */
 /* $Id$ */
 
 #define EXTERN extern
@@ -114,10 +114,10 @@
 }
 
 /*
-    creg   currrent virtual register
+    creg   current virtual register
     dreg   spare virtual register
 
-    rname[creg]   currrent real register
+    rname[creg]   current real register
     rname[dreg]   spare real register
 
     regs[]        virtual register usage
@@ -126,7 +126,7 @@
     reg_name[rname[creg]]
 
     freg    current floating point register
-    fregv   calue in floating point register
+    fregv   value in floating point register
  */
 
 static int dreg; /* general temporal register */
@@ -1920,7 +1920,7 @@
     }
     if (chk) return;
     if (n->dsp != -1) {
-	n->dsp = -1;   /* initiallized flag */
+	n->dsp = -1;   /* initialized flag */
 	printf(".globl\t%s\n",name);
 	data_mode(name);
 	align(t);
@@ -2391,7 +2391,7 @@
     } else if (xreg<= -REG_LVAR_OFFSET) {
 	code_drlvar(REG_LVAR_OFFSET+xreg,1,freg);
 	free_lvar(xreg+REG_LVAR_OFFSET);
-	/* pushed order is reversed.   We don't need this for comutable 
+	/* pushed order is reversed.   We don't need this for commutable 
 	    operator, but it is ok to do this.  */
         printf("\tfxch\t%%st(1)\n");
     } 
@@ -3081,8 +3081,8 @@
 /*
      prepare asm operands
 
-     char *constraints sgtring
-     int  oeprand expre
+     char *constraints string
+     int  operand expr
      int  mode          (ASM_INPUT,ASM_OUTPUT)
      int  replacement list
      int  output operands count
--- a/mc-code-mips.c	Sat Jun 19 21:45:19 2004 +0900
+++ b/mc-code-mips.c	Sun Jun 20 20:54:24 2004 +0900
@@ -1,4 +1,4 @@
-/* Micro-C Code Generatation Part for Power PC (Mac OS X) */
+/* Micro-C Code Generation Part for Power PC (Mac OS X) */
 /* $Id$ */
 
 #define EXTERN extern
@@ -298,7 +298,7 @@
      $2,$3 return value. (dpcmp return value on $2)
      $0  special register
      $4-$7  input register
-     r18-r24 saved register variable (input register for code segement)
+     r18-r24 saved register variable (input register for code segment)
      $25    jump register
      $31    stack pointer
      $fp    frame pointer
@@ -1118,7 +1118,7 @@
     int p,p1;
     char *rrn;
 
-    p1 = ptcptr; p = cadr(p1); /* unnecesary, if ptcptr is initialized */
+    p1 = ptcptr; p = cadr(p1); /* unnecessary, if ptcptr is initialized */
     while(ptcptr) {
 	if(car(ptcptr)==g) return caddr(ptcptr);
 	p1=p; p=ptcptr;
@@ -1478,7 +1478,7 @@
     int lb;
 
     lb=fwdlabel();
-    // should put on diffirent segement
+    // should put on different segement
     printf("\t.rdata\n\t.align 2\n");
     printf("$L_%d:\n",lb);
     output_mode = RODATA_EMIT_MODE;
@@ -2125,9 +2125,9 @@
     set_ireg(CREG_REGISTER,0);
 
     //  Struct arguments need emit_copy. it destructs 3 input registers.
-    //  But it returns no value on a register. So calcurate it here.
+    //  But it returns no value on a register. So calculate it here.
     //  We cannot do this in the previous loop, because the copied struct may be
-    //  override by other complex arguments. But bofore this we have to check
+    //  override by other complex arguments. But before this we have to check
     //  complex_.
 
     if (stargs) {
@@ -3254,7 +3254,7 @@
     }
     if (chk) return;
     if (n->dsp != -1) {
-	n->dsp = -1;   /* initiallized flag */
+	n->dsp = -1;   /* initialized flag */
 	if (n->sc!=STATIC)
 	    printf(".globl\t%s\n",name);
 	data_mode(name);
@@ -5284,8 +5284,8 @@
 /*
      prepare asm operands
 
-     char *constraints sgtring
-     int  oeprand expre
+     char *constraints string
+     int  operand expr
      int  mode          (ASM_INPUT,ASM_OUTPUT)
      int  replacement list
      int  output operands count
--- a/mc-code-powerpc.c	Sat Jun 19 21:45:19 2004 +0900
+++ b/mc-code-powerpc.c	Sun Jun 20 20:54:24 2004 +0900
@@ -1,4 +1,4 @@
-/* Micro-C Code Generatation Part for Power PC (Mac OS X) */
+/* Micro-C Code Generation Part for Power PC (Mac OS X) */
 /* $Id$ */
 
 #define EXTERN extern
@@ -259,7 +259,7 @@
 
      r0    return value etc.
      r3-r10  input register
-     r22-r29 saved register variable (input register for code segement)
+     r22-r29 saved register variable (input register for code segment)
      r30   stack pointer
      r31   0
      r1    frame pointer
@@ -354,7 +354,7 @@
 /* if size of local variables / input variables is more then 64k,
    lo16 does not work. We have to use ha16 also. But we can't know
    the exact size in one path compile. We may safely use lvar16ha 
-   if disp or max_func_args > 32k. Of course this is reduantant for
+   if disp or max_func_args > 32k. Of course this is redundant for
    smaller offset. But who cares who use very large local variables?
  */
 
@@ -1080,7 +1080,7 @@
     int p,p1;
     char *rrn;
 
-    p1 = ptcptr; p = cadr(p1); /* unnecesary, if ptcptr is initialized */
+    p1 = ptcptr; p = cadr(p1); /* unnecessary, if ptcptr is initialized */
     while(ptcptr) {
 	if(car(ptcptr)==g) return caddr(ptcptr);
 	p1=p; p=ptcptr;
@@ -1694,7 +1694,7 @@
 void
 set_lreg_operand(int reg,int mode)
 {
-    // save_stack,clear_ptr_cache is assmued    
+    // save_stack,clear_ptr_cache is assumed    
     if (!is_longlong_reg(reg)) { error(-1); return; }
     if (mode) {
 	if (regv_l(reg)!=3)
@@ -1707,7 +1707,7 @@
 void
 set_lreg_operand1(int reg,int mode)
 {
-    // save_stack,clear_ptr_cache is assmued    
+    // save_stack,clear_ptr_cache is assumed    
     if (!is_longlong_reg(reg)) { error(-1); return; }
     if (mode) {
 	if (regv_l(reg)!=5)
@@ -2038,9 +2038,9 @@
     set_ireg(CREG_REGISTER,0);
 
     //  Struct arguments need emit_copy. it destructs 3 input registers.
-    //  But it returns no value on a register. So calcurate it here.
+    //  But it returns no value on a register. So calculate it here.
     //  We cannot do this in the previous loop, because the copied struct may be
-    //  override by other complex arguments. But bofore this we have to check
+    //  override by other complex arguments. But before this we have to check
     //  complex_.
 
     if (stargs) {
@@ -2119,7 +2119,7 @@
 	} else if (t==DOUBLE||t==FLOAT) {
 	    if (reg_arg<MAX_INPUT_REGISTER_VAR) {
 		/* sigh... 
-                   printf requies floating value in integer registers
+                   printf requires floating value in integer registers
                  */
 		if (dots) {
 		    if (car(e4)==DRLVAR) {
@@ -2151,7 +2151,7 @@
 	    }
 	    if (dots && freg_arg>=4 && freg_arg<MAX_INPUT_DREGISTER_VAR) { 
 		/* oh my god! 
-                   it requies integer register and floating register and
+                   it requires integer register and floating register and
                    stack value. You are crazy.
                  */
 		arg_assign = list2(
@@ -2953,7 +2953,7 @@
     }
     if (chk) return;
     if (n->dsp != -1) {
-	n->dsp = -1;   /* initiallized flag */
+	n->dsp = -1;   /* initialized flag */
 	printf(".globl\t_%s\n",name);
 	data_mode(name);
 	align(t);
@@ -4967,7 +4967,7 @@
      prepare asm operands
 
      char *constraints sgtring
-     int  oeprand expre
+     int  oeprand expr
      int  mode          (ASM_INPUT,ASM_OUTPUT)
      int  replacement list
      int  output operands count
--- a/mc-codegen.c	Sat Jun 19 21:45:19 2004 +0900
+++ b/mc-codegen.c	Sun Jun 20 20:54:24 2004 +0900
@@ -1,4 +1,4 @@
-/* Micro-C Generic Code Generatation Part */
+/* Micro-C Generic Code Generation Part */
 /* $Id$ */
 
 #define EXTERN extern
@@ -1814,7 +1814,7 @@
            &    overwrite by this asm and can't be used as input register
            ignored in this compiler
         constraints
-           m    value expression is modified (no coresponding register)
+           m    value expression is modified (no corresponding register)
                         information for compiler
            r    register for input or output 
 			input register, output register can be shared
--- a/mc-parse.c	Sat Jun 19 21:45:19 2004 +0900
+++ b/mc-parse.c	Sun Jun 20 20:54:24 2004 +0900
@@ -121,6 +121,8 @@
 static int in_quote=0;
 static int lastexp = 0;
 
+static int bit_field_disp;
+
 int
 main(int argc, char **argv)
 {
@@ -754,6 +756,15 @@
                with arg type list. See def/ADECL  */
 	    if (mode!=GDECL)
 		n->dsp=arg;
+	} else if(sym==COLON) { /* brain dead bit-field */
+	    if (mode=GSDECL||mode==GUDECL||mode=LSDECL||mode==LUDECL) {
+		if (scalar(type) || type==LONGLONG || type==ULONGLONG) {
+		    getsym(0);
+		    n->ty = list4(BIT_FILED,type,0 /* bit offset */,symval);
+		}
+	    }
+	    error(SYERR);
+	    return n;
 	} else
 	    return n;
     }
@@ -982,6 +993,8 @@
 def(NMTBL *n)
 {
     int sz,nsc,ndsp;
+    int sbit_f = bit_field_disp;
+    bit_field_disp = 0;  // default is 0, recover only in bit-field
 
     conv->def_(n);
     if (n==0) {
@@ -995,15 +1008,24 @@
 	if ((mode==GDECL)) {
 	    fcheck(n);
 	    return n;
-	    /* function and code segement are defined using fdecl/code_decl */
+	    /* function and code segment are defined using fdecl/code_decl */
             /* in decl() */
 	}
     }
     if (mode==GSDECL||mode==LSDECL|| mode==GUDECL||mode==LUDECL) {
-          /* Struct fileds name lists are in the struct type or tag. */
+          /* Struct fields name lists are in the struct type or tag. */
           /* Only name in the table is used. */
+	if (car(n->ty)==BIT_FIELD) {
+	    bit_field_disp=sbit_f;   // default is 0, recover only here.
+            // n->ty = list4(BIT_FILED,type,bit_offset,symval);
+	    caddr(n->ty) = bit_field_disp;  // bitwise offset
+	    bit_field_disp += cadddr(n->ty);
+	    sz = bit_field_disp/BIT_OF_BYTE;
+	    bit_field_disp %= BIT_OF_BYTE;
+	}  else {
+	    sz = size(type);
+	}
 	fields = list4(type,fields,(int)(n->nm),disp);
-	sz = size(type);
     } else {
 	if (n->sc!=EMPTY &&  !(n->sc==EXTRN||n->sc==EXTRN1||n->sc==STATIC)) {
 	  /* redefined case */
@@ -1021,7 +1043,7 @@
     case STADECL:
 	nsc = GVAR;
 	ndsp = gpc;
-	if (n->dsp!=-1)     /* don't set dsp if initialzed static */
+	if (n->dsp!=-1)     /* don't set dsp if initialized static */
 	    n->dsp = ndsp;  /* emit_data will override this */
 	if (stmode==EXTRN)
 	    nsc = EXTRN;
@@ -1253,7 +1275,7 @@
     decl_str_init = decl_str_init_save;
 }
 
-// data strucutre initialization
+// data structure initialization
 
 static int
 decl_data(int t, NMTBL *n,int offset,int skip)
@@ -1318,6 +1340,8 @@
 	    }
 	    return offset; /* not reached */
 	}
+    } else if (t1==BIT_FIELD) {
+	error(DCERR); // not supported now
     } else if (t1==STRUCT) {
         if (sym==LC) {
             conv->lc_(); conv->decl_data_begin_();
@@ -1368,7 +1392,7 @@
 static int
 sdecl(int s)
 {
-    int smode,sdisp,type0=0;
+    int smode,sdisp,sbit_filed_disp,type0=0;
     NMTBL *nptr0,*gnptr0;
     int sfields = fields;
 
@@ -1379,7 +1403,9 @@
     else
 	mode=(s==STRUCT?LSDECL:LUDECL);
     sdisp=disp;
+    sbit_field_disp=bit_field_disp;
     disp=0;
+    bit_field_disp=0;
     if (sdecl_f) conv->sdecl_(s);
     if (getsym(TAG) == IDENT) {
 	nptr0 = nptr;
@@ -1416,6 +1442,7 @@
 
     stypedecl=1;
     disp=sdisp;
+    bit_field_disp=sbit_field_disp;
     mode=smode;
     fields = sfields;
     return type0;
@@ -1664,7 +1691,7 @@
 	str_ret.nm = "str_ret"; str_ret.sc = EMPTY;
 	str_ret.dsp = 0; str_ret.ty = 0;
 	type=list2(POINTER,t);
-	/* fix all arguments's offset */
+	/* fix all argument's offset */
 	sz = size(type);
 	for(t=fnptr->dsp;t;t=cadr(t)) {
 	    n=(NMTBL *)caddr(t);
@@ -1732,7 +1759,7 @@
 checkret(void)
 {
     if (cslabel==0) {
-	if (!control) error(-1); // no excute code in switch
+	if (!control) error(-1); // no execute code in switch
 	jmp(cslabel=fwdlabel());
     } else if (retpending) {
 	ret();
@@ -2069,7 +2096,7 @@
     if (retpending) { ret(); retpending=0; }
     if (!cslabel) {
 	if (!control) {
-	    // immiediate after switch(i) (ususal case)
+	    // immediate after switch(i) (usual case)
 	    // use it for jump to table lookup
 
 	    cmpdimm(car(clist),csvalue1,cslabel=fwdlabel(),1);
@@ -2081,8 +2108,8 @@
 
 	} else {
 	    // checkret() sequence inconsistent
-	    // This can't happen, because checkret() force teble lookup jump
-	    // before any executable instruction in switch such as siwth-for.
+	    // This can't happen, because checkret() force table lookup jump
+	    // before any executable instruction in switch such as switch-for.
 	    error(-1);  
 	}
     }
@@ -2173,7 +2200,7 @@
     lfree=slfree;
     conv->return_end_();
     checksym(SM);
-    /* control = 0; still control continue until pending return emittion */
+    /* control = 0; still control continue until pending return emission */
     retpending = 1;
 }
 
@@ -2433,6 +2460,17 @@
     error(TYERR); return e2;
 }
 
+static int
+coarse(int otype,int e,int itype)
+{
+    if(otype==LONGLONG) return longlong_value(e,itype);
+    else if(otype==ULONGLONG) return ulonglong_value(e,itype);
+    else if(otype==UCHAR||otype==UNSIGNED) return unsigned_value(e,itype);
+    else if(otype==FLOAT) return float_value(e,itype);
+    else if(otype==DOUBLE) return double_value(e,itype);
+    return int_value(e,itype);
+}
+
 /* assign statement */
 
 /* keep type */
@@ -2448,7 +2486,7 @@
     return e1;
 }
 
-/* with converion (will destroy type global variable) */
+/* with conversion (will destroy type global variable) */
 
 int
 assign_expr(int e1,int e2,int t,int type) {
@@ -2482,6 +2520,10 @@
 	e2=(t==UNSIGNED)?unsigned_value(e2,type):int_value(e2,type);
 	type=t;
 	return(list3(ASS,e1,e2));
+    } else if (car(t)==BIT_FIELD) {
+	e2 = coarse(cadr(t),e2,type);
+	type = cadr(t);
+	return(list3(BASS,e1,e2));
     } else if((car(t)==STRUCT||car(t)==UNION)) {
 	if (size(t)!=size(type)) error(TYERR);
 	type=t;
@@ -2546,7 +2588,6 @@
 	t=type;
 	getsym(0);
 	e2=rvalue(expr1());
-
 	if(!(integral(type)||type==FLOAT||type==DOUBLE||
 	    type==LONGLONG||type==ULONGLONG
 		)) error(TYERR);
@@ -2570,22 +2611,32 @@
 	    return(list4(LASSOP,e1,e2,op+LOP+((op==MUL+AS||op==DIV+AS)?US:0)));
 	}
 #endif
-	if(!integral(type)) error(TYERR);
-	if((t==UNSIGNED||type==UNSIGNED)&&
+	if((t==UNSIGNED||t==UCHAR||t==USHORT||type==UNSIGNED)&&
 	    (op==MUL||op==DIV||op==MOD))
 	    op=op+US;
-	if(t==UNSIGNED&&(op==RSHIFT||op==LSHIFT))
+	if((t==UNSIGNED||t==UCHAR||t==USHORT)&&(op==RSHIFT||op==LSHIFT))
 	    op=op+US;
 	if(t==CHAR) {
 	    type= INT;
 	    return(list4(CASSOP,e1,e2,op));
 	}
-	/*
+	if(t==UCHAR) {
+	    type= UNSIGNED;
+	    return(list4(CUASSOP,e1,e2,op));
+	}
 	if(t==SHORT) {
 	    type= INT;
 	    return(list4(SASSOP,e1,e2,op));
 	}
-	*/
+	if(t==USHORT) {
+	    type= UNSIGNED;
+	    return(list4(SUASSOP,e1,e2,op));
+	}
+	if (t>0 && car(t)==BIT_FIELD) {
+	    e2 = coarse(cadr(t),e2,type);
+	    type = cadr(t);
+	    return(list4(BASSOP,e1,e2,list2(op,t)));
+	}
 	type=t;
 	if(integral(t)) return(list4(ASSOP,e1,e2,op));
         /* pointer += ... */
@@ -3300,6 +3351,11 @@
 	    return e;
 	case POINTER:
 	    break;
+	case BIT_FIELD:
+	    return list4(RBIT_FILED,caddr(type),cadddr(type),rvalue(cadddr(e)));
+            /*                      bit offset,   bit size,  rvalue */
+	    type = cadr(e);
+	    break;
 	default:
 	    error(TYERR);
 	}
@@ -3393,7 +3449,7 @@
     /* type = list4(s,disp,fields,tag_nptr); */
     /* print_fields(caddr(type),"strop"); */
     type = search_struct_type(type,nptr->nm,&dsp);
-    if (!type) { error(TYERR); return INT; }
+    if (!type) { error(TYERR); type=INT; return e; }
     if(dsp) {
 	switch(car(e)) {
 	case GVAR:
@@ -3416,12 +3472,17 @@
 	    e=list2(INDIRECT,e);
 	}
     }
+    if (type>0&&car(type)==BIT_FIELD) {
+	getsym(0);
+	// n->ty = list4(BIT_FILED,type,bit_offset, bit_size);
+	return     list4(BIT_FILED,     caddr(type),cadddr(type), e);
+    }
     getsym(0);
     return e;
 }
 
 #if FLOAT_CODE
-/* binary floating compuation */
+/* binary floating computation */
 
 #define DTYPE(dop) (dop==DOP?DOUBLE:FLOAT)
 
@@ -3626,7 +3687,7 @@
 }
 #endif
 
-/* binary integer compuation */
+/* binary integer computation */
 
 static int
 binop(int op, int e1, int e2, int t1, int t2)
@@ -3864,7 +3925,7 @@
     type = cadr(ftype); 
     if(type==CHAR) type=INT;
     else if(car(type)==STRUCT||car(type)==UNION) {
-	/* make temporaly struct for return value */
+	/* make temporary struct for return value */
 	/* but it is better to see we can reuse old one */
 	if (tmp_struct) {
 	    sz = size(tmp_struct->ty);
@@ -4895,7 +4956,7 @@
 // fprintf(stderr,"macro def: ch %c *chptr %c\n",ch,*chptr);
     getsym(0);
 // fprintf(stderr,"macro def: %s =>",name); 
-    if (nptr->sc != EMPTY) { /* override exisiting macro */
+    if (nptr->sc != EMPTY) { /* override existing macro */
     }
     args = 0;
     if (ch=='(') {
--- a/mc-switch.c	Sat Jun 19 21:45:19 2004 +0900
+++ b/mc-switch.c	Sun Jun 20 20:54:24 2004 +0900
@@ -32,7 +32,7 @@
 
 
 /*
-   group continous case value
+   group continuous case value
  */
 
 static int
--- a/mc.h	Sat Jun 19 21:45:19 2004 +0900
+++ b/mc.h	Sun Jun 20 20:54:24 2004 +0900
@@ -78,6 +78,7 @@
 #define VOLATILE	(-57)
 #define TYPEOF	(-58)
 #define ASM	(-59)
+#define BITFIELD	(-60)
 
 /* reserved word end */
 
@@ -110,6 +111,7 @@
 #define DOP	600
 #define FOP	800
 #define LOP	1000
+#define BOP	1200    // bit field
 
 /* tree node tags start */
 
@@ -139,6 +141,10 @@
 #define LURGVAR	(LOP+URGVAR)
 #define LRLVAR	(LOP+RLVAR)
 #define LURLVAR	(LOP+URLVAR)
+#define BRGVAR	(BOP+RGVAR)
+#define BURGVAR	(BOP+URGVAR)
+#define BRLVAR	(BOP+RLVAR)
+#define BURLVAR	(BOP+URLVAR)
 
 #define CONST	7
 #define DCONST	(DOP+CONST)
@@ -303,14 +309,16 @@
 #define LEOR	(LOP+EOR)
 #define LBOR	(LOP+BOR)
 
+#define BASS	69
 
-#define STASS	69
+#define STASS	70
+
 
 #define BINARY_ARGS(i) (MUL<=(i%SOP)&&(i%SOP)<=STASS)
 
 /* tarnary  argments */
 
-#define COND	70
+#define COND	71
 #define SCOND	(SOP+COND)
 #define DCOND	(DOP+COND)
 #define FCOND	(FOP+COND)
@@ -320,19 +328,19 @@
 
 /* not appeared as tags */
 
-#define I2I	71
-#define I2U	72
-#define I2D	73
-#define I2F	74
-#define I2LL	75
-#define I2ULL	76
+#define I2I	72
+#define I2U	73
+#define I2D	74
+#define I2F	75
+#define I2LL	76
+#define I2ULL	77
 
-#define U2I	77
-#define U2U	78
-#define U2D	79
-#define U2F	80
-#define U2LL	81
-#define U2ULL	82
+#define U2I	78
+#define U2U	79
+#define U2D	80
+#define U2F	81
+#define U2LL	82
+#define U2ULL	83
 
 #define D2I	(DOP+I2I)
 #define D2U	(DOP+I2U)
@@ -362,17 +370,17 @@
 #define ULL2LL	(LOP+U2LL)
 #define ULL2ULL	(LOP+U2ULL)
 
-#define LPAR	83
-#define RPAR	84
-#define LBRA	85
-#define RBRA	86
-#define LC	87
-#define RC	88
-#define COLON	89
-#define SM	90
-#define PERIOD	91
-#define ARROW	92
-#define CNAME	93
+#define LPAR	84
+#define RPAR	85
+#define LBRA	86
+#define RBRA	87
+#define LC	88
+#define RC	89
+#define COLON	90
+#define SM	91
+#define PERIOD	92
+#define ARROW	93
+#define CNAME	94
 
 /* tree node tags end */