format
This commit is contained in:
parent
4dfd6f2fc0
commit
757fb71b9a
|
@ -56,8 +56,7 @@ const char *TYPE_STR[] = {
|
||||||
|
|
||||||
const size_t NARGS = sizeof(ARGS) / sizeof(ARGS[0]);
|
const size_t NARGS = sizeof(ARGS) / sizeof(ARGS[0]);
|
||||||
|
|
||||||
static
|
static ArgMeta arg_meta(char arg) {
|
||||||
ArgMeta arg_meta(char arg) {
|
|
||||||
for (size_t ii = 0; ii < NARGS; ii += 1) {
|
for (size_t ii = 0; ii < NARGS; ii += 1) {
|
||||||
ArgMeta meta = ARGS[ii];
|
ArgMeta meta = ARGS[ii];
|
||||||
if (meta.chr == arg) {
|
if (meta.chr == arg) {
|
||||||
|
|
|
@ -6,8 +6,7 @@ typedef struct ByteVec_s {
|
||||||
size_t len;
|
size_t len;
|
||||||
} ByteVec;
|
} ByteVec;
|
||||||
|
|
||||||
static
|
static AsmError ensure_push(ByteVec *vec, size_t el_size, size_t extra) {
|
||||||
AsmError ensure_push(ByteVec *vec, size_t el_size, size_t extra) {
|
|
||||||
if (vec->len + extra < vec->len) {
|
if (vec->len + extra < vec->len) {
|
||||||
return ErrOutOfMemory;
|
return ErrOutOfMemory;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,7 @@ typedef struct InstHtNode_s {
|
||||||
} InstHtNode;
|
} InstHtNode;
|
||||||
typedef InstHtNode *InstHt;
|
typedef InstHtNode *InstHt;
|
||||||
|
|
||||||
static
|
static uint32_t inst_hash(const char *s, size_t len) {
|
||||||
uint32_t inst_hash(const char *s, size_t len) {
|
|
||||||
uint32_t hash = 0;
|
uint32_t hash = 0;
|
||||||
uint32_t mul = 75;
|
uint32_t mul = 75;
|
||||||
for (size_t ii = 0; ii < len; ii += 1) {
|
for (size_t ii = 0; ii < len; ii += 1) {
|
||||||
|
@ -16,8 +15,7 @@ uint32_t inst_hash(const char *s, size_t len) {
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static InstHt build_lookup(void) {
|
||||||
InstHt build_lookup(void) {
|
|
||||||
const size_t size = 256;
|
const size_t size = 256;
|
||||||
InstHt table = (InstHt)malloc(size * sizeof(InstHtNode));
|
InstHt table = (InstHt)malloc(size * sizeof(InstHtNode));
|
||||||
if (table == NULL) {
|
if (table == NULL) {
|
||||||
|
@ -42,8 +40,7 @@ InstHt build_lookup(void) {
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static size_t inst_lookup(InstHt ht, const char *s, size_t len) {
|
||||||
size_t inst_lookup(InstHt ht, const char *s, size_t len) {
|
|
||||||
uint32_t hash = inst_hash(s, len);
|
uint32_t hash = inst_hash(s, len);
|
||||||
uint8_t *node = (uint8_t *)&ht[(size_t)(hash & 0xff)];
|
uint8_t *node = (uint8_t *)&ht[(size_t)(hash & 0xff)];
|
||||||
for (size_t ii = 0; ii < 2; ii += 1) {
|
for (size_t ii = 0; ii < 2; ii += 1) {
|
||||||
|
|
117
src/hbas.c
117
src/hbas.c
|
@ -20,8 +20,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -42,8 +42,7 @@ SOFTWARE.
|
||||||
|
|
||||||
// Print space-separated hex dump of each byte, 16 bytes per line.
|
// Print space-separated hex dump of each byte, 16 bytes per line.
|
||||||
// Can be reversed with `xxd -p -r`.
|
// Can be reversed with `xxd -p -r`.
|
||||||
static
|
static void hex_dump(char *data, size_t len) {
|
||||||
void hex_dump(char *data, size_t len) {
|
|
||||||
char buf[48];
|
char buf[48];
|
||||||
const char *alphabet = "0123456789abcdef";
|
const char *alphabet = "0123456789abcdef";
|
||||||
for (size_t ii = 0; ii < len; ii += 1) {
|
for (size_t ii = 0; ii < len; ii += 1) {
|
||||||
|
@ -61,8 +60,7 @@ void hex_dump(char *data, size_t len) {
|
||||||
|
|
||||||
#define MIN_SIZE 4096
|
#define MIN_SIZE 4096
|
||||||
|
|
||||||
static
|
static int slurp(FILE *fd, ByteVec *out) {
|
||||||
int slurp(FILE *fd, ByteVec *out) {
|
|
||||||
ByteVec rv = {malloc(MIN_SIZE), MIN_SIZE, 0};
|
ByteVec rv = {malloc(MIN_SIZE), MIN_SIZE, 0};
|
||||||
size_t bread = 1;
|
size_t bread = 1;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -109,8 +107,7 @@ typedef struct LabelVec_s {
|
||||||
size_t len;
|
size_t len;
|
||||||
} LabelVec;
|
} LabelVec;
|
||||||
|
|
||||||
static
|
static size_t label_lookup(LabelVec *labels, char *name, size_t len) {
|
||||||
size_t label_lookup(LabelVec *labels, char *name, size_t len) {
|
|
||||||
size_t nlabels = labels->len;
|
size_t nlabels = labels->len;
|
||||||
Label *buf = labels->buf;
|
Label *buf = labels->buf;
|
||||||
for (size_t ii = 0; ii < nlabels; ii += 1) {
|
for (size_t ii = 0; ii < nlabels; ii += 1) {
|
||||||
|
@ -122,8 +119,7 @@ size_t label_lookup(LabelVec *labels, char *name, size_t len) {
|
||||||
return INVALID;
|
return INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static bool check_valid_int(uint64_t val, size_t size, uint8_t sign) {
|
||||||
bool check_valid_int(uint64_t val, size_t size, uint8_t sign) {
|
|
||||||
// All 64-bit values are considered valid.
|
// All 64-bit values are considered valid.
|
||||||
if (size == 8) {
|
if (size == 8) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -162,8 +158,8 @@ bool check_valid_int(uint64_t val, size_t size, uint8_t sign) {
|
||||||
// safety: assumes the buffer has enough place for specified integer size.
|
// safety: assumes the buffer has enough place for specified integer size.
|
||||||
// `sign` is a bitset, where bit `1` indicates that value accepts a signed int,
|
// `sign` is a bitset, where bit `1` indicates that value accepts a signed int,
|
||||||
// and bit `2` indicates that value accepts an unsigned int.
|
// and bit `2` indicates that value accepts an unsigned int.
|
||||||
static
|
static AsmError push_int_le(char *buf, uint64_t val, size_t size,
|
||||||
AsmError push_int_le(char *buf, uint64_t val, size_t size, uint8_t sign) {
|
uint8_t sign) {
|
||||||
if (!check_valid_int(val, size, sign)) {
|
if (!check_valid_int(val, size, sign)) {
|
||||||
return ErrImmediateOverflow;
|
return ErrImmediateOverflow;
|
||||||
}
|
}
|
||||||
|
@ -186,37 +182,37 @@ AsmError push_string(char *buf, char *input, size_t len) {
|
||||||
pos += 1;
|
pos += 1;
|
||||||
chr = input[pos];
|
chr = input[pos];
|
||||||
switch (chr) {
|
switch (chr) {
|
||||||
case '\\':
|
case '\\':
|
||||||
chr = '\\';
|
chr = '\\';
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
chr = '"';
|
chr = '"';
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
chr = '\r';
|
chr = '\r';
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
chr = '\n';
|
chr = '\n';
|
||||||
break;
|
break;
|
||||||
case '0':
|
case '0':
|
||||||
chr = '\0';
|
chr = '\0';
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
chr = '\t';
|
chr = '\t';
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
if (pos + 2 >= len) {
|
if (pos + 2 >= len) {
|
||||||
return ErrDanglingEscape;
|
return ErrDanglingEscape;
|
||||||
}
|
}
|
||||||
char high = get_hex(input[pos + 1]);
|
char high = get_hex(input[pos + 1]);
|
||||||
char low = get_hex(input[pos + 2]);
|
char low = get_hex(input[pos + 2]);
|
||||||
if (high > 15 || low > 15) {
|
if (high > 15 || low > 15) {
|
||||||
return ErrStringBadHex;
|
return ErrStringBadHex;
|
||||||
}
|
}
|
||||||
chr = high << 4 | low;
|
chr = high << 4 | low;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ErrBadStringEscape;
|
return ErrBadStringEscape;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buf[ndata] = chr;
|
buf[ndata] = chr;
|
||||||
|
@ -225,9 +221,8 @@ AsmError push_string(char *buf, char *input, size_t len) {
|
||||||
return ErrOk;
|
return ErrOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static AsmError assemble_instr(InstHt ht, char *input, size_t len, Token *tok,
|
||||||
AsmError assemble_instr(InstHt ht, char *input, size_t len, Token *tok,
|
ByteVec *rv, HoleVec *holes) {
|
||||||
ByteVec *rv, HoleVec *holes) {
|
|
||||||
const InstDesc *inst;
|
const InstDesc *inst;
|
||||||
const char *type_str;
|
const char *type_str;
|
||||||
size_t nargs;
|
size_t nargs;
|
||||||
|
@ -327,8 +322,8 @@ AsmError assemble_instr(InstHt ht, char *input, size_t len, Token *tok,
|
||||||
return ErrOk;
|
return ErrOk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static AsmError push_data(char *input, size_t len, ByteVec *out, Token *tok,
|
||||||
AsmError push_data(char *input, size_t len, ByteVec *out, Token *tok, size_t word_size) {
|
size_t word_size) {
|
||||||
while (1) {
|
while (1) {
|
||||||
*tok = token(input, len, tok->start + tok->len);
|
*tok = token(input, len, tok->start + tok->len);
|
||||||
if (tok->kind == TokNumber) {
|
if (tok->kind == TokNumber) {
|
||||||
|
@ -375,20 +370,20 @@ AsmError assemble_directive(char *input, size_t len, ByteVec *out, Token *tok) {
|
||||||
if (byte0 == 'd') {
|
if (byte0 == 'd') {
|
||||||
size_t word_size;
|
size_t word_size;
|
||||||
switch (byte1) {
|
switch (byte1) {
|
||||||
case 'b':
|
case 'b':
|
||||||
word_size = 1;
|
word_size = 1;
|
||||||
break;
|
break;
|
||||||
case 'w':
|
case 'w':
|
||||||
word_size = 2;
|
word_size = 2;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
word_size = 4;
|
word_size = 4;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
word_size = 8;
|
word_size = 8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ErrInvalidDirective;
|
return ErrInvalidDirective;
|
||||||
}
|
}
|
||||||
return push_data(input, len, out, tok, word_size);
|
return push_data(input, len, out, tok, word_size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
static
|
static int parse_register(char *name, size_t len) {
|
||||||
int parse_register(char *name, size_t len) {
|
|
||||||
if (name[0] != 'r') {
|
if (name[0] != 'r') {
|
||||||
return 256; // Register name should start with 'r'
|
return 256; // Register name should start with 'r'
|
||||||
}
|
}
|
||||||
|
|
61
src/token.c
61
src/token.c
|
@ -19,8 +19,7 @@ typedef struct Token_s {
|
||||||
uint64_t num;
|
uint64_t num;
|
||||||
} Token;
|
} Token;
|
||||||
|
|
||||||
static
|
static Token token_ident(char *input, size_t len, size_t pos) {
|
||||||
Token token_ident(char *input, size_t len, size_t pos) {
|
|
||||||
size_t start = pos;
|
size_t start = pos;
|
||||||
while (pos < len) {
|
while (pos < len) {
|
||||||
char chr = input[pos];
|
char chr = input[pos];
|
||||||
|
@ -35,8 +34,7 @@ Token token_ident(char *input, size_t len, size_t pos) {
|
||||||
return (Token){TokIdent, start, pos - start, 0};
|
return (Token){TokIdent, start, pos - start, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static Token token_number(char *input, size_t len, size_t pos) {
|
||||||
Token token_number(char *input, size_t len, size_t pos) {
|
|
||||||
char *ptr = &input[pos];
|
char *ptr = &input[pos];
|
||||||
char next = '\0';
|
char next = '\0';
|
||||||
size_t start = pos;
|
size_t start = pos;
|
||||||
|
@ -112,8 +110,7 @@ Token token_number(char *input, size_t len, size_t pos) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static char get_hex(char chr) {
|
||||||
char get_hex(char chr) {
|
|
||||||
char chru = chr & ~0x20;
|
char chru = chr & ~0x20;
|
||||||
if (chr >= '0' && chr <= '9') {
|
if (chr >= '0' && chr <= '9') {
|
||||||
return chr - '0';
|
return chr - '0';
|
||||||
|
@ -124,8 +121,7 @@ char get_hex(char chr) {
|
||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static Token token_string(char *input, size_t len, size_t pos) {
|
||||||
Token token_string(char *input, size_t len, size_t pos) {
|
|
||||||
size_t start = pos;
|
size_t start = pos;
|
||||||
size_t ndata = 0;
|
size_t ndata = 0;
|
||||||
for (pos += 1; pos < len; pos += 1) {
|
for (pos += 1; pos < len; pos += 1) {
|
||||||
|
@ -133,32 +129,38 @@ Token token_string(char *input, size_t len, size_t pos) {
|
||||||
return (Token){TokString, start, pos + 1 - start, ndata};
|
return (Token){TokString, start, pos + 1 - start, ndata};
|
||||||
}
|
}
|
||||||
if (input[pos] == '\n' || input[pos] == '\r') {
|
if (input[pos] == '\n' || input[pos] == '\r') {
|
||||||
return (Token){TokInvalid, start, pos + 1 - start, ErrStringNewLine};
|
return (Token){TokInvalid, start, pos + 1 - start,
|
||||||
|
ErrStringNewLine};
|
||||||
}
|
}
|
||||||
if (input[pos] == '\\') {
|
if (input[pos] == '\\') {
|
||||||
if (pos + 1 >= len) {
|
if (pos + 1 >= len) {
|
||||||
return (Token){TokInvalid, start, pos - start, ErrDanglingEscape};
|
return (Token){TokInvalid, start, pos - start,
|
||||||
|
ErrDanglingEscape};
|
||||||
}
|
}
|
||||||
pos += 1;
|
pos += 1;
|
||||||
switch (input[pos]) {
|
switch (input[pos]) {
|
||||||
case '\\':
|
case '\\':
|
||||||
case '"':
|
case '"':
|
||||||
case 'r':
|
case 'r':
|
||||||
case 'n':
|
case 'n':
|
||||||
case '0':
|
case '0':
|
||||||
case 't':
|
case 't':
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
if (pos + 2 >= len) {
|
if (pos + 2 >= len) {
|
||||||
return (Token){TokInvalid, start, pos - start, ErrDanglingEscape};
|
return (Token){TokInvalid, start, pos - start,
|
||||||
}
|
ErrDanglingEscape};
|
||||||
if (get_hex(input[pos + 1]) > 15 || get_hex(input[pos + 2]) > 15) {
|
}
|
||||||
return (Token){TokInvalid, start, pos - start, ErrStringBadHex};
|
if (get_hex(input[pos + 1]) > 15 ||
|
||||||
}
|
get_hex(input[pos + 2]) > 15) {
|
||||||
pos += 2;
|
return (Token){TokInvalid, start, pos - start,
|
||||||
break;
|
ErrStringBadHex};
|
||||||
default:
|
}
|
||||||
return (Token){TokInvalid, start, pos - start, ErrBadStringEscape};
|
pos += 2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (Token){TokInvalid, start, pos - start,
|
||||||
|
ErrBadStringEscape};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ndata += 1;
|
ndata += 1;
|
||||||
|
@ -166,8 +168,7 @@ Token token_string(char *input, size_t len, size_t pos) {
|
||||||
return (Token){TokString, start, pos - start, ndata};
|
return (Token){TokString, start, pos - start, ndata};
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static Token token(char *input, size_t len, size_t pos) {
|
||||||
Token token(char *input, size_t len, size_t pos) {
|
|
||||||
char chr, chru;
|
char chr, chru;
|
||||||
char *ptr = &input[pos];
|
char *ptr = &input[pos];
|
||||||
while (pos < len && (input[pos] == ' ' || input[pos] == '\t')) {
|
while (pos < len && (input[pos] == ' ' || input[pos] == '\t')) {
|
||||||
|
|
Loading…
Reference in a new issue