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> #include <string.h>


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


#define DIR_INCLUDE ".include" #define DIR_INCLUDE ".include"


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


#define IS_LOCAL_DIRECTIVE(line) \ #define IS_LOCAL_DIRECTIVE(line) \
(IS_DIRECTIVE(line, DIR_ORIGIN) || IS_DIRECTIVE(line, DIR_BLOCK) || \ (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) \ #define DIRECTIVE_OFFSET(line, d) \
(DIRECTIVE_HAS_ARG(line, d) ? strlen(d) : 0) (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; uint8_t *bytes = NULL;
size_t nbytes = 0; size_t nbytes = 0;


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


uint32_t temp; 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() OUT_OF_MEMORY()
bytes[nbytes - 1] = temp; bytes[nbytes - 1] = temp;


if (arg++ == end)
if (arg < end - 1 && *arg == ',' && *(arg + 1) == ' ')
arg += 2;
else if (arg++ >= end)
break; 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. Parse data encoded in a line into an ASMData object.


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


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


Loading…
Cancel
Save