meow.git
meow.c
/* meow - 6502 assembler
* Copyright (C) 2024-2025 ArcNyxx
* see LICENCE file for licensing information */
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "direct.h"
#include "instruct.h"
#include "label.h"
#include "meow.h"
static char *fname;
static size_t fline;
char ps[0xffff] = { 0 };
uint16_t pc = 0;
void
meow(const char *msg, ...)
{
fputs("meow: ", stderr);
va_list ap;
va_start(ap, msg);
vfprintf(stderr, msg, ap);
va_end(ap);
if (msg[strlen(msg) - 1] == ' ')
perror(NULL);
else
fprintf(stderr, ": %s:%lu\n", fname, fline);
}
bool
islabel(const char *label)
{
if (!isalpha(label[0]) && label[0] != '_')
return false;
for (size_t i = 1; label[i] != '\0'; ++i)
if (!isalnum(label[i]) && label[i] != '_')
return false;
return true;
}
long
strnum(const char *str, char **endptr)
{
int base = 10;
const char *place = str;
if (str[0] == '%') {
base = 2;
++place;
} else if (str[0] == '$') {
base = 16;
++place;
}
errno = 0;
return strtol(place, endptr, base);
}
int
main(int argc, char **argv)
{
char *line = NULL;
size_t size = 0;
for (int i = 1; i < argc; ++i) {
FILE *fp;
fname = argv[i];
if ((fp = fopen(fname, "r")) == NULL) {
meow("fatal: unable to open file: %s: ", fname);
return 1;
}
for (errno = 0, fline = 1; getline(&line, &size, fp) >= 1;
errno = 0, ++fline) {
char *semi;
if ((semi = strchr(line, ';')) != NULL)
semi[0] = '\0'; /* ignore comment */
char *str;
if ((str = strtok(line, " \t\n\r")) == NULL)
continue;
if (str[0] == '.') {
direct(str);
} else if (str[strlen(str) - 1] == ':') {
str[strlen(str) - 1] = '\0';
labeldef(str, pc);
} else {
instruct(str);
}
}
if (errno) {
meow("fatal: unable to continue reading file: %s: ",
fname);
return 1;
}
fclose(fp);
}
labelchk();
fwrite(ps, 0xffff, 1, stdout);
}