summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2021-08-19 18:49:25 +0000
committerAndreas Baumann <mail@andreasbaumann.cc>2021-08-19 18:49:25 +0000
commitb74b9a8ef45137611e53e779d932d9d222e8eb35 (patch)
tree2db882d77318369a0fe63cfbb7ed5a83e4f5c11e
parent3f553969451504d020ff90644edd348ffbcd2907 (diff)
downloadcompilertests-b74b9a8ef45137611e53e779d932d9d222e8eb35.tar.gz
compilertests-b74b9a8ef45137611e53e779d932d9d222e8eb35.tar.bz2
added symbol struct and memory management
-rw-r--r--miniany/REQUIREMENTS5
-rw-r--r--miniany/c4.c9
-rw-r--r--miniany/cc.c24
-rw-r--r--miniany/libc-freestanding.c174
4 files changed, 201 insertions, 11 deletions
diff --git a/miniany/REQUIREMENTS b/miniany/REQUIREMENTS
index 9274af4..9cf810d 100644
--- a/miniany/REQUIREMENTS
+++ b/miniany/REQUIREMENTS
@@ -44,4 +44,7 @@ not implementing:
a constant expression. It also seperates syntactical stuff like '['
from logical stuff like 'declaration of array size' and 'derefencing
a pointer'.
-
+- void * allowing to omit (char *) from and to for instance structs
+ in dynamic memory management
+- typedefs are just syntactic sugar, I use them mostly for 'struct T' -> 'T'
+
diff --git a/miniany/c4.c b/miniany/c4.c
index a20715c..f9f3f98 100644
--- a/miniany/c4.c
+++ b/miniany/c4.c
@@ -63,7 +63,7 @@ enum {
// opcodes
enum { LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PSH ,
OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,
- OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU,IALP,SCMP,EXIT };
+ OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU,IALP,SCMP,SDUP,EXIT };
// types
enum { CHAR, INT, PTR = 256, PTR2 = 512 };
@@ -82,7 +82,7 @@ void next()
while (le < e) {
printf("%8.4s", &"LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PSH ,"
"OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,"
- "OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU,IALP,SCMP,EXIT,"[*++le * 5]);
+ "OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU,IALP,SCMP,SDUP,EXIT,"[*++le * 5]);
if (*le <= ADJ) printf(" %d\n", *++le); else printf("\n");
}
}
@@ -488,7 +488,7 @@ int main(int argc, char **argv)
p = "break case char default else enum if int return sizeof do struct switch while "
"EOF EXIT_SUCCESS EXIT_FAILURE NULL "
- "open read close printf malloc free memset memcmp getchar putstring putnl putchar putint isspace isdigit isalnum isalpha strcmp exit void main";
+ "open read close printf malloc free memset memcmp getchar putstring putnl putchar putint isspace isdigit isalnum isalpha strcmp strdup exit void main";
i = Break; while (i <= While) { next(); id->tk = i++; } // add keywords to symbol table
// add library constants
next(); id->class = Num; id->type = INT; id->val = -1;
@@ -681,7 +681,7 @@ int main(int argc, char **argv)
printf("%d> %.4s", cycle,
&"LEA ,IMM ,JMP ,JSR ,BZ ,BNZ ,ENT ,ADJ ,LEV ,LI ,LC ,SI ,SC ,PSH ,"
"OR ,XOR ,AND ,EQ ,NE ,LT ,GT ,LE ,GE ,SHL ,SHR ,ADD ,SUB ,MUL ,DIV ,MOD ,"
- "OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU.IALP,SCMP,EXIT,"[i * 5]);
+ "OPEN,READ,CLOS,PRTF,MALC,FREE,MSET,MCMP,GETC,PUTS,PUTN,PUTC,PUTI,ISPC,IDGT,IANU.IALP,SCMP,SDUP,EXIT,"[i * 5]);
if (i <= ADJ) printf(" %d\n", *pc); else printf("\n");
}
switch (i) {
@@ -735,6 +735,7 @@ int main(int argc, char **argv)
case IANU: t = sp + pc[1]; a = isalnum( (int)t[-1]); break;
case IALP: t = sp + pc[1]; a = isalpha( (int)t[-1]); break;
case SCMP: t = sp + pc[1]; a = strcmp((char *)t[-1], (char *)t[-2]); break;
+ case SDUP: t = sp + pc[1]; a = (int)strdup((char *)t[-1]); break;
case EXIT: printf("exit(%d) cycle = %d\n", *sp, cycle); return *sp;
default: printf("unknown instruction = %d! cycle = %d\n", i, cycle); return -1;
}
diff --git a/miniany/cc.c b/miniany/cc.c
index cf4f880..d77def0 100644
--- a/miniany/cc.c
+++ b/miniany/cc.c
@@ -278,25 +278,39 @@ void parseExpression( )
}
}
-/*
struct Symbol {
char *name;
+ struct Symbol *next;
};
struct Symbol *symbol;
-*/
-void newSymbol( char *s )
+struct Symbol *createSymbol( char *s )
{
+ struct Symbol *sym;
+ sym = (struct Symbol *)malloc( sizeof ( struct Symbol ) );
+ sym->name = strdup( s );
+ sym->next = NULL;
+
+ return sym;
+}
+
+void freeSymbol( struct Symbol *sym )
+{
+ free( sym->name );
+ free( (char *)sym );
}
void parseDeclaration( )
{
+ struct Symbol *sym;
+
expect( S_INT, "int" );
expect( S_IDENT, "identifier" );
putstring( "Adding glob: " ); putstring( ident ); putnl( );
- newSymbol( ident );
+ sym = createSymbol( ident );
+ freeSymbol( sym );
expect( S_SEMICOLON, ";" );
}
@@ -325,7 +339,7 @@ int main( int argc, char **argv )
row = 1;
pushback = 0;
DEBUG_SCANNER = 1;
- /* symbol = NULL; */
+ symbol = NULL;
ident = "12345678901234567890";
token = getToken( );
diff --git a/miniany/libc-freestanding.c b/miniany/libc-freestanding.c
index fdec615..2bcdf0c 100644
--- a/miniany/libc-freestanding.c
+++ b/miniany/libc-freestanding.c
@@ -62,7 +62,8 @@ enum {
enum {
SYSCALL_EXIT = 1,
SYSCALL_READ = 3,
- SYSCALL_WRITE = 4
+ SYSCALL_WRITE = 4,
+ SYSCALL_BRK = 45
};
enum {
@@ -71,6 +72,10 @@ enum {
int errno;
+enum {
+ ENOMEM = 1
+};
+
int syscall1( int id, int arg0 )
{
int retval;
@@ -245,3 +250,170 @@ void exit( int status )
{
syscall1( SYSCALL_EXIT, status );
}
+
+int system_brk( char *addr )
+{
+ return syscall1( SYSCALL_BRK, (int )addr );
+}
+
+char *current_brk = 0;
+
+int brk( char *addr )
+{
+ char *p;
+
+ p = (char *)system_brk( addr );
+ if( (int)p < 0 ) {
+ return -1;
+ }
+ if( p == current_brk ) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ current_brk = p;
+
+ return 0;
+}
+
+char *sbrk( int inc )
+{
+ char *old_brk;
+ int res;
+
+ if( current_brk == 0 ) {
+ brk( 0 );
+ }
+
+ if( inc == 0 ) {
+ return current_brk;
+ }
+
+ old_brk = current_brk;
+
+ res = brk( ( char *)current_brk + inc );
+ if( res == -1 ) {
+ return (char *)-1;
+ }
+
+ return old_brk;
+}
+
+struct mem_header {
+ int size;
+ int used;
+ struct mem_header *next;
+ int align;
+};
+
+struct mem_header *mem_head = NULL;
+struct mem_header *mem_tail = NULL;
+char *initial_brk = NULL;
+
+int mem_align( int n )
+{
+ return ( n + sizeof( int ) - 1 ) & ~( sizeof( int ) - 1 );
+}
+
+char *malloc( int size )
+{
+ int total_size;
+ char *ptr;
+ struct mem_header *header;
+
+ total_size = mem_align( sizeof( struct mem_header ) + size );
+
+ header = mem_head;
+ while( header != NULL ) {
+ if( !header->used && header->size >= size ) {
+ header->used = 1;
+ return (char *)( header + 1 );
+ }
+ header = header->next;
+ }
+
+ if( initial_brk == NULL ) {
+ initial_brk = sbrk( 0 );
+ }
+
+ ptr = sbrk( total_size );
+ if( ptr == (char *)-1 ) {
+ return NULL;
+ }
+
+ header = (struct mem_header *)ptr;
+ header->size = size;
+ header->used = 1;
+ header->next = NULL;
+
+ if( mem_head == NULL ) {
+ mem_head = header;
+ }
+ if( mem_tail != NULL ) {
+ mem_tail->next = header;
+ }
+ mem_tail = header;
+
+ return (char *)( header + 1 );
+}
+
+void free( char *ptr )
+{
+ struct mem_header *header, *tmp;
+ char *actual_brk;
+
+ if( ptr == NULL ) {
+ putstring( "warning: freeing a NULL pointer\n" );
+ return;
+ }
+
+ header = (struct mem_header *)ptr - 1;
+ if( !header->used ) {
+ putstring( "warning: double free in linked list detected\n" );
+ return;
+ }
+ header->used = 0;
+
+ actual_brk = sbrk( 0 );
+ if( (char *)ptr + header->size == actual_brk ) {
+ tmp = mem_head;
+ while( tmp != NULL ) {
+ if( tmp->next == mem_tail ) {
+ tmp->next = NULL;
+ mem_tail = tmp;
+ }
+ tmp = tmp->next;
+ }
+ if( mem_head == mem_tail ) {
+ mem_head = NULL;
+ mem_tail = NULL;
+ }
+ sbrk( - header->size - sizeof( struct mem_header ) );
+ }
+}
+
+char *memcpy( char *d, char *s, int len )
+{
+ char *p;
+ char *q;
+
+ p = s;
+ q = d;
+ while( len-- ) {
+ *q = *p;
+ q++;
+ p++;
+ }
+
+ return d;
+}
+
+char *strdup( char *s )
+{
+ char *c;
+
+ c = malloc( strlen( s ) + 1 );
+ memcpy( c, s, strlen( s ) + 1 );
+
+ return c;
+}