~swisschili/toolchain-6502

c382994c73972918bc7723b5b7836c74e8e92bd6 — swissChili a month ago 6a92301 assembler-flex-bison
Start work on preprocessor
M as/CMakeLists.txt => as/CMakeLists.txt +1 -1
@@ 13,6 13,6 @@ else()
endif()


add_executable(6502-as main.c as.h as.c map.h map.c hash.c hash.c)
add_executable(6502-as main.c as.h as.c pp.c map.h map.c hash.c hash.c)

install(TARGETS 6502-as)

M as/as.c => as/as.c +6 -6
@@ 20,9 20,6 @@ enum
	ARG_IMP,					/* Implied argument */
};

#define ERR "\033[31m"
#define GREEN "\033[32m"
#define RESET "\033[0m"
#define MAX_LEN (0xFFFF - 0x600)
#define MAX_INSTS (MAX_LEN / 2)



@@ 583,7 580,8 @@ uint32_t assemble(char *code, FILE *out)
			uint16_t lbl;
			if (!(lbl = ll_find(last_node, insts[i]->label)))
			{
				printf(ERR "Error on line %d: label '%s' is not defined" RESET "\n", insts[i]->line, insts[i]->label);
				printf(ERR "Error on line %d: label '%s' is not defined" RESET "\n",
					   insts[i]->line, insts[i]->label);
				goto cleanup;
			}
			curr_pc += 3;


@@ 596,7 594,8 @@ uint32_t assemble(char *code, FILE *out)
			uint16_t lbl;
			if (!(lbl = ll_find(last_node, insts[i]->label)))
			{
				printf(ERR "Error on line %d: label '%s' is not defined" RESET "\n", insts[i]->line, insts[i]->label);
				printf(ERR "Error on line %d: label '%s' is not defined" RESET "\n",
					   insts[i]->line, insts[i]->label);
				goto cleanup;
			}
			curr_pc += 2;


@@ 604,7 603,8 @@ uint32_t assemble(char *code, FILE *out)
			printf("ARG_REL, pc (after) == %x, diff = %hx\n", curr_pc, (uint8_t) diff);
			if ((diff < 0 ? -diff : diff) > 0xFF)
			{
				printf(ERR "Error on line %d: label '%s' is too far away for a relative jump" RESET "\n", insts[i]->line, insts[i]->label);
				printf(ERR "Error on line %d: label '%s' is too far away for a relative jump" RESET "\n",
					   insts[i]->line, insts[i]->label);
				printf("pc == %hx, label is at %hx\n", curr_pc, lbl);
				goto cleanup;
			}

M as/as.h => as/as.h +18 -1
@@ 1,9 1,26 @@
#pragma once

#include "map.h"

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>

#define ERR "\033[31m"
#define GREEN "\033[32m"
#define RESET "\033[0m"

char *strtok_fix(char *string, const char *token);
uint32_t skip_ws(char **code);
char *parse_label_name(char **code);
bool ws_end(char **code);

/**
 * @returns 0 on success, error code otherwise
 */
int preproc(char *code, FILE *out, map_t *macros, int flags);

/*
/**
 * @returns NULL on failure, printing info to stderr
 */
uint32_t assemble(char *code, FILE *out);

M as/main.c => as/main.c +18 -1
@@ 1,10 1,12 @@
#include "as.h"
#include "map.h"

#include <stdio.h>
#include <stdlib.h>
#include <bits/getopt_core.h>
#include <unistd.h>

// TODO: handle all the possible IO errors
int main(int argc, char **argv)
{
	char c;


@@ 38,7 40,22 @@ int main(int argc, char **argv)
	fread(text, len, 1, in);
	text[len] = 0;

	uint32_t built = assemble(text, out);
	FILE *temp = tmpfile();

	map_t *macros = new_map();
	uint32_t processed = preproc(text, temp, macros, 0);
	free_map_items(macros);

	fseek(temp, 0, SEEK_END);
	ssize_t temp_len = ftell(in);
	fseek(temp, 0, SEEK_SET);

	char *processed_text = malloc(len + 1);
	fread(processed_text, len, 1, in);
	text[temp_len] = 0;
	
	uint32_t built = assemble(processed_text, out);

	free(text);
	free(processed_text);
}

A as/pp.c => as/pp.c +77 -0
@@ 0,0 1,77 @@
#include "as.h"
#include "map.h"

#include <errno.h>
#include <string.h>
#include <stdlib.h>

enum /* State */
{
	NORMAL,			/* Default State */
	MACRO_DEF		/* In Macro Definition */
};

enum /* Flags */
{
	PRESERVE_MACRO_ARGS,
};

int preproc(char *in, FILE *out, map_t *macros, int flags)
{
	int line_no = 1,
		err = 0,
		state = NORMAL;
	char *line = strtok_fix(in, "\n"),
		*macro_name = NULL;

	while (line)
	{
		skip_ws(&line);

		if (*line == '%')
		{
			// Line is preprocessor directive
			
			char *directive = parse_label_name(&line);
			if (!directive)
			{
				fprintf(stderr, ERR "Expected preprocessor directive on line %d\n" RESET,
						line_no);
				err = EINVAL;
				goto cleanup;
			}
			else
			{
				if (!strcasecmp(directive, "macro"))
				{
					skip_ws(&line);
					macro_name = parse_label_name(&line);
					if (!macro_name)
					{
						fprintf(stderr, ERR "Expected name after %%macro on line %d\n" RESET,
								line_no);
						err = EINVAL;
						goto cleanup;
					}

					if (!ws_end(&line))
					{
						fprintf(stderr, ERR "Expected new line after macro definition\n" RESET);
						err = EINVAL;
						goto cleanup;
					}

					state = MACRO_DEF;
				}
			}
		}

		fprintf(out, "%s\n", line);
		
		line = strtok_fix(NULL, "\n");
		line_no++;
	}
	
cleanup:
	return err;
}

A as/test/test-abs-jump.s => as/test/test-abs-jump.s +16 -0
@@ 0,0 1,16 @@
;;; This program should test for a bug involving endianness.

start:
	lda #$FF
	sta $200					; Put something on the screen, just to see
	jmp second-pixel
	brk

second-pixel:
	lda #$E0					; Red
	sta $201
	sta $220
	sta $221					; Draw a box around the white pixel

loop:							; Infinite loop
	jmp loop

A docs/.sass-cache/e3a0acadbd5d6bc6cf7ba6a2321a4fa55d361330/styles.scssc => docs/.sass-cache/e3a0acadbd5d6bc6cf7ba6a2321a4fa55d361330/styles.scssc +0 -0

M docs/build.lua => docs/build.lua +1 -1
@@ 4,7 4,7 @@ site = Site

-- site.processors.md = markdownProcessor
site.processors.scss = {
	process = cmdProcessor("sass -"),
	process = cmdProcessor("sass"),
	extension = "css"
}
site.processors.webm = {

M docs/content/demo.webm => docs/content/demo.webm +0 -0

M docs/templates/page.html => docs/templates/page.html +1 -1
@@ 14,7 14,7 @@
				</p>

				<ul>
					<li><a href="https://github.com/swissChili/6502">Git</a></li>
					<li><a href="https://git.sr.ht/~swisschili/toolchain-6502">Git</a></li>
					<li><a href="https://builds.sr.ht/~swisschili/6502">
						<img src="https://builds.sr.ht/~swisschili/6502.svg"></a>
					</li>

A test-abs-jump.bin => test-abs-jump.bin +0 -0