⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pl0asm.c

📁 经过修改的PL0编译程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************
   Program :  Recursive Descent Compiler for PL/0
   Module  :  PL0ASM - Code generator: intermediate (postfix) code
              -> 80X86 assembler code for MS-DOS
   File    :  pl0asm.c
   Compiler:  Borland C 3.1 - 4.5, GNU C 2.7.1
   Author  :  H. Weber
   Revision:  Aug. 1998
********************************************************************/

#include <stdio.h>
#include <string.h>
#include "pl0code.h"
#define codemax  1000


FILE *asmcode, *intcode;
struct instr {
     int  o;      /* opcode */
     int  l;      /* level of declaration */
     int  a;      /* rel. address in DSA */
     int  lab;    /* label necessary */
     char oc[4];  /* mnemonic for comment */
   };
struct instr code[codemax];
int  strno = 0;   /* number of strings */
int  label = 0;   /* curr. number of label */
int  currdata;    /* number of current data objects */
int  comment = 0; /* comment flag */
int  os2 = 0;     /* OS/2 flag    */
char currproc[6]; /* name of current procedure */


void readcode(int *count)
/* read intermediate code */
{
   int  no, o, k;
   char oc[4];

   *count = 0;
   while (!feof(intcode) && *count < codemax) {
      k = fscanf(intcode, "%3d  %3s  %2d %5d",
		 &no, oc, &code[*count].l,
		 &code[*count].a);
      if (k < 4) break;
      if      (strcmp(oc, "NUL") == 0) o = NUL;
      else if (strcmp(oc, "ADD") == 0) o = ADD;
      else if (strcmp(oc, "SUB") == 0) o = SUB;
      else if (strcmp(oc, "MPY") == 0) o = MPY;
      else if (strcmp(oc, "DVD") == 0) o = DVD;
      else if (strcmp(oc, "NEG") == 0) o = NEG;
      else if (strcmp(oc, "ODD") == 0) o = ODD;
      else if (strcmp(oc, "EQL") == 0) o = EQL;
      else if (strcmp(oc, "NEQ") == 0) o = NEQ;
      else if (strcmp(oc, "LSS") == 0) o = LSS;
      else if (strcmp(oc, "GTR") == 0) o = GTR;
      else if (strcmp(oc, "LEQ") == 0) o = LEQ;
      else if (strcmp(oc, "GEQ") == 0) o = GEQ;
      else if (strcmp(oc, "LIT") == 0) o = LIT;
      else if (strcmp(oc, "RET") == 0) o = RET;
      else if (strcmp(oc, "CAL") == 0) o = CAL;
      else if (strcmp(oc, "LOD") == 0) o = LOD;
      else if (strcmp(oc, "STO") == 0) o = STO;
      else if (strcmp(oc, "INT") == 0) o = INT;
      else if (strcmp(oc, "JPU") == 0) o = JPU;
      else if (strcmp(oc, "JPC") == 0) o = JPC;
      else if (strcmp(oc, "INP") == 0) o = INP;
      else if (strcmp(oc, "PRN") == 0) o = PRN;
      else if (strcmp(oc, "ASC") == 0) o = ASC;
      else if (strcmp(oc, "PRS") == 0) o = PRS;
      else if (strcmp(oc, "PRL") == 0) o = PRL;
      else {
	 fprintf(stderr, "Unknown opcode symbol %s\n", oc);
	 exit(1);
      }                           
      strcpy(code[*count].oc, oc);
      code[(*count)++].o = o;
   }
   if (*count == codemax) {
      fprintf(stderr, "Program too long.");
      exit(1);
   }
   (*count)--;
}

void checklabels(int count)
{
   int i, oc;

   for (i=0; i<=count; i++)
      code[i].lab = 0;
   for (i=0; i<=count; i++) {
      oc = code[i].o;
      if (oc == JPU || oc == JPC )
	 code[code[i].a].lab = 1;
   }
}

void gl(char *buf)
{
   sprintf(buf, "m%03d", ++label);
}

void ga(int col, char *s)
{
   char s1[80] ;

   if (col == 1) {
      strcpy(s1, "        ");
      strcat(s1, s);
   }
   else strcpy(s1, s);
   fprintf(asmcode, "%s\n", s1);
}

void gencomm(int pc)
{
   char s[50];

   sprintf(s, "; ---- %03d %s %2d %3d", pc,
	   code[pc].oc, code[pc].l, code[pc].a);
   ga(0, s);
}

void genlab(int pc)
{
   char buf[5];

   sprintf(buf, "l%03d:", pc);
   ga(0, buf);
}

void genstrings(int count)
{
   int pc = 0;
   int j, l;
   char s[80], s3[100];

   while (pc <= count) {
      if (code[pc].o == PRS) {
	 s[0] = '\'';
	 l = code[pc].a;
	 for (j=1; j<=l; j++)
	    s[j] = code[pc+j].a;
	 s[l+1] = '$';
	 s[l+2] = '\'';
	 s[l+3] = 0;
	 strno++;
	 sprintf(s3, "str%02d   db      ", strno);
	 strcat(s3, s);
	 ga(0, s3);
	 pc+= code[pc].a;
      }
      else pc++;
   }
}

void g_addsub(int op)
{
   ga(1, "pop     ax     ");
   ga(1, "mov     bp,sp  ");
   if (op == ADD)
      ga(1, "add     [bp],ax");
   else
      ga(1, "sub     [bp],ax");
}

void g_mpy()
{
   ga(1, "pop     ax           ");
   ga(1, "mov     bp,sp        ");
   ga(1, "imul    word ptr [bp]");
   ga(1, "mov     [bp],ax      ");
}

void g_dvd()
{
   ga(1, "mov     bp,sp");
   ga(1, "pop     ax   ");
   ga(1, "pop     ax   ");
   ga(1, "cwd          ");
   ga(1, "idiv    word ptr [bp]");
   ga(1, "push    ax   ");
}

void g_neg()
{
   ga(1, "pop     ax");
   ga(1, "neg     ax");
   ga(1, "push    ax");
}

void g_odd()
{
   ga(1, "pop     ax   ");
   ga(1, "cwd          ");
   ga(1, "mov     bx, 2");
   ga(1, "idiv    bx   ");
   ga(1, "push    dx   ");
}

void g_rel(int op)
{
   char s[30];
   char rel1[5], rel2[5];

   gl(rel1);
   gl(rel2);
   ga(1, "pop     ax     ");
   ga(1, "pop     bx     ");
   ga(1, "cmp     bx, ax ");
   switch(op) {
      case EQL : strcpy(s, "je "); break;
      case NEQ : strcpy(s, "jne"); break;
      case LSS : strcpy(s, "jl "); break;
      case GTR : strcpy(s, "jg "); break;
      case LEQ : strcpy(s, "jle"); break;
      case GEQ : strcpy(s, "jge"); break;
   }
   strcat(s, "     ");
   strcat(s, rel1);
   ga(1, s);
   ga(1, "sub     ax, ax");
   strcpy(s, "jmp     ");
   strcat(s, rel2);
   ga(1, s);
   strcpy(s, rel1);
   strcat(s, ":   mov     ax, 1");
   ga(0, s);
   strcpy(s, rel2);
   strcat(s, ":   push    ax");
   ga(0, s);
}

void g_lit(int a)
{
   char s[20];

   sprintf(s, "mov     ax, %d", a);
   ga(1, s);
   ga(1, "push    ax");
}

void g_ret()
{
   char s[20];
//   int i;

   sprintf(s, "add     sp, %d", 2*currdata);
   ga(1, s);
   ga(1, "ret");                      /* Return */
   sprintf(s, "%s   endp", currproc); /* Ende Prozedur */
   ga(0, s);
   ga(0, ";");
}

void g_cal(int l, int a)
{
   char s[100];

   sprintf(s, "mov     cx, %d", l);
   ga(1, s);
   ga(1, "call    p_sbs     ");
   ga(1, "push    dx        ");
   ga(1, "mov     bp, sp    ");
   ga(1, "mov     ax, [base]");
   ga(1, "push    ax        ");
   ga(1, "mov     [base], bp");
   sprintf(s, "call    pr%03d", a);
   ga(1, s);
   ga(1, "pop     dx");
   ga(1, "mov     [base], dx");
   ga(1, "pop     dx");
}

void g_lod(int l, int a)
{
   char s[80];

   if (l == 0)
      ga(1, "mov     bp, [base]");
   else {
      sprintf(s, "mov     cx, %d", l);
      ga(1, s);
      ga(1, "call    p_sbs");
      ga(1, "mov     bp, dx    ");
   }
   sprintf(s, "push    word ptr [bp-2*%d]", a);
   ga(1, s);
}

void g_sto(int l, int a)
{
   char s[80];

   ga(1, "pop     ax   ");
   if (l == 0)
      ga(1, "mov     bp, [base]");
   else {
      sprintf(s, "mov     cx, %d", l);
      ga(1, s);
      ga(1, "call    p_sbs ");
      ga(1, "mov     bp, dx");
   }
   sprintf(s, "mov     word ptr [bp-2*%d], ax", a);
   ga(1, s);
}

void g_int(int a, int pc)
{
   char s[20];

   sprintf(currproc, "pr%03d", pc);
   sprintf(s, "%s   proc", currproc);
   ga(0, s);
   sprintf(s, "sub     sp, %d", 2*a);
   ga(1, s);
   currdata = a;
}

void g_jpu(int a)
{
   char s[80];

   sprintf(s, "jmp     far ptr l%03d", a);
   ga(1, s);
}

void g_jpc(int a)
{
   char s[80], jpc1[6], jpc2[6];

   gl(jpc1);
   gl(jpc2);
   ga(1, "pop     ax     ");
   ga(1, "cmp     ax, 0  ");
   strcpy(s, "je      ");
   strcat(s, jpc1);
   ga(1, s);
   strcpy(s, "jmp     ");
   strcat(s, jpc2);
   ga(1, s);
   strcat(jpc1, ":");
   sprintf(s, "%s   jmp     far ptr l%03d",
	   jpc1, a);
   ga(0, s);
   strcat(jpc2, ":");
   ga(0, jpc2);
}

void g_inp()
{
   ga(1, "mov     bx, offset buffer");
   ga(1, "mov     al, [blen]       ");
   ga(1, "call    instring         ");
   ga(1, "mov     bx, offset buffer");
   ga(1, "sub     al, 2");
   ga(1, "mov     ch, 0            ");
   ga(1, "mov     cl, al           ");
   ga(1, "call    string2number    ");
   ga(1, "push    ax               ");
}

void g_prn()
{
   ga(1, "pop     ax               ");  /* Zahl  */
   ga(1, "mov     cx, 5            ");  /* L刵ge */
   ga(1, "call    printint         ");
}

void g_prs(int a, int *pc)
{
   char s[80];

   sprintf(s, "mov     bx, offset str%02d", ++strno);
   ga(1, s);
   ga(1, "call    outstring");
   *pc += a;    /* overread ASC opcodes */
}

void g_prl()
{
   ga(1, "mov     bx, offset crlf");
   ga(1, "call    outstring      ");
}

void prolog1()
{
   ga(0, "; Assembler prolog");
   if (os2) {
     ga(0, ";Generated by PL0ASM for MS OS/2 1.X");
     ga(1, ".model   small, pascal, os_os2");
     ga(1, "includelib os2.lib");
     ga(1, "include os2.inc");
   } else {
     ga(0, ";Generated by PL0ASM for MS-DOS 3.X, 4.X, 5.X");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -