--- a/c99.y
+++ b/c99.y
@@ -11,11 +11,18 @@
 
 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
 
-%union { char str[128]; }
+%union { char str[4096]; }
 
 %start translation_unit
 
 %{
+#include <string.h>
+#include <stdio.h>
+
+// get tail of a string
+#define TAIL(str) (&str[strlen(str)-1])
+
+
 /* fifo to store expression strings */
 #define NULL 0
 
@@ -45,12 +52,17 @@
 
 // pop one entry from the specific category
 char *fifo_pop(fifo_entry_t type);
+char *lifo_pop(fifo_entry_t type);
 
 // tag all from category "all" to new type
 // this way we can collect new stuff in all and push
 // it to the correct section when we know more about
 // our context
 void fifo_tag(fifo_entry_t type);
+
+// map c datatype to iec (standard and userdefined)
+char *maptype(char *ctype);
+
 
 %}
 
@@ -232,12 +244,13 @@
 
 declaration
 	: declaration_specifiers ';'
-	{ sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
+	{ sprintf($<str>$, "%s %s\n",$<str>1, $<str>2); }
 	| declaration_specifiers init_declarator_list ';'
 	{
 		char *p;
 		while( (p=fifo_pop(decl_all)) != NULL)
 		{
+//			sprintf(TAIL($<str>$), p, $<str>1);
 			printf(p, $<str>1);
 			strcpy($<str>$, "");
 		}
@@ -249,8 +262,14 @@
 	| storage_class_specifier declaration_specifiers
 	{ sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
 	| type_specifier
+	{
+		sprintf($<str>$, "%s",maptype($<str>1));
+	}
 	| type_specifier declaration_specifiers
-	{ sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
+	{
+		sprintf($<str>$, "%s %s",$<str>1, $<str>2);
+		sprintf($<str>$, "%s",maptype($<str>$));
+	}
 	| type_qualifier
 	| type_qualifier declaration_specifiers
 	{ sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
@@ -370,14 +389,14 @@
 declarator
 	: pointer direct_declarator
 	{ 
-		sprintf($<str>$, "%s POINTER TO %%s;\n",$<str>2);
+		sprintf($<str>$, "%s: POINTER TO %%s;\n",$<str>2);
 		fifo_push(decl_all, $<str>$);
 	}
 	| direct_declarator
 	{
 		if (strlen($<str>1) > 0)
 		{
-			sprintf($<str>$, "%s %%s;\n",$<str>1);
+			sprintf($<str>$, "%s: %%s;\n",$<str>1);
 			fifo_push(decl_all, $<str>$);
 		}
 	}
@@ -391,7 +410,19 @@
 	| direct_declarator '[' type_qualifier_list ']'
 	| direct_declarator '[' assignment_expression ']'
 	{
-		sprintf($<str>$, "%s: ARRAY[ %s ] OF %%s;\n",$<str>1, $<str>3);
+		if (strlen($<str>1) > 0)
+		{
+			sprintf($<str>$, "%s: ARRAY[0..(%s-1)] OF %%s;\n",$<str>1, $<str>3);
+		}
+		else
+		{
+			char *p;
+			p = lifo_pop(decl_all);
+			sprintf($<str>1, ",0..(%s-1)] OF %%s;\n",$<str>3);
+			strcpy($<str>$, p);
+			strcpy(strchr($<str>$, ']'), $<str>1);
+//			sprintf($<str>$, p, $<str>1);
+		}
 		fifo_push(decl_all, $<str>$);
 		strcpy($<str>$, "");
 	}
@@ -401,11 +432,23 @@
 	| direct_declarator '[' '*' ']'
 	| direct_declarator '[' ']'
 	| direct_declarator '(' parameter_type_list ')'
-	{ sprintf($<str>$, "FUNCTION %s:",$<str>1); }
+	{
+		sprintf($<str>$, "FUNCTION %s:",$<str>1);
+		fifo_push(decl_all, $<str>$);
+		strcpy($<str>$, "");
+	}
 	| direct_declarator '(' identifier_list ')'
-	{ sprintf($<str>$, "FUNCTION %s:",$<str>1); }
+	{
+		sprintf($<str>$, "FUNCTION %s:",$<str>1);
+		fifo_push(decl_all, $<str>$);
+		strcpy($<str>$, "");
+	}
 	| direct_declarator '(' ')'
-	{ sprintf($<str>$, "FUNCTION %s:",$<str>1); }
+	{
+		sprintf($<str>$, "FUNCTION %s:",$<str>1);
+		fifo_push(decl_all, $<str>$);
+		strcpy($<str>$, "");
+	}
 	;
 
 pointer
@@ -512,23 +555,25 @@
 compound_statement
 	: '{' '}'
 	| '{' block_item_list '}'
+	{ sprintf($<str>$, "%s",$<str>2); }
 	;
 
 block_item_list
 	: block_item
 	| block_item_list block_item
+	{ sprintf($<str>$, "%s %s",$<str>1, $<str>2); }
 	;
 
 block_item
 	: declaration
 	| statement
-	{ printf("%s\n",$<str>1); }
+//	{ printf("%s\n",$<str>1); }
 	;
 
 expression_statement
 	: ';'
 	| expression ';'
-	{ sprintf($<str>$, "%s;",$<str>1); }
+	{ sprintf($<str>$, "%s;\n",$<str>1); }
 	;
 
 selection_statement
@@ -566,13 +611,19 @@
 
 function_definition
 	: declaration_specifiers declarator declaration_list compound_statement
+	{
+		printf("%s %s %s %s", $<str>1, $<str>2, $<str>3, $<str>4);
+	}
 	| declaration_specifiers declarator compound_statement
+	{
+		printf("%s %s %s", $<str>1, $<str>2, $<str>3);
+	}
 	;
 
 declaration_list
 	: declaration
 	| declaration_list declaration
-	{ printf("| %s %s\n",$<str>1, $<str>2); }
+	{ sprintf($<str>$, "%s %s\n",$<str>1, $<str>2); }
 	;
 
 
@@ -605,6 +656,16 @@
 		strcpy(s_fifos[type].fifo[s_fifos[type].write], psz);
 		s_fifos[type].write = fifow_next;
 	}
+}
+
+char *lifo_pop(fifo_entry_t type)
+{
+	if (s_fifos[type].read != s_fifos[type].write)
+	{
+		s_fifos[type].write = (s_fifos[type].write + FIFO_SIZE - 1) % FIFO_SIZE;
+		return s_fifos[type].fifo[s_fifos[type].write];
+	}
+	return NULL;
 }
 
 char *fifo_pop(fifo_entry_t type)
@@ -625,3 +686,30 @@
 	while ((p = fifo_pop(decl_all)) != NULL)
 		fifo_push(type, p);
 }
+
+char *maptype(char *ctype)
+{
+	if (!strcmp(ctype, "char"))
+		return "BYTE";
+	if (!strcmp(ctype, "short"))
+		return "INT";
+	if (!strcmp(ctype, "int"))
+		return "DINT";
+	if (!strcmp(ctype, "long"))
+		return "DINT";
+	if (!strcmp(ctype, "long DINT"))
+		return "LINT";
+
+	if (!strcmp(ctype, "unsigned BYTE"))
+		return "UBYTE";
+	if (!strcmp(ctype, "unsigned INT"))
+		return "UINT";
+	if (!strcmp(ctype, "unsigned DINT"))
+		return "UDINT";
+	if (!strcmp(ctype, "unsigned DINT"))
+		return "UDINT";
+	if (!strcmp(ctype, "unsigned LINT"))
+		return "ULINT";
+	printf("maptype: not found: %s\n", ctype);
+	return ctype;
+}