mirror of https://git.sr.ht/~kikoodx/bcasm
189 lines
3.1 KiB
C
189 lines
3.1 KiB
C
/* SPDX-License-Identifier: MIT */
|
|
/* Copyright (C) 2021 KikooDX */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
static void parse(char *path);
|
|
static char* get_op(int id);
|
|
static char* get_long_op(int id);
|
|
static char* get_value(int id);
|
|
|
|
static int counter = 0; /* line number */
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
assert(argc == 2);
|
|
parse(argv[1]);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
static void
|
|
parse(char *path)
|
|
{
|
|
FILE *fp;
|
|
char line[256];
|
|
char *token = NULL;
|
|
char *op1, *op2;
|
|
|
|
fp = fopen(path, "r");
|
|
assert(fp != NULL);
|
|
|
|
while (fgets(line, sizeof(line), fp) != NULL)
|
|
{
|
|
token = strtok(line, "\n\t\r ");
|
|
counter++;
|
|
|
|
if (token == NULL || line[0] == ';')
|
|
{
|
|
continue;
|
|
}
|
|
else if (strcmp(token, "NOP") == 0)
|
|
{
|
|
printf("'\n");
|
|
}
|
|
else if (strcmp(token, "MOV") == 0)
|
|
{
|
|
op1 = get_value(1);
|
|
op2 = get_value(2);
|
|
if (strcmp(op2, "Ans") == 0)
|
|
{
|
|
printf("%s\n", op1);
|
|
}
|
|
else
|
|
{
|
|
printf("%s->%s\n", op1, op2);
|
|
}
|
|
}
|
|
else if (strcmp(token, "ADD") == 0)
|
|
{
|
|
op1 = get_value(1);
|
|
printf("Ans+%s\n", op1);
|
|
}
|
|
else if (strcmp(token, "SUB") == 0)
|
|
{
|
|
op1 = get_value(1);
|
|
printf("Ans-%s\n", op1);
|
|
}
|
|
else if (strcmp(token, "MUL") == 0)
|
|
{
|
|
op1 = get_value(1);
|
|
printf("Ans*%s\n", op1);
|
|
}
|
|
else if (strcmp(token, "DIV") == 0)
|
|
{
|
|
op1 = get_value(1);
|
|
printf("Ans/%s\n", op1);
|
|
}
|
|
else if (strcmp(token, "MOD") == 0)
|
|
{
|
|
op1 = get_value(1);
|
|
printf("MOD(Ans,%s\n", op1);
|
|
}
|
|
else if (strcmp(token, "NEG") == 0)
|
|
{
|
|
printf("-Ans\n");
|
|
}
|
|
else if (strcmp(token, "LBL") == 0)
|
|
{
|
|
op1 = get_op(1);
|
|
printf("Lbl %s\n", op1);
|
|
}
|
|
else if (strcmp(token, "JMP") == 0)
|
|
{
|
|
op1 = get_op(1);
|
|
printf("Goto %s\n", op1);
|
|
}
|
|
else if (strcmp(token, "JEZ") == 0)
|
|
{
|
|
op1 = get_op(1);
|
|
printf("Ans=0=>Goto %s\n", op1);
|
|
}
|
|
else if (strcmp(token, "JNZ") == 0)
|
|
{
|
|
op1 = get_op(1);
|
|
printf("Ans=>Goto %s\n", op1);
|
|
}
|
|
else if (strcmp(token, "JMZ") == 0)
|
|
{
|
|
op1 = get_op(1);
|
|
printf("Ans>0=>Goto %s\n", op1);
|
|
}
|
|
else if (strcmp(token, "JLZ") == 0)
|
|
{
|
|
op1 = get_op(1);
|
|
printf("Ans<0=>Goto %s\n", op1);
|
|
}
|
|
else if (strcmp(token, "CLS") == 0)
|
|
{
|
|
printf("ClrText\n");
|
|
}
|
|
else if (strcmp(token, "DSP") == 0)
|
|
{
|
|
printf("AnsDisps");
|
|
}
|
|
else if (strcmp(token, "LOC") == 0)
|
|
{
|
|
printf("Locate X,Y,Ans\n");
|
|
}
|
|
else if (strcmp(token, "#include") == 0)
|
|
{
|
|
op1 = get_long_op(1);
|
|
parse(op1);
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "line %d: unknown token '%s'\n", counter, token);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
}
|
|
|
|
static char*
|
|
get_op(int id)
|
|
{
|
|
char *op = strtok(NULL, "\n\t\r, ");
|
|
if (op == NULL)
|
|
{
|
|
fprintf(stderr, "line %d: missing op %d\n", counter, id);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
return op;
|
|
}
|
|
|
|
static char*
|
|
get_long_op(int id)
|
|
{
|
|
char *op = strtok(NULL, "\"");
|
|
if (op == NULL)
|
|
{
|
|
fprintf(stderr, "line %d: missing long op %d\n", counter, id);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
return op;
|
|
}
|
|
|
|
static char*
|
|
get_value(int id)
|
|
{
|
|
char *op = get_op(id);
|
|
if (strcmp(op, "ANS") == 0)
|
|
{
|
|
return "Ans";
|
|
}
|
|
if (strcmp(op, "GTK") == 0)
|
|
{
|
|
return "Getkey";
|
|
}
|
|
if (strcmp(op, "INP") == 0)
|
|
{
|
|
return "?";
|
|
}
|
|
return op;
|
|
}
|