asm

custom asm compiler (learn project)
git clone git://git.evenfri.xyz/asm.git
Log | Files | Refs

main.c (2680B)


      1 #include "asm.h"
      2 
      3 enum token_kind {
      4   tok_mnem,
      5   tok_dst,
      6   tok_src,
      7   tok_comma,
      8   tok_other,
      9 };
     10 
     11 typedef struct token token;
     12 struct token {
     13   enum token_kind kind;
     14   char *val;
     15   token *next;
     16 };
     17 
     18 typedef struct {
     19   char *name;
     20   uint8_t opcode;
     21 } mnem_t;
     22 
     23 static mnem_t mnem_table[] = {
     24   {"hlt", 0x00},
     25   {"mov", 0x88},
     26   {"sub", 0x28},
     27 };
     28 static size_t mnem_count = sizeof(mnem_table) / sizeof(mnem_t);
     29 
     30 uint8_t mnem_find(char *s) {
     31   for (size_t i = 0; i < mnem_count; i++) {
     32     if (strcmp(s, mnem_table[i].name) == 0) {
     33       return mnem_table[i].opcode;
     34     }
     35   }
     36   fprintf(stderr, "%s: %s: unknown mnemonic\n", PROGRAM_NAME, s);
     37   return 0xff;
     38 }
     39 
     40 
     41 void clear_code(char *s) {
     42   char *rd = s;
     43   char *wr = s;
     44 
     45   while (*rd != '\0') {
     46     if (*rd == CHAR_COMMENT) {
     47       while (*rd != '\n' && *rd != '\0') {
     48         rd++;
     49       }
     50     }
     51 
     52     if (*rd == CHAR_NEWLINE) {
     53       *wr++ = ' ';
     54       rd++;
     55       continue;
     56     }
     57 
     58     if (*rd != '\0') {
     59       *wr++ = *rd++;
     60     }
     61   }
     62   *wr = '\0';
     63 }
     64 
     65 void free_tokens(token *tok) {
     66   while (tok) {
     67     token *next = tok->next;
     68     free(tok->val);
     69     free(tok);
     70     tok = next;
     71   }
     72 }
     73 
     74 token* new_token(enum token_kind kind, char *val) {
     75   token *tok = calloc(1, sizeof(token));
     76   tok->kind = kind;
     77   tok->val = strdup(val);
     78 
     79   return tok;
     80 }
     81 
     82 token* tokenize(char *s) {
     83   token head = {0};
     84   token *cur = &head;
     85 
     86   char *delim = " \t,";
     87   char *p = strtok(s, delim);
     88 
     89   int op_index = 0;
     90 
     91   while (p != NULL) {
     92     enum token_kind kind;
     93 
     94     int is_mnemonic = 0;
     95     for (size_t i = 0; i < mnem_count; i++) {
     96       if (strcmp(p, mnem_table[i].name) == 0) {
     97         is_mnemonic = 1;
     98         break;
     99       }
    100     }
    101 
    102     if (is_mnemonic) {
    103       op_index = 0;
    104     }
    105 
    106     if (op_index == 0) {
    107       kind = tok_mnem;
    108     } else if (op_index == 1) {
    109       kind = tok_dst;
    110     } else {
    111       kind = tok_src;
    112     }
    113     op_index++;
    114 
    115     cur->next = new_token(kind, p);
    116     cur = cur->next;
    117 
    118     p = strtok(NULL, delim);
    119   }
    120   return head.next;
    121 }
    122 
    123 int main(int argc, char *argv[]) {
    124   if (argc < 2) {
    125     fprintf(stderr, "%s: no input files\n", PROGRAM_NAME);
    126     exit(1);
    127   }
    128 
    129   char *code = read_file(argv[1]);
    130   if (!code) {
    131     perror(PROGRAM_NAME);
    132     exit(1);
    133   }
    134 
    135   clear_code(code);
    136 
    137   token *head = tokenize(code);
    138   token *curr = head;
    139 
    140   while (curr != NULL) {
    141     printf("%s is ", curr->val);
    142 
    143     if (curr->kind == tok_mnem) {
    144       uint8_t opcode = mnem_find(curr->val);
    145       printf("0x%02x", opcode);
    146     }
    147 
    148     if (curr->kind == tok_dst) {
    149       printf("dest");
    150     }
    151 
    152     if (curr->kind == tok_src) {
    153       printf("src");
    154     }
    155 
    156     printf("\n");
    157     curr = curr->next;
    158   }
    159 
    160   free_tokens(head);
    161   free(code);
    162   return 0;
    163 }