Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "defs.h"
- #include "label.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
- #include <ctype.h>
- enum { Ok, OpCodeErr, DstTypeErr, DstValErr, SrcTypeErr, SrcValErr };
- static void capitalize(char *str)
- {
- while(*str)
- {
- *str = toupper(*str);
- ++str;
- }
- }
- static int getOpCode(char *tok)
- {
- if(!strcmp(tok, "MOV")) return Mov;
- if(!strcmp(tok, "ADD")) return Add;
- if(!strcmp(tok, "SUB")) return Sub;
- if(!strcmp(tok, "MUL")) return Mul;
- if(!strcmp(tok, "DIV")) return Div;
- if(!strcmp(tok, "MOD")) return Mod;
- if(!strcmp(tok, "NOT")) return Not;
- if(!strcmp(tok, "AND")) return And;
- if(!strcmp(tok, "OR")) return Or;
- if(!strcmp(tok, "XOR")) return Xor;
- if(!strcmp(tok, "BNOT")) return BNot;
- if(!strcmp(tok, "BAND")) return BAnd;
- if(!strcmp(tok, "BOR")) return BOr;
- if(!strcmp(tok, "BXOR")) return BXor;
- if(!strcmp(tok, "JMP")) return Jmp;
- if(!strcmp(tok, "JMPIF")) return JmpIf;
- if(!strcmp(tok, "READ")) return Read;
- if(!strcmp(tok, "WRITE")) return Write;
- return -1;
- }
- static void catchError(int errNo, int lineNo)
- {
- if(errNo != Ok)
- {
- printf("Somewhing is wrong with line %d\n", lineNo);
- exit(1);
- }
- }
- static unsigned getOperandType(char *tok)
- {
- return isdigit(tok[0]) ? Const
- : tok[0] == 'R' ? Reg
- : tok[0] == 'M' ? Mem
- : -1;
- }
- static int getOperandVal(char *tok, int type)
- {
- return strtol(&tok[type != Const], NULL, 0);
- }
- #define DST 1
- #define SRC 2
- static int getDstOperand(command_t *cmd, char *tok)
- {
- unsigned type, val;
- type = getOperandType(tok);
- if(type == -1)
- return DstTypeErr;
- cmd->dstType = type;
- cmd->dst = getOperandVal(tok, type);
- return Ok;
- }
- static int getSrcOperand(command_t *cmd, char *tok)
- {
- unsigned type, val;
- type = getOperandType(tok);
- if(type == -1)
- return SrcTypeErr;
- cmd->srcType = type;
- cmd->src = getOperandVal(tok, type);
- return Ok;
- }
- static int getOperands(command_t *cmd, int flags)
- {
- char *tok;
- int errNo;
- if(flags & DST)
- {
- tok = strtok(NULL, " \t\n");
- errNo = getDstOperand(cmd, tok);
- if(errNo != Ok)
- return errNo;
- }
- if(flags & SRC)
- {
- tok = strtok(NULL, " \t\n");
- errNo = getSrcOperand(cmd, tok);
- if(errNo != Ok)
- return errNo;
- }
- return Ok;
- }
- int main(int argc, char **argv)
- {
- FILE *asmFile, *binFile, *tmpFile;
- char line[0x100];
- uint16_t numCmd = 0;
- labelMapping_t labelMapping;
- asmFile = fopen(argv[1], "rb");
- binFile = fopen(argv[2], "wb");
- tmpFile = tmpfile();
- memset(&labelMapping, 0, sizeof(labelMapping_t));
- for(int lineNo = 1;
- fgets(line, sizeof(line), asmFile);
- ++lineNo)
- {
- command_t cmd;
- char *tok;
- capitalize(line);
- tok = strtok(line, " \t\n");
- if(!tok)
- continue;
- if(tok[0] == '.')
- {
- addLabelDef(&labelMapping, tok, numCmd);
- continue;
- }
- {
- int code = getOpCode(tok);
- if(code == -1)
- catchError(OpCodeErr, lineNo);
- cmd.opCode = code;
- }
- switch(cmd.opCode)
- {
- case Mov:
- {
- catchError(getOperands(&cmd, DST|SRC), lineNo);
- if(cmd.dstType == Const)
- catchError(DstTypeErr, lineNo);
- }
- break;
- case Add: case Sub: case Mul: case Div: case Mod:
- case Not: case And: case Or: case Xor:
- case BNot: case BAnd: case BOr: case BXor:
- {
- catchError(getOperands(&cmd, DST|SRC), lineNo);
- if(cmd.dstType != Reg)
- catchError(DstTypeErr, lineNo);
- if(cmd.srcType == Mem)
- catchError(SrcTypeErr, lineNo);
- }
- break;
- case Jmp: case JmpIf:
- {
- tok = strtok(NULL, " \t\n");
- if(tok[0] == '.')
- {
- cmd.dstType = Const;
- addLabelUse(&labelMapping, tok, numCmd);
- }
- else
- {
- catchError(getDstOperand(&cmd, tok), lineNo);
- if(cmd.dstType == Mem)
- catchError(DstTypeErr, lineNo);
- }
- if(cmd.opCode == JmpIf)
- {
- catchError(getOperands(&cmd, SRC), lineNo);
- if(cmd.srcType == Mem)
- catchError(SrcTypeErr, lineNo);
- }
- }
- break;
- case Read:
- {
- catchError(getOperands(&cmd, DST), lineNo);
- if(cmd.dstType != Mem)
- catchError(DstTypeErr, lineNo);
- }
- break;
- case Write:
- {
- catchError(getOperands(&cmd, SRC), lineNo);
- if(cmd.srcType != Mem)
- catchError(SrcTypeErr, lineNo);
- }
- break;
- }
- fwrite(&cmd, sizeof(command_t), 1, tmpFile);
- ++numCmd;
- }
- rewind(tmpFile);
- for(uint16_t cmdNo = 0, labelUseNo = 0;
- cmdNo < numCmd;
- ++cmdNo)
- {
- command_t cmd;
- fread(&cmd, sizeof(command_t), 1, tmpFile);
- if(labelUseNo < labelMapping.uses.num
- && labelMapping.uses.ptr[labelUseNo].cmdNo == cmdNo)
- {
- uint16_t labelNo = labelMapping.uses.ptr[labelUseNo].labelNo;
- cmd.dst = labelMapping.defs.ptr[labelNo].cmdNo;
- ++labelUseNo;
- }
- fwrite(&cmd, sizeof(command_t), 1, binFile);
- }
- fclose(tmpFile);
- fclose(binFile);
- fclose(asmFile);
- }
Advertisement
Add Comment
Please, Sign In to add comment