interpreter

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

common.h (6342B)


      1 #ifndef AWA_COMMON_H_
      2 #define AWA_COMMON_H_
      3 
      4 #include <stdlib.h>
      5 #include <string.h>
      6 #include <stdint.h>
      7 #include <stdio.h>
      8 #include <stdbool.h>
      9 #include <ctype.h>
     10 #include <errno.h>
     11 #include <assert.h>
     12 
     13 static char awascii_table[64] = "AWawJELYHOSIUMjelyhosiumPCNTpcntBDFGRbdfgr0123456789 .,!'()~_/;\n";
     14 static uint8_t awascii_table_inverse[256] = {
     15     ['A'] = 0, ['W'] = 1, ['a'] = 2, ['w'] = 3,
     16     ['J'] = 4, ['E'] = 5, ['L'] = 6, ['Y'] = 7,
     17     ['H'] = 8, ['O'] = 9, ['S'] = 10, ['I'] = 11, ['U'] = 12, ['M'] = 13,
     18     ['j'] = 14, ['e'] = 15, ['l'] = 16, ['y'] = 17,
     19     ['h'] = 18, ['o'] = 19, ['s'] = 20, ['i'] = 21, ['u'] = 22, ['m'] = 23,
     20     ['P'] = 24, ['C'] = 25, ['N'] = 26, ['T'] = 27,
     21     ['p'] = 28, ['c'] = 29, ['n'] = 30, ['t'] = 31,
     22     ['B'] = 32, ['D'] = 33, ['F'] = 34, ['G'] = 35, ['R'] = 36,
     23     ['b'] = 37, ['d'] = 38, ['f'] = 39, ['g'] = 40, ['r'] = 41,
     24     ['0'] = 42, ['1'] = 43, ['2'] = 44, ['3'] = 45, ['4'] = 46, ['5'] = 47, ['6'] = 48, ['7'] = 49, ['8'] = 50, ['9'] = 51,
     25     [' '] = 52, ['.'] = 53, [','] = 54, ['!'] = 55, ['\''] = 56, ['('] = 57, [')'] = 58, ['~'] = 59, ['_'] = 60, ['/'] = 61, [';'] = 62, ['\n'] = 63,
     26 };
     27 
     28 enum awatisms {
     29     AWA_NOP             = 0x00,
     30     AWA_PRINT           = 0x01,
     31     AWA_PRINT_NUM       = 0x02,
     32     AWA_READ            = 0x03,
     33     AWA_READ_NUM        = 0x04,
     34     AWA_TERMINATE       = 0x1F,
     35 
     36     AWA_BLOW            = 0x05,
     37     AWA_SUBMERGE        = 0x06,
     38     AWA_POP             = 0x07,
     39     AWA_DUPLICATE       = 0x08,
     40     AWA_SURROUND        = 0x09,
     41     AWA_MERGE           = 0x0A,
     42 
     43     AWA_ADD             = 0x0B,
     44     AWA_SUBTRACT        = 0x0C,
     45     AWA_MULTIPLY        = 0x0D,
     46     AWA_DIVIDE          = 0x0E,
     47     AWA_COUNT           = 0x0F,
     48 
     49     AWA_LABEL           = 0x10,
     50     AWA_JUMP            = 0x11,
     51     AWA_EQUAL_TO        = 0x12,
     52     AWA_LESS_THAN       = 0x13,
     53     AWA_GREATER_THAN    = 0x14,
     54 
     55     AWA_SYSCALL         = 0x15,
     56     AWA_DOUBLE_POP      = 0x16,
     57 
     58 };
     59 #define AWA_OPCODE_MAX 32
     60 
     61 #ifdef __linux
     62 #include "sys/syscall.h"
     63 #include "unistd.h"
     64 #define awa_syscall(...) syscall(__VA_ARGS__)
     65 #endif
     66 
     67 static char* awatism_opcode_names[AWA_OPCODE_MAX] = {
     68     [AWA_NOP]           = "nop",
     69     [AWA_PRINT]         = "prn",
     70     [AWA_PRINT_NUM]     = "pr1",
     71     [AWA_READ]          = "red",
     72     [AWA_READ_NUM]      = "r3d",
     73     [AWA_TERMINATE]     = "trm",
     74 
     75     [AWA_BLOW]          = "blo",
     76     [AWA_SUBMERGE]      = "sbm",
     77     [AWA_POP]           = "pop",
     78     [AWA_DUPLICATE]     = "dpl",
     79     [AWA_SURROUND]      = "srn",
     80     [AWA_MERGE]         = "mrg",
     81 
     82     [AWA_ADD]           = "4dd",
     83     [AWA_SUBTRACT]      = "sub",
     84     [AWA_MULTIPLY]      = "mul",
     85     [AWA_DIVIDE]        = "div",
     86     [AWA_COUNT]         = "cnt",
     87 
     88     [AWA_LABEL]         = "lbl",
     89     [AWA_JUMP]          = "jmp",
     90     [AWA_EQUAL_TO]      = "eql",
     91     [AWA_LESS_THAN]     = "lss",
     92     [AWA_GREATER_THAN]  = "gr8",
     93 
     94     [AWA_SYSCALL]       = "sys",
     95     [AWA_DOUBLE_POP]    = "p0p",
     96 };
     97 
     98 static uint8_t awatism_param_sizes_bits[AWA_OPCODE_MAX] = {
     99     [AWA_BLOW]      = 8,
    100     [AWA_SUBMERGE]  = 5,
    101     [AWA_SURROUND]  = 5,
    102     [AWA_LABEL]     = 5,
    103     [AWA_JUMP]      = 5,
    104     [AWA_SYSCALL]   = 10,
    105 };
    106 
    107 typedef struct awatism awatism_t;
    108  struct awatism {
    109     uint8_t opcode;
    110     union {
    111         uint8_t    u8;
    112         int8_t     s8;
    113         uint16_t  u16;
    114     };
    115 
    116     awatism_t* next;
    117 
    118     int current_pos_bytes;
    119 };
    120 
    121 #define llist_queue_push(f,l,n) ((f)==0) ? (f)=(l)=(n) : ((l)->next=(n), (l)=(n), (n)->next=0)
    122 #define llist_queue_pop(f,l) ((f)==(l)) ? ((f)=(l)=0) : ((f)=(f)->next)
    123 
    124 #define llist_stack_push(f,n) ((n)->next=(f), (f)=(n))
    125 #define llist_stack_pop(f) ((f)==0) ? 0 : ((f)=(f->next))
    126 
    127 #define awa_debug_printf(...) printf(__VA_ARGS__)
    128 
    129 typedef struct awa_bubble awa_bubble_t;
    130 struct awa_bubble {
    131     awa_bubble_t* next;
    132     awa_bubble_t* first;
    133     awa_bubble_t* last;
    134     int val;
    135 };
    136 
    137 typedef struct {
    138     bool failed_parse;
    139 
    140     char* source;
    141 
    142     awatism_t* awatism_first;
    143     awatism_t* awatism_last;
    144 
    145     awatism_t* awalabel_table[64];
    146 
    147     awa_bubble_t* bubble_first;
    148 
    149     bool cmp_skip_next_flag;
    150     bool last_print_was_number_flag;
    151 } awa_program_t;
    152 
    153 typedef struct {
    154     const char* awatalk;
    155     int pos;
    156     int total_size;
    157 } awa_parser_t;
    158 
    159 typedef struct {
    160     const char* line_start;
    161     int col;
    162     int line;
    163     int line_len;
    164 } awa_line_info_t;
    165 
    166 static awa_line_info_t awa_get_line_and_col(awa_parser_t parser)
    167 {
    168     awa_line_info_t res = {0};
    169     res.line_start = parser.awatalk;
    170     for (;;) {
    171         const char* current_newline = strchr(res.line_start == parser.awatalk ? parser.awatalk : res.line_start, '\n');
    172         if (!current_newline) break;
    173         if (parser.pos < current_newline - parser.awatalk) break;
    174         res.line_start = current_newline + 1;
    175         res.line++;
    176     }
    177     const char* newline_after = strchr(res.line_start, '\n');
    178     if (newline_after) res.line_len = newline_after - res.line_start - 1;
    179     else               res.line_len = strlen(res.line_start);
    180     res.col = parser.pos - (res.line_start - parser.awatalk);
    181     return res;
    182 }
    183 
    184 static void awa_print_line(awa_line_info_t line)
    185 {
    186     awa_debug_printf("%.*s\n", line.line_len+1, line.line_start);
    187 }
    188 
    189 static void awa_print_awatism(awatism_t awatism) {
    190     awa_debug_printf("%s", awatism_opcode_names[awatism.opcode]);
    191     switch (awatism.opcode) {
    192     case AWA_BLOW:
    193     {
    194         if (awatism.u8 < 64) {
    195             if (awascii_table[awatism.u8] == '\n')
    196                 awa_debug_printf(" %d [\\n]", (int)awatism.s8);
    197             else
    198                 awa_debug_printf(" %d [%c]", (int)awatism.s8, awascii_table[awatism.s8]);
    199         } else {
    200             awa_debug_printf(" %d", (int)awatism.s8);
    201         }
    202         break;
    203     } break;
    204     case AWA_SUBMERGE:
    205     case AWA_SURROUND:
    206     case AWA_LABEL:
    207     case AWA_JUMP:
    208     case AWA_SYSCALL:
    209     {
    210         awa_debug_printf(" %d", (int)awatism.u8);
    211         break;
    212     } break;
    213     }
    214 }
    215 
    216 static void awa_recursive_debug_print_bubble(awa_bubble_t* bubble) {
    217     if (bubble->first) {
    218         awa_debug_printf("(");
    219         for (awa_bubble_t* b = bubble->first; b; b = b->next) {
    220             if (b != bubble->first) awa_debug_printf(", ");
    221             awa_recursive_debug_print_bubble(b);
    222         }
    223         awa_debug_printf(")");
    224     } else {
    225         awa_debug_printf("%d", bubble->val);
    226     }
    227 }
    228 
    229 
    230 #endif // AWA_COMMON_H_