WONKY



LOG | FILES | OVERVIEW


#ifndef WONKY_PRINT
#define WONKY_PRINT WONKY_PRINT
#include <print.h>

void print_token(struct wonky_stream *out,struct token *token)
{
	wonky_fprintf(out,"[TOKEN %WSl: ",token->delta->location);
	print_token_text(out,token);
	wonky_fprintf(out,"]\n");
}

char print_tokens_of_program(struct wonky_stream *out,char **base_source_names)
{

	struct Source_File *src;
	struct Program *program;
	struct Token_Pointer *ptr;
	struct Preprocessing_Translation_Unit *hold_unit;

	char *this_directory[]={"./",NULL};
	_Bool ret;

	wonky_assert(base_source_names!=NULL);

	if(*base_source_names==NULL)
	{
		return 0;
	}

	ret=0;

	program=get_program();

	do
	{
		src=get_source_file_from_string(*base_source_names,gstrnlen(*base_source_names,1000),program);

		hold_unit=lex(src,program);
		if(program->errors->size>0 || hold_unit==NULL)
		{
			ret=1;
			print_errors(out,program->errors);
			break;
		}

		wonky_fprintf(out,"\nTOKENS OF %s {\n",base_source_names[0]);

		ptr=get_token_ptr(hold_unit,program);
		print_tokens(out,ptr);
		wonky_fprintf(out,"\n} END OF TOKENS\n");
		++program->current_translation_unit_number;
	}while(*(++base_source_names));
	

	return ret;
}
void print_tokens(struct wonky_stream *out,struct Token_Pointer *ptr)
{
	while(token_ptr_has_remaining_tokens(ptr))
	{
		print_token(out,token_ptr_get_token_under_pointer(ptr));
	}
}

void print_ast_enum(struct wonky_stream *out,enum AST_Type op)
{
	static const char *map[AST_TYPE_END]
		=
		{
			[OP_COMMA]=",",
			[OP_ADDITION]="+",
			[OP_SUBTRACTION]="-",
			[OP_MUL]="*",
			[OP_DIV]="/",
			[OP_REMAINDER]="%",
			[OP_COND]="CONDITIONAL",
			[OP_FUNCTION]="FUNCTION_CALL",
			[OP_ASSIGN]="=",
			[OP_ADD_ASSIGN]="+=",
			[OP_SUBTRACT_ASSIGN]="-=",
			[OP_MULTIPLY_ASSIGN]="*=",
			[OP_REMAINDER_ASSIGN]="%=",
			[OP_DIV_ASSIGN]="/=",
			[OP_SHIFT_LEFT_ASSIGN]="<<=",
			[OP_SHIFT_RIGHT_ASSIGN]=">>=",
			[OP_AND_ASSIGN]="&=",
			[OP_XOR_ASSIGN]="^=",
			[OP_PIPE_ASSIGN]="|=",
			[OP_NOP]="NOP",
			[OP_LOGICAL_OR]="||",
			[OP_LOGICAL_AND]="&&",
			[OP_LOGICAL_NOT]="!",
			[OP_BITWISE_OR]="|",
			[OP_BITWISE_AND]="&",
			[OP_BITWISE_XOR]="^",
			[OP_BITWISE_NOT]="~",
			[OP_ADDR_OF]="&",
			[OP_DEREFERENCE]="*",
			[OP_MEMBER_TROUGH_PTR]="->",
			[OP_MEMBER]=".",
			[OP_ARR_SUBSCRIPT]="ARR_SUBSCRIPT",
			[OP_POSTFIX_INC]="++",
			[OP_POSTFIX_DEC]="--",
			[OP_PREFIX_INC]="++",
			[OP_PREFIX_DEC]="--",
			[OP_UNARY_PLUS]="+",
			[OP_UNARY_MINUS]="-",
			[OP_CAST]="CAST",
			[OP_SIZEOF]="sizeof",
			[OP_SHIFT_LEFT]="<<",
			[OP_SHIFT_RIGHT]=">>",
			[OP_LESS_EQ]="<=",
			[OP_GREATER_EQ]=">=",
			[OP_LESS]="<",
			[OP_GREATER]=">",
			[OP_EQUAL]="==",
			[OP_NOT_EQUAL]="!=",
			[OP_CONSTANT]="CONSTANT",
			[OP_STRING_LITERAL]="STRING_LITERAL",
			[ST_COMPOUND]="COMPOUND_STATEMENT",
			[ST_EXPRESSION]="EXPRESSION",
			[ST_SWITCH]="switch",
			[ST_IF]="if",
			[ST_WHILE]="while",
			[ST_DO_WHILE]="do_while",
			[ST_GOTO]="goto",
			[ST_LABEL]="LABEL",
			[ST_CASE]="case",
			[ST_DEFAULT]="default",
			[ST_CONTINUE]="continue",
			[ST_BREAK]="break",
			[ST_RETURN]="return",
			[ST_FOR]="for",
			[ST_FUNCTION_DEFINITION]="FUNCTION_DEFINITION",
			[TRANSLATION_UNIT]="TRANSLATION_UNIT",
		};
	wonky_assert(is_valid_ast_enum(op));
	/*following is not an assert because a lot of enums are not printed :-(*/
	if(map[op]==NULL)
	{

	}else
	{
		wonky_fprintf(out,"%s",map[op]);
	}
}

void print_error_tree(struct wonky_stream *out,struct AST_Error *error,short indentation)
{
	wonky_fprintf(out,"ERROR-(%WA)",error);
}
void print_designator_expression_tree(struct wonky_stream *out,struct AST_Designator *designator,short indentation)
{
	print_indentation(out,indentation);
	print_id(out,designator->id);
}
void print_binary_expression_tree(struct wonky_stream *out,struct AST_Binary_Expression *bin)
{
	if(bin->type==OP_ARR_SUBSCRIPT)
		wonky_fprintf(out,"%WA[%WA]",bin->left,bin->right);
	else
		wonky_fprintf(out,"(%WA%WAE%WA)",bin->left,bin->type,bin->right);
}
void print_conditional_expression_tree(struct wonky_stream *out,struct AST_Conditional_Expression *cond)
{
	wonky_fprintf(out,"(%WA?%WA:%WA)",cond->left,cond->center,cond->right);
}
void print_function_expression_tree(struct wonky_stream *out,struct AST_Function_Expression *function_call)
{
	size_t i;
	print_ast(out,(struct AST*)function_call->id,0);	
	wonky_fprintf(out,"(");

	if(function_call->number_of_arguments>0)
	{
		for(i=0;i<function_call->number_of_arguments;++i)
		{
			print_ast(out,(struct AST*)function_call->arg_list[i],0);
			if(i!=function_call->number_of_arguments-1)
				wonky_fprintf(out,",");
		}
	}
	wonky_fprintf(out,")");
}
void print_unary_expression_tree(struct wonky_stream *out,struct AST_Unary_Expression *unary_expression)
{
	if(unary_expression->type==OP_CAST)
	{
		wonky_fprintf(out,"(");
		print_expression_value_type(out,unary_expression->value);
		wonky_fprintf(out,")(");

		print_ast(out,(struct AST*)unary_expression->operand,0);
		wonky_fprintf(out,")");
	}else
	{
		wonky_fprintf(out,"%WAE%WA");
	}
}
void print_labeled_statement_tree(struct wonky_stream *out,struct AST_Labeled_Statement *lab,short indentation)
{
	print_indentation(out,indentation);
	if(lab->type!=ST_LABEL)
		print_ast_enum(out,lab->type);
	if(lab->label!=NULL)
		print_denoted(out,(struct Denoted*)lab->label);
}
void print_compound_statement_tree(struct wonky_stream *out,struct AST_Compound_Statement *comp,short indentation)
{
	struct Queue_Node *it;
	print_indentation(out,indentation);	
	wonky_fprintf(out,"{\n");
	
	for(it=comp->components->first;it!=NULL;it=it->prev)
		wonky_fprintf(out,"%Wi%WA\n",indentation+1,it->data);

	print_indentation(out,indentation);	
	wonky_fprintf(out,"}\n");
}
void print_if_statement_tree(struct wonky_stream *out,struct AST_If_Statement *ifs,short indentation)
{
	print_indentation(out,indentation);	
	wonky_fprintf(out,"if(%WA)\n%Wi%WA",ifs->condition,indentation,ifs->body_statement);
	if(ifs->else_statement!=NULL)
		wonky_fprintf(out,"\nelse\n%Wi%WA",indentation,ifs->else_statement);
	
}
void print_switch_statement_tree(struct wonky_stream *out,struct AST_Switch_Statement *swi,short indentation)
{
	print_indentation(out,indentation);	
	wonky_fprintf(out,"switch(%WA)\n%Wi%WA",swi->condition,indentation,swi->body_statement);
}
void print_while_statement_tree(struct wonky_stream *out,struct AST_While_Statement *whi,short indentation)
{
	print_indentation(out,indentation);	
	wonky_fprintf(out,"while(%WA)\n%Wi%WA",whi->condition,indentation,whi->body_statement);
}
void print_do_while_statement_tree(struct wonky_stream *out,struct AST_Do_While_Statement *whi,short indentation)
{
	print_indentation(out,indentation);	
	wonky_fprintf(out,"do\n%Wi%WA\n",indentation,whi->body_statement);
	print_indentation(out,indentation);	
	wonky_fprintf(out,"while(%WA);",whi->condition);
}
void print_for_statement_tree(struct wonky_stream *out,struct AST_For_Statement *fo,short indentation)
{
	print_indentation(out,indentation);	
	wonky_fprintf(out,"for(%WA;%WA;WA)\n%Wi%WA",fo->initialisation,fo->condition,
							fo->update,indentation,fo->body_statement);
}
void print_return_statement_tree(struct wonky_stream *out,struct AST_Return_Statement *return_expression,short indentation)
{
	print_indentation(out,indentation);
	wonky_fprintf(out,"return %WA;",return_expression->return_expression);
}
void print_goto_statement_tree(struct wonky_stream *out,struct AST_Goto_Statement *got,short indentation)
{
	print_indentation(out,indentation);
	wonky_fprintf(out,"goto %Wd;",got->label);
}

void print_type(struct wonky_stream *out,struct Type *type,char should_print_struct_union)
{
	print_type_qualifier(out,type);
	print_type_sign(out,type);
	print_type_constraint(out,type);

	switch(type->specifier)
	{
		case TS_VOID:
			wonky_fprintf(out," void");
			return;
		case TS_CHAR:
			wonky_fprintf(out," char");
			return;
		case TS_INT:
			wonky_fprintf(out," int");
			return;
		case TS_FLOAT:
			wonky_fprintf(out," float");
			return;
		case TS_DOUBLE:
			wonky_fprintf(out," double");
			return;
		case TS_UNION:
		case TS_STRUCT:
			if(should_print_struct_union)
			{
				print_struct_union(out,((struct Type_Struct_Union*)type)->struct_union);
			}else
			{
				wonky_fprintf(out," %s",(type->specifier==TS_STRUCT?"struct":"union"));
			}
			return;
		case TS_ENUM:
			print_enumeration(out,((struct Type_Enum*)type)->enumeration);
			return;
		case TS_POINTER:
			wonky_fprintf(out," pointer to");
			print_type(out,((struct Type_Pointer*)type)->points_to,0);
			return;
		case TS_ARRAY:
			{
				wonky_fprintf(out," array of [%zu] of",((struct Type_Array*)type)->number_of_elements);
				print_type(out,((struct Type_Array*)type)->is_array_of,should_print_struct_union);
				return;
			}
		case TS_FUNC:
			wonky_fprintf(out,"function taking arguments (");
			print_function_args(out,(struct Type_Function*)type);
			wonky_fprintf(out,") returning");
			print_type(out,((struct Type_Function*)type)->return_type,should_print_struct_union);
			return;
		case TS_NONE:
			wonky_fprintf(out,"NONE");
			return;
		case TS_ERROR:
			wonky_fprintf(out,"[ERROR TYPE!]");
			return;

	}
	wonky_assert(SHOULD_NOT_REACH_HERE);
}
void print_denoted(struct wonky_stream *out,struct Denoted *denoted)
{

	switch(denoted->denotation)
	{
		case DT_Macro:
			wonky_fprintf(out,"macro");
			return;
		case DT_Macro_Parameter:
			wonky_fprintf(out,"macro parameter");
			return;
		case DT_Statement:
			wonky_fprintf(out,"label");
			return;
		case DT_Object:
			switch(((struct Denoted_Object*)denoted)->linkage)
			{
				case LINKAGE_INTERNAL:
					wonky_fprintf(out,"internally linked ");
					break;
				case LINKAGE_EXTERNAL:
					wonky_fprintf(out,"externally linked ");
					break;
				case LINKAGE_NONE:
					break;
				default:
					wonky_assert(SHOULD_NOT_REACH_HERE);
			}
			wonky_fprintf(out,"denoted object %WI%Wo is a %WT",((struct Denoted_Object*)denoted)->id,
									   ((struct Denoted_Object*)denoted)->object,
									   ((struct Denoted_Object*)denoted)->object->type
									   );
			return;
		case DT_Typedef:
			wonky_fprintf(out,"typedef %WI to %WT",((struct Denoted_Type*)denoted)->id,((struct Denoted_Type*)denoted)->type);
			return;
		case DT_Function:
			wonky_fprintf(out,"%WI is ",((struct Denoted_Function*)denoted)->id);
			switch(((struct Denoted_Function*)denoted)->linkage)
			{
				case LINKAGE_INTERNAL:
					wonky_fprintf(out,"an internally linked");
					break;
				case LINKAGE_EXTERNAL:
					wonky_fprintf(out,"an externally linked");
					break;
				case LINKAGE_NONE:
					break;
				default:
					wonky_assert(SHOULD_NOT_REACH_HERE);
			}
			print_type(out,((struct Denoted_Function*)denoted)->type,1);
			return;
		case DT_Enum:
			wonky_fprintf(out,"%WI is ",((struct Denoted_Enum*)denoted)->enumeration->id);
			print_enumeration(out,((struct Denoted_Enum*)denoted)->enumeration);
			return;
		case DT_Enum_Constant:
			wonky_fprintf(out,"%d",((struct Denoted_Enum_Const*)denoted)->value);
			return;
		case DT_Struct_Union_Tag:
			wonky_fprintf(out,"%WI is",((struct Denoted_Struct_Union*)denoted)->struct_union->id);
			print_struct_union(out,((struct Denoted_Struct_Union*)denoted)->struct_union);
			return;
		case DT_Error:
			wonky_fprintf(out,"denotation error");
			return;
		case DT_Prototype:
			wonky_fprintf(out,"denotation prototype");
			return;
		default:
			wonky_assert(SHOULD_NOT_REACH_HERE);
		
	}
	wonky_assert(SHOULD_NOT_REACH_HERE);
}
void print_list_of_denoted(struct wonky_stream *out,struct Queue *denoted)
{
	struct Queue_Node *it;
	for(it=denoted->first;it!=NULL;it=it->prev)
	{
		print_denoted(out,(struct Denoted*)it->data);
		if(it->prev!=NULL)
			wonky_fprintf(out,",");
	}
}
void print_enumeration(struct wonky_stream *out,struct Enum *enumeration)
{
	wonky_fprintf(out,"enum ");
	print_list_of_denoted(out,enumeration->consts);
}
void print_struct_union(struct wonky_stream *out,struct Struct_Union *struct_union)
{
	switch(struct_union->specifier)
	{
		case TS_UNION:
			wonky_fprintf(out,"union ");
			break;
		case TS_STRUCT:
			wonky_fprintf(out,"struct  ");
			break;
		default:
			wonky_assert(SHOULD_NOT_REACH_HERE);
	}
	wonky_fprintf(out,"{");
	print_list_of_denoted(out,struct_union->members);
	wonky_fprintf(out,"}");

}
void print_object(struct wonky_stream *out,struct Object *object)
{
	if(object->kind==OBJECT_KIND_NORMAL)
	{
		print_normal_object(out,object);
	}else
	{
		print_bitfield_object(out,(struct Object_Bitfield*)object);
	}
}
void print_normal_object(struct wonky_stream *out,struct Object *object)
{
	wonky_fprintf(out," normal object that");
}
void print_bitfield_object(struct wonky_stream *out,struct Object_Bitfield *object)
{
	wonky_fprintf(out,"bitfield object with %zu bits",object->number_of_bits);
}
void print_translation_unit_tree(struct wonky_stream *out,struct AST_Translation_Unit *unit,short indentation)
{
	struct Queue_Node *it;	
	struct AST* hold;
	for(it=unit->function_definitions->first;it!=NULL;it=it->prev)
	{
		hold=(struct AST*)(it->data);
		print_ast(out,hold,indentation);
		if(hold->type!=ST_FUNCTION_DEFINITION)
			wonky_fprintf(out,";\n");
	}
}
void print_ast(struct wonky_stream *out,struct AST* tree,short indentation)
{
	if(tree==NULL)
	{
		print_indentation(out,indentation);
		wonky_fprintf(out,"NULLAST");
		return;
	}
	switch(tree->type)
	{
		case OP_DESIGNATOR:
			print_designator_expression_tree(out,(struct AST_Designator*)tree,indentation);
			break;
		case OP_MEMBER_TROUGH_PTR:
		case OP_MEMBER:
		case OP_BITWISE_AND:
		case OP_BITWISE_XOR:
		case OP_LOGICAL_AND:
		case OP_LOGICAL_OR:
		case OP_XOR_ASSIGN:
		case OP_PIPE_ASSIGN:
		case OP_SHIFT_RIGHT_ASSIGN:
		case OP_ADD_ASSIGN:
		case OP_SUBTRACT_ASSIGN:
		case OP_MULTIPLY_ASSIGN:
		case OP_REMAINDER_ASSIGN:
		case OP_DIV_ASSIGN:
		case OP_SUBTRACTION:
		case OP_MUL:
		case OP_DIV:
		case OP_REMAINDER:
		case OP_EQUAL:
		case OP_LESS:
		case OP_LESS_EQ:
		case OP_SHIFT_LEFT:
		case OP_BITWISE_OR:
		case OP_AND_ASSIGN:
		case OP_ARR_SUBSCRIPT:
		case OP_SHIFT_LEFT_ASSIGN:
		case OP_ASSIGN:
		case OP_ADDITION:
		case OP_COMMA:
		case OP_SHIFT_RIGHT:
		case OP_GREATER_EQ:
		case OP_GREATER:
		case OP_NOT_EQUAL:
			print_binary_expression_tree(out,(struct AST_Binary_Expression*)tree);
			break;
		case OP_COND:
			print_conditional_expression_tree(out,(struct AST_Conditional_Expression*)tree);
			break;
		case OP_FUNCTION:
			print_function_expression_tree(out,(struct AST_Function_Expression*)tree);
			break;
		case OP_LOGICAL_NOT:
		case OP_UNARY_MINUS:
		case OP_SIZEOF:
		case OP_ADDR_OF:
		case OP_DEREFERENCE:
		case OP_POSTFIX_INC:
		case OP_PREFIX_INC:
		case OP_UNARY_PLUS:
		case OP_POSTFIX_DEC:
		case OP_PREFIX_DEC:
		case OP_CAST:
		case OP_BITWISE_NOT:
			print_unary_expression_tree(out,(struct AST_Unary_Expression*)tree);
			break;
		case OP_STRING_LITERAL:
			print_string_literal(out,(struct AST_String_Literal*)tree);
			break;
		case OP_CONSTANT:
			print_constant_tree(out,(struct AST_Constant*)tree);
			break;
		case OP_NOP:
			wonky_fprintf(out,"NOP");
			break;
		case ST_SWITCH:
			print_switch_statement_tree(out,(struct AST_Switch_Statement*)tree,indentation);
			break;
		case ST_IF:
			print_if_statement_tree(out,(struct AST_If_Statement*)tree,indentation);
			break;
		case ST_WHILE:
			print_while_statement_tree(out,(struct AST_While_Statement*)tree,indentation);
			break;
		case ST_DO_WHILE:
			print_do_while_statement_tree(out,(struct AST_Do_While_Statement*)tree,indentation);
			break;
		case ST_GOTO:
			print_goto_statement_tree(out,(struct AST_Goto_Statement*)tree,indentation);
			break;
		case ST_DEFAULT:
		case ST_LABEL:
		case ST_CASE:
			print_labeled_statement_tree(out,(struct AST_Labeled_Statement*)tree,indentation);
			break;
		case ST_CONTINUE:
			wonky_fprintf(out,"continue");
			break;
		case ST_BREAK:
			wonky_fprintf(out,"break");
			break;
		case ST_RETURN:
			print_return_statement_tree(out,(struct AST_Return_Statement*)tree,indentation);
			break;
		case ST_FOR:
			print_for_statement_tree(out,(struct AST_For_Statement*)tree,indentation);
			break;
		case ST_COMPOUND:
			print_compound_statement_tree(out,(struct AST_Compound_Statement*)tree,indentation);
			break;
		case ST_OBJECT_DECLARATION:
			print_indentation(out,indentation);
			print_denoted(out,(struct Denoted*)((struct AST_Object_Declaration*)tree)->object);
			break;
		case ST_TYPE_DEFINITION:
			print_denoted(out,(struct Denoted*)((struct AST_Type_Definition*)tree)->definition);
			break;
		case ST_FUNCTION_DECLARATION:
			print_denoted(out,(struct Denoted*)((struct AST_Function_Declaration*)tree)->function);
			break;
		case ST_FUNCTION_DEFINITION:
			print_function_definition(out,(struct AST_Function_Definition*)tree,indentation);
			break;
		case TRANSLATION_UNIT:
			print_translation_unit_tree(out,(struct AST_Translation_Unit*)tree,indentation);
			break;
		case ERROR:
			print_error_tree(out,(struct AST_Error*)tree,indentation);
			break;
		default:
			wonky_fprintf(out,"NOT POSSIBLE");
	}

}

void print_function_definition(struct wonky_stream *out,struct AST_Function_Definition *function,short indentation)
{
	print_indentation(out,indentation);
	wonky_fprintf(out,"%WI is",function->function->id);
	switch(function->function->linkage)
	{
		case LINKAGE_EXTERNAL:
			wonky_fprintf(out," an externally linked ");
			break;
		case LINKAGE_INTERNAL:
			wonky_fprintf(out," an internally linked ");
			break;
		default:
			wonky_assert(SHOULD_NOT_REACH_HERE);
	}
	wonky_fprintf(out,"%WT\n%Wi%WA",function->function->type,indentation,function->body);
}
void print_program_ast(struct wonky_stream *out,struct Program *program)
{
	size_t i;
	struct Queue_Node *it;

	wonky_fprintf(out,"EXTERNALLY DEFINED {\n\tFUNCTIONS {\n");
	for(it=program->functions_without_a_definition->first;it!=NULL;it=it->prev)
		wonky_fprintf(out,"%Wi%WA\n",2,it->data);
	wonky_fprintf(out,"\t}\n\tOBJECTS {\n");
	for(it=program->external_objects_without_an_initialiser->first;it!=NULL;it=it->prev)
		wonky_fprintf(out,"%Wi%WA\n",2,it->data);
	wonky_fprintf(out,"\t}");
	for(it=program->translation_units->first;it!=NULL;it=it->prev)
		wonky_fprintf(out,"\n\tTRANSLATION_UNIT {\n%Wi%Wa\n\t} TRANSLATION_UNIT_END\n",2,it->data);
}
void print_keyword_enum(struct wonky_stream *out,enum LEXER_TYPE kw)
{
	switch(kw)
	{
		case KW_AUTO:
			wonky_fprintf(out,"KW_AUTO");
			break;
		case KW_DO:
			wonky_fprintf(out,"KW_DO");
			break;
		case KW_DOUBLE:
			wonky_fprintf(out,"KW_DOUBLE");
			break;
		case KW_INT:
			wonky_fprintf(out,"KW_INT");
			break;
		case KW_STRUCT:
			wonky_fprintf(out,"KW_STRUCT");
			break;
		case KW_BREAK:
			wonky_fprintf(out,"KW_BREAK");
			break;
		case KW_ELSE:
			wonky_fprintf(out,"KW_ELSE");
			break;
		case PKW_DEFINED:
			wonky_fprintf(out,"KW_DEFINED");
			break;
		case KW_LONG:
			wonky_fprintf(out,"KW_LONG");
			break;
		case KW_SWITCH:
			wonky_fprintf(out,"KW_SWITCH");
			break;
		case KW_CASE:
			wonky_fprintf(out,"KW_CASE");
			break;
		case KW_ENUM:
			wonky_fprintf(out,"KW_ENUM");
			break;
		case KW_REGISTER:
			wonky_fprintf(out,"KW_REGISTER");
			break;
		case KW_TYPEDEF:
			wonky_fprintf(out,"KW_TYPEDEF");
			break;
		case KW_CHAR:
			wonky_fprintf(out,"KW_CHAR");
			break;
		case KW_EXTERN:
			wonky_fprintf(out,"KW_EXTERN");
			break;
		case KW_RETURN:
			wonky_fprintf(out,"KW_RETURN");
			break;
		case KW_UNION:
			wonky_fprintf(out,"KW_UNION");
			break;
		case KW_CONST:
			wonky_fprintf(out,"KW_CONST");
			break;
		case KW_FLOAT:
			wonky_fprintf(out,"KW_FLOAT");
			break;
		case KW_SHORT:
			wonky_fprintf(out,"KW_SHORT");
			break;
		case KW_UNSIGNED:
			wonky_fprintf(out,"KW_UNSIGNED");
			break;
		case KW_CONTINUE:
			wonky_fprintf(out,"KW_CONTINUE");
			break;
		case KW_FOR:
			wonky_fprintf(out,"KW_FOR");
			break;
		case KW_SIGNED:
			wonky_fprintf(out,"KW_SIGNED");
			break;
		case KW_VOID:
			wonky_fprintf(out,"KW_VOID");
			break;
		case KW_DEFAULT:
			wonky_fprintf(out,"KW_DEFAULT");
			break;
		case KW_GOTO:
			wonky_fprintf(out,"KW_GOTO");
			break;
		case KW_SIZEOF:
			wonky_fprintf(out,"KW_SIZEOF");
			break;
		case KW_VOLATILE:
			wonky_fprintf(out,"KW_VOLATILE");
			break;
		case KW_IF:
			wonky_fprintf(out,"KW_IF");
			break;
		case KW_STATIC:
			wonky_fprintf(out,"KW_STATIC");
			break;
		case KW_WHILE:
			wonky_fprintf(out,"KW_WHILE");
			break;
		case KW_EXCLAMATION:
			wonky_fprintf(out,"KW_EXCLAMATION");
			break;
		case KW_PERCENT:
			wonky_fprintf(out,"KW_PERCENT");
			break;
		case KW_AND:
			wonky_fprintf(out,"KW_AND");
			break;
		case KW_AND_AND:
			wonky_fprintf(out,"KW_AND_AND");
			break;
		case KW_OPEN_NORMAL:
			wonky_fprintf(out,"KW_OPEN_NORMAL");
			break;
		case KW_CLOSE_NORMAL:
			wonky_fprintf(out,"KW_CLOSE_NORMAL");
			break;
		case KW_STAR:
			wonky_fprintf(out,"KW_STAR");
			break;
		case KW_PLUS:
			wonky_fprintf(out,"KW_PLUS");
			break;
		case KW_COMMA:
			wonky_fprintf(out,"KW_COMMA");
			break;
		case KW_MINUS:
			wonky_fprintf(out,"KW_MINUS");
			break;
		case KW_DOT:
			wonky_fprintf(out,"KW_DOT");
			break;
		case KW_ARROW:
			wonky_fprintf(out,"KW_ARROW");
			break;
		case KW_COLUMN:
			wonky_fprintf(out,"KW_COLUMN");
			break;
		case KW_SEMICOLON:
			wonky_fprintf(out,"KW_SEMICOLON");
			break;
		case KW_LESS:
			wonky_fprintf(out,"KW_LESS");
			break;
		case KW_EQ:
			wonky_fprintf(out,"KW_EQ");
			break;
		case KW_EQEQ:
			wonky_fprintf(out,"KW_EQEQ");
			break;
		case KW_MORE:
			wonky_fprintf(out,"KW_MORE");
			break;
		case KW_QUESTION:
			wonky_fprintf(out,"KW_QUESTION");
			break;
		case KW_HAT:
			wonky_fprintf(out,"KW_HAT");
			break;
		case KW_PIPE:
			wonky_fprintf(out,"KW_PIPE");
			break;
		case KW_PIPE_PIPE:
			wonky_fprintf(out,"KW_PIPE_PIPE");
			break;
		case KW_TILDE:
			wonky_fprintf(out,"KW_TILDE");
			break;
		case KW_PLUSPLUS:
			wonky_fprintf(out,"KW_PLUSPLUS");
			break;
		case KW_MINUSMINUS:
			wonky_fprintf(out,"KW_MINUSMINUS");
			break;
		case KW_SHIFT_RIGHT:
			wonky_fprintf(out,"KW_SHIFT_RIGHT");
			break;
		case KW_SHIFT_LEFT:
			wonky_fprintf(out,"KW_SHIFT_LEFT");
			break;
		case KW_LESS_EQ:
			wonky_fprintf(out,"KW_LESS_EQ");
			break;
		case KW_MORE_EQ:
			wonky_fprintf(out,"KW_MORE_EQ");
			break;
		case KW_NOT_EQ:
			wonky_fprintf(out,"KW_NOT_EQ");
			break;
		case KW_PLUS_EQ:
			wonky_fprintf(out,"KW_PLUS_EQ");
			break;
		case KW_MINUS_EQ:
			wonky_fprintf(out,"KW_MINUS_EQ");
			break;
		case KW_STAR_EQ:
			wonky_fprintf(out,"KW_STAR_EQ");
			break;
		case KW_PERCENT_EQ:
			wonky_fprintf(out,"KW_PERCENT_EQ");
			break;
		case KW_SHIFT_LEFT_EQ:
			wonky_fprintf(out,"KW_SHIFT_LEFT_EQ");
			break;
		case KW_SHIFT_RIGHT_EQ:
			wonky_fprintf(out,"KW_SHIFT_RIGHT_EQ");
			break;
		case KW_AND_EQ:
			wonky_fprintf(out,"KW_AND_EQ");
			break;
		case KW_HAT_EQ:
			wonky_fprintf(out,"KW_HAT_EQ");
			break;
		case KW_PIPE_EQ:
			wonky_fprintf(out,"KW_PIPE_EQ");
			break;
		case KW_HASHTAG:
			wonky_fprintf(out,"KW_HASHTAG");
			break;
		case KW_HASHTAG_HASHTAG:
			wonky_fprintf(out,"KW_HASHTAG_HASHTAG");
			break;
		case KW_ELIPSIS:
			wonky_fprintf(out,"KW_ELIPSIS");
			break;
		case KW_DIV:
			wonky_fprintf(out,"KW_DIV");
			break;
		case KW_INLINE:
			wonky_fprintf(out,"KW_INLINE");
			break;
		case KW_RESTRICT:
			wonky_fprintf(out,"KW_RESTRICT");
			break;
		case KW_BOOL:
			wonky_fprintf(out,"KW_BOOL");
			break;
		case KW_COMPLEX:
			wonky_fprintf(out,"KW_COMPLEX");
			break;
		case KW_IMAGINARY:
			wonky_fprintf(out,"KW_IMAGINARY");
			break;
		case KW_OPEN_SQUARE:
			wonky_fprintf(out,"KW_OPEN_SQUARE");
			break;
		case KW_CLOSE_SQUARE:
			wonky_fprintf(out,"KW_CLOSE_SQUARE");
			break;
		case KW_CLOSE_CURLY:
			wonky_fprintf(out,"KW_CLOSE_CURLY");
			break;
		case KW_OPEN_CURLY:
			wonky_fprintf(out,"KW_OPEN_CURLY");
			break;
		case KW_DIV_EQ:
			wonky_fprintf(out,"KW_DIV_EQ");
			break;
		case KW_FORWARD_SLASH:
			wonky_fprintf(out,"KW_FORWARD_SLASH");
			break;
		case KW_NOTYPE:
			wonky_fprintf(out,"KW_NOTYPE");
			break;
		case KW_HEXADECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_HEXADECIMAL_CONSTANT");
			break;
		case KW_DECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_DECIMAL_CONSTANT");
			break;
		case KW_OCTAL_CONSTANT:
			wonky_fprintf(out,"KW_OCTAL_CONSTANT");
			break;
		case KW_UNSIGNED_DECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_UNSIGNED_DECIMAL_CONSTANT");
			break;
		case KW_UNSIGNED_OCTAL_CONSTANT:
			wonky_fprintf(out,"KW_UNSIGNED_OCTAL_CONSTANT");
			break;
		case KW_UNSIGNED_HEXADECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_UNSIGNED_HEXADECIMAL_CONSTANT");
			break;
		case KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT");
			break;
		case KW_UNSIGNED_LONG_OCTAL_CONSTANT:
			wonky_fprintf(out,"KW_UNSIGNED_LONG_OCTAL_CONSTANT");
			break;
		case KW_UNSIGNED_LONG_DECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_UNSIGNED_LONG_DECIMAL_CONSTANT");
			break;
		case KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT");
			break;
		case KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT");
			break;
		case KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT:
			wonky_fprintf(out,"KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT");
			break;
		case KW_LONG_HEXADECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_LONG_HEXADECIMAL_CONSTANT");
			break;
		case KW_LONG_OCTAL_CONSTANT:
			wonky_fprintf(out,"KW_LONG_OCTAL_CONSTANT");
			break;
		case KW_LONG_DECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_LONG_DECIMAL_CONSTANT");
			break;
		case KW_LONG_LONG_HEXADECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_LONG_LONG_HEXADECIMAL_CONSTANT");
			break;
		case KW_LONG_LONG_OCTAL_CONSTANT:
			wonky_fprintf(out,"KW_LONG_LONG_OCTAL_CONSTANT");
			break;
		case KW_LONG_LONG_DECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_LONG_LONG_DECIMAL_CONSTANT");
			break;
		case KW_DOUBLE_DECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_DOUBLE_DECIMAL_CONSTANT");
			break;
		case KW_LONG_DOUBLE_DECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_LONG_DOUBLE_DECIMAL_CONSTANT");
			break;
		case KW_FLOAT_DECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_FLOAT_DECIMAL_CONSTANT");
			break;
		case KW_DOUBLE_HEXADECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_DOUBLE_HEXADECIMAL_CONSTANT");
			break;
		case KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT");
			break;
		case KW_FLOAT_HEXADECIMAL_CONSTANT:
			wonky_fprintf(out,"KW_FLOAT_HEXADECIMAL_CONSTANT");
			break;
		case KW_COMMENT:
			wonky_fprintf(out,"KW_COMMENT");
			break;
		case KW_ID:
			wonky_fprintf(out,"KW_ID");
			break;
		case KW_CHAR_CONSTANT:
			wonky_fprintf(out,"KW_CHAR_CONSTANT");
			break;
		case KW_WIDE_CHAR_CONSTANT:
			wonky_fprintf(out,"KW_WIDE_CHAR_CONSTANT");
			break;
		case KW_STRING:
			wonky_fprintf(out,"KW_STRING");
			break;
		case KW_WIDE_STRING:
			wonky_fprintf(out,"KW_WIDE_STRING");
			break;
		case PKW_IF:
			wonky_fprintf(out,"PKW_IF");
			break;
		case PKW_IFDEF:
			wonky_fprintf(out,"PKW_IFDEF");
			break;
		case PKW_IFNDEF:
			wonky_fprintf(out,"PKW_IFNDEF");
			break;
		case PKW_ELIF:
			wonky_fprintf(out,"PKW_ELIF");
			break;
		case PKW_ELSE:
			wonky_fprintf(out,"PKW_ELSE");
			break;
		case PKW_ENDIF:
			wonky_fprintf(out,"PKW_ENDIF");
			break;
		case PKW_INCLUDE:
			wonky_fprintf(out,"PKW_INCLUDE");
			break;
		case PKW_DEFINE:
			wonky_fprintf(out,"PKW_DEFINE");
			break;
		case PKW_UNDEF:
			wonky_fprintf(out,"PKW_UNDEF");
			break;
		case PKW_LINE:
			wonky_fprintf(out,"PKW_LINE");
			break;
		case PKW_ERROR:
			wonky_fprintf(out,"PKW_ERROR");
			break;
		case PKW_PRAGMA:
			wonky_fprintf(out,"PKW_PRAGMA");
			break;
		case PKW_COMMENT:
			wonky_fprintf(out,"PKW_COMMENT");
			break;
		case PKW_NOTYPE:
			wonky_fprintf(out,"PKW_NOTYPE");
			break;
		default:
			wonky_fprintf(out,"KW_ERROR");
	}
}
void print_errors(struct wonky_stream *out,struct Queue *errors)
{
	struct Queue_Node *it;
	for(it=errors->first;it!=NULL;it=it->prev)
		print_message(out,(struct Wonky_Message*)it->data);
}
void print_function_args(struct wonky_stream *out,struct Type_Function *func)
{
	size_t i;
	if(func->number_of_arguments==0)
		return;

	print_denoted_argument(out,func->arguments[0]);
	for(i=1;i<func->number_of_arguments;++i)
		wonky_fprintf(out,", %Wd",func->arguments[i]);
}
void print_denoted_argument(struct wonky_stream *out,struct Denoted_Object *denoted)
{
	wonky_fprintf(out,"denoted object ");
	if(denoted->id)
		print_id(out,denoted->id);
	wonky_fprintf(out,"%Wo is a %WT",denoted->object,denoted->object->type);
	return;
}
void print_type_qualifier(struct wonky_stream *out,struct Type *type)
{
	if(type_is_constant(type))
		wonky_fprintf(out,"constant ");
	if(type_is_volatile(type))
		wonky_fprintf(out," volatile ");
}

void print_type_constraint_enum(struct wonky_stream *out,enum Type_Specifier specifier)
{
	switch(specifier)
	{
		case TC_LONG:
			wonky_fprintf(out,"long ");
			break;
		case TC_LONG_LONG:
			wonky_fprintf(out,"long long ");
			break;
		case TC_SHORT:
			wonky_fprintf(out,"short");
			break;
	}
}
void print_type_sign_enum(struct wonky_stream *out,enum Type_Signedness sign)
{
	if(sign==TSIGN_UNSIGNED)
		wonky_fprintf(out,"unsigned ");
}

void print_type_constraint(struct wonky_stream *out,struct Type *type)
{
	switch(type->specifier)
	{
		case TS_VOID:
		case TS_CHAR:
		case TS_INT:
		case TS_FLOAT:
		case TS_DOUBLE:
			print_type_constraint_enum(out,AS_BASIC_TYPE_PTR(type)->constraint);
	}
}
void print_type_sign(struct wonky_stream *out,struct Type *type)
{
	switch(type->specifier)
	{
		case TS_VOID:
		case TS_CHAR:
		case TS_INT:
		case TS_FLOAT:
		case TS_DOUBLE:
			print_type_sign_enum(out,AS_BASIC_TYPE_PTR(type)->sign);
			break;	
	}
}

void print_constant_tree(struct wonky_stream *out,struct AST_Constant *constant)
{
	wonky_assert(constant && constant->value && constant->value->constant);
	wonky_fprintf(out,"(const(%WT) %WC)",constant->value->constant->type,constant->value->constant);
}
void print_string_literal(struct wonky_stream *out,struct AST_String_Literal *string)
{
	wonky_fprintf(out,"%WC",string->value->constant);
}

void print_expression_value(struct wonky_stream *out,struct Expression_Value *value)
{
	wonky_fprintf(out,"EXPRESSION VALUE of type");
}
void print_expression_value_type(struct wonky_stream *out,struct Expression_Value *expression_value)
{
	switch(expression_value->type)
	{
		case VALUE_LVALUE:
			print_type(out, ((struct Expression_Value_LValue*)expression_value)->object->type,1);
			return;
		case VALUE_TEMP:
			print_type(out,((struct Expression_Value_RValue*)expression_value)->temp_object->type,1);
			return;
		case VALUE_FUNCTION_DESIGNATOR:
			print_type(out,((struct Expression_Value_Function_Designator*)expression_value)->function->type,1);
			return;
		case VALUE_CONSTANT:
			print_type(out, ((struct Expression_Value_Constant*)expression_value)->constant->type,1);
			return;
		case VALUE_VOID:
			wonky_fprintf(out,"void");
			return;
	}	
	wonky_assert(SHOULD_NOT_REACH_HERE);
}

void print_id(struct wonky_stream *out,struct identifier *id)
{
	wonky_fprintf(out,"%s",id->data);
}
#undef TOK
#undef INDENT
void print_indentation(struct wonky_stream *out,short indentation)
{
	for(short i=0;i<indentation;++i)
		wonky_write(out,"\t",1);
}
void print_constant(struct wonky_stream *out,struct Constant *constant)
{
	wonky_assert(constant->value);
	switch(constant->type->specifier)
	{
		case TS_VOID:
			wonky_fprintf(out,"void SHOULD NOT REACH HERE");
			break;
		case TS_CHAR:
			wonky_fprintf(out,"%c",*(char*)constant->value);
			break;
		case TS_INT:
			wonky_fprintf(out,"%d",*(int*)constant->value);
			break;
		case TS_FLOAT:
			wonky_fprintf(out,"%f",*(float*)constant->value);
			break;
		case TS_DOUBLE:
			wonky_fprintf(out,"%f",*(double*)constant->value);
			break;
		case TS_STRUCT:
			wonky_fprintf(out,"%WT",constant->type);
			break;
		case TS_ENUM:
			wonky_fprintf(out,"%WT",constant->type);
			break;
		case TS_UNION:
			wonky_fprintf(out,"%WT",constant->type);
			break;
		case TS_POINTER:
			wonky_fprintf(out,"%p",*(void**)constant->value);
			break;
		case TS_ARRAY:
			wonky_fprintf(out,"%WT",constant->type);
			break;
		case TS_VARIABLE_LENGTH_ARRAY:
			wonky_fprintf(out,"var length array %WT",constant->type);
			break;
		case TS_FUNC:
			wonky_fprintf(out,"FUNCTION %WT",constant->type);
			break;
		case TS_NONE:
			wonky_fprintf(out,"NONE CONSTANT");
			break;
		case TS_ERROR:
			wonky_fprintf(out,"ERROR CONSTANT");
			break;
	}
}
void print_token_text(struct wonky_stream *out,struct token *token)
{
	switch(token->type)
	{
		case KW_AUTO:
			wonky_fprintf(out,"auto");
			break;
		case KW_DO:
			wonky_fprintf(out,"do");
			break;
		case KW_DOUBLE:
			wonky_fprintf(out,"double");
			break;
		case KW_INT:
			wonky_fprintf(out,"int");
			break;
		case KW_STRUCT:
			wonky_fprintf(out,"struct");
			break;
		case KW_BREAK:
			wonky_fprintf(out,"break");
			break;
		case KW_ELSE:
			wonky_fprintf(out,"else");
			break;
		case KW_LONG:
			wonky_fprintf(out,"long");
			break;
		case KW_SWITCH:
			wonky_fprintf(out,"switch");
			break;
		case KW_CASE:
			wonky_fprintf(out,"case");
			break;
		case KW_ENUM:
			wonky_fprintf(out,"enum");
			break;
		case KW_REGISTER:
			wonky_fprintf(out,"register");
			break;
		case KW_TYPEDEF:
			wonky_fprintf(out,"typedef");
			break;
		case KW_CHAR:
			wonky_fprintf(out,"char");
			break;
		case KW_EXTERN:
			wonky_fprintf(out,"extern");
			break;
		case KW_RETURN:
			wonky_fprintf(out,"return");
			break;
		case KW_UNION:
			wonky_fprintf(out,"union");
			break;
		case KW_CONST:
			wonky_fprintf(out,"const");
			break;
		case KW_FLOAT:
			wonky_fprintf(out,"float");
			break;
		case KW_SHORT:
			wonky_fprintf(out,"short");
			break;
		case KW_UNSIGNED:
			wonky_fprintf(out,"unsigned");
			break;
		case KW_CONTINUE:
			wonky_fprintf(out,"continue");
			break;
		case KW_FOR:
			wonky_fprintf(out,"for");
			break;
		case KW_SIGNED:
			wonky_fprintf(out,"signed");
			break;
		case KW_VOID:
			wonky_fprintf(out,"void");
			break;
		case KW_DEFAULT:
			wonky_fprintf(out,"default");
			break;
		case KW_GOTO:
			wonky_fprintf(out,"goto");
			break;
		case KW_SIZEOF:
			wonky_fprintf(out,"sizeof");
			break;
		case KW_VOLATILE:
			wonky_fprintf(out,"volatile");
			break;
		case KW_IF:
			wonky_fprintf(out,"if");
			break;
		case KW_STATIC:
			wonky_fprintf(out,"static");
			break;
		case KW_WHILE:
			wonky_fprintf(out,"while");
			break;
		case KW_EXCLAMATION:
			wonky_fprintf(out,"!");
			break;
		case KW_PERCENT:
			wonky_fprintf(out,"%");
			break;
		case KW_AND:
			wonky_fprintf(out,"&");
			break;
		case KW_AND_AND:
			wonky_fprintf(out,"&&");
			break;
		case KW_OPEN_NORMAL:
			wonky_fprintf(out,"(");
			break;
		case KW_CLOSE_NORMAL:
			wonky_fprintf(out,")");
			break;
		case KW_STAR:
			wonky_fprintf(out,"*");
			break;
		case KW_PLUS:
			wonky_fprintf(out,"+");
			break;
		case KW_COMMA:
			wonky_fprintf(out,",");
			break;
		case KW_MINUS:
			wonky_fprintf(out,"-");
			break;
		case KW_DOT:
			wonky_fprintf(out,".");
			break;
		case KW_ARROW:
			wonky_fprintf(out,"->");
			break;
		case KW_COLUMN:
			wonky_fprintf(out,":");
			break;
		case KW_SEMICOLON:
			wonky_fprintf(out,";");
			break;
		case KW_LESS:
			wonky_fprintf(out,"<");
			break;
		case KW_EQ:
			wonky_fprintf(out,"=");
			break;
		case KW_EQEQ:
			wonky_fprintf(out,"==");
			break;
		case KW_MORE:
			wonky_fprintf(out,">");
			break;
		case KW_QUESTION:
			wonky_fprintf(out,"?");
			break;
		case KW_HAT:
			wonky_fprintf(out,"^");
			break;
		case KW_PIPE:
			wonky_fprintf(out,"|");
			break;
		case KW_PIPE_PIPE:
			wonky_fprintf(out,"||");
			break;
		case KW_TILDE:
			wonky_fprintf(out,"~");
			break;
		case KW_PLUSPLUS:
			wonky_fprintf(out,"++");
			break;
		case KW_MINUSMINUS:
			wonky_fprintf(out,"--");
			break;
		case KW_SHIFT_RIGHT:
			wonky_fprintf(out,">>");
			break;
		case KW_SHIFT_LEFT:
			wonky_fprintf(out,"<<");
			break;
		case KW_LESS_EQ:
			wonky_fprintf(out,"<=");
			break;
		case KW_MORE_EQ:
			wonky_fprintf(out,">=");
			break;
		case KW_NOT_EQ:
			wonky_fprintf(out,"!=");
			break;
		case KW_PLUS_EQ:
			wonky_fprintf(out,"+=");
			break;
		case KW_MINUS_EQ:
			wonky_fprintf(out,"-=");
			break;
		case KW_STAR_EQ:
			wonky_fprintf(out,"*=");
			break;
		case KW_PERCENT_EQ:
			wonky_fprintf(out,"%=");
			break;
		case KW_SHIFT_LEFT_EQ:
			wonky_fprintf(out,"<<=");
			break;
		case KW_SHIFT_RIGHT_EQ:
			wonky_fprintf(out,">>=");
			break;
		case KW_AND_EQ:
			wonky_fprintf(out,"&=");
			break;
		case KW_HAT_EQ:
			wonky_fprintf(out,"^=");
			break;
		case KW_PIPE_EQ:
			wonky_fprintf(out,"|=");
			break;
		case KW_HASHTAG:
			wonky_fprintf(out,"#");
			break;
		case KW_HASHTAG_HASHTAG:
			wonky_fprintf(out,"##");
			break;
		case KW_ELIPSIS:
			wonky_fprintf(out,"...");
			break;
		case KW_DIV:
			wonky_fprintf(out,"/");
			break;
		case KW_INLINE:
			wonky_fprintf(out,"inline");
			break;
		case KW_RESTRICT:
			wonky_fprintf(out,"restrict");
			break;
		case KW_BOOL:
			wonky_fprintf(out,"_Bool");
			break;
		case KW_COMPLEX:
			wonky_fprintf(out,"_Complex");
			break;
		case KW_IMAGINARY:
			wonky_fprintf(out,"_Imaginary");
			break;
		case KW_OPEN_SQUARE:
			wonky_fprintf(out,"[");
			break;
		case KW_CLOSE_SQUARE:
			wonky_fprintf(out,"]");
			break;
		case KW_CLOSE_CURLY:
			wonky_fprintf(out,"}");
			break;
		case KW_OPEN_CURLY:
			wonky_fprintf(out,"{");
			break;
		case KW_DIV_EQ:
			wonky_fprintf(out,"/=");
			break;
		case KW_FORWARD_SLASH:
			wonky_fprintf(out,"/");
			break;
		case KW_NOTYPE:
			wonky_fprintf(out,"NOTYPE");
			break;
		case KW_HEXADECIMAL_CONSTANT:
		case KW_DECIMAL_CONSTANT:
		case KW_OCTAL_CONSTANT :
		case KW_UNSIGNED_DECIMAL_CONSTANT:
		case KW_UNSIGNED_OCTAL_CONSTANT:
		case KW_UNSIGNED_HEXADECIMAL_CONSTANT:
		case KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT:
		case KW_UNSIGNED_LONG_OCTAL_CONSTANT:
		case KW_UNSIGNED_LONG_DECIMAL_CONSTANT:
		case KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT:
		case KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT:
		case KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT:
		case KW_LONG_HEXADECIMAL_CONSTANT:
		case KW_LONG_OCTAL_CONSTANT:
		case KW_LONG_DECIMAL_CONSTANT:
		case KW_LONG_LONG_HEXADECIMAL_CONSTANT:
		case KW_LONG_LONG_OCTAL_CONSTANT:
		case KW_LONG_LONG_DECIMAL_CONSTANT:
		case KW_DOUBLE_DECIMAL_CONSTANT:
		case KW_LONG_DOUBLE_DECIMAL_CONSTANT:
		case KW_FLOAT_DECIMAL_CONSTANT:
		case KW_DOUBLE_HEXADECIMAL_CONSTANT:
		case KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT:
		case KW_FLOAT_HEXADECIMAL_CONSTANT:
		case KW_CHAR_CONSTANT:
		case KW_WIDE_CHAR_CONSTANT:
		case KW_CONSTANT:
			print_constant(out,((struct token_constant*)token)->constant);
			break;
		case KW_ID:
			print_id(out,((struct token_identifier*)token)->id);
			break;
		case KW_STRING:
		case KW_WIDE_STRING:
			wonky_fprintf(out,"%s",((struct token_string*)token)->constant->value);
			break;
		case PKW_MACRO_ARGUMENT:
			wonky_fprintf(out,"MACRO ARGUMENT -_(:/)_-");
			break;
		case PKW_HASHTAG_UNARY_OP:
			wonky_fprintf(out,"#argument");
			break;
		case PKW_HASHTAG_HASHTAG_OP:
			{
				struct Queue_Node *it;
				it=((struct token_hashtag_hastag_operator*)token)->operands->first;
				if(it)
					print_token(out,(struct token*)it->data);
				it=it->prev;
				for(;it;it=it->prev)
					wonky_fprintf(out,"##%Wt",(struct token*)it->data);
			}
			break;
		case PKW_DEFINED:
			wonky_fprintf(out,"defined(...)");
			break;
		case PKW_IF:
			wonky_fprintf(out,"PKW_IF");
			break;
		case PKW_IFDEF:
			wonky_fprintf(out,"PKW_IFDEF");
			break;
		case PKW_IFNDEF:
			wonky_fprintf(out,"PKW_IFNDEF");
			break;
		case PKW_ELIF:
			wonky_fprintf(out,"PKW_ELIF");
			break;
		case PKW_ELSE:
			wonky_fprintf(out,"PKW_ELSE");
			break;
		case PKW_ENDIF:
			wonky_fprintf(out,"PKW_ENDIF");
			break;
		case PKW_INCLUDE:
			wonky_fprintf(out,"PKW_INCLUDE");
			break;
		case PKW_DEFINE:
			wonky_fprintf(out,"PKW_DEFINE");
			break;
		case PKW_UNDEF:
			wonky_fprintf(out,"PKW_UNDEF");
			break;
		case PKW_LINE:
			wonky_fprintf(out,"PKW_LINE");
			break;
		case PKW_ERROR:
			wonky_fprintf(out,"PKW_ERROR");
			break;
		case PKW_PRAGMA:
			wonky_fprintf(out,"PKW_PRAGMA");
			break;
		case PKW_COMMENT:
			wonky_fprintf(out,"PKW_COMMENT");
			break;

		default:
			wonky_fprintf(out,"NOTYPE:%d",token->type);

	}
}
void print_raw_token_text(struct wonky_stream *out,struct token *token)
{
	wonky_write(out,
			token->delta->location->src->src
			+
			token->delta->location->starting_byte_index
		       ,
		        token->delta->location->length);

}
#endif