From adbe0006f50c1f4a5c1d7444ab44baf29ee64b1e Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Wed, 28 Nov 2018 19:41:09 +0100 Subject: [PATCH] asm: adding symbol table datastructure. --- src/as/symtab.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++ src/as/symtab.h | 37 +++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 src/as/symtab.c create mode 100644 src/as/symtab.h diff --git a/src/as/symtab.c b/src/as/symtab.c new file mode 100644 index 0000000..9ac9867 --- /dev/null +++ b/src/as/symtab.c @@ -0,0 +1,121 @@ +/* symtab.c + * + * Copyright (C) 2018 Henrik Hautakoski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include +#include "symtab.h" + +// TODO: Right now, the symtab is implemented as a simple dynamic growing array. +// This is fine for now, but for lookup speed. A hashtable is more efficient. + +// How much memory that should be allocated each time. +// Note: this should be defined as number of `struct symbol` objects, not bytes. +#define BLOCK_SIZE 32 + +// Helper macro to calculate number of bytes the table need. +#define __M_SIZE(t) \ + ((t)->size * sizeof(struct symbol)) + +struct symbol { + // The label associated with the location. + char label[SYMTAB_LABEL_MAXLEN]; + + // Location (program adress) + uint16_t loc; +}; + +// Symbol table structure. +struct symtab { + // Array of symbols. + struct symbol *data; + + // Number of symbols in the array. + size_t num; + + // Total number of symbols the array can hold. + size_t size; +}; + +symtab_t* symtab_init() { + + struct symtab *table = malloc(sizeof(struct symtab)); + + table->num = 0; + table->size = BLOCK_SIZE; + table->data = malloc(__M_SIZE(table)); + + return table; +} + +void symtab_free(symtab_t *table) { + + if (!table) + return; + + if (table->data) + free(table->data); + + memset(table, 0, sizeof(struct symtab)); + free(table); +} + +int symtab_set(symtab_t *table, const char *label, uint16_t loc) { + + // Check if it exist first. + int index = symtab_get(table, label, NULL); + + // Entry did not exists. Insert + if (index < 0) { + struct symbol *sym; + + // We have one more. + table->num += 1; + + // Make sure we resize the memory. + if (table->num > table->size) { + table->size += BLOCK_SIZE; + table->data = realloc(table->data, __M_SIZE(table)); + } + + // insert the symbol at the end. + sym = table->data + (table->num - 1); + strncpy(sym->label, label, SYMTAB_LABEL_MAXLEN); + sym->loc = loc; + + return 0; + } + + // Could not insert. return as error. + return -1; +} + +int symtab_get(symtab_t *table, const char *label, uint16_t *loc) { + + // Linear search here for simplicity. + for(size_t i = 0; i < table->num; i++) { + struct symbol *sym = table->data + i; + + if (!strncmp(sym->label, label, SYMTAB_LABEL_MAXLEN)) { + + if (loc) *loc = sym->loc; + return i; + } + } + return -1; +} diff --git a/src/as/symtab.h b/src/as/symtab.h new file mode 100644 index 0000000..cd1cd68 --- /dev/null +++ b/src/as/symtab.h @@ -0,0 +1,37 @@ +/* symtab.h + * + * Copyright (C) 2018 Henrik Hautakoski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#ifndef ASM_SYMTAB_H +#define ASM_SYMTAB_H + +#include + +#define SYMTAB_LABEL_MAXLEN 32 + +typedef struct symtab symtab_t; + +symtab_t* symtab_init(); + +void symtab_free(symtab_t *table); + +int symtab_set(symtab_t *table, const char *label, uint16_t loc); + +int symtab_get(symtab_t *table, const char *label, uint16_t *loc); + +#endif /* ASM_SYMTAB_H */