minipentium.c

来自「压缩包里面的都是精致的基本C语言小程序」· C语言 代码 · 共 462 行

C
462
字号
#include <stdio.h>#include "../lib/error.h"#include "../lib/commonInter.h"#include "../lib/mystdlib.h"#include "../lib/nat.h"#include "../lib/poly.h"#include "../lib/file.h"#include "../lib/control.h"#include "miniPentium.h"str toStringOperand (operand o);void toStringInstr (linkedList l, instruction i);operand miniPNewOperandNum (int i){  operand o = checkedMalloc (sizeof (*o));  o->kind = PNUM;  (o->u).i = i;    return o;}operand miniPNewOperandId (str id){  operand o = checkedMalloc (sizeof (*o));  o->kind = PID;  (o->u).id = id;    return o;}instruction miniPNewInstrMovl (operand src, str dst){  instruction i = checkedMalloc (sizeof (*i));  i->kind = MOVL;  i->src = src;  i->dst = dst;    return i;}instruction miniPNewInstrAddl (operand src, str dst){  instruction i = checkedMalloc (sizeof (*i));  i->kind = ADDL;  i->src = src;  i->dst = dst;    return i;}instruction miniPNewInstrSubl (operand src, str dst){  instruction i = checkedMalloc (sizeof (*i));  i->kind = SUBL;  i->src = src;  i->dst = dst;    return i;}instruction miniPNewInstrMull (operand src, str dst){  instruction i = checkedMalloc (sizeof (*i));  i->kind = MULL;  i->src = src;  i->dst = dst;    return i;}instruction miniPNewInstrPrint (operand src){  instruction i = checkedMalloc (sizeof (*i));  i->kind = PPRINT;  i->src = src;    return i;}instruction miniPNewInstrComment (str c){  instruction i = checkedMalloc (sizeof (*i));  i->kind = COMMENT;  i->dst = c;    return i;}pentiumProg miniPNewProg (linkedList instructions){  pentiumProg p = checkedMalloc (sizeof (*p));  p->instructions = instructions;  return p;}void miniPPrettyPrintOperand (operand o){  switch (o->kind)  {    case PID:    {      strOutput ((o->u).id);      break;    }    case PNUM:     {      printf ("%d", (o->u).i);      break;    }    default: break;  }    return;}void miniPPrettyPrintInstruction (instruction s){  switch (s->kind)  {    case MOVL:      {        printf ("movl\t");        miniPPrettyPrintOperand (s->src);        printf (", ");        strOutput (s->dst);        printf ("\n");        break;      }    case ADDL:      {        printf ("addl\t");        miniPPrettyPrintOperand (s->src);        printf (", ");        strOutput (s->dst);        printf ("\n");        break;      }    case SUBL:      {        printf ("subl\t");        miniPPrettyPrintOperand (s->src);        printf (", ");        strOutput (s->dst);        printf ("\n");        break;      }    case MULL:      {        printf ("mull\t");        miniPPrettyPrintOperand (s->src);        printf (", ");        strOutput (s->dst);        printf ("\n");        break;      }    case PPRINT:      {        printf ("print\t");        miniPPrettyPrintOperand (s->src);        printf ("\n");        break;      }    case COMMENT:      {        str tmp = strConcat (newStr ("// "), s->dst);        strOutput (tmp);        printf ("\n");        break;      }    default:      {        error ("no this case\n");        break;      }  }}typedef void (*f) (poly);void miniPPrettyPrintProg (pentiumProg p){  linkedList l = p->instructions;  linkedListForeach (l, (f)miniPPrettyPrintInstruction);  return;}set setOperand (operand o){  switch (o->kind)  {    case PID:    {      set s = newSet ();      setInsert2 (s, ((o->u).id));      return s;    }    case PNUM:     {      return newSet ();    }    default:    {      error ("no this case\n");      return newSet ();    }  }  return newSet ();  }set setOfInstruction (instruction s, set st){  switch (s->kind)  {    case MOVL:      {        set temp = setOperand (s->src);        setInsert2 (temp, s->dst);        return setUnion2 (temp, st);      }    case ADDL:      {        set temp = setOperand (s->src);        setInsert2 (temp, s->dst);        return setUnion2 (temp, st);      }    case SUBL:      {        set temp = setOperand (s->src);        setInsert2 (temp, s->dst);        return setUnion2 (temp, st);      }    case MULL:      {        set temp = setOperand (s->src);        setInsert2 (temp, s->dst);        return setUnion2 (temp, st);      }    case PPRINT:      {        set temp = setOperand (s->src);        return setUnion2 (temp, st);      }    case COMMENT:      {        return st;      }    default:      {        error ("no this case\n");        return newSet ();      }  }  return newSet ();}set miniPSetOfId (pentiumProg p){    linkedList l = linkedListGetFirst (p->instructions);  set s = newSet ();    while (l)  {    s = setOfInstruction (l->data, s);    l = l->next;  }  return s;}static void emit (linkedList l, str s){  linkedListInsertHead (l, s);}str toStringOperand (operand o){  switch (o->kind)  {    case PID:    {      return ((o->u).id);    }    case PNUM:     {      nat n = newNat ((o->u).i);      str s = getVft (n)->toString (n);      s = strConcat (newStr ("$"), s);      return s;    }    default: return newStr ("");  }  return newStr ("");}void toStringInstr (linkedList l, instruction s){  switch (s->kind)  {    case MOVL:      {        str a = newStr ("movl\t");        str b = toStringOperand (s->src);        a = strConcat (a, b);        a = strConcat (a, newStr (", "));        a = strConcat (a, newStr ("%eax\n"));        a = strConcat (a, newStr ("movl\t"));        a = strConcat (a, newStr ("%eax, "));        a = strConcat (a, s->dst);        a = strConcat (a, newStr ("\n"));        emit (l, a);        break;      }    case ADDL:      {        str a = newStr ("movl\t");        str b = toStringOperand (s->src);        a = strConcat (a, b);        a = strConcat (a, newStr (", "));        a = strConcat (a, newStr ("%eax\n"));        a = strConcat (a, newStr ("addl\t%eax, "));        a = strConcat (a, (s->dst));        a = strConcat (a, newStr ("\n"));        emit (l, a);        break;      }    case SUBL:      {        str a = newStr ("movl\t");        str b = toStringOperand (s->src);        a = strConcat (a, b);        a = strConcat (a, newStr (", "));        a = strConcat (a, newStr ("%eax\n"));        a = strConcat (a, newStr ("subl\t%eax, "));        a = strConcat (a, (s->dst));        a = strConcat (a, newStr ("\n"));        emit (l, a);        break;      }    case MULL:      {        str a = newStr ("movl\t");        str b = toStringOperand (s->src);        a = strConcat (a, b);        a = strConcat (a, newStr (", "));        a = strConcat (a, newStr ("%eax\n"));        a = strConcat (a, newStr ("mull\t"));        a = strConcat (a, (s->dst));        a = strConcat (a, newStr ("\n"));        a = strConcat (a, newStr ("movl\t%eax, "));        a = strConcat (a, (s->dst));        a = strConcat (a, newStr ("\n"));        emit (l, a);        break;      }    case PPRINT:      {        str a = toStringOperand (s->src);        str b = newStr ("pushl\t");                a = strConcat (b, a);        a = strConcat (a, newStr ("\n"));        str s1 = newStr ("$LC0");        s1 = strConcat (b, s1);        s1 = strConcat (s1, newStr ("\n"));        a = strConcat (a, s1);        str s2 = newStr ("call\t_printf\n");        a = strConcat (a, s2);        emit (l, a);        break;      }    case COMMENT:      {        str a = newStr ("\n// ");        a = strConcat (a, s->dst);        a = strConcat (a, newStr ("\n"));        emit (l, a);        break;      }    default:      {        error ("no this case\n");        break;      }  }}str miniPToStringProg (pentiumProg p){  linkedList l = newLinkedList ();    linkedList temp = linkedListGetFirst (p->instructions);    while (temp)  {    toStringInstr (l, temp->data);    temp = temp->next;  }    l = linkedListReverse (l);    str s = newStr ("");  l = l->next;  while (l)  {    s = strConcat (s, l->data);    l = l->next;  }      return s;}void miniPToExe (pentiumProg p){  str s = miniPToStringProg (p);  set st = miniPSetOfId (p);  linkedList l = linkedListGetFirst (setToLinkedList2 (st));    //linkedListOutput (l);    str s1 = newStr ("\t.data\n");  s1 = strConcat (newStr ("// hummmmmm, :-)\n"), s1);  while (l)  {    s1 = strConcat (s1, l->data);    s1 = strConcat (s1, newStr (":\n"));    s1 = strConcat (s1, newStr ("\t.int 0\n"));    l = l->next;  }  s1 = strConcat (s1, newStr ("LC0:\n\t.ascii \"%d\\n\\0\""));  s1 = strConcat (s1, newStr ("\n\n"));    str s2 = newStr ("\t.text\n");  s2 = strConcat (s2, newStr ("\t.globl _main\n"));  s2 = strConcat (s2, newStr ("_main:\n"));  s2 = strConcat (s2, newStr ("pushl\t%ebp\n"));  s2 = strConcat (s2, newStr ("movl\t%esp, %ebp\n"));    s = strConcat (s2, s);  s = strConcat (s1, s);    str s3 = newStr ("leave\nret\n\n");  s = strConcat (s, s3);    file f = fileOpen ("my.s", "w+");  filePuts (s, f);  fileClose (f);    str command = newStr ("gcc -o my.exe my.s");  checkedSystem (strToCharStar (command));    if (!controlKeepS)  {    command = newStr ("del my.s");    checkedSystem (strToCharStar (command));  }  else  {  }    return;}

⌨️ 快捷键说明

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