Files
SplitBit-Emulator/Source/Assembler/Assm-util.h
T

90 lines
2.6 KiB
C

// Assm-util.h
// Utility functions for the SplitBit Assembler's first pass.
// Written by Anachronaut
// 10/25/2024
#ifndef ASSMUTL_H
#define ASSMUTL_H
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "Assm-util.h"
#include "assembly.h"
#define MAX_INCLUDES 128
// Type values.
#define UNKNOWN 0
#define KEYWORD 1
#define INSTRUCTION 2
#define LABEL 3
#define LABEL_DEFINITION 4
#define VALUE 5
#define STRING 6
// A name from the Vector Segment, used as the operand of SWI. It stands for a vector
// number rather than an address, so it emits one byte where a label emits two.
#define VECTOR_REFERENCE 7
// Zero bytes put down to move the cursor along, from #Reserve. How many is known as
// soon as it is read.
#define PADDING 8
// The same, from #Align, where how many depends on where the cursor has got to. The
// count is worked out in the second pass and the alignment itself is kept in address.
#define ALIGNMENT 9
// Keyword values.
#define KEYWORD_INCLUDE 1
#define KEYWORD_PROGRAM 2
#define KEYWORD_DATA 3
#define KEYWORD_VECTORS 4
#define KEYWORD_ALIGN 5
#define KEYWORD_RESERVE 6
// Destination values.
#define NOWHERE 0
#define PROGRAM 1
#define DATA 2
// The Vector Segment does not become bytes at an address the way the other two do. It
// says which handler belongs to which vector, and the assembler works out the rest.
#define VECTORS 3
// For colorful text.
#define RESET "\x1B[0m"
#define RED "\x1B[31m"
#define GREEN "\x1B[32m"
#define YELLOW "\x1B[33m"
#define BLUE "\x1B[34m"
#define MAGENTA "\x1B[35m"
#define CYAN "\x1B[36m"
#define WHITE "\x1B[37m"
typedef struct {
char* token;
char* fileName;
int lineNumber;
uint8_t byteValue;
uint8_t dataPointer[MAX_DATA_POINTER_OPERANDS]; // Which Data Pointers this instruction works through, if any.
int byteLength;
uint16_t address;
int type; // "KEYWORD", "INSTRUCTION" , "LABEL" , "VALUE", "STRING"
int destination; // "NOWHERE", "PROGRAM", "DATA"
} intermediateElement;
int checkIfKeyword(intermediateElement *currentElement);
int checkIfInstruction(intermediateElement *currentElement);
int checkIfLiteralValue(intermediateElement *currentElement);
int checkIfLabel(intermediateElement *currentElement);
int readToken(intermediateElement *currentElement, FILE *file, int *lineNumber);
// Reads a count written the way a literal is, but allowing the full range of an address
// rather than a single byte. #Align and #Reserve both take one, and neither number is
// ever emitted as a byte, so there is no reason to hold them to a byte's range.
uint16_t readCount(intermediateElement *currentElement, const char *what);
#endif