add stuff
This commit is contained in:
parent
9eb3922ad6
commit
ffd29ea5af
@ -52,6 +52,8 @@ jnz r/i16
|
|||||||
cmp r/i16
|
cmp r/i16
|
||||||
mov r/i16/m r
|
mov r/i16/m r
|
||||||
mov r r/i16/m
|
mov r r/i16/m
|
||||||
|
movb m r
|
||||||
|
movb r m
|
||||||
in r/i16
|
in r/i16
|
||||||
out r/i16 r/i16
|
out r/i16 r/i16
|
||||||
call r/i16
|
call r/i16
|
||||||
|
50
asm/hash.c
Normal file
50
asm/hash.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include "hash.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
Hasher* hasher_new()
|
||||||
|
{
|
||||||
|
Hasher* hasher = malloc(sizeof(Hasher));
|
||||||
|
*hasher = (Hasher) {};
|
||||||
|
return hasher;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t hasher_finish(Hasher hasher)
|
||||||
|
{
|
||||||
|
return hasher.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hasher_free(Hasher* hasher)
|
||||||
|
{
|
||||||
|
free(hasher);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hasher_hash_u64(Hasher* hasher, uint64_t v)
|
||||||
|
{
|
||||||
|
uint64_t value = hasher->state + v;
|
||||||
|
|
||||||
|
value ^= value >> 33;
|
||||||
|
value *= 0xff51afd7ed558ccdL;
|
||||||
|
value ^= value >> 33;
|
||||||
|
value *= 0xc4ceb9fe1a85ec53L;
|
||||||
|
value ^= value >> 33;
|
||||||
|
|
||||||
|
hasher->state = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hasher_hash_u8(Hasher* hasher, uint8_t v)
|
||||||
|
{
|
||||||
|
hasher_hash_u64(hasher, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void string_hash(Hasher* hasher, const char* str)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; str[i] != '\0'; ++i) {
|
||||||
|
hasher_hash_u8(hasher, (uint8_t)str[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void size_hash(Hasher* hasher, size_t value)
|
||||||
|
{
|
||||||
|
hasher_hash_u64(hasher, (uint64_t)value);
|
||||||
|
}
|
18
asm/hash.h
Normal file
18
asm/hash.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef HASH_H
|
||||||
|
#define HASH_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64_t state;
|
||||||
|
} Hasher;
|
||||||
|
|
||||||
|
uint64_t hasher_finish(Hasher hasher);
|
||||||
|
void hasher_hash_u64(Hasher* hasher, uint64_t v);
|
||||||
|
void hasher_hash_u8(Hasher* hasher, uint8_t v);
|
||||||
|
|
||||||
|
void string_hash(Hasher* hasher, const char* str);
|
||||||
|
void size_hash(Hasher* hasher, size_t value);
|
||||||
|
|
||||||
|
#endif
|
66
asm/main.c
66
asm/main.c
@ -1,6 +1,10 @@
|
|||||||
|
#include "hash.h"
|
||||||
|
#include "map.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
|
#include "vec.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -12,6 +16,15 @@ typedef struct {
|
|||||||
|
|
||||||
static int parse_args(Args* args, int argc, char** argv);
|
static int parse_args(Args* args, int argc, char** argv);
|
||||||
|
|
||||||
|
DEFINE_VEC(LineVec, line_vec, PLine*)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t line_idx;
|
||||||
|
char* ident;
|
||||||
|
} Label;
|
||||||
|
|
||||||
|
DEFINE_STRINGMAP(LabelMap, label_map, Label)
|
||||||
|
|
||||||
static char* read_text_file(const char* filename);
|
static char* read_text_file(const char* filename);
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
@ -21,6 +34,8 @@ int main(int argc, char** argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LabelMap labels = {};
|
||||||
|
|
||||||
char* text = read_text_file(args.input_file);
|
char* text = read_text_file(args.input_file);
|
||||||
if (!text) {
|
if (!text) {
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -28,9 +43,10 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
Parser* parser = parser_new(args.input_file, text);
|
Parser* parser = parser_new(args.input_file, text);
|
||||||
|
|
||||||
size_t lines_capacity = 1024;
|
LineVec lines;
|
||||||
PLine** lines = malloc(sizeof(PLine*) * lines_capacity);
|
line_vec_construct(&lines);
|
||||||
size_t lines_size = 0;
|
|
||||||
|
Label* super_label = nullptr;
|
||||||
|
|
||||||
while (!parser_done(parser)) {
|
while (!parser_done(parser)) {
|
||||||
if (parser_next_is_const(parser)) {
|
if (parser_next_is_const(parser)) {
|
||||||
@ -41,10 +57,52 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
PLabel* label;
|
PLabel* label;
|
||||||
while ((label = parser_parse_label(parser)) != nullptr) { }
|
while ((label = parser_parse_label(parser)) != nullptr) {
|
||||||
|
if (label->local) {
|
||||||
|
char* ident = calloc(1,
|
||||||
|
strlen(super_label->ident) + strlen(label->ident) + 2);
|
||||||
|
strcat(ident, super_label->ident);
|
||||||
|
strcat(ident, ".");
|
||||||
|
strcat(ident, label->ident);
|
||||||
|
|
||||||
|
label_map_set(&labels,
|
||||||
|
ident,
|
||||||
|
(Label) {
|
||||||
|
.line_idx = lines.size + 1,
|
||||||
|
.ident = ident,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
label_map_set(&labels,
|
||||||
|
label->ident,
|
||||||
|
(Label) {
|
||||||
|
.line_idx = lines.size + 1,
|
||||||
|
.ident = strdup(label->ident),
|
||||||
|
});
|
||||||
|
super_label = label_map_at(&labels, label->ident);
|
||||||
|
}
|
||||||
|
plabel_free(label);
|
||||||
|
}
|
||||||
|
PLine* line = parser_parse_line(parser);
|
||||||
|
|
||||||
|
line_vec_push(&lines, line);
|
||||||
|
|
||||||
|
printf("ident = '%s'\n", line->ident);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parser_free(parser);
|
||||||
|
free(text);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < lines.size; ++i) {
|
||||||
|
pline_free(lines.data[i]);
|
||||||
|
}
|
||||||
|
line_vec_destroy(&lines);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < labels.entries.size; ++i) {
|
||||||
|
free(labels.entries.data[i].value.ident);
|
||||||
|
}
|
||||||
|
label_map_destroy(&labels);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
106
asm/map.h
Normal file
106
asm/map.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#ifndef MAP
|
||||||
|
#define MAP
|
||||||
|
|
||||||
|
#include "hash.h"
|
||||||
|
#include "vec.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define DEFINE_MAP(TYPENAME, FN_PREFIX, KEY_TYPE, VALUE_TYPE, HASH_FN) \
|
||||||
|
\
|
||||||
|
typedef struct { \
|
||||||
|
uint64_t keyhash; \
|
||||||
|
VALUE_TYPE value; \
|
||||||
|
} _internal_TYPENAME##Entry; \
|
||||||
|
\
|
||||||
|
DEFINE_VEC(_internal_TYPENAME##EntryVec, \
|
||||||
|
_internal_##FN_PREFIX##_entryvec, \
|
||||||
|
_internal_TYPENAME##Entry) \
|
||||||
|
\
|
||||||
|
typedef struct { \
|
||||||
|
_internal_TYPENAME##EntryVec entries; \
|
||||||
|
} TYPENAME; \
|
||||||
|
\
|
||||||
|
[[maybe_unused]] static void FN_PREFIX##_construct(TYPENAME* map) \
|
||||||
|
{ \
|
||||||
|
*map = (TYPENAME) {}; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
[[maybe_unused]] static void FN_PREFIX##_destroy(TYPENAME* map) \
|
||||||
|
{ \
|
||||||
|
_internal_##FN_PREFIX##_entryvec_destroy(&map->entries); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
[[maybe_unused]] static bool _internal_##FN_PREFIX##_find_entry_idx( \
|
||||||
|
TYPENAME* map, \
|
||||||
|
size_t* target_idx, \
|
||||||
|
uint64_t keyhash, \
|
||||||
|
size_t begin, \
|
||||||
|
size_t end) \
|
||||||
|
{ \
|
||||||
|
if (begin == end) { \
|
||||||
|
*target_idx = begin; \
|
||||||
|
return false; \
|
||||||
|
} \
|
||||||
|
size_t middle_idx = (end - begin) / 2 + begin; \
|
||||||
|
_internal_TYPENAME##Entry* middle_entry \
|
||||||
|
= &map->entries.data[middle_idx]; \
|
||||||
|
if (keyhash < middle_entry->keyhash) { \
|
||||||
|
return _internal_##FN_PREFIX##_find_entry_idx( \
|
||||||
|
map, target_idx, keyhash, begin, middle_idx); \
|
||||||
|
} else if (keyhash > middle_entry->keyhash) { \
|
||||||
|
return _internal_##FN_PREFIX##_find_entry_idx( \
|
||||||
|
map, target_idx, keyhash, middle_idx + 1, end); \
|
||||||
|
} else { \
|
||||||
|
*target_idx = middle_idx; \
|
||||||
|
return true; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
[[maybe_unused]] static void FN_PREFIX##_set( \
|
||||||
|
TYPENAME* map, KEY_TYPE key, VALUE_TYPE value) \
|
||||||
|
{ \
|
||||||
|
Hasher hasher = {}; \
|
||||||
|
HASH_FN(&hasher, key); \
|
||||||
|
uint64_t keyhash = hasher_finish(hasher); \
|
||||||
|
\
|
||||||
|
size_t target_idx; \
|
||||||
|
bool exists = _internal_##FN_PREFIX##_find_entry_idx( \
|
||||||
|
map, &target_idx, keyhash, 0, map->entries.size); \
|
||||||
|
\
|
||||||
|
if (exists) { \
|
||||||
|
map->entries.data[target_idx].value = value; \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
_internal_##FN_PREFIX##_entryvec_push( \
|
||||||
|
&map->entries, (_internal_TYPENAME##Entry) {}); \
|
||||||
|
for (size_t i = map->entries.size - 1; i > target_idx; --i) { \
|
||||||
|
map->entries.data[i] = map->entries.data[i - 1]; \
|
||||||
|
} \
|
||||||
|
map->entries.data[target_idx] \
|
||||||
|
= (_internal_TYPENAME##Entry) { keyhash, value }; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
[[maybe_unused]] static VALUE_TYPE* FN_PREFIX##_at( \
|
||||||
|
TYPENAME* map, KEY_TYPE key) \
|
||||||
|
{ \
|
||||||
|
Hasher hasher = {}; \
|
||||||
|
HASH_FN(&hasher, key); \
|
||||||
|
uint64_t keyhash = hasher_finish(hasher); \
|
||||||
|
\
|
||||||
|
size_t target_idx; \
|
||||||
|
bool exists = _internal_##FN_PREFIX##_find_entry_idx( \
|
||||||
|
map, &target_idx, keyhash, 0, map->entries.size); \
|
||||||
|
\
|
||||||
|
if (!exists) { \
|
||||||
|
return nullptr; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return &map->entries.data[target_idx].value; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define DEFINE_STRINGMAP(TYPENAME, FN_PREFIX, VALUE_TYPE) \
|
||||||
|
DEFINE_MAP(TYPENAME, FN_PREFIX, const char*, VALUE_TYPE, string_hash)
|
||||||
|
|
||||||
|
#endif
|
28
asm/parse.c
28
asm/parse.c
@ -812,3 +812,31 @@ void pexpr_free(PExpr* expr)
|
|||||||
}
|
}
|
||||||
free(expr);
|
free(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pconst_free(PConst* stmt)
|
||||||
|
{
|
||||||
|
free(stmt->ident);
|
||||||
|
pexpr_free(stmt->value);
|
||||||
|
free(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pinclude_free(PInclude* stmt)
|
||||||
|
{
|
||||||
|
free(stmt->filename);
|
||||||
|
free(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void plabel_free(PLabel* stmt)
|
||||||
|
{
|
||||||
|
free(stmt->ident);
|
||||||
|
free(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pline_free(PLine* stmt)
|
||||||
|
{
|
||||||
|
free(stmt->ident);
|
||||||
|
for (size_t i = 0; i < stmt->ops_size; ++i) {
|
||||||
|
pexpr_free(stmt->ops[i]);
|
||||||
|
}
|
||||||
|
free(stmt);
|
||||||
|
}
|
||||||
|
@ -50,17 +50,23 @@ typedef struct {
|
|||||||
PExpr* value;
|
PExpr* value;
|
||||||
} PConst;
|
} PConst;
|
||||||
|
|
||||||
|
void pconst_free(PConst* stmt);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Loc loc;
|
Loc loc;
|
||||||
char* filename;
|
char* filename;
|
||||||
} PInclude;
|
} PInclude;
|
||||||
|
|
||||||
|
void pinclude_free(PInclude* stmt);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Loc loc;
|
Loc loc;
|
||||||
char* ident;
|
char* ident;
|
||||||
bool local;
|
bool local;
|
||||||
} PLabel;
|
} PLabel;
|
||||||
|
|
||||||
|
void plabel_free(PLabel* stmt);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Loc loc;
|
Loc loc;
|
||||||
char* ident;
|
char* ident;
|
||||||
@ -68,6 +74,8 @@ typedef struct {
|
|||||||
size_t ops_size;
|
size_t ops_size;
|
||||||
} PLine;
|
} PLine;
|
||||||
|
|
||||||
|
void pline_free(PLine* stmt);
|
||||||
|
|
||||||
typedef struct Parser Parser;
|
typedef struct Parser Parser;
|
||||||
|
|
||||||
Parser* parser_new(const char* filename, const char* text);
|
Parser* parser_new(const char* filename, const char* text);
|
||||||
|
40
asm/vec.h
Normal file
40
asm/vec.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef VEC_H
|
||||||
|
#define VEC_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define DEFINE_VEC(TYPENAME, FN_PREFIX, TYPE) \
|
||||||
|
\
|
||||||
|
typedef struct { \
|
||||||
|
TYPE* data; \
|
||||||
|
size_t size; \
|
||||||
|
size_t capacity; \
|
||||||
|
} TYPENAME; \
|
||||||
|
\
|
||||||
|
[[maybe_unused]] static void FN_PREFIX##_construct(TYPENAME* vec) \
|
||||||
|
{ \
|
||||||
|
*vec = (TYPENAME) {}; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
[[maybe_unused]] static void FN_PREFIX##_destroy(TYPENAME* vec) \
|
||||||
|
{ \
|
||||||
|
if (vec->data) { \
|
||||||
|
free(vec->data); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
[[maybe_unused]] static void FN_PREFIX##_push(TYPENAME* vec, TYPE value) \
|
||||||
|
{ \
|
||||||
|
if (!vec->data || vec->capacity == 0) { \
|
||||||
|
vec->capacity = 4; \
|
||||||
|
vec->data = malloc(sizeof(TYPE) * vec->capacity); \
|
||||||
|
} else if (vec->size + 1 >= vec->capacity) { \
|
||||||
|
vec->capacity *= 2; \
|
||||||
|
vec->data = realloc(vec->data, sizeof(TYPE) * vec->capacity); \
|
||||||
|
} \
|
||||||
|
vec->data[vec->size] = value; \
|
||||||
|
vec->size += 1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user