new version, different interface
authorceriel <none@none>
Tue, 30 Jun 1987 12:55:30 +0000 (12:55 +0000)
committerceriel <none@none>
Tue, 30 Jun 1987 12:55:30 +0000 (12:55 +0000)
12 files changed:
modules/src/read_em/.distr
modules/src/read_em/EM_vars.c
modules/src/read_em/Makefile
modules/src/read_em/em_comp.h
modules/src/read_em/m_C_funcs [new file with mode: 0755]
modules/src/read_em/m_C_mnem
modules/src/read_em/m_C_mnem_na
modules/src/read_em/mkcalls.c
modules/src/read_em/read_em.3
modules/src/read_em/read_em.c
modules/src/read_em/reade.c
modules/src/read_em/readk.c

index a221e0c..82e6343 100644 (file)
@@ -4,6 +4,7 @@ argtype
 em_comp.h
 m_C_mnem
 m_C_mnem_na
+m_C_funcs
 mkcalls.c
 read_em.3
 read_em.c
index f623dc5..12e379d 100644 (file)
@@ -6,6 +6,11 @@
 
 /* Variables must be declared somewhere ... */
 
+#include <em_arith.h>
+
 char   *EM_error;
 char   *EM_filename;
 unsigned int EM_lineno;
+int    EM_wordsize, EM_pointersize;
+arith  em_holorbsssize;
+int    em_holorbssinit;
index 4f9396d..d397600 100644 (file)
@@ -48,13 +48,13 @@ cmp:                all
                $(COMPARE) man/read_em.3
 
 pr:
-               @pr Makefile m_C_mnem m_C_mnem_na argtype $(SRCFILES)
+               @pr Makefile m_C_funcs m_C_mnem m_C_mnem_na argtype $(SRCFILES)
 
 opr:
                make pr | opr
 
 clean:
-               rm -f *.o *.a C_mnem C_mnem_narg
+               rm -f *.o *.a C_funcs C_mnem C_mnem_narg
 
 libread_emk.a: $(K_OFILES)
                ar r libread_emk.a $(K_OFILES)
@@ -80,11 +80,11 @@ read_emeV.o:        read_em.c em_comp.h reade.c
                $(CC) -c $(CFLAGS) -DCHECKING read_em.c
                mv read_em.o read_emeV.o
 
-makecalls.o:   C_mnem C_mnem_narg em_comp.h mkcalls.c
+makecalls.o:   C_funcs C_mnem C_mnem_narg em_comp.h mkcalls.c
                $(CC) -c $(CFLAGS) mkcalls.c
                mv mkcalls.o makecalls.o
 
-makecallsV.o:  C_mnem C_mnem_narg em_comp.h mkcalls.c
+makecallsV.o:  C_funcs C_mnem C_mnem_narg em_comp.h mkcalls.c
                $(CC) -c $(CFLAGS) -DCHECKING mkcalls.c
                mv mkcalls.o makecallsV.o
 
@@ -94,7 +94,10 @@ C_mnem:              m_C_mnem argtype
 C_mnem_narg:   m_C_mnem_na argtype
                sh m_C_mnem_na > C_mnem_narg
 
-lintlib:       C_mnem C_mnem_narg
+C_funcs:       m_C_funcs argtype
+               sh m_C_funcs > C_funcs
+
+lintlib:       C_mnem C_mnem_narg C_funcs
                lint $(INCLUDES) $(DEFINES) -DCOMPACT -DCHECKING -Cread_emkV $(KSRCFILES)
                lint $(INCLUDES) $(DEFINES) -DCHECKING -Cread_emeV $(ESRCFILES)
                mv llib-lread_emeV.ln llib-lread_emkV.ln $(MODULES)/lib
index a2babeb..e1da31b 100644 (file)
@@ -4,10 +4,30 @@
  */
 /* $Header$ */
 
+struct e_arg {
+       int     ems_argtype;            /* type of this argument */
+       union e_simple_arg {
+               arith   emu_cst;        /* a cst */
+               label   emu_dlb;        /* a numeric data label */
+               label   emu_ilb;        /* an instruction label */
+               char    *emu_dnam;      /* a data label */
+               char    *emu_pnam;      /* a procedure name */
+               char    *emu_string;    /* a string (fcon,icon,ucon,scon) */
+       }       ems_arg;
+       arith   ems_szoroff;
+};
+#define ema_cst        ems_arg.emu_cst
+#define ema_dlb        ems_arg.emu_dlb
+#define ema_ilb        ems_arg.emu_ilb
+#define ema_dnam       ems_arg.emu_dnam
+#define ema_pnam       ems_arg.emu_pnam
+#define ema_string     ems_arg.emu_string
+
+
 struct e_instr {
-       int     em_type;                /* Type of this instr */
-#define EM_MNEM                256             /* A machine instruction */
-#define        EM_PSEU         257             /* A pseudo */
+       int             em_type;        /* Type of this instr */
+#define EM_MNEM        256             /* A machine instruction */
+#define EM_PSEU        257             /* A pseudo */
 #define EM_STARTMES    258             /* Start of a MES pseudo */
 #define EM_MESARG      259             /* A member in a MES list */
 #define EM_ENDMES      260             /* End of a MES pseudo */
@@ -16,54 +36,36 @@ struct e_instr {
 #define EM_DEFDNAM     263             /* A non-numeric data label def */
 #define EM_ERROR       264             /* Recoverable error */
 #define EM_FATAL       265             /* Unrecoverable error */
-       union {
-             struct {
-                  int  emus_opcode;    /* Opcode of instruction */
-                  struct e_args *emus_args;    /* Arguments of instruction */
-             } emu_mp;
-             label     emu_deflb;      /* Numeric label definition */
-             char      *emu_defdnam;   /* Non-numeric label definition */
-             struct e_args     *emu_arg;       /* For an argument */
-       } em_i; 
-#define em_opcode      em_i.emu_mp.emus_opcode
-#define em_args                em_i.emu_mp.emus_args
-#define em_deflb       em_i.emu_deflb
-#define em_defdnam     em_i.emu_defdnam
-#define em_arg         em_i.emu_arg
+#define EM_EOF         266             /* End of file */
+       int             em_opcode;
+       struct e_arg    em_arg;
 };
 
-struct e_args {
-       struct e_args   *em_next;       /* Next argument */
-       short   em_argtype;             /* Type of this argument */
-       union {
-              arith    emu_cst;                /* A constant */
-              label    emu_ilb;                /* An instruction label */
-              char     *emu_pnam;      /* A procedure name (not including '$') */
-              struct {
-                     label     emus_dlb;
-                     arith     emus_noff;
-              } emu_ndlb;              /* Numeric data label + offset */
-              struct {
-                     char      *emus_dnam;
-                     arith     emus_soff;
-              } emu_sdlb;              /* String data label + offset */
-              struct {
-                     char      *emus_str;
-                     arith     emus_size;
-              } emu_con;                       /* An scon, icon, ucon or fcon */
-       } em_value;
-#define em_cst         em_value.emu_cst
-#define em_ilb         em_value.emu_ilb
-#define em_pnam                em_value.emu_pnam
-#define em_dlb         em_value.emu_ndlb.emus_dlb
-#define em_noff                em_value.emu_ndlb.emus_noff
-#define em_dnam                em_value.emu_sdlb.emus_dnam
-#define em_soff                em_value.emu_sdlb.emus_soff
-#define em_str         em_value.emu_con.emus_str
-#define em_size                em_value.emu_con.emus_size
-};
+extern arith
+       em_holorbsssize;
+extern int
+       em_holorbssinit;
+
+#define em_ilb         em_arg.ema_ilb
+#define em_dlb         em_arg.ema_dlb
+#define em_dnam        em_arg.ema_dnam
+#define em_argtype     em_arg.ems_argtype
+#define em_cst         em_arg.ema_cst
+#define em_pnam        em_arg.ema_pnam
+#define em_string      em_arg.ema_string
+#define em_off         em_arg.ems_szoroff
+#define em_size        em_arg.ems_szoroff
+#define em_exc1        em_arg.ema_cst
+#define em_exc2        em_arg.ems_szoroff
+
+#define em_holsize     em_holorbsssize
+#define em_bsssize     em_holorbsssize
+#define em_holinit     em_holorbssinit
+#define em_bssinit     em_holorbssinit
 
-extern char *EM_error;
-extern unsigned int EM_lineno;
-extern char *EM_filename;
-extern int EM_wordsize, EM_pointersize;
+extern char
+       *EM_error, *EM_filename;
+extern unsigned int
+       EM_lineno;
+extern int
+       EM_wordsize, EM_pointersize;
diff --git a/modules/src/read_em/m_C_funcs b/modules/src/read_em/m_C_funcs
new file mode 100755 (executable)
index 0000000..dd89cc8
--- /dev/null
@@ -0,0 +1,25 @@
+EM_TABLE=../../../etc/em_table
+ed - $EM_TABLE << EOF
+1,/^\$/d
+1,/^\$/d
+1,\$s/^\(...\).*/int C_\\1();/
+w blabla1
+q
+EOF
+ed - $EM_TABLE << A
+1,/^\$/d
+1,/^\$/d
+/^\$/d
+1,\$s/^\(...\).*/C_\\1,/
+\$a
+};
+.
+1i
+static int (*C_funcs[])() = {
+0,
+.
+w blabla2
+q
+A
+cat blabla1 blabla2 > C_funcs
+rm blabla1 blabla2
index f31347e..479da76 100755 (executable)
@@ -1,91 +1,73 @@
 EM_TABLE=../../../etc/em_table
-echo "switch(opcode) {"
+echo "switch(p->em_opcode) {"
+echo ' default: EM_error = "Illegal mnemonic"; break;'
 for i in - cdflnorswz p b
 do
        list=`./argtype $i $EM_TABLE`
        case $i in
        -)      args='()'
-               echo "/* no arguments */"
+               echo "  /* no arguments */"
                ;;
        cdflnorswz)
-               args='(arg->em_cst)'
-               echo "/* one integer constant argument */"
+               args='(p->em_cst)'
+               echo "  /* one integer constant argument */"
                ;;
        p)
-               args='(arg->em_pnam)'
-               echo "/* a procedure name argument */"
+               args='(p->em_pnam)'
+               echo "  /* a procedure name argument */"
                ;;
        b)
 
 : Grumbl, an instruction label as argument is encoded in a sp_cst2
 
-               args='((label) (arg->em_cst))'
-               echo "/* An instruction label argument */"
+               args='((label) (p->em_cst))'
+               echo "  /* An instruction label argument */"
                ;;
        esac
        for i in $list
        do
-               cat << EOF
-       case op_$i:
-               C_$i$args;
-               break;
-EOF
+               echo "  case op_$i:"
        done
+       echo "          (*C_funcs[p->em_opcode])$args; break;"
 done
 list=`./argtype g $EM_TABLE`
-cat << 'EOF'
-       default:
-/* a "g" argument */
-               if (arg->em_argtype == nof_ptyp) {
-                       switch(opcode) {
-                               default:
-                                       EM_error = "Illegal mnemonic";
-                                       break;
-EOF
 for i in $list
 do
-       cat << EOF
-                               case op_$i:
-                                       C_${i}_dlb(arg->em_dlb, arg->em_noff);
-                                       break;
-EOF
+       echo "  case op_$i:"
 done
 cat << 'EOF'
-                       }
-               }
-               else if (arg->em_argtype == sof_ptyp) {
-                       switch(opcode) {
-                               default:
-                                       EM_error = "Illegal mnemonic";
-                                       break;
+       /* a "g" argument */
+               if (p->em_argtype == nof_ptyp) {
+                       switch(p->em_opcode) {
 EOF
 for i in $list
 do
        cat << EOF
                                case op_$i:
-                                       C_${i}_dnam(arg->em_dnam, arg->em_soff);
+                                       C_${i}_dlb(p->em_dlb, p->em_off);
                                        break;
 EOF
 done
 cat << 'EOF'
                        }
                }
-               else /*argtype == cst_ptyp */ {
-                       switch(opcode) {
-                               default:
-                                       EM_error = "Illegal mnemonic";
-                                       break;
+               else if (p->em_argtype == sof_ptyp) {
+                       switch(p->em_opcode) {
 EOF
 for i in $list
 do
        cat << EOF
                                case op_$i:
-                                       C_$i(arg->em_cst);
+                                       C_${i}_dnam(p->em_dnam, p->em_off);
                                        break;
 EOF
 done
 cat << 'EOF'
                        }
                }
+               else /*argtype == cst_ptyp */ {
+                       (*C_funcs[p->em_opcode])(p->em_cst);
+                       break;
+               }
 }
 EOF
index d0bdab9..c4dd5ff 100755 (executable)
@@ -1,6 +1,6 @@
 EM_TABLE=../../../etc/em_table
 list=`./argtype w $EM_TABLE`
-echo "switch(opcode) {"
+echo "switch(p->em_opcode) {"
 for i in $list
 do
        cat << EOF
index d3bb31e..17622ef 100644 (file)
@@ -21,6 +21,8 @@
 extern char em_flag[]; /* One per EM instruction: indicates parameter kind */
 extern short em_ptyp[];        /* One per parameter kind: indicates parameter type */
 
+#include "C_funcs"
+
 static int listtype = 0;       /* indicates pseudo when generating code for
                                   variable length argument lists
                                   (only for MES)
@@ -31,45 +33,41 @@ static int listtype = 0;    /* indicates pseudo when generating code for
        The argument must be of a type allowed by "typset".
        Return a pointer to the next argument.
 */
-PRIVATE struct e_args *
-c_getarg(args, typset)
-       register struct e_args *args;
+PRIVATE
+checkarg(arg, typset)
+       register struct e_arg *arg;
 {
 
-       if (((!typset) && args) ||
-           ((!args) && typset)) {
+       if (((!typset) && arg->ems_argtype) ||
+           ((!arg->ems_argtype) && typset)) {
                /* End of arguments expected, but there are more, or
                   an argument expected, but there is none
                */
                EM_error = "Illegal number of parameters";
-               return 0;
+               return;
        }
 
-       if (!args) return 0;
-       if (!(args->em_argtype & typset)) {
+       if (!(arg->ems_argtype & typset)) {
                /* Type error */
                EM_error = "Illegal parameter type";
        }
-
-       return args->em_next;
 }
 #else not CHECKING
-#define c_getarg(arg, x)       ((arg) ? (arg)->em_next : (arg))
+#define c_getarg(arg, x)
 #endif CHECKING
 
 /*     EM_doinstr: An EM instruction
 */
 PRIVATE
-EM_doinstr(opcode, arg)
-       register struct e_args *arg;
+EM_doinstr(p)
+       register struct e_instr *p;
 {
        register int parametertype;     /* parametertype of the instruction */
-       register struct e_args *args;
 
-       parametertype = em_flag[opcode-sp_fmnem] & EM_PAR;
+       parametertype = em_flag[p->em_opcode-sp_fmnem] & EM_PAR;
 #ifdef CHECKING
        if (parametertype != PAR_NO && parametertype != PAR_W) {
-               if (!arg) {
+               if (p->em_argtype == 0) {
                        EM_error = "Illegal number of parameters";
                        return;
                }
@@ -79,13 +77,11 @@ EM_doinstr(opcode, arg)
                case PAR_NO:
                        break;
                default:
-                       args = c_getarg(arg, em_ptyp[parametertype]);
-                       args = c_getarg(args, 0);
+                       checkarg(&(p->em_arg), em_ptyp[parametertype]);
                        break;
                case PAR_W:
-                       if (arg) {
-                               args = c_getarg(arg, cst_ptyp);
-                               args = c_getarg(args, 0);
+                       if (p->em_argtype != 0) {
+                               checkarg(&(p->em_arg), cst_ptyp);
                        }
                        else {
 #include "C_mnem_narg"
@@ -97,73 +93,62 @@ EM_doinstr(opcode, arg)
 }
 
 PRIVATE
-EM_dopseudo(opcode, args)
-       register struct e_args *args;
+EM_dopseudo(p)
+       register struct e_instr *p;
 {
-       register struct e_args *arg;
 
-       switch(opcode) {
+       switch(p->em_opcode) {
                case ps_exc: {
-                       register struct e_args *args2;
-
-                       arg = c_getarg(args, cst_ptyp);
-                       args2 = c_getarg(arg, cst_ptyp);
-                       args2 = c_getarg(args2, 0);
-                       C_exc(args->em_cst, arg->em_cst);
+                       C_exc(p->em_exc1, p->em_exc2);
                        break;
                }
                case ps_hol: {
-                       register struct e_args *args2, *args3;
-
-                       arg = c_getarg(args, cst_ptyp);
-                       args2 = c_getarg(arg, par_ptyp);
-                       args3 = c_getarg(args2, cst_ptyp);
-                       args3 = c_getarg(args3, 0);
-                       switch(arg->em_argtype) {
+                       checkarg(&(p->em_arg), par_ptyp);
+                       switch(p->em_argtype) {
                            case cst_ptyp:
-                               C_hol_cst(args->em_cst,
-                                         arg->em_cst,
-                                         (int) (args2->em_cst));
+                               C_hol_cst(em_holsize,
+                                         p->em_cst,
+                                         em_holinit);
                                break;
                            case ico_ptyp:
-                               C_hol_icon(args->em_cst,
-                                          arg->em_str,
-                                          arg->em_size, 
-                                          (int)(args2->em_cst));
+                               C_hol_icon(em_holsize,
+                                          p->em_string,
+                                          p->em_size, 
+                                          em_holinit);
                                break;
                            case uco_ptyp:
-                               C_hol_ucon(args->em_cst,
-                                          arg->em_str,
-                                          arg->em_size,
-                                          (int)(args2->em_cst));
+                               C_hol_ucon(em_holsize,
+                                          p->em_string,
+                                          p->em_size,
+                                          em_holinit);
                                break;
                            case fco_ptyp:
-                               C_hol_fcon(args->em_cst,
-                                          arg->em_str,
-                                          arg->em_size, 
-                                          (int)(args2->em_cst));
+                               C_hol_fcon(em_holsize,
+                                          p->em_string,
+                                          p->em_size, 
+                                          em_holinit);
                                break;
                            case sof_ptyp:
-                               C_hol_dnam(args->em_cst,
-                                          arg->em_dnam,
-                                          arg->em_soff, 
-                                          (int)(args2->em_cst));
+                               C_hol_dnam(em_holsize,
+                                          p->em_dnam,
+                                          p->em_off, 
+                                          em_holinit);
                                break;
                            case nof_ptyp:
-                               C_hol_dlb(args->em_cst,
-                                         arg->em_dlb,
-                                         arg->em_noff, 
-                                         (int)(args2->em_cst));
+                               C_hol_dlb(em_holsize,
+                                         p->em_dlb,
+                                         p->em_off, 
+                                         em_holinit);
                                break;
                            case ilb_ptyp:
-                               C_hol_ilb(args->em_cst,
-                                         arg->em_ilb, 
-                                         (int)(args2->em_cst));
+                               C_hol_ilb(em_holsize,
+                                         p->em_ilb, 
+                                         em_holinit);
                                break;
                            case pro_ptyp:
-                               C_hol_pnam(args->em_cst, 
-                                          arg->em_pnam, 
-                                          (int)(args2->em_cst));
+                               C_hol_pnam(em_holsize,
+                                          p->em_pnam, 
+                                          em_holinit);
                                break;
                            default:
                                EM_error = "Illegal parameter type";
@@ -172,57 +157,52 @@ EM_dopseudo(opcode, args)
                        break;
                }
                case ps_bss: {
-                       register struct e_args *args2, *args3;
-
-                       arg = c_getarg(args, cst_ptyp);
-                       args2 = c_getarg(arg, par_ptyp);
-                       args3 = c_getarg(args2, cst_ptyp);
-                       args3 = c_getarg(args3, 0);
-                       switch(arg->em_argtype) {
+                       checkarg(&(p->em_arg), par_ptyp);
+                       switch(p->em_argtype) {
                            case cst_ptyp:
-                               C_bss_cst(args->em_cst,
-                                         arg->em_cst,
-                                         (int)(args2->em_cst));
+                               C_bss_cst(em_bsssize,
+                                         p->em_cst,
+                                         em_bssinit);
                                break;
                            case ico_ptyp:
-                               C_bss_icon(args->em_cst,
-                                          arg->em_str,
-                                          arg->em_size, 
-                                          (int)(args2->em_cst));
+                               C_bss_icon(em_bsssize,
+                                          p->em_string,
+                                          p->em_size, 
+                                          em_bssinit);
                                break;
                            case uco_ptyp:
-                               C_bss_ucon(args->em_cst,
-                                          arg->em_str,
-                                          arg->em_size,
-                                          (int)(args2->em_cst));
+                               C_bss_ucon(em_bsssize,
+                                          p->em_string,
+                                          p->em_size,
+                                          em_bssinit);
                                break;
                            case fco_ptyp:
-                               C_bss_fcon(args->em_cst,
-                                          arg->em_str,
-                                          arg->em_size, 
-                                          (int)(args2->em_cst));
+                               C_bss_fcon(em_bsssize,
+                                          p->em_string,
+                                          p->em_size, 
+                                          em_bssinit);
                                break;
                            case sof_ptyp:
-                               C_bss_dnam(args->em_cst,
-                                          arg->em_dnam,
-                                          arg->em_soff, 
-                                          (int)(args2->em_cst));
+                               C_bss_dnam(em_bsssize,
+                                          p->em_dnam,
+                                          p->em_off, 
+                                          em_bssinit);
                                break;
                            case nof_ptyp:
-                               C_bss_dlb(args->em_cst,
-                                         arg->em_dlb,
-                                         arg->em_noff, 
-                                         (int)(args2->em_cst));
+                               C_bss_dlb(em_bsssize,
+                                         p->em_dlb,
+                                         p->em_off, 
+                                         em_bssinit);
                                break;
                            case ilb_ptyp:
-                               C_bss_ilb(args->em_cst,
-                                         arg->em_ilb, 
-                                         (int)(args2->em_cst));
+                               C_bss_ilb(em_bsssize,
+                                         p->em_ilb, 
+                                         em_bssinit);
                                break;
                            case pro_ptyp:
-                               C_bss_pnam(args->em_cst
-                                          arg->em_pnam, 
-                                          (int)(args2->em_cst));
+                               C_bss_pnam(em_bsssize
+                                          p->em_pnam, 
+                                          em_bssinit);
                                break;
                            default:
                                EM_error = "Illegal parameter type";
@@ -231,80 +211,72 @@ EM_dopseudo(opcode, args)
                        break;
                }
                case ps_end:
-                       if (args) {
-                               arg = c_getarg(args, cst_ptyp);
-                               arg = c_getarg(arg, 0);
-                               C_end(args->em_cst);
+                       if (p->em_argtype != 0) {
+                               checkarg(&(p->em_arg), cst_ptyp);
+                               C_end(p->em_cst);
                                break;
                        }
                        C_end_narg();
                        break;
                case ps_exa:
                case ps_ina:
-                       arg = c_getarg(args, lab_ptyp);
-                       arg = c_getarg(arg, 0);
-                       if (args->em_argtype == nof_ptyp) {
-                               if (opcode == ps_exa) {
-                                       C_exa_dlb(args->em_dlb);
+                       checkarg(&(p->em_arg), lab_ptyp);
+                       if (p->em_argtype == nof_ptyp) {
+                               if (p->em_opcode == ps_exa) {
+                                       C_exa_dlb(p->em_dlb);
                                }
-                               else    C_ina_dlb(args->em_dlb);
+                               else    C_ina_dlb(p->em_dlb);
                                break;
                        }
-                       if (opcode == ps_exa) {
-                               C_exa_dnam(args->em_dnam);
+                       if (p->em_opcode == ps_exa) {
+                               C_exa_dnam(p->em_dnam);
                        }
-                       else    C_ina_dnam(args->em_dnam);
+                       else    C_ina_dnam(p->em_dnam);
                        break;
                case ps_exp:
+                       checkarg(&(p->em_arg), pro_ptyp);
+                       C_exp(p->em_pnam);
+                       break;
                case ps_inp:
-                       arg = c_getarg(args, pro_ptyp);
-                       arg = c_getarg(arg, 0);
-                       if (opcode == ps_exp) {
-                               C_exp(args->em_pnam);
-                       }
-                       else    C_inp(args->em_pnam);
+                       checkarg(&(p->em_arg), pro_ptyp);
+                       C_inp(p->em_pnam);
                        break;
                case ps_pro:
-                       arg = c_getarg(args, pro_ptyp);
-                       if (arg) {
-                               struct e_args *args2;
-
-                               args2 = c_getarg(arg, cst_ptyp);
-                               args2 = c_getarg(args2, 0);
-                               C_pro(args->em_pnam, arg->em_cst);
+                       checkarg(&(p->em_arg), pro_ptyp);
+                       if (p->em_size >= 0) {
+                               C_pro(p->em_pnam, p->em_size);
                        }
-                       else    C_pro_narg(args->em_pnam);
+                       else    C_pro_narg(p->em_pnam);
                        break;
                case ps_con:
-                       arg = c_getarg(args, val_ptyp);
-                       arg = c_getarg(arg, 0);
-                       switch(args->em_argtype) {
+                       checkarg(&(p->em_arg), val_ptyp);
+                       switch(p->em_argtype) {
                                case ilb_ptyp:
-                                       C_con_ilb(args->em_ilb);
+                                       C_con_ilb(p->em_ilb);
                                        break;
                                case nof_ptyp:
-                                       C_con_dlb(args->em_dlb, args->em_noff);
+                                       C_con_dlb(p->em_dlb, p->em_off);
                                        break;
                                case sof_ptyp:
-                                       C_con_dnam(args->em_dnam, args->em_soff);
+                                       C_con_dnam(p->em_dnam, p->em_off);
                                        break;
                                case cst_ptyp:
-                                       C_con_cst(args->em_cst);
+                                       C_con_cst(p->em_cst);
                                        break;
                                case pro_ptyp:
-                                       C_con_pnam(args->em_pnam);
+                                       C_con_pnam(p->em_pnam);
                                        break;
                                case str_ptyp:
-                                       C_con_scon(args->em_str, args->em_size);
+                                       C_con_scon(p->em_string, p->em_size);
                                        break;
                                case ico_ptyp:
-                                       C_con_icon(args->em_str, args->em_size);
+                                       C_con_icon(p->em_string, p->em_size);
                                        break;
                                case uco_ptyp:
-                                       C_con_ucon(args->em_str, args->em_size);
+                                       C_con_ucon(p->em_string, p->em_size);
                                        break;
                                case fco_ptyp:
-                                       C_con_fcon(args->em_str, args->em_size);
+                                       C_con_fcon(p->em_string, p->em_size);
                                        break;
                                default:
                                        EM_error = "Illegal argument type";
@@ -312,35 +284,34 @@ EM_dopseudo(opcode, args)
                        }
                        break;
                case ps_rom:
-                       arg = c_getarg(args, val_ptyp);
-                       arg = c_getarg(arg, 0);
-                       switch(args->em_argtype) {
+                       checkarg(&(p->em_arg), val_ptyp);
+                       switch(p->em_argtype) {
                                case ilb_ptyp:
-                                       C_rom_ilb(args->em_ilb);
+                                       C_rom_ilb(p->em_ilb);
                                        break;
                                case nof_ptyp:
-                                       C_rom_dlb(args->em_dlb, args->em_noff);
+                                       C_rom_dlb(p->em_dlb, p->em_off);
                                        break;
                                case sof_ptyp:
-                                       C_rom_dnam(args->em_dnam, args->em_soff);
+                                       C_rom_dnam(p->em_dnam, p->em_off);
                                        break;
                                case cst_ptyp:
-                                       C_rom_cst(args->em_cst);
+                                       C_rom_cst(p->em_cst);
                                        break;
                                case pro_ptyp:
-                                       C_rom_pnam(args->em_pnam);
+                                       C_rom_pnam(p->em_pnam);
                                        break;
                                case str_ptyp:
-                                       C_rom_scon(args->em_str, args->em_size);
+                                       C_rom_scon(p->em_string, p->em_size);
                                        break;
                                case ico_ptyp:
-                                       C_rom_icon(args->em_str, args->em_size);
+                                       C_rom_icon(p->em_string, p->em_size);
                                        break;
                                case uco_ptyp:
-                                       C_rom_ucon(args->em_str, args->em_size);
+                                       C_rom_ucon(p->em_string, p->em_size);
                                        break;
                                case fco_ptyp:
-                                       C_rom_fcon(args->em_str, args->em_size);
+                                       C_rom_fcon(p->em_string, p->em_size);
                                        break;
                                default:
                                        EM_error = "Illegal argument type";
@@ -354,40 +325,37 @@ EM_dopseudo(opcode, args)
 }
 
 PRIVATE
-EM_docon(args)
-       register struct e_args *args;
+EM_docon(p)
+       register struct e_instr *p;
 {
-       register struct e_args *arg;
-
-       arg = c_getarg(args, val_ptyp);
-       arg = c_getarg(arg, 0);
-       switch(args->em_argtype) {
+       checkarg(&(p->em_arg), val_ptyp);
+       switch(p->em_argtype) {
                case ilb_ptyp:
-                       C_ilb(args->em_ilb);
+                       C_ilb(p->em_ilb);
                        break;
                case nof_ptyp:
-                       C_dlb(args->em_dlb, args->em_noff);
+                       C_dlb(p->em_dlb, p->em_off);
                        break;
                case sof_ptyp:
-                       C_dnam(args->em_dnam, args->em_soff);
+                       C_dnam(p->em_dnam, p->em_off);
                        break;
                case cst_ptyp:
-                       C_cst(args->em_cst);
+                       C_cst(p->em_cst);
                        break;
                case pro_ptyp:
-                       C_pnam(args->em_pnam);
+                       C_pnam(p->em_pnam);
                        break;
                case str_ptyp:
-                       C_scon(args->em_str, args->em_size);
+                       C_scon(p->em_string, p->em_size);
                        break;
                case ico_ptyp:
-                       C_icon(args->em_str, args->em_size);
+                       C_icon(p->em_string, p->em_size);
                        break;
                case uco_ptyp:
-                       C_ucon(args->em_str, args->em_size);
+                       C_ucon(p->em_string, p->em_size);
                        break;
                case fco_ptyp:
-                       C_fcon(args->em_str, args->em_size);
+                       C_fcon(p->em_string, p->em_size);
                        break;
                default:
                        EM_error = "Illegal argument type";
@@ -396,18 +364,16 @@ EM_docon(args)
 }
 
 PRIVATE
-EM_dostartmes(args)
-       register struct e_args *args;
+EM_dostartmes(p)
+       register struct e_instr *p;
 {
-       register struct e_args *arg;
 
        if (listtype) {
                EM_error = "Message not ended";
                return;
        }
-       arg = c_getarg(args, cst_ptyp);
-       arg = c_getarg(arg, 0);
-       C_mes_begin((int) (args->em_cst));
+       checkarg(&(p->em_arg), cst_ptyp);
+       C_mes_begin((int) (p->em_cst));
        listtype = ps_mes;
 }
 
@@ -429,27 +395,27 @@ EM_mkcalls(line)
                        break;
                case EM_MNEM:
                        /* normal instruction */
-                       EM_doinstr(line->em_opcode, line->em_args);
+                       EM_doinstr(line);
                        break;
                case EM_DEFILB:
                        /* defining occurrence of an instruction label */
-                       C_df_ilb(line->em_deflb);
+                       C_df_ilb(line->em_ilb);
                        break;
                case EM_DEFDLB:
                        /* defining occurrence of a global data label */
-                       C_df_dlb(line->em_deflb);
+                       C_df_dlb(line->em_dlb);
                        break;
                case EM_DEFDNAM:
                        /* defining occurrence of a non-numeric data label */
-                       C_df_dnam(line->em_defdnam);
+                       C_df_dnam(line->em_dnam);
                        break;
                case EM_PSEU:
                        /* pseudo */
-                       EM_dopseudo(line->em_opcode, line->em_args);
+                       EM_dopseudo(line);
                        break;
                case EM_STARTMES:
                        /* start of a MES pseudo */
-                       EM_dostartmes(line->em_arg);
+                       EM_dostartmes(line);
                        break;
                case EM_MESARG:
                case EM_ENDMES:
@@ -460,7 +426,7 @@ EM_mkcalls(line)
                        }
 #endif
                        if (line->em_type == EM_MESARG) {
-                               EM_docon(line->em_arg);
+                               EM_docon(line);
                                break;
                        }
                        C_mes_end();
index 08cc45d..c4477fc 100644 (file)
@@ -24,7 +24,8 @@ EM_mkcalls\ \-\ a module to read EM assembly code
 .br
 .B char *filename;
 .PP
-.B struct e_instr *EM_getinstr()
+.B int EM_getinstr(instr)
+.B struct e_instr *instr;
 .PP
 .B int EM_mkcalls(instr)
 .br
@@ -51,65 +52,83 @@ with an error message in \fIEM_error\fR.
 \fIEM_close\fR must be called after all other calls to this package.
 .PP
 \fIEM_getinstr\fR reads an EM instruction, and
-returns it as a pointer to a structure having the following
-layout:
+returns it in the structure pointed to by \fIinstr\fR.
+This structure has the following layout:
 .br
 .PP
-.ta \w'struct'u +\w'struct e_instr *\ \ \ \ \ \ \ \ \ 'u +\w'em_argtype\ \ \ \ \ \ 'u
+.ta \w'struct\ \ \ 'u +\w'struct e_instr *\ \ \ \ \ \ 'u +\w'em_opcode\ \ \ 'u +\w'*emu_string\ \ \ 'u
 .nf
-struct e_instr {
-       int     em_type;        /* Type of this instruction */
-       union {
-             struct {
-                  int  emus_opcode;    /* Opcode of instruction */
-                  struct e_args        *emus_args;     /* Arguments of instruction */
-             } emu_mp;
-             label     emu_deflb;      /* Numeric label definition */
-             char      *emu_defdnam;   /* Non-numeric label definition */
-             struct e_args     *emu_arg;       /* For a message argument */
-       } em_i; 
-#define em_opcode    \kaem_i.emu_mp.emus_opcode
-#define em_args\h'|\nau'em_i.emu_mp.emus_args
-#define em_deflb\h'|\nau'em_i.emu_deflb
-#define em_defdnam\h'|\nau'em_i.emu_defdnam
-#define em_arg\h'|\nau'em_i.emu_arg
+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+/* $Header$ */
+
+struct e_arg {
+       int     ems_argtype;            /* type of this argument */
+       union e_simple_arg {
+               arith   emu_cst;        /* a cst */
+               label   emu_dlb;        /* a numeric data label */
+               label   emu_ilb;        /* an instruction label */
+               char    *emu_dnam;      /* a data label */
+               char    *emu_pnam;      /* a procedure name */
+               char    *emu_string;    /* a string (fcon,icon,ucon,scon) */
+       }       ems_arg;
+       arith   ems_szoroff;
 };
-.fi
-.PP
-Possible arguments to the EM instruction read are supplied in a linked list
-of structures:
-.PP
-.nf
-struct e_args {
-       struct e_args   *em_next;       /* Next argument */
-       short   em_argtype;     /* Type of this argument */
-       union {
-              arith    emu_cst;        /* A constant */
-              label    emu_ilb;        /* An instruction label */
-              char     *emu_pnam;      /* A procedure name (not including '$') */
-              struct {
-                     label     emus_dlb;
-                     arith     emus_noff;
-              } emu_ndlb;              /* Numeric data label + offset */
-              struct {
-                     char      *emus_dnam;
-                     arith     emus_soff;
-              } emu_sdlb;              /* String data label + offset */
-              struct {
-                     char      *emus_str;
-                     arith     emus_size;
-              } emu_con;               /* An scon, icon, ucon or fcon */
-       } em_value;
-#define em_cst\h'|\nau'em_value.emu_cst
-#define em_ilb\h'|\nau'em_value.emu_ilb
-#define em_pnam\h'|\nau'em_value.emu_pnam
-#define em_dlb\h'|\nau'em_value.emu_ndlb.emus_dlb
-#define em_noff\h'|\nau'em_value.emu_ndlb.emus_noff
-#define em_dnam\h'|\nau'em_value.emu_sdlb.emus_dnam
-#define em_soff\h'|\nau'em_value.emu_sdlb.emus_soff
-#define em_str\h'|\nau'em_value.emu_con.emus_str
-#define em_size\h'|\nau'em_value.emu_con.emus_size
+#define ema_cst        ems_arg.emu_cst
+#define ema_dlb        ems_arg.emu_dlb
+#define ema_ilb        ems_arg.emu_ilb
+#define ema_dnam       ems_arg.emu_dnam
+#define ema_pnam       ems_arg.emu_pnam
+#define ema_string     ems_arg.emu_string
+
+
+struct e_instr {
+       int             em_type;        /* Type of this instr */
+#define EM_MNEM        256             /* A machine instruction */
+#define EM_PSEU        257             /* A pseudo */
+#define EM_STARTMES    258             /* Start of a MES pseudo */
+#define EM_MESARG      259             /* A member in a MES list */
+#define EM_ENDMES      260             /* End of a MES pseudo */
+#define EM_DEFILB      261             /* An instruction label definition */
+#define EM_DEFDLB      262             /* A numeric data label definition */
+#define EM_DEFDNAM     263             /* A non-numeric data label def */
+#define EM_ERROR       264             /* Recoverable error */
+#define EM_FATAL       265             /* Unrecoverable error */
+#define EM_EOF         266             /* End of file */
+       int             em_opcode;
+       struct e_arg    em_arg;
 };
+
+extern arith
+       em_holorbsssize;
+extern int
+       em_holorbssinit;
+
+#define em_ilb         em_arg.ema_ilb
+#define em_dlb         em_arg.ema_dlb
+#define em_dnam        em_arg.ema_dnam
+#define em_argtype     em_arg.ems_argtype
+#define em_cst         em_arg.ema_cst
+#define em_pnam        em_arg.ema_pnam
+#define em_string      em_arg.ema_string
+#define em_off         em_arg.ems_szoroff
+#define em_size        em_arg.ems_szoroff
+#define em_exc1        em_arg.ema_cst
+#define em_exc2        em_arg.ems_szoroff
+
+#define em_holsize     em_holorbsssize
+#define em_bsssize     em_holorbsssize
+#define em_holinit     em_holorbssinit
+#define em_bssinit     em_holorbssinit
+
+extern char
+       *EM_error, *EM_filename;
+extern unsigned int
+       EM_lineno;
+extern int
+       EM_wordsize, EM_pointersize;
 .fi
 .PP
 The named types \fBarith\fR and \fBlabel\fR refer to types on the local machine
@@ -119,8 +138,10 @@ Common definitions are \fBlong\fR for \fBarith\fR and \fBunsigned int\fR for
 \fBlabel\fR.
 .PP
 The \fIe_instr\fR structure consists of the fields
-\fIem_type\fR, containing the type of this \fIe_instr\fR, and
-\fIem_i\fR, containing its value of this \fIe_instr\fR.
+\fIem_type\fR, containing the type of this \fIe_instr\fR,
+\fIem_opcode\fR, containing the opcode of an instruction,
+\fIem_arg\fR, containing a possible argument,
+and two other fields for special purposes explained later.
 .PP
 The possible values of
 \fIem_type\fR, defined in <em_comp.h>, are summarized below:
@@ -136,21 +157,24 @@ Meaning
 an EM machine instruction.
 .br
 .PD 0
-.IP "  em_args" \nau
+.IP "  em_arg" \nau
 The \fIem_opcode\fR field
-contains the opcode of the instruction, and \fIem_args\fR may indicate
-arguments.
+contains the opcode of the instruction, and \fIem_arg\fR may contain an
+argument.
 .IP "EM_PSEU   em_opcode" \nau
 an EM pseudo instruction.
-.IP "  em_args" \nau
+.IP "  em_arg" \nau
 The \fIem_opcode\fR field
-contains the opcode, and \fIem_args\fR may indicate arguments.
+contains the opcode, and \fIem_arg\fR may contain an argument.
 As consecutive CON-pseudos are allocated consecutively, a CON delivered by
 \fIEM_getinstr\fR has exactly one argument.
 If the CON-pseudo read has more, they are delivered as separate CON's.
 The same holds for ROM-pseudos.
 Also, if the length of a string constant exceeds 256 characters, it will be
 delivered as several CON's or ROM's.
+There are two "special" pseudo's, that use other variables, HOL and BSS.
+They use them as indicated in the #defines.
+The EXC pseudo has its arguments encoded as indicated in the #defines.
 .IP "EM_STARTMES       em_arg" \nau
 the start of a MES pseudo.
 .br
@@ -160,19 +184,19 @@ The other arguments, if any, are delivered as separate EM_MESARG's.
 an argument of a MES pseudo.
 .IP "EM_ENDMES none" \nau
 the end of a MES pseudo.
-.IP "EM_DEFILB em_deflb" \nau
+.IP "EM_DEFILB em_ilb" \nau
 an instruction label definition.
 .br
-The field \fIem_deflb\fR contains the label (instruction labels are always
+The field \fIem_ilb\fR contains the label (instruction labels are always
 numeric).
-.IP "EM_DEFDLB em_deflb" \nau
+.IP "EM_DEFDLB em_dlb" \nau
 a numeric data label definition.
 .br
-The field \fIem_deflb\fR contains the label.
-.IP "EM_DEFDNAM        em_defdnam" \nau
+The field \fIem_dlb\fR contains the label.
+.IP "EM_DEFDNAM        em_dnam" \nau
 a non-numeric data label definition.
 .br
-The field \fIem_defdnam\fR contains the label.
+The field \fIem_dnam\fR contains the label.
 .IP "EM_ERROR  none" \nau
 an error in the input that makes the rest of the data in the structure 
 meaningless.
@@ -184,13 +208,16 @@ a fatal error.
 .br
 \fIEM_error\fR contains an
 error message.
+.IP "EM_EOF    none" \nau
+end of file
 .PD
 .PP
-The \fIe_args\fR structure consists of the fields
-\fIem_next\fR, containing a pointer to the next argument or null,
-the field \fIem_argtype\fR, containing the type of this argument, and
-the field \fIem_value\fR, containing the value of the argument.
-The possible values of \fIem_argtype\fR, defined in <em_ptyp.h>,
+The \fIe_arg\fR structure consists of the fields
+the field \fIems_argtype\fR, containing the type of this argument or 0
+if absent,
+the field \fIems_arg\fR, containing the value of the argument,
+and \fIems_szoroff\fR, containing an optional offset or size.
+The possible values of \fIems_argtype\fR, defined in <em_ptyp.h>,
 are summarized below:
 .br
 .ta \w'dlb_ptyp\ \ \ \ 'u +\w'em_opcode\ \ \ 'u
@@ -200,50 +227,52 @@ are summarized below:
 .di
 .IP "Value     Selector" \nau
 Meaning
-.IP "ilb_ptyp  em_ilb" \nau
+.IP "0 none" \nau
+no argument.
+.IP "ilb_ptyp  emu_ilb" \nau
 an instruction label.
 .PD 0
-.IP "nof_ptyp  em_dlb" \nau
+.IP "nof_ptyp  emu_dlb" \nau
 an offset from a numeric data label.
-.IP "  em_noff" \nau
+.IP "  ems_szoroff" \nau
 The
-\fIem_noff\fR field contains the offset and the
-\fIem_dlb\fR field contains the label.
-.IP "sof_ptyp  em_dnam" \nau
+\fIems_szodiff\fR field contains the offset and the
+\fIemu_dlb\fR field contains the label.
+.IP "sof_ptyp  emu_dnam" \nau
 an offset from a non-numeric data label.
-.IP "  em_soff" \nau
-The \fIem_soff\fR field contains the offset and the \fIem_dnam\fR field
+.IP "  ems_szoroff" \nau
+The \fIems_szoroff\fR field contains the offset and the \fIemu_dnam\fR field
 contains the label, represented as a string.
-.IP "cst_ptyp  em_cst" \nau
+.IP "cst_ptyp  emu_cst" \nau
 a numeric constant.
-.IP "pro_ptyp  em_pnam" \nau
+.IP "pro_ptyp  emu_pnam" \nau
 a procedure name, not including the '$',
 represented as a string.
-.IP "str_ptyp  em_str" \nau
+.IP "str_ptyp  emu_string" \nau
 a string constant.
-.IP "  em_size" \nau
-The string is found in \fIem_str\fR, represented as a row of bytes, of
-length \fIem_size\fR.
-.IP "ico_ptyp  em_str" \nau
+.IP "  ems_szoroff" \nau
+The string is found in \fIemu_string\fR, represented as a row of bytes, of
+length \fIems_szoroff\fR.
+.IP "ico_ptyp  emu_string" \nau
 an integer constant.
-.IP "  em_size" \nau
-A string representation of the constant is found in \fIem_str\fR.
-It has size \fIem_size\fR bytes on the target machine.
-.IP "uco_ptyp  em_str" \nau
+.IP "  ems_szoroff" \nau
+A string representation of the constant is found in \fIemu_string\fR.
+It has size \fIems_szoroff\fR bytes on the target machine.
+.IP "uco_ptyp  emu_string" \nau
 an unsigned constant.
-.IP "  em_size" \nau
-A string representation of the constant is found in \fIem_str\fR.
-It has size \fIem_size\fR bytes on the target machine.
-.IP "fco_ptyp  em_str" \nau
+.IP "  ems_szoroff" \nau
+A string representation of the constant is found in \fIemu_string\fR.
+It has size \fIems_szoroff\fR bytes on the target machine.
+.IP "fco_ptyp  emu_string" \nau
 a floating constant.
-.IP "  em_size" \nau
-A string representation of the constant is found in \fIem_str\fR.
-It has size \fIem_size\fR bytes on the target machine.
+.IP "  ems_szoroff" \nau
+A string representation of the constant is found in \fIemu_string\fR.
+It has size \fIems_szoroff\fR bytes on the target machine.
 .PD
 .PP
 When an error occurs, \fIEM_error\fR is set to indicate the reason.
-\fIEM_error\fR also is the only means of detecting whether an error
-occurred. The EM_ERROR described above is only set when the error
+\fIEM_getinstr\fR returns 1 if all goes well, 0 if it does not.
+The EM_ERROR described above is only set when the error
 is serious enough.
 .PP
 The routine \fIEM_mkcalls\fR "translates" the EM instruction indicated
@@ -281,10 +310,8 @@ em_code(3)
 A.S. Tanenbaum, H. v Staveren, E.G. Keizer, J.W. Stevenson, "\fBDescription
 of a Machine Architecture for use with Block Structured Languages\fR",
 Informatica Rapport IR-81, Vrije Universiteit, Amsterdam, 1983.
-.SH DIAGNOSTICS
-\fIEM_getinstr\fR returns a null pointer on end of file.
 .SH REMARKS
-All information must be considered to be contained in a static area so it
+All strings must be considered to be contained in a static area, so
 must be copied to be saved.
 .SH BUGS
 As CON's and ROM's may be delivered in several parts, the count fields in
@@ -292,4 +319,4 @@ a static exchange may be wrong.
 .PP
 Please report bugs to the author.
 .SH AUTHOR
-Ceriel J.H. Jacobs <ceriel@vu44.UUCP>
+Ceriel J.H. Jacobs <ceriel@cs.vu.nl>
index 48f1215..29e372c 100644 (file)
@@ -60,26 +60,17 @@ _fill()
        }
 }
 
-#define NARGS  3               /* Maximum number of arguments */
 #define STRSIZ 256             /* Maximum length of strings */
 
-static struct e_instr emhead;  /* Where we put the head */
-static struct e_args emargs[NARGS+2];  /* Where we put the arguments.
-                                          We need some more because some
-                                          arguments are constructed
-                                       */
-static struct e_args *i_emargs;
-#define argentry()     (i_emargs++)
+static struct e_instr *emhead; /* Where we put the head */
+static struct e_instr aheads[3];
+static int ahead;
+
 static struct string {
        int length;
        char str[STRSIZ + 1];
-} strings[NARGS];              /* Room for strings */
-static struct string *i_strings;               /* Index of last one used */
-#define stringentry()  (i_strings++)
+} string;
 
-static struct e_args *argp;    /* Indicates arguments yet to be
-                                  delivered
-                               */
 #ifdef COMPACT
 static arith strleft;          /* count # of chars left to read
                                   in a string
@@ -104,11 +95,10 @@ static long wordmask[] = { /* allowed bits in a word */
 };
 
 static int wsize, psize;       /* word size and pointer size */
-int EM_wordsize, EM_pointersize;
 
 #ifdef CHECKING
 static char *argrange = "Argument range error";
-#define check(expr) (expr || !EM_error || (EM_error = argrange))
+#define check(expr) (expr || EM_error || (EM_error = argrange))
 #else not CHECKING
 #define check(x)       /* nothing */
 #endif CHECKING
@@ -120,7 +110,7 @@ PRIVATE
 xerror(s)
        char *s;
 {
-       if (emhead.em_type != EM_FATAL) emhead.em_type = EM_ERROR;
+       if (emhead->em_type != EM_FATAL) emhead->em_type = EM_ERROR;
        if (!EM_error) EM_error = s;
 }
 
@@ -129,7 +119,7 @@ PRIVATE
 xfatal(s)
        char *s;
 {
-       emhead.em_type = EM_FATAL;
+       emhead->em_type = EM_FATAL;
        if (!EM_error) EM_error = s;
 }
 
@@ -196,68 +186,59 @@ PRIVATE
 startmes(p)
        register struct e_instr *p;
 {
-       register struct e_args *ap;
 
-       ap = getarg(cst_ptyp);
-       p->em_arg = ap;
+       getarg(cst_ptyp, &(p->em_arg));
        state = MES;
 
-       if (ap->em_cst == ms_emx) {
+       if (p->em_cst == ms_emx) {
                if (wsize || psize) {
                        if (!EM_error) EM_error = "Duplicate ms_emx";
                }
-               argp = ap = getarg(cst_ptyp);
-               wsize = ap->em_cst;
-               EM_wordsize = ap->em_cst;
-               ap->em_next = getarg(cst_ptyp);
-               ap = ap->em_next;
-               psize = ap->em_cst;
-               EM_pointersize = ap->em_cst;
+               p = &aheads[ahead++];
+               getarg(cst_ptyp, &(p->em_arg));
+               wsize = p->em_cst;
+               EM_wordsize = p->em_cst;
+               p->em_type = EM_MESARG;
+               p = &aheads[ahead++];
+               getarg(cst_ptyp, &(p->em_arg));
+               psize = p->em_cst;
+               EM_pointersize = p->em_cst;
+               p->em_type = EM_MESARG;
        }
 }
 
 
 /* EM_getinstr: read an "EM_line"
 */
-EXPORT struct e_instr *
-EM_getinstr()
+EXPORT int
+EM_getinstr(p)
+       register struct e_instr *p;
 {
-       register struct e_instr *p = &emhead;
-       register struct e_args *args;
 
-       i_emargs = emargs;
-       i_strings = strings;
        EM_error = 0;
+       if (ahead) {
+               *p = aheads[--ahead];
+               return 1;
+       }
+       emhead = p;
 #ifdef CHECKING
        if (!EM_initialized) {
                EM_error = "Initialization not done";
                p->em_type = EM_FATAL;
-               return p;
+               return 0;
        }
 #endif CHECKING
 
-       if (argp) {     /* We have some arguments left to deliver */
-               args = argp;
-               argp = args->em_next;
-               p->em_type = EM_MESARG;
-               p->em_arg = args;
-               args->em_next = 0;
-               return p;
-       }
-
        if (!state) {           /* All clear, get a new line */
-               p = gethead();
-               if (!p) {       /* End of file */
-                       return p;
-               }
+               gethead(p);
                switch(p->em_type) {
+               case EM_EOF:
+                       return EM_error == 0;
                case EM_MNEM: {
                        register int i,j;
-                       register struct e_args *ap;
                        extern char em_flag[];
                        extern short em_ptyp[]; 
 
-                       p->em_args = 0;
                        j = em_flag[p->em_opcode - sp_fmnem] & EM_PAR;
                        i = em_ptyp[j];
                        if (j == PAR_NO) {      /* No arguments */
@@ -266,11 +247,11 @@ EM_getinstr()
 #ifndef COMPACT
                        if (j == PAR_B) i = ptyp(sp_ilb2);
 #endif COMPACT
-                       ap = getarg(i);
+                       getarg(i, &(p->em_arg));
 #ifndef COMPACT
                        if (j == PAR_B) {
-                               ap->em_cst = ap->em_ilb;
-                               ap->em_argtype = cst_ptyp;
+                               p->em_cst = p->em_ilb;
+                               p->em_argtype = cst_ptyp;
                        }
 #endif COMPACT
                        /* range checking
@@ -278,48 +259,47 @@ EM_getinstr()
 #ifdef CHECKING
                        if (wsize <= 4 && psize <= 4) switch(j) {
                        case PAR_B:
-                               check(ap->em_cst <= 32767);
+                               check(p->em_cst <= 32767);
                                /* Fall through */
                        case PAR_N:
-                               check(ap->em_cst >= 0);
+                               check(p->em_cst >= 0);
                                break;
                        case PAR_G:
-                               if (ap->em_argtype == cst_ptyp) {
-                                       check(ap->em_cst >= 0);
+                               if (p->em_argtype == cst_ptyp) {
+                                       check(p->em_cst >= 0);
                                }
                                /* Fall through */
                        case PAR_F:
                                /* ??? not in original em_decode or em_encode */
                        case PAR_L:
-                       {       arith m = ap->em_cst >= 0 ? ap->em_cst :
-                                                           - ap->em_cst;
+                       {       arith m = p->em_cst >= 0 ? p->em_cst :
+                                                           - p->em_cst;
 
                                /* Check that the number fits in a pointer */
                                check((m & ~wordmask[psize]) == 0);
                                break;
                        }
                        case PAR_W:
-                               if (!ap) break;
-                               check((ap->em_cst & ~wordmask[wsize]) == 0);
+                               if (p->em_argtype == 0) break;
+                               check((p->em_cst & ~wordmask[wsize]) == 0);
                                /* Fall through */
                        case PAR_S:
-                               check(ap->em_cst > 0);
+                               check(p->em_cst > 0);
                                /* Fall through */
                        case PAR_Z:
-                               check(ap->em_cst >= 0 &&
-                                     ap->em_cst % wsize == 0);
+                               check(p->em_cst >= 0 &&
+                                     p->em_cst % wsize == 0);
                                break;
                        case PAR_O:
-                               check(ap->em_cst > 0 &&
-                                     ( ap->em_cst % wsize == 0 ||
-                                       wsize % ap->em_cst == 0));
+                               check(p->em_cst > 0 &&
+                                     ( p->em_cst % wsize == 0 ||
+                                       wsize % p->em_cst == 0));
                                break;
                        case PAR_R:
-                               check(ap->em_cst >= 0 && ap->em_cst <= 2);
+                               check(p->em_cst >= 0 && p->em_cst <= 2);
                                break;
                        }
 #endif CHECKING
-                       p->em_args = ap;
 #ifndef COMPACT
                        checkeol();
 #endif COMPACT
@@ -332,18 +312,20 @@ EM_getinstr()
                           type ROM or CON is in process
                        */
                        {
-                       register struct e_args *ap = 0, *ap1;
+                       struct e_arg dummy;
 
                        switch(p->em_opcode) {
                        case ps_bss:
                        case ps_hol:
-                               ap = getarg(cst_ptyp);
-                               ap->em_next = ap1 = getarg(par_ptyp);
-                               ap->em_next->em_next = ap1 = getarg(cst_ptyp);
+                               getarg(cst_ptyp, &dummy);
+                               em_holsize = dummy.ema_cst;
+                               getarg(par_ptyp, &(p->em_arg));
+                               getarg(cst_ptyp, &dummy);
+                               em_holinit = dummy.ema_cst;
 #ifdef CHECKING
                                /* Check that the last value is 0 or 1
                                */
-                               if (ap1->em_cst != 1 && ap1->em_cst != 0) {
+                               if (em_holinit != 1 && em_holinit != 0) {
                                  if (! EM_error)
                                   EM_error="Third argument of hol/bss not 0/1";
                                }
@@ -351,36 +333,41 @@ EM_getinstr()
                                break;
                        case ps_exa:
                        case ps_ina:
-                               ap = getarg(lab_ptyp);
+                               getarg(lab_ptyp, &(p->em_arg));
                                break;
                        case ps_exp:
                        case ps_inp:
-                               ap = getarg(pro_ptyp);
+                               getarg(pro_ptyp, &(p->em_arg));
                                break;
                        case ps_exc:
-                               ap = getarg(cst_ptyp);
-                               ap->em_next = getarg(cst_ptyp);
+                               getarg(cst_ptyp, &dummy);
+                               p->em_exc1 = dummy.ema_cst;
+                               getarg(cst_ptyp, &dummy);
+                               p->em_exc2 = dummy.ema_cst;
                                break;
                        case ps_pro:
-                               ap = getarg(pro_ptyp);
-                               ap->em_next = getarg(cst_ptyp|ptyp(sp_cend));
+                               getarg(pro_ptyp, &(p->em_arg));
+                               getarg(cst_ptyp|ptyp(sp_cend), &dummy);
+                               if (dummy.ems_argtype == 0) {
+                                       p->em_off = -1;
+                               }
+                               else    p->em_off = dummy.ema_cst;
                                break;
                        case ps_end:
-                               ap = getarg(cst_ptyp|ptyp(sp_cend));
+                               getarg(cst_ptyp|ptyp(sp_cend), &(p->em_arg));
                                break;
                        case ps_con:
-                               ap = getarg(val_ptyp);
+                               getarg(val_ptyp, &(p->em_arg));
                                state |= CON;
                                break;
                        case ps_rom:
-                               ap = getarg(val_ptyp);
+                               getarg(val_ptyp, &(p->em_arg));
                                state |= ROM;
                                break;
                        default:
                                xerror("Bad pseudo");
                                break;
                        }
-                       p->em_args = ap;
                        }
 #ifndef COMPACT
                        if (p->em_opcode != ps_con && p->em_opcode != ps_rom) {
@@ -397,7 +384,7 @@ EM_getinstr()
                        psize = 2;
                        EM_error = "EM code should start with mes 2";
                }
-               return p;
+               return EM_error == 0;
        }
 
        if (state & INSTRING) { /* We already delivered part of a string.
@@ -406,11 +393,9 @@ EM_getinstr()
                register struct string *s;
                
                s = getstring(0);
-               args = argentry();
-               args->em_next = 0;
-               args->em_argtype = str_ptyp;
-               args->em_str = s->str;
-               args->em_size = s->length;
+               p->em_argtype = str_ptyp;
+               p->em_string = s->str;
+               p->em_size = s->length;
                switch(state & PSEUMASK) {
                default:
                        assert(0);
@@ -418,50 +403,45 @@ EM_getinstr()
                        if (!EM_error)
                                EM_error = "String too long in message";
                        p->em_type = EM_MESARG;
-                       p->em_arg = args;
                        break;
                case CON:
                        p->em_type = EM_PSEU;
                        p->em_opcode = ps_con;
-                       p->em_args = args;
                        break;
                case ROM:
                        p->em_type = EM_PSEU;
                        p->em_opcode = ps_rom;
-                       p->em_args = args;
                        break;
                }
-               return p;
+               return EM_error == 0;
        }
 
        /* Here, we are in a state reading arguments */
-       args = getarg(any_ptyp);
+       getarg(any_ptyp, &(p->em_arg));
        if (EM_error && p->em_type != EM_FATAL) {
-               return p;
+               return 0;
        }
-       if (!args) {    /* No more arguments */
+       if (p->em_argtype == 0) {       /* No more arguments */
 #ifndef COMPACT
                checkeol();
 #endif
                if (state == MES) {
                        state = 0;
                        p->em_type = EM_ENDMES;
-                       return p;
+                       return EM_error == 0;
                }
                /* Here, we have to get the next instruction */
                state = 0;
-               return EM_getinstr();
+               return EM_getinstr(p);
        }
 
        /* Here, there was an argument */
        if (state == MES) {
                p->em_type = EM_MESARG;
-               p->em_arg = args;
-               return p;
+               return EM_error == 0;
        }
        p->em_type = EM_PSEU;
-       p->em_args = args;
        if (state == CON) p->em_opcode = ps_con;
        else    p->em_opcode = ps_rom;
-       return p;
+       return EM_error == 0;
 }
index 0e528b6..5170ad9 100644 (file)
@@ -169,7 +169,7 @@ getname()
        register struct string *s;
        register int c;
 
-       s = stringentry();
+       s = &string;
        p = s->str;
        c = getbyte();
 
@@ -200,7 +200,7 @@ getstring()
        register int c;
        static int termc;
 
-       s = stringentry();
+       s = &string;
        p = s->str;
 
        if (!(state & INSTRING)) {      /* Not reading a string yet */
@@ -241,19 +241,20 @@ getstring()
        return s;
 }
 
-PRIVATE struct e_args *gettyp();
+PRIVATE gettyp();
 
 PRIVATE int
 offsetted(argtyp, ap)
        arith *ap;
 {
        register int c;
-       register struct e_args *ap1;
 
        if ((c = nospace()) == '+' || c == '-') {
-               ap1 = gettyp(cst_ptyp);
-               if (c == '-') *ap = -(ap1->em_cst);
-               else *ap = ap1->em_cst;
+               struct e_arg dummy;
+
+               gettyp(cst_ptyp, &dummy);
+               if (c == '-') *ap = -(dummy.ema_cst);
+               else *ap = dummy.ema_cst;
                return sp_doff;
        }
        else    *ap = 0;
@@ -265,16 +266,15 @@ offsetted(argtyp, ap)
 PRIVATE int
 getnumber(c, ap)
        register int c;
-       register struct e_args *ap;
+       register struct e_arg *ap;
 {
-       register char *p;
+       char str[STRSIZ + 1];
+       register char *p = str;
        int n;
-       register struct string *s = stringentry();
        int expsign;
        long str2long();
 
-       p = s->str;
-       ap->em_argtype = cst_ptyp;
+       ap->ems_argtype = cst_ptyp;
        expsign = 0;
 
        if (c == '+' || c == '-') {
@@ -285,16 +285,14 @@ getnumber(c, ap)
        if (! isdigit(c)) {
                ungetbyte(c);
                syntax("digit expected");
-               i_strings--;
                return sp_cst4;
        }
 
        n = sp_cst4;
 
        for (;;) {
-               if (p >= &(s->str[STRSIZ])) {
+               if (p >= &(str[STRSIZ])) {
                        syntax("number too long");
-                       i_strings--;
                        return sp_cst4;
                }
 
@@ -325,26 +323,29 @@ getnumber(c, ap)
        }       
 
        if (c == 'I' || c == 'U' || c == 'F') {
-               ap->em_str = s->str;
-               ap->em_size = gettyp(cst_ptyp)->em_cst;
+               struct e_arg dummy;
+
+               strcpy(string.str, str);
+               ap->ema_string = string.str;
+               gettyp(cst_ptyp, &dummy);
+               ap->ems_szoroff = dummy.ema_cst;
 
                switch(c) {
                case 'I':
-                       ap->em_argtype = ico_ptyp;
+                       ap->ems_argtype = ico_ptyp;
                        return sp_icon;
                case 'U':
-                       ap->em_argtype = uco_ptyp;
+                       ap->ems_argtype = uco_ptyp;
                        return sp_ucon;
                case 'F':
-                       ap->em_argtype = fco_ptyp;
+                       ap->ems_argtype = fco_ptyp;
                        return sp_fcon;
                }
                assert(0);
        }
 
        ungetbyte(c);
-       ap->em_cst = (arith) str2long(s->str, 10);
-       i_strings--;    
+       ap->ema_cst = (arith) str2long(str, 10);
        return sp_cst4;
 }
 
@@ -353,7 +354,7 @@ PRIVATE int getexpr();
 PRIVATE int
 getfactor(c, ap)
        register int c;
-       register struct e_args *ap;
+       register struct e_arg *ap;
 {
        if (c == '(') {
                if (getexpr(nospace(), ap) != sp_cst4) {
@@ -371,7 +372,7 @@ getfactor(c, ap)
 PRIVATE int
 getterm(c, ap) 
        register int c;
-       register struct e_args *ap;
+       register struct e_arg *ap;
 {
        arith left;
 
@@ -383,15 +384,15 @@ getterm(c, ap)
                        break;
                }
 
-               left = ap->em_cst;
+               left = ap->ema_cst;
                if (getfactor(nospace(), ap) != sp_cst4) {
                        syntax("factor expected");
                        break;
                }
 
-               if (c == '*') ap->em_cst *= left;
-               else if (c == '/') ap->em_cst = left / ap->em_cst;
-               else    ap->em_cst = left % ap->em_cst;
+               if (c == '*') ap->ema_cst *= left;
+               else if (c == '/') ap->ema_cst = left / ap->ema_cst;
+               else    ap->ema_cst = left % ap->ema_cst;
        }
        return sp_cst4;
 }
@@ -399,7 +400,7 @@ getterm(c, ap)
 PRIVATE int
 getexpr(c, ap)
        register int c;
-       register struct e_args *ap;
+       register struct e_arg *ap;
 {
        arith left;
 
@@ -411,14 +412,14 @@ getexpr(c, ap)
                        break;
                }
 
-               left = ap->em_cst;
+               left = ap->ema_cst;
                if (getterm(nospace(), ap) != sp_cst4) {
                        syntax("term expected");
                        break;
                }
 
-               if (c == '+') ap->em_cst += left;
-               else ap->em_cst = left - ap->em_cst;
+               if (c == '+') ap->ema_cst += left;
+               else ap->ema_cst = left - ap->ema_cst;
        }
        return sp_cst4;
 }
@@ -426,25 +427,22 @@ getexpr(c, ap)
 PRIVATE int
 get15u()
 {
-       register struct e_args *ap = argentry();
+       struct e_arg dummy;
 
-       ap->em_next = 0;
-       if (getnumber(getbyte(), ap) != sp_cst4) {
+       if (getnumber(getbyte(), &dummy) != sp_cst4) {
                syntax("integer expected");
        }
-       else check((ap->em_cst & ~077777) == 0);
-       i_emargs--;
-       return (int) (ap->em_cst);
+       else check((dummy.ema_cst & ~077777) == 0);
+       return (int) (dummy.ema_cst);
 }
 
-PRIVATE struct e_args *
-gettyp(typset)
+PRIVATE
+gettyp(typset, ap)
+       register struct e_arg *ap;
 {
        register int c, t;
-       register struct e_args *ap = argentry();
        register int argtyp;
 
-       ap->em_next = 0;
        if ((c = nospace()) == '\n') {
                ungetbyte(c);
                out("newline\n");
@@ -453,31 +451,31 @@ gettyp(typset)
        else if (isdigit(c) || c == '+' || c == '-' || c == '(') {
                out("expr\n");
                argtyp = getexpr(c, ap);
-               if (argtyp == sp_cst4 && fit16i(ap->em_cst)) argtyp = sp_cst2;
+               if (argtyp == sp_cst4 && fit16i(ap->ema_cst)) argtyp = sp_cst2;
        }
        else if (isalpha(c) || c == '_') {
                out("name\n");
                ungetbyte(c);
-               ap->em_dnam = getname()->str;
-               ap->em_argtype = sof_ptyp;
-               argtyp = offsetted(sp_dnam, &(ap->em_soff));
+               ap->ema_dnam = getname()->str;
+               ap->ems_argtype = sof_ptyp;
+               argtyp = offsetted(sp_dnam, &(ap->ems_szoroff));
        }
        else if (c == '.') {
                out(".label\n");
-               ap->em_dlb = get15u();
-               ap->em_argtype = nof_ptyp;
-               argtyp = offsetted(sp_dlb2, &(ap->em_noff));
+               ap->ema_dlb = get15u();
+               ap->ems_argtype = nof_ptyp;
+               argtyp = offsetted(sp_dlb2, &(ap->ems_szoroff));
        }
        else if (c == '*') {
                out("*label\n");
-               ap->em_ilb = get15u();
-               ap->em_argtype = ilb_ptyp;
+               ap->ema_ilb = get15u();
+               ap->ems_argtype = ilb_ptyp;
                argtyp = sp_ilb2;
        }
        else if (c == '$') {
                out("$name\n");
-               ap->em_pnam = getname()->str;
-               ap->em_argtype = pro_ptyp;
+               ap->ema_pnam = getname()->str;
+               ap->ems_argtype = pro_ptyp;
                argtyp = sp_pnam;
        }
        else if (c == '"' || c == '\'') {
@@ -486,34 +484,38 @@ gettyp(typset)
                out("string\n");
                ungetbyte(c);
                s = getstring(0);
-               ap->em_str = s->str;
-               ap->em_size = s->length;        
-               ap->em_argtype = str_ptyp;
+               ap->ema_string = s->str;
+               ap->ems_szoroff = s->length;    
+               ap->ems_argtype = str_ptyp;
                argtyp = sp_scon;
        }
        else if (c == '?') {
                out("?\n");
                argtyp = sp_cend;
+               ap->ems_argtype = 0;
        }
        else {
                /* c != '\n', so "ungetbyte" not neccesary */
                syntax("operand expected");
-               return ap;
+               return;
        }
 
        t = argtyp - sp_fspec;
        assert(t >= 0 && t < 16);
        if ((typset & (1 << t)) == 0) {
                syntax("Bad argument type");
-               return ap;
+               return;
        }
 
-       if (argtyp == sp_cend) return 0;
-       return ap;
+       if (argtyp == sp_cend) {
+               ap->ems_argtype = 0;
+       }
+       return;
 }
 
-PRIVATE struct e_args *
-getarg(typset)
+PRIVATE
+getarg(typset, ap)
+       struct e_arg *ap;
 {
        register int c;
 
@@ -527,7 +529,7 @@ getarg(typset)
                }
        }
        argnum++;
-       return gettyp(typset);
+       return gettyp(typset, ap);
 }
 
 /* getmnem: We found the start of either an instruction or a pseudo.
@@ -573,23 +575,19 @@ getmnem(c, p)
                p->em_type = EM_PSEU;
                break;
        }
-       i_strings--;
 }
 
 PRIVATE
 line_line()
 {
-       register struct e_args *ap;
        static char filebuf[STRSIZ + 1];
        char *btscpy();
+       struct e_arg dummy;
 
-       ap = gettyp(ptyp(sp_cst2));
-       EM_lineno = ap->em_cst;
-       i_emargs--;
-       ap = gettyp(str_ptyp);
-       btscpy(filebuf, ap->em_str, (int) ap->em_size);
-       i_emargs--;
-       i_strings--;
+       gettyp(ptyp(sp_cst2), &dummy);
+       EM_lineno = dummy.ema_cst;
+       gettyp(str_ptyp, &dummy);
+       btscpy(filebuf, dummy.ema_string, (int) dummy.ems_szoroff);
        EM_filename = filebuf;
 }
 
@@ -597,32 +595,29 @@ PRIVATE
 getlabel(c, p)
        register struct e_instr *p;
 {
-       register struct e_args *ap;
 
        ungetbyte(c);
-       ap = gettyp(lab_ptyp|ptyp(sp_cst2));
-       switch(ap->em_argtype) {
+       gettyp(lab_ptyp|ptyp(sp_cst2), &(p->em_arg));
+       switch(p->em_argtype) {
        case cst_ptyp:
                p->em_type = EM_DEFILB;
-               p->em_deflb = ap->em_cst;
+               p->em_ilb = p->em_cst;
                break;
        case sof_ptyp:
                p->em_type = EM_DEFDNAM;
-               p->em_defdnam = ap->em_dnam;
                break;
        case nof_ptyp:
                p->em_type = EM_DEFDLB;
-               p->em_deflb = ap->em_dlb;
                break;
        }
        checkeol();
 }
 
-PRIVATE struct e_instr *
-gethead()
+PRIVATE
+gethead(p)
+       struct e_instr *p;
 {
        register int c;
-       register struct e_instr *p = &emhead;
 
        argnum = 1;
        for (;;) {      
@@ -632,20 +627,23 @@ gethead()
                        do      c = getbyte();
                        while (c != '\n' && c != EOF);
                }
-               if (c == EOF) return 0;
+               if (c == EOF) {
+                       p->em_type = EM_EOF;
+                       return;
+               }
                if (c == '\n') continue;
                if (isspace(c)) {
                        c = nospace();
                        if (isalpha(c) || c == '_') {
                                getmnem(c, p);
-                               return p;
+                               return;
                        }
                        ungetbyte(c);
                }
                else if (c == '#') line_line();
                else {
                        getlabel(c, p);
-                       return p;
+                       return;
                }
                checkeol();
        }
index c8534e8..161f723 100644 (file)
@@ -39,39 +39,38 @@ get32()
 PRIVATE struct string *getstring();
 
 /* getarg : read an argument of any type, and check it against "typset"
-   if neccesary. Return a pointer to the argument.
+   if neccesary. Put result in "ap".
 */
-PRIVATE struct e_args *
-getarg(typset)
+PRIVATE
+getarg(typset, ap)
+       register struct e_arg *ap;
 {
-       register struct e_args *ap = argentry();
        register int i = getbyte();
 #ifdef CHECKING
        int argtyp;
 #endif CHECKING
 
-       ap->em_next = 0;
        switch(i) {
        default:
                if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) { /* A cst */
-                       ap->em_cst = i - sp_zcst0;
-                       ap->em_argtype = cst_ptyp;
+                       ap->ema_cst = i - sp_zcst0;
+                       ap->ems_argtype = cst_ptyp;
                        i = sp_cst2;
                }
                break;
 
        case sp_dlb1:   /* Numeric data label encoded in one byte */
-               ap->em_dlb = getbyte();
-               ap->em_noff = 0;
-               ap->em_argtype = nof_ptyp;
+               ap->ema_dlb = getbyte();
+               ap->ems_szoroff = 0;
+               ap->ems_argtype = nof_ptyp;
                break;
 
        case sp_dlb2:   /* Numeric data label encoded in two bytes */
-               ap->em_dlb = get16();
-               ap->em_noff = 0;
-               ap->em_argtype = nof_ptyp;
+               ap->ema_dlb = get16();
+               ap->ems_szoroff = 0;
+               ap->ems_argtype = nof_ptyp;
 #ifdef CHECKING
-               if (ap->em_dlb > 32767 && !EM_error) {
+               if (ap->ema_dlb > 32767 && !EM_error) {
                        EM_error = "Illegal data label";
                        break;
                }
@@ -79,15 +78,15 @@ getarg(typset)
                break;
 
        case sp_ilb1:   /* Instruction label encoded in one byte */
-               ap->em_ilb = getbyte();
-               ap->em_argtype = ilb_ptyp;
+               ap->ema_ilb = getbyte();
+               ap->ems_argtype = ilb_ptyp;
                break;
 
        case sp_ilb2:   /* Instruction label encoded in two bytes */
-               ap->em_ilb = get16();
-               ap->em_argtype = ilb_ptyp;
+               ap->ema_ilb = get16();
+               ap->ems_argtype = ilb_ptyp;
 #ifdef CHECKING
-               if (ap->em_ilb > 32767 && !EM_error) {
+               if (ap->ema_ilb > 32767 && !EM_error) {
                        EM_error = "Illegal instruction label";
                        break;
                }
@@ -95,13 +94,13 @@ getarg(typset)
                break;
 
        case sp_cst2:   /* A cst encoded in two bytes */
-               ap->em_cst = get16();
-               ap->em_argtype = cst_ptyp;
+               ap->ema_cst = get16();
+               ap->ems_argtype = cst_ptyp;
                break;
 
        case sp_cst4:   /* A cst encoded in four bytes */
-               ap->em_cst = get32();
-               ap->em_argtype = cst_ptyp;
+               ap->ema_cst = get32();
+               ap->ems_argtype = cst_ptyp;
                break;
 
        case sp_pnam:   /* A procedure name */
@@ -114,8 +113,8 @@ getarg(typset)
                        xerror("Procedure name too long");
                }
 #endif CHECKING
-               ap->em_pnam = p->str;
-               ap->em_argtype = pro_ptyp;
+               ap->ema_pnam = p->str;
+               ap->ems_argtype = pro_ptyp;
                break;
        }
 
@@ -129,25 +128,19 @@ getarg(typset)
                        xerror("Data label too long");
                }
 #endif CHECKING
-               ap->em_dnam = p->str;
-               ap->em_soff = 0;
-               ap->em_argtype = sof_ptyp;
+               ap->ema_dnam = p->str;
+               ap->ems_szoroff = 0;
+               ap->ems_argtype = sof_ptyp;
                break;
        }
 
        case sp_doff:   /* A data label + offset */
        {
-               register struct e_args *ap1;
-
-               ap1 = getarg(lab_ptyp);
-               *ap = *ap1;
-               i_emargs--;
-               ap1 = getarg(cst_ptyp);
-               if (ap->em_argtype == sof_ptyp) {       /* non-numeric label */
-                       ap->em_soff = ap1->em_cst;
-               }
-               else    ap->em_noff = ap1->em_cst;
-               i_emargs--;
+               struct e_arg dummy;
+
+               getarg(lab_ptyp, ap);
+               getarg(cst_ptyp, &dummy);
+               ap->ems_szoroff = dummy.ema_cst;
                break;
        }
 
@@ -157,16 +150,16 @@ getarg(typset)
        {
                register struct string *p;
 
-               ap->em_size = getarg(cst_ptyp)->em_cst;
-               i_emargs--;
+               getarg(cst_ptyp, ap);
+               ap->ems_szoroff = ap->ema_cst;
                p = getstring(0);
 #ifdef CHECKING
                if (state & INSTRING) {
                        xerror("Numeric constant too long");
                }
 #endif CHECKING
-               ap->em_argtype = ptyp(i);
-               ap->em_str = p->str;
+               ap->ems_argtype = ptyp(i);
+               ap->ema_string = p->str;
                break;
        }
 
@@ -175,34 +168,37 @@ getarg(typset)
                register struct string *p;
 
                p = getstring(0);
-               ap->em_argtype = str_ptyp;
-               ap->em_str = p->str;
-               ap->em_size = p->length;
+               ap->ems_argtype = str_ptyp;
+               ap->ema_string = p->str;
+               ap->ems_szoroff = p->length;
                break;
        }
        }
 #ifdef CHECKING
        argtyp = i;
-       if (EM_error) return 0;
+       if (EM_error) return;
 
        if (i == EOF) {
                xfatal("Unexpected EOF");
-               return 0;
+               return;
        }
 
        if ((i -= sp_fspec) < 0 || i >= 16) {
                xerror("Illegal byte");
-               return 0;
+               return;
        }
 
        if ((typset & (1 << i)) == 0 && !EM_error) {
                EM_error = "Bad argument type";
        }
-       if (argtyp == sp_cend) return 0;
+       if (argtyp == sp_cend) {
+               ap->ems_argtype = 0;
+       }
 #else not CHECKING
-       if (i == sp_cend) return 0;
+       if (i == sp_cend) {
+               ap->ems_argtype = 0;
+       }
 #endif CHECKING
-       return ap;
 }
 
 #ifdef CHECKING
@@ -238,13 +234,14 @@ getstring(isident)
 {
        register char *p;
        register int n;
-       register struct string *s;
+       register struct string *s = &string;
 
        if (!(state & INSTRING)) {      /* Not reading a string yet */
-               struct e_args *ap = getarg(cst_ptyp);
+               struct e_arg dummy;
+
+               getarg(cst_ptyp, &dummy);
                                        /* Read length of string */
-               i_emargs--;
-               strleft = ap->em_cst;
+               strleft = dummy.ema_cst;
 #ifdef CHECKING
                if (strleft < 0) {
                        xerror("Negative length in string");
@@ -253,8 +250,6 @@ getstring(isident)
 #endif CHECKING
        }
 
-       s = stringentry();
-
        if (strleft <= STRSIZ) {        /* Handle the whole string */
                n = strleft;
                state &= ~INSTRING;
@@ -286,11 +281,11 @@ getstring(isident)
 
 /* gethead: read the start of an EM-line
 */
-PRIVATE struct e_instr *
-gethead()
+PRIVATE
+gethead(p)
+       register struct e_instr *p;
 {
        register int i;
-       register struct e_instr *p = &emhead;
 
        EM_lineno++;
 
@@ -298,7 +293,7 @@ gethead()
                /* A mnemonic */
                p->em_type = EM_MNEM;
                p->em_opcode = i;
-               return p;
+               return;
        }
 
        if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) {   /* A pseudo */
@@ -307,26 +302,26 @@ gethead()
                }
                else    p->em_type = EM_PSEU;
                p->em_opcode = i;
-               return p;
+               return;
        }
 
        if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) {   /* Instruction label */
                p->em_type = EM_DEFILB;
-               p->em_deflb = i - sp_filb0;
-               return p;
+               p->em_ilb = i - sp_filb0;
+               return;
        }
 
        switch(i) {
        case sp_ilb1:   /* Instruction label */
                p->em_type = EM_DEFILB;
-               p->em_deflb = getbyte();
+               p->em_ilb = getbyte();
                break;
 
        case sp_ilb2:   /* Instruction label */
                p->em_type = EM_DEFILB;
-               p->em_deflb = get16();
+               p->em_ilb = get16();
 #ifdef CHECKING
-               if (p->em_deflb > 32767 && !EM_error) {
+               if (p->em_ilb > 32767 && !EM_error) {
                        EM_error = "Illegal instruction label definition";
                }
 #endif CHECKING
@@ -334,14 +329,14 @@ gethead()
 
        case sp_dlb1:   /* Numeric data label */
                p->em_type = EM_DEFDLB;
-               p->em_deflb = getbyte();
+               p->em_dlb = getbyte();
                break;
 
        case sp_dlb2:   /* Numeric data label */
                p->em_type = EM_DEFDLB;
-               p->em_deflb = get16();
+               p->em_dlb = get16();
 #ifdef CHECKING
-               if (p->em_deflb > 32767 && !EM_error) {
+               if (p->em_dlb > 32767 && !EM_error) {
                        EM_error = "Illegal data label definition";
                }
 #endif CHECKING
@@ -353,19 +348,20 @@ gethead()
 
                p->em_type = EM_DEFDNAM;
                if (!(s = getstring(1))) {
-                       p->em_defdnam = "";
+                       p->em_dnam = "";
                }
-               else    p->em_defdnam = s->str;
+               else    p->em_dnam = s->str;
                break;
        }               
 
        case EOF:       /* End of file */
-               return 0;
+               p->em_type = EM_EOF;
+               return;
 
        default:
                xerror("Unknown opcode");
                break;
        }
 
-       return p;
+       return;
 }