summaryrefslogtreecommitdiff
path: root/minilib
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-01-01 19:31:12 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2017-01-01 19:31:12 +0100
commit69fe7b182a1eedfb75c611f7dd35fa60200426f4 (patch)
tree329a0c6cc9b06c23d8782ece09f0f7dfa9b16b13 /minilib
downloadcompilertests-69fe7b182a1eedfb75c611f7dd35fa60200426f4.tar.gz
compilertests-69fe7b182a1eedfb75c611f7dd35fa60200426f4.tar.bz2
initial checkin
Diffstat (limited to 'minilib')
-rw-r--r--minilib/README5
-rw-r--r--minilib/arena.c31
-rw-r--r--minilib/arena.h13
-rw-r--r--minilib/ctype.c21
-rw-r--r--minilib/ctype.h6
-rw-r--r--minilib/hash.c109
-rw-r--r--minilib/hash.h26
-rw-r--r--minilib/io.c81
-rw-r--r--minilib/io.h6
-rw-r--r--minilib/minilib.c11
-rw-r--r--minilib/minilib.h3
-rw-r--r--minilib/stddef.h9
-rw-r--r--minilib/stdlib.c11
-rw-r--r--minilib/stdlib.h3
-rw-r--r--minilib/string.c87
-rw-r--r--minilib/string.h8
-rw-r--r--minilib/utils.c30
-rw-r--r--minilib/utils.h4
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 );