all repos — xyw @ f6833929f178103c195a4b1aa0ca604b04f1f3d2

A minimal virtual machine and assembler for terminals.

xyw.c

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
#include <stdio.h>
#include <string.h>
#include "xyw.h"

int xyw_debug = 0;
int xyw_argv_processed = 0;
char *xyw_argv[32];
int xyw_argc = 0;

// Instruction mnemonics definition
const char xyw_instructions[][4] = {
    "HLT", "NOP", "PSH", "POP",
    "LDB", "LDW", "STB", "STW",
    "INC", "DEC", "SHL", "SHR",
    "ADD", "SUB", "MUL", "DIV",
    "EQU", "NEQ", "GTH", "LTH",
    "NOT", "AND", "IOR", "XOR",
    "DUP", "SWP", "OVR", "ROT",
    "JMP", "JCN", "JSR", "RTS"};

int flag(const char *arg, const char *str)
{
    if (!str || !arg || !*str)
        return 0;
    if (strncmp(arg, "--", 2) == 0 && strcmp(arg + 2, str) == 0)
        return 1;
    if (arg[0] == '-' && arg[1] != '\0' && arg[2] == '\0' && arg[1] == str[0])
        return 1;
    return 0;
}

int main(int argc, char *argv[])
{
    xyw_argc = argc;

    for (int i = 1; i < argc && i < 32; i++)
    {
        xyw_argv[i] = argv[i];
        if (flag(argv[i], "debug"))
        {
            xyw_debug = 1;
        }
    }

    for (int i = 1; i < argc; i++)
    {
        if (flag(argv[i], "debug"))
        {
            continue; // already handled
        }

        const char *input_file = argv[i];
        char output_file[256];
        const char *ext = strrchr(input_file, '.');
        if (ext && strcmp(ext, ".xyw") == 0)
        {
            snprintf(output_file, sizeof(output_file), "%.*s.xim", (int)(ext - input_file), input_file);
            if (xyw_assemble(input_file, output_file) != 0)
            {
                fprintf(stderr, "Assembly failed for file: %s\n", input_file);
                return -1;
            }
            else
            {
                if (xyw_debug)
                {
                    printf("Assembled %s to %s\n", input_file, output_file);
                }
            }
            break;
        }
        else if (ext && strcmp(ext, ".xim") == 0)
        {
            if (xyw_run(input_file) != 0)
            {
                fprintf(stderr, "Execution failed for file: %s\n", input_file);
                return -1;
            }
            break;
        }
    }
    return 0;
}