diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2017-01-01 19:31:12 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2017-01-01 19:31:12 +0100 |
commit | 69fe7b182a1eedfb75c611f7dd35fa60200426f4 (patch) | |
tree | 329a0c6cc9b06c23d8782ece09f0f7dfa9b16b13 /minilib | |
download | compilertests-69fe7b182a1eedfb75c611f7dd35fa60200426f4.tar.gz compilertests-69fe7b182a1eedfb75c611f7dd35fa60200426f4.tar.bz2 |
initial checkin
Diffstat (limited to 'minilib')
-rw-r--r-- | minilib/README | 5 | ||||
-rw-r--r-- | minilib/arena.c | 31 | ||||
-rw-r--r-- | minilib/arena.h | 13 | ||||
-rw-r--r-- | minilib/ctype.c | 21 | ||||
-rw-r--r-- | minilib/ctype.h | 6 | ||||
-rw-r--r-- | minilib/hash.c | 109 | ||||
-rw-r--r-- | minilib/hash.h | 26 | ||||
-rw-r--r-- | minilib/io.c | 81 | ||||
-rw-r--r-- | minilib/io.h | 6 | ||||
-rw-r--r-- | minilib/minilib.c | 11 | ||||
-rw-r--r-- | minilib/minilib.h | 3 | ||||
-rw-r--r-- | minilib/stddef.h | 9 | ||||
-rw-r--r-- | minilib/stdlib.c | 11 | ||||
-rw-r--r-- | minilib/stdlib.h | 3 | ||||
-rw-r--r-- | minilib/string.c | 87 | ||||
-rw-r--r-- | minilib/string.h | 8 | ||||
-rw-r--r-- | minilib/utils.c | 30 | ||||
-rw-r--r-- | minilib/utils.h | 4 |
18 files changed, 464 insertions, 0 deletions
diff --git a/minilib/README b/minilib/README new file mode 100644 index 0000000..614b106 --- /dev/null +++ b/minilib/README @@ -0,0 +1,5 @@ +Design +------ + +This abstraction layer, mappable to C runtime on the host environment +and to a minios implementation later. diff --git a/minilib/arena.c b/minilib/arena.c new file mode 100644 index 0000000..7a938e0 --- /dev/null +++ b/minilib/arena.c @@ -0,0 +1,31 @@ +#include "arena.h" +#include "minilib.h" +#include "io.h" + +static char p[ARENA_SIZE]; +static char *ptr = p; + +void *allocate( int size ) +{ + char *m; + + if( ptr - p + size < ARENA_SIZE ) { + m = ptr; + ptr = ptr + size; + return m; + } + + print( "OUT OF MEMORY" ); + + halt( ); +} + +void deallocate( void **p ) +{ + if( *p == 0 ) { + print( "DEALLOCATING ALREADY FREED POINTER" ); + halt( ); + } + + *p = 0; +} diff --git a/minilib/arena.h b/minilib/arena.h new file mode 100644 index 0000000..3f486e4 --- /dev/null +++ b/minilib/arena.h @@ -0,0 +1,13 @@ +#pragma once + +/* TODO: simplest possible arena implementation, a fixed memory size + * and allocated memory is returned in sequence from the pool. + * deallocation does nothing but invalidating the pointer + */ + +enum { + ARENA_SIZE = 65535 +}; + +extern void *allocate( int size ); +extern void deallocate( void **p ); diff --git a/minilib/ctype.c b/minilib/ctype.c new file mode 100644 index 0000000..98e351b --- /dev/null +++ b/minilib/ctype.c @@ -0,0 +1,21 @@ +#include "ctype.h" + +int isalpha( int c ) +{ + return (unsigned int)( c | 32 ) - 'a' < 26; +} + +int isdigit( int c ) +{ + return (unsigned int)c - '0' < 10; +} + +int isalnum( int c ) +{ + return isalpha( c ) || isdigit( c ); +} + +int isspace( int c ) +{ + return c == ' ' || c == '\t' || c == '\r' || c == '\n'; +} diff --git a/minilib/ctype.h b/minilib/ctype.h new file mode 100644 index 0000000..f19fbce --- /dev/null +++ b/minilib/ctype.h @@ -0,0 +1,6 @@ +#pragma once + +extern int isalpha( int c ); +extern int isdigit( int c ); +extern int isalnum( int c ); +extern int isspace( int c ); diff --git a/minilib/hash.c b/minilib/hash.c new file mode 100644 index 0000000..4d32305 --- /dev/null +++ b/minilib/hash.c @@ -0,0 +1,109 @@ +#include "hash.h" +#include "arena.h" +#include "string.h" +#include "stddef.h" + +void inthash_init( intHashTable *ht, int size ) +{ + ht->table = (intHashEntry **)allocate( size * sizeof( intHashEntry ) ); + memset( ht->table, 0, size * sizeof( intHashEntry ) ); + ht->capacity = size; + ht->size = 0; +} + +void inthash_done( intHashTable *ht ) +{ + deallocate( (void **)&ht->table ); +} + +static int hash_string( char *s ) +{ + int h = 5381; + int c; + + while( ( c = *s++ ) ) { + h = ((h << 5) + h) + c; + } + + return h; +} + +void inthash_set( intHashTable *ht, char *key, int value ) +{ + int h; + intHashEntry *entry; + intHashEntry *new; + + h = hash_string( key ) % ht->capacity; + entry = ht->table[h]; + + while( entry != NULL && strcmp( key, entry->key ) > 0 ) { + entry = entry->next; + } + + if( entry != NULL && strcmp( key, entry->key ) == 0 ) { + entry->value = value; + } else { + new = (intHashEntry *)allocate( sizeof( intHashEntry ) ); + new->key = key; + new->value = value; + new->next = ht->table[h]; + ht->table[h] = new; + } +} + +int inthash_get( intHashTable *ht, char *key) +{ + int h; + intHashEntry *entry; + + h = hash_string( key ) % ht->capacity; + entry = ht->table[h]; + + while( entry != NULL && strcmp( key, entry->key ) != 0 ) { + entry = entry->next; + } + + if( entry != NULL && strcmp( key, entry->key ) == 0 ) { + return entry->value; + } + + return -1; +} + +intHashEntry *inthash_getfirst( intHashTable *ht, intHashIterator *it ) +{ + it->pos = 0; + it->entry = ht->table[0]; + it->ht = ht; + + while( it->entry == NULL ) { + it->pos++; + if( it->pos > ht->capacity ) { + return NULL; + } + it->entry = ht->table[it->pos]; + } + + return it->entry; +} + +intHashEntry *inthash_getnext( intHashIterator *it ) +{ + if( it->entry != NULL ) { + it->entry = it->entry->next; + if( it->entry != NULL ) { + return it->entry; + } + } + + do { + it->pos++; + if( it->pos > it->ht->capacity ) { + return NULL; + } + it->entry = it->ht->table[it->pos]; + } while( it->entry == NULL ); + + return it->entry; +} diff --git a/minilib/hash.h b/minilib/hash.h new file mode 100644 index 0000000..4be951c --- /dev/null +++ b/minilib/hash.h @@ -0,0 +1,26 @@ +#pragma once + +typedef struct intHashEntry { + char *key; + int value; + struct intHashEntry *next; +} intHashEntry; + +typedef struct intHashTable { + int capacity; + int size; + intHashEntry **table; +} intHashTable; + +typedef struct intHashIterator { + int pos; + intHashEntry *entry; + intHashTable *ht; +} intHashIterator; + +extern void inthash_init( intHashTable *ht, int size ); +extern void inthash_done( intHashTable *ht ); +extern void inthash_set( intHashTable *ht, char *key, int value ); +extern int inthash_get( intHashTable *ht, char *key ); +extern intHashEntry *inthash_getfirst( intHashTable *ht, intHashIterator *it ); +extern intHashEntry *inthash_getnext( intHashIterator *it ); diff --git a/minilib/io.c b/minilib/io.c new file mode 100644 index 0000000..006f5df --- /dev/null +++ b/minilib/io.c @@ -0,0 +1,81 @@ +#include "io.h" +#include "minilib.h" +#include "arena.h" +#include "string.h" + +/* TODO: this is the Linux hosted environment */ +#define _GNU_SOURCE +#include <unistd.h> +#include <sys/syscall.h> + +#include <stdio.h> + +void print( char *s ) +{ + syscall( __NR_write, STDOUT_FILENO, s, strlen( s ) ); + syscall( __NR_write, STDOUT_FILENO, "\n", 1 ); +} + +int readfile( char *filename, char *s, int size ) +{ + /* TODO: this is host-only */ + FILE *f = fopen( filename, "rb" ); + + if( !f ) { + return -1; + } + + fread( s, size, 1, f ); + + fclose( f ); + + return 0; +} + +int writefile( char *filename, char *s, int size ) +{ + /* TODO: this is host-only */ + FILE *f = fopen( filename, "wb" ); + + if( !f ) { + return -1; + } + + fwrite( s, size, 1, f ); + + fclose( f ); + + return 0; +} + +char *readallfile( char *filename ) +{ + /* TODO: this is host-only */ + FILE *f = fopen( filename, "rb" ); + int size; + char *buf; + + if( !f ) { + return NULL; + } + + fseek( f, 0, SEEK_END ); + size = ftell( f ); + rewind( f ); + + if( size == 0 ) { + return NULL; + } + + buf = allocate( size + 1 ); + + if( fread( buf, size, 1, f ) != 1 ) { + return NULL; + } + + buf[size] = '\0'; + + fclose( f ); + + return buf; +} diff --git a/minilib/io.h b/minilib/io.h new file mode 100644 index 0000000..b2c8033 --- /dev/null +++ b/minilib/io.h @@ -0,0 +1,6 @@ +#pragma once + +extern void print( char *s ); +extern int readfile( char *filename, char *s, int size ); +extern int writefile( char *filename, char *s, int size ); +extern char *readallfile( char *filename ); diff --git a/minilib/minilib.c b/minilib/minilib.c new file mode 100644 index 0000000..54f7f9d --- /dev/null +++ b/minilib/minilib.c @@ -0,0 +1,11 @@ +#include "minilib.h" +#include "io.h" +#include "stdlib.h" + +void halt( void ) +{ + print( "SYSTEM HALT" ); + + /* TODO: this is host-only */ + exit( 1 ); +} diff --git a/minilib/minilib.h b/minilib/minilib.h new file mode 100644 index 0000000..2e9dd3d --- /dev/null +++ b/minilib/minilib.h @@ -0,0 +1,3 @@ +#pragma once + +extern void halt( void ); diff --git a/minilib/stddef.h b/minilib/stddef.h new file mode 100644 index 0000000..a288c39 --- /dev/null +++ b/minilib/stddef.h @@ -0,0 +1,9 @@ +#pragma once + +#define NULL ( (void *) 0) + +/* TODO: drawn in by using some functions from the host */ +#define size_t int + +/* TODO: drawn in by using some functions from the host */ +#define wchar_t int diff --git a/minilib/stdlib.c b/minilib/stdlib.c new file mode 100644 index 0000000..96b9b58 --- /dev/null +++ b/minilib/stdlib.c @@ -0,0 +1,11 @@ +#include "stdlib.h" + +/* TODO: this is the Linux hosted environment */ +#define _GNU_SOURCE +#include <unistd.h> +#include <sys/syscall.h> + +void exit( int status ) +{ + syscall( __NR_exit, status ); +} diff --git a/minilib/stdlib.h b/minilib/stdlib.h new file mode 100644 index 0000000..4300381 --- /dev/null +++ b/minilib/stdlib.h @@ -0,0 +1,3 @@ +#pragma once + +extern void exit( int status ); diff --git a/minilib/string.c b/minilib/string.c new file mode 100644 index 0000000..a3606d8 --- /dev/null +++ b/minilib/string.c @@ -0,0 +1,87 @@ +#include "string.h" +#include "arena.h" + +char *memset( void *s, int c, int n ) +{ + char *p; + + p = s; + while( n > 0 ) { + *p = c; + p++; + n--; + } + + return s; +} + +char *strcat( char *d, char *s ) +{ + char *p; + + for( p = d; *p != '\0'; p++ ); + + while( *s ) { + *p = *s; + p++; + s++; + } + + *p = '\0'; + + return d; +} + +char *strcpy( char *d, char *s ) +{ + char *p; + + p = d; + while( *s ) { + *p = *s; + p++; + s++; + } + + *p = '\0'; + + return d; +} + +int strlen( char *s ) +{ + char *p; + int len; + + p = s; + len = 0; + while( *p ) { + p++; + len++; + } + + return len; +} + +int strcmp( char *s1, char *s2 ) +{ + while( *s1 && *s2 && *s1 == *s2 ) { + s1++; + s2++; + } + + return *s1 - *s2; +} + +char *strdup( char *s ) +{ + char *p; + + p = (char *)allocate( strlen( s ) + 1 ); + if( !p ) { + return 0; + } + strcpy( p, s ); + + return p; +} diff --git a/minilib/string.h b/minilib/string.h new file mode 100644 index 0000000..60cd785 --- /dev/null +++ b/minilib/string.h @@ -0,0 +1,8 @@ +#pragma once + +extern char *memset( void *p, int c, int n ); +extern char *strcat( char *d, char *s ); +extern char *strcpy( char *d, char *s ); +extern int strlen( char *s ); +extern int strcmp( char *s1, char *s2 ); +extern char *strdup( char *s ); diff --git a/minilib/utils.c b/minilib/utils.c new file mode 100644 index 0000000..eea0758 --- /dev/null +++ b/minilib/utils.c @@ -0,0 +1,30 @@ +#include "utils.h" + +static char hexdigits[17] = "0123456789abcdef"; + +void strtohex( char *p, int len, char *s ) +{ + while( len > 0 ) { + char c = *p; + + *s = hexdigits[( c >> 4 ) & 0xf]; + s++; + *s = hexdigits[c & 0xf]; + s++; + + p++; + len--; + } + + *s = '\0'; +} + +void inttohex( int i, char *s ) +{ + *s = hexdigits[( i >> 4 ) & 0xf]; + s++; + *s = hexdigits[i & 0xf]; + s++; + + *s = '\0'; +} diff --git a/minilib/utils.h b/minilib/utils.h new file mode 100644 index 0000000..1ab26de --- /dev/null +++ b/minilib/utils.h @@ -0,0 +1,4 @@ +#pragma once + +extern void strtohex( char *p, int len, char *s ); +extern void inttohex( int i, char *s ); |