Browse Source

Implement space directive; allow commas in .byte.

master
Ben Kurtovic 9 years ago
parent
commit
295f6eb70f
3 changed files with 41 additions and 6 deletions
  1. +5
    -3
      src/assembler/directives.h
  2. +5
    -3
      src/assembler/parse_util.c
  3. +31
    -0
      src/assembler/tokenizer.c

+ 5
- 3
src/assembler/directives.h View File

@@ -6,7 +6,7 @@
#include <string.h>

#define DIRECTIVE_MARKER '.'
#define NUM_DIRECTIVES 15
#define NUM_DIRECTIVES 16

#define DIR_INCLUDE ".include"

@@ -22,6 +22,7 @@
#define DIR_ORIGIN ".org"
#define DIR_BLOCK ".block"
#define DIR_BYTE ".byte"
#define DIR_SPACE ".space"
#define DIR_ASCII ".ascii"
#define DIR_ASCIZ ".asciz"
#define DIR_ASCIIZ ".asciiz"
@@ -35,8 +36,9 @@

#define IS_LOCAL_DIRECTIVE(line) \
(IS_DIRECTIVE(line, DIR_ORIGIN) || IS_DIRECTIVE(line, DIR_BLOCK) || \
IS_DIRECTIVE(line, DIR_BYTE) || IS_DIRECTIVE(line, DIR_ASCII) || \
IS_DIRECTIVE(line, DIR_ASCIZ) || IS_DIRECTIVE(line, DIR_ASCIIZ))
IS_DIRECTIVE(line, DIR_BYTE) || IS_DIRECTIVE(line, DIR_SPACE) || \
IS_DIRECTIVE(line, DIR_ASCII) || IS_DIRECTIVE(line, DIR_ASCIZ) || \
IS_DIRECTIVE(line, DIR_ASCIIZ))

#define DIRECTIVE_OFFSET(line, d) \
(DIRECTIVE_HAS_ARG(line, d) ? strlen(d) : 0)


+ 5
- 3
src/assembler/parse_util.c View File

@@ -147,9 +147,9 @@ bool parse_bytes(uint8_t **result, size_t *length, const char *arg, ssize_t size
uint8_t *bytes = NULL;
size_t nbytes = 0;

while (arg != end) {
while (arg < end) {
const char *start = arg;
while (arg != end && *arg != ' ')
while (arg != end && *arg != ' ' && *arg != ',')
arg++;

uint32_t temp;
@@ -164,7 +164,9 @@ bool parse_bytes(uint8_t **result, size_t *length, const char *arg, ssize_t size
OUT_OF_MEMORY()
bytes[nbytes - 1] = temp;

if (arg++ == end)
if (arg < end - 1 && *arg == ',' && *(arg + 1) == ' ')
arg += 2;
else if (arg++ >= end)
break;
}



+ 31
- 0
src/assembler/tokenizer.c View File

@@ -146,6 +146,31 @@ static ErrorInfo* handle_block_directive(
}

/*
Parse a .space directive, which fills a region with a single byte.
*/
static bool parse_space(
uint8_t **result, size_t *length, const char *arg, ssize_t size)
{
uint8_t *bytes;
size_t nbytes;
if (!parse_bytes(&bytes, &nbytes, arg, size))
return false;

if (nbytes < 1 || nbytes > 2) {
free(bytes);
return false;
}

*length = bytes[0];
if (!(*result = malloc(sizeof(uint8_t) * (*length))))
OUT_OF_MEMORY()

memset(*result, nbytes == 2 ? bytes[1] : 0, *length);
free(bytes);
return true;
}

/*
Parse data encoded in a line into an ASMData object.

On success, return NULL and store the instruction in *data_ptr. On failure,
@@ -160,6 +185,9 @@ static ErrorInfo* parse_data(
if (IS_DIRECTIVE(line, DIR_BYTE)) {
directive = DIR_BYTE;
parser = parse_bytes;
} else if (IS_DIRECTIVE(line, DIR_SPACE)) {
directive = DIR_SPACE;
parser = parse_space;
} else if (IS_DIRECTIVE(line, DIR_ASCII)) {
directive = DIR_ASCII;
} else if (IS_DIRECTIVE(line, DIR_ASCIZ)) {
@@ -205,6 +233,9 @@ static ErrorInfo* parse_instruction(
// TODO
DEBUG("parse_instruction(): %.*s", (int) line->length, line->data)

// SYNTAX NOTES:
// see http://clrhome.org/table/ and http://www.z80.info/z80undoc.htm

// return error_info_create(line, ET_PARSER, ED_PARSE_SYNTAX);

ASMInstruction *inst = malloc(sizeof(ASMInstruction));


Loading…
Cancel
Save