Guest User

compile.c

a guest
Nov 27th, 2022
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.32 KB | Source Code | 0 0
  1. #include "defs.h"
  2. #include "label.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <stdint.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8.  
  9. enum { Ok, OpCodeErr, DstTypeErr, DstValErr, SrcTypeErr, SrcValErr };
  10.  
  11. static void capitalize(char *str)
  12. {
  13.   while(*str)
  14.   {
  15.     *str = toupper(*str);
  16.     ++str;
  17.   }
  18. }
  19.  
  20. static int getOpCode(char *tok)
  21. {
  22.   if(!strcmp(tok, "MOV"))   return Mov;
  23.   if(!strcmp(tok, "ADD"))   return Add;
  24.   if(!strcmp(tok, "SUB"))   return Sub;
  25.   if(!strcmp(tok, "MUL"))   return Mul;
  26.   if(!strcmp(tok, "DIV"))   return Div;
  27.   if(!strcmp(tok, "MOD"))   return Mod;
  28.   if(!strcmp(tok, "NOT"))   return Not;
  29.   if(!strcmp(tok, "AND"))   return And;
  30.   if(!strcmp(tok, "OR"))    return Or;
  31.   if(!strcmp(tok, "XOR"))   return Xor;
  32.   if(!strcmp(tok, "BNOT"))  return BNot;
  33.   if(!strcmp(tok, "BAND"))  return BAnd;
  34.   if(!strcmp(tok, "BOR"))   return BOr;
  35.   if(!strcmp(tok, "BXOR"))  return BXor;
  36.   if(!strcmp(tok, "JMP"))   return Jmp;
  37.   if(!strcmp(tok, "JMPIF")) return JmpIf;
  38.   if(!strcmp(tok, "READ"))  return Read;
  39.   if(!strcmp(tok, "WRITE")) return Write;
  40.  
  41.   return -1;
  42. }
  43.  
  44. static void catchError(int errNo, int lineNo)
  45. {
  46.   if(errNo != Ok)
  47.   {
  48.     printf("Somewhing is wrong with line %d\n", lineNo);
  49.     exit(1);
  50.   }
  51. }
  52.  
  53. static unsigned getOperandType(char *tok)
  54. {
  55.   return isdigit(tok[0]) ? Const
  56.          : tok[0] == 'R' ? Reg
  57.          : tok[0] == 'M' ? Mem
  58.                          : -1;
  59. }
  60.  
  61. static int getOperandVal(char *tok, int type)
  62. {
  63.   return strtol(&tok[type != Const], NULL, 0);
  64. }
  65.  
  66. #define DST 1
  67. #define SRC 2
  68.  
  69. static int getDstOperand(command_t *cmd, char *tok)
  70. {
  71.   unsigned type, val;
  72.  
  73.   type = getOperandType(tok);
  74.  
  75.   if(type == -1)
  76.     return DstTypeErr;
  77.  
  78.   cmd->dstType = type;
  79.   cmd->dst = getOperandVal(tok, type);
  80.  
  81.   return Ok;
  82. }
  83.  
  84. static int getSrcOperand(command_t *cmd, char *tok)
  85. {
  86.   unsigned type, val;
  87.  
  88.   type = getOperandType(tok);
  89.  
  90.   if(type == -1)
  91.     return SrcTypeErr;
  92.  
  93.   cmd->srcType = type;
  94.   cmd->src = getOperandVal(tok, type);
  95.  
  96.   return Ok;
  97. }
  98.  
  99. static int getOperands(command_t *cmd, int flags)
  100. {
  101.   char *tok;
  102.   int errNo;
  103.  
  104.   if(flags & DST)
  105.   {
  106.     tok = strtok(NULL, " \t\n");
  107.     errNo = getDstOperand(cmd, tok);
  108.     if(errNo != Ok)
  109.       return errNo;
  110.   }
  111.  
  112.   if(flags & SRC)
  113.   {
  114.     tok = strtok(NULL, " \t\n");
  115.     errNo = getSrcOperand(cmd, tok);
  116.     if(errNo != Ok)
  117.       return errNo;
  118.   }
  119.  
  120.   return Ok;
  121. }
  122.  
  123. int main(int argc, char **argv)
  124. {
  125.   FILE *asmFile, *binFile, *tmpFile;
  126.   char line[0x100];
  127.   uint16_t numCmd = 0;
  128.   labelMapping_t labelMapping;
  129.  
  130.   asmFile = fopen(argv[1], "rb");
  131.   binFile = fopen(argv[2], "wb");
  132.   tmpFile = tmpfile();
  133.  
  134.   memset(&labelMapping, 0, sizeof(labelMapping_t));
  135.  
  136.   for(int lineNo = 1;
  137.       fgets(line, sizeof(line), asmFile);
  138.       ++lineNo)
  139.   {
  140.     command_t cmd;
  141.     char *tok;
  142.  
  143.     capitalize(line);
  144.  
  145.     tok = strtok(line, " \t\n");
  146.  
  147.     if(!tok)
  148.       continue;
  149.  
  150.     if(tok[0] == '.')
  151.     {
  152.       addLabelDef(&labelMapping, tok, numCmd);
  153.       continue;
  154.     }
  155.  
  156.     {
  157.       int code = getOpCode(tok);
  158.  
  159.       if(code == -1)
  160.         catchError(OpCodeErr, lineNo);
  161.  
  162.       cmd.opCode = code;
  163.     }
  164.  
  165.     switch(cmd.opCode)
  166.     {
  167.       case Mov:
  168.       {
  169.         catchError(getOperands(&cmd, DST|SRC), lineNo);
  170.         if(cmd.dstType == Const)
  171.           catchError(DstTypeErr, lineNo);
  172.       }
  173.       break;
  174.       case Add: case Sub: case Mul: case Div: case Mod:
  175.       case Not: case And: case Or: case Xor:
  176.       case BNot: case BAnd: case BOr: case BXor:
  177.       {
  178.         catchError(getOperands(&cmd, DST|SRC), lineNo);
  179.         if(cmd.dstType != Reg)
  180.           catchError(DstTypeErr, lineNo);
  181.         if(cmd.srcType == Mem)
  182.           catchError(SrcTypeErr, lineNo);
  183.       }
  184.       break;
  185.       case Jmp: case JmpIf:
  186.       {
  187.         tok = strtok(NULL, " \t\n");
  188.         if(tok[0] == '.')
  189.         {
  190.           cmd.dstType = Const;
  191.           addLabelUse(&labelMapping, tok, numCmd);
  192.         }
  193.         else
  194.         {
  195.           catchError(getDstOperand(&cmd, tok), lineNo);
  196.           if(cmd.dstType == Mem)
  197.             catchError(DstTypeErr, lineNo);
  198.         }
  199.  
  200.         if(cmd.opCode == JmpIf)
  201.         {
  202.           catchError(getOperands(&cmd, SRC), lineNo);
  203.           if(cmd.srcType == Mem)
  204.             catchError(SrcTypeErr, lineNo);
  205.         }
  206.       }
  207.       break;
  208.       case Read:
  209.       {
  210.         catchError(getOperands(&cmd, DST), lineNo);
  211.         if(cmd.dstType != Mem)
  212.           catchError(DstTypeErr, lineNo);
  213.       }
  214.       break;
  215.       case Write:
  216.       {
  217.         catchError(getOperands(&cmd, SRC), lineNo);
  218.         if(cmd.srcType != Mem)
  219.           catchError(SrcTypeErr, lineNo);
  220.       }
  221.       break;
  222.     }
  223.  
  224.     fwrite(&cmd, sizeof(command_t), 1, tmpFile);
  225.     ++numCmd;
  226.   }
  227.  
  228.   rewind(tmpFile);
  229.  
  230.   for(uint16_t cmdNo = 0, labelUseNo = 0;
  231.       cmdNo < numCmd;
  232.       ++cmdNo)
  233.   {
  234.     command_t cmd;
  235.     fread(&cmd, sizeof(command_t), 1, tmpFile);
  236.  
  237.     if(labelUseNo < labelMapping.uses.num
  238.       && labelMapping.uses.ptr[labelUseNo].cmdNo == cmdNo)
  239.     {
  240.       uint16_t labelNo = labelMapping.uses.ptr[labelUseNo].labelNo;
  241.       cmd.dst = labelMapping.defs.ptr[labelNo].cmdNo;
  242.       ++labelUseNo;
  243.     }
  244.  
  245.     fwrite(&cmd, sizeof(command_t), 1, binFile);
  246.   }
  247.  
  248.   fclose(tmpFile);
  249.   fclose(binFile);
  250.   fclose(asmFile);
  251. }
  252.  
Advertisement
Add Comment
Please, Sign In to add comment