WONKY



LOG | FILES | OVERVIEW


#ifndef WONKY_STREAM_C
#define WONKY_STREAM_C WONKY_STREAM_C
#include <wonky_stream.h>




ssize_t wonky_read(struct wonky_stream *s,void *dst,size_t num_bytes)
{
	return s->read(s->state,dst,num_bytes);
}
ssize_t wonky_write(struct wonky_stream *s,void *src,size_t num_bytes)
{
	return s->write(s->state,src,num_bytes);
}
ssize_t wonky_fseek(struct wonky_stream *s,size_t where,int whence)
{
	return s->fseek(s->state,where,whence);
}
ssize_t wonky_eof(struct wonky_stream *s)
{
	return s->eof(s->state);
}
#warning not clear what wonky_printf format is
/*
	%WE pointer to struct Wonky_Error
 
 */
int wonky_printf(const char *format,...)
{
	va_list args;
	int ret;
	struct wonky_stream s=wonky_stream_from_file(stdout); 

	va_start(args,format);
	ret=wonky_vfprintf(&s,format,args);
	va_end(args);

	fflush(stdout);
	return ret;
}
int wonky_vprintf(const char *format,va_list args)
{
	struct wonky_stream s=wonky_stream_from_file(stdout); 
	return wonky_vfprintf(&s,format,args);
}

int wonky_fprintf(struct wonky_stream *s,const char *format,...)
{
	va_list args;
	int ret;

	va_start(args,format);
	ret=wonky_vfprintf(s,format,args);	
	va_end(args);

	return ret;
}
int wonky_vfprintf(struct wonky_stream *s,const char *format,va_list args)
{
	if(format==NULL || s==NULL)
		return 0;

	struct wonky__scanformat fmt;
	short indentation=0;

	for(size_t i=0;format[i]!='\0';)
	{
		if(format[i]=='%')
		{
			wonky__parse_scan_format(format+i,&fmt);
			wonky__from_scanformat(&fmt,args,s,&indentation);
			i+=fmt.forward_crawl;
		}else
		{
			wonky_write(s,(void*)format+i,1);
			++i;
		}
	}

}

ssize_t wonky_stream_int_to_decimal(struct wonky_stream *s,intmax_t a)
{
	char hold[2]={0,0};
	ssize_t ret=0;
	ssize_t hret;
	intmax_t d;

	if(a==0)
		return wonky_write(s,"0",1);
	else if(a<0)
	{
		ret=wonky_write(s,"-",1);
		a=-a;
	}


	for(d=1;d*10<=a;d*=10);
	for(d;d>0;d/=10)
	{
		hold[0]=a/d+'0';
		hret=wonky_write(s,hold,1);
		if(hret<0)
			return -ret;
		else
			ret+=hret;
		a=a%d;
	}
	return ret;
}
ssize_t wonky_stream_uint_to_decimal(struct wonky_stream *s,uintmax_t a)
{
	char hold[2]={0,0};
	ssize_t ret=0;
	ssize_t hret;
	uintmax_t d;

	if(a==0)
		return wonky_write(s,"0",1);

	for(d=1;d*10<=a;d*=10);
	for(d;d>0;d/=10)
	{
		hold[0]=a/d+'0';
		hret=wonky_write(s,hold,1);
		if(hret<0)
			return -ret;
		else
			ret+=hret;
		a=a%d;
	}
	return ret;
}
ssize_t wonky_stream_uint_to_hexadecimal(struct wonky_stream *s,uintmax_t a)
{
	char hold[2]={0,0};
	ssize_t ret=0;
	ssize_t hret;
	uintmax_t d;
	if(a==0)
		return wonky_write(s,"0",1);

	for(d=1;d*16<=a;d*=16);
	for(d;d>0;d/=16)
	{
		if(a/d<10)
			hold[0]=a/d+'0';
		else
			hold[0]=a/d-10+'A';
		hret=wonky_write(s,hold,1);
		if(hret<0)
			return -ret;
		else
			ret+=hret;
		a=a%d;
	}
	return ret;
}
ssize_t wonky_stream_uint_to_octal(struct wonky_stream *s,uintmax_t a)
{
	char hold[2]={0,0};
	ssize_t ret=0;
	ssize_t hret;
	uintmax_t d;

	if(a==0)
		return wonky_write(s,"0",1);

	for(d=1;d*8<=a;d*=8);
	for(d;d>0;d/=8)
	{
		hold[0]=a/d+'0';
		hret=wonky_write(s,hold,1);
		if(hret<0)
			return -ret;
		else
			ret+=hret;
		a=a%d;
	}
	return ret;
}
ssize_t wonky_stream_double_to_decimal(struct wonky_stream *s,double d)
{
	int32_t exponent;
	uint64_t mantissa;
	ssize_t ret=0;
	ssize_t hret;

	exponent=wonky__double_get_exponent(d)-1023;
	mantissa=wonky__double_get_mantissa(d)|0x0010000000000000;


	for(mantissa;(mantissa&1)==0;mantissa>>=1,++exponent);
	exponent-=52;

	if(wonky__double_is_negative(d))
	{
		hret=wonky_write(s,"-",1);
		if(hret<0)
			return hret;
		else
			ret+=hret;
	}

	if(exponent<0)
	{
		if(-exponent<64)
		{
			hret=wonky_stream_from_fraction(s,mantissa,(uint64_t)1<<-exponent,10);
			if(hret<0)
				return hret;
		}else
		{
			hret=wonky_stream_uint_to_decimal(s,mantissa);
			if(hret<0)
				return hret;
			else
				ret+=hret;
			hret=wonky_write(s,"e",1);
			if(hret<0)
				return -ret;
			else
				ret+=hret;
			hret=wonky_stream_int_to_decimal(s,exponent);
			if(hret<0)
				return -ret;
			else
				ret+=hret;
		}
	}else
	{
		hret=wonky_stream_uint_to_decimal(s,mantissa);
		if(hret<0)
			return hret;
		else
			ret+=hret;
		hret=wonky_write(s,"e",1);
		if(hret<0)
			return -ret;
		else
			ret+=hret;

		hret=wonky_stream_int_to_decimal(s,exponent);
		if(hret<0)
			return -ret;
		else
			ret+=hret;
	}


	return ret;

}
ssize_t wonky_stream_from_fraction(struct wonky_stream *s,uint64_t a,uint64_t b,int precision)
{
	char hold[2]={0,0};
	ssize_t ret=0;
	ssize_t hret;
	if(a==0)
	{
		return wonky_write(s,"0",1);
	}else
	{
		hret=wonky_stream_int_to_decimal(s,a/b);
		if(hret<0)
			return hret;
		else
			ret+=hret;

		hret=wonky_write(s,".",1);
		if(hret<0)
			return -ret;
		else
			ret+=hret;
		a=a%b*10;
		--precision;
		while(precision>=0 && a!=0)
		{
			hold[0]=a/b+'0';
			hret=wonky_write(s,hold,1);
			a=(a%b)*10;
			--precision;
		}
	}

	return ret;
}
void wonky__from_scanformat(struct wonky__scanformat *fmt,va_list args,struct wonky_stream *s,short *indentation)
{
	switch(fmt->conversion)
	{
		case WONKY__CONVERSION_PERCENT:
			wonky_write(s,"%",1);
			break;
		case WONKY__CONVERSION_INT_DECIMAL:
			{
				switch(fmt->modifier)
				{
					case WONKY__MOD_LONG:
						wonky_stream_int_to_decimal(s,va_arg(args,long int));
						break;
					case WONKY__MOD_LONG_LONG:
						wonky_stream_int_to_decimal(s,va_arg(args,long long int));
						break;
					case WONKY__MOD_INTMAX:
						wonky_stream_int_to_decimal(s,va_arg(args,intmax_t));
						break;
					case WONKY__MOD_SIZE_T:
						wonky_stream_int_to_decimal(s,va_arg(args,ssize_t));
						break;
					case WONKY__MOD_PTRDIFF:
						wonky_stream_int_to_decimal(s,va_arg(args,ptrdiff_t));
						break;
					default:
						wonky_stream_int_to_decimal(s,va_arg(args,int));
						break;
				}
			}
			break;
		case WONKY__CONVERSION_INT_OCTAL:
			{
				switch(fmt->modifier)
				{
					case WONKY__MOD_LONG:
						wonky_stream_uint_to_octal(s,va_arg(args,long unsigned int));
						break;
					case WONKY__MOD_LONG_LONG:
						wonky_stream_uint_to_octal(s,va_arg(args,long long unsigned int));
						break;
					case WONKY__MOD_INTMAX:
						wonky_stream_uint_to_octal(s,va_arg(args,uintmax_t));
						break;
					case WONKY__MOD_SIZE_T:
						wonky_stream_uint_to_octal(s,va_arg(args,size_t));
						break;
					case WONKY__MOD_PTRDIFF:
						wonky_stream_uint_to_octal(s,va_arg(args,ptrdiff_t));
						break;
					default:
						wonky_stream_uint_to_octal(s,va_arg(args,unsigned int));
						break;
				}
			}
			break;
		case WONKY__CONVERSION_POINTER:
		case WONKY__CONVERSION_INT_HEXADECIMAL:
			{
				switch(fmt->modifier)
				{
					case WONKY__MOD_LONG:
						wonky_stream_uint_to_hexadecimal(s,va_arg(args,long unsigned int));
						break;
					case WONKY__MOD_LONG_LONG:
						wonky_stream_uint_to_hexadecimal(s,va_arg(args,long long unsigned int));
						break;
					case WONKY__MOD_INTMAX:
						wonky_stream_uint_to_hexadecimal(s,va_arg(args,uintmax_t));
						break;
					case WONKY__MOD_SIZE_T:
						wonky_stream_uint_to_hexadecimal(s,va_arg(args,size_t));
						break;
					case WONKY__MOD_PTRDIFF:
						wonky_stream_uint_to_hexadecimal(s,va_arg(args,ptrdiff_t));
						break;
					default:
						wonky_stream_uint_to_hexadecimal(s,va_arg(args,unsigned int));
						break;
				}
			}
			break;
		case WONKY__CONVERSION_INT_UNSIGNED_DECIMAL:
			{
				switch(fmt->modifier)
				{
					case WONKY__MOD_LONG:
						wonky_stream_uint_to_decimal(s,va_arg(args,long unsigned int));
						break;
					case WONKY__MOD_LONG_LONG:
						wonky_stream_uint_to_decimal(s,va_arg(args,long long unsigned int));
						break;
					case WONKY__MOD_INTMAX:
						wonky_stream_uint_to_decimal(s,va_arg(args,uintmax_t));
						break;
					case WONKY__MOD_SIZE_T:
						wonky_stream_uint_to_decimal(s,va_arg(args,size_t));
						break;
					case WONKY__MOD_PTRDIFF:
						wonky_stream_uint_to_decimal(s,va_arg(args,ptrdiff_t));
						break;
					default:
						wonky_stream_uint_to_decimal(s,va_arg(args,unsigned int));
						break;
				}
			}
			break;
		case WONKY__CONVERSION_CHAR:
			{
				char a=va_arg(args,int);
				wonky_write(s,&a,1);
			}
			break;
		case WONKY__CONVERSION_DOUBLE_DECIMAL:
			{
				switch(fmt->modifier)
				{
					case WONKY__MOD_LONG:
					case WONKY__MOD_LONG_LONG:
						wonky_stream_double_to_decimal(s,va_arg(args,long double));
						break;
					default:
						wonky_stream_double_to_decimal(s,va_arg(args,double));
						break;
				}
			}
			break;
		case WONKY__CONVERSION_CSTRING:
			{
				char *st=va_arg(args,char*);
				if(st==NULL)
				{
					wonky_write(s,"(null)",sizeof("(null)")-1);
				}else
				{
					size_t l=gstrlen(st);
					wonky_write(s,st,l);
				}
			}
			break;
		case WONKY__CONVERSION_WONKY_ERROR:
			{
				print_message(s,va_arg(args,struct Wonky_Message*));
			}
			break;
		case WONKY__CONVERSION_WONKY_TOKEN:
			{
				print_token(s,va_arg(args,struct token*));
			}
			break;
		case WONKY__CONVERSION_WONKY_INDENTATION:
			*indentation=va_arg(args,int);
			break;
		case WONKY__CONVERSION_WONKY_AST:
			print_ast(s,va_arg(args,struct AST*),*indentation);
			break;
		case WONKY__CONVERSION_WONKY_AST_ENUM:
			print_ast_enum(s,va_arg(args,enum AST_Type));
			break;
		case WONKY__CONVERSION_WONKY_ID:
			print_id(s,va_arg(args,struct identifier*));
			break;
		case WONKY__CONVERSION_WONKY_DENOTED:
			print_denoted(s,va_arg(args,struct Denoted*));
			break;
		case WONKY__CONVERSION_WONKY_TYPE:
			print_type(s,va_arg(args,struct Type*),1);
			break;
		case WONKY__CONVERSION_WONKY_OBJECT:
			print_object(s,va_arg(args,struct Object*));
			break;
		case WONKY__CONVERSION_WONKY_CONSTANT:
			print_constant(s,va_arg(args,struct Constant*));
			break;
		case WONKY__CONVERSION_WONKY_SOURCE_NAME:
			{
				struct Source_Name *sn=va_arg(args,struct Source_Name*);
				wonky_write(s,sn->name,sn->name_size);
			}
			break;
		case WONKY__CONVERSION_WONKY_INCLUSION_CHAIN:
			{
				struct Token_Pointer *tp=va_arg(args,struct Token_Pointer*);
				struct Token_Pointer_Context *hold;
				_Bool print_line=0;
				wonky_assert(tp!=NULL);
				if(tp->call_stack->size>2)
				{
					wonky_write(s,"\n",1);
					for(struct Stack_Node *it=tp->call_stack->first;it;it=it->next)
					{
						hold=(struct Token_Pointer_Context*)it->data;		
						wonky_assert(hold);
						if(hold->is_file_inclusion)
						{
							if(print_line)
								wonky_write(s,"\n",1);
							wonky_write(s,"\tIncluded in ",sizeof("\tIncluded in ")-1);
							wonky_write(s,hold->filename,hold->filename_size);
							wonky_fprintf(s,":%zu",hold->line+1);
							print_line=1;
						}

					}
				}

			}
			break;
		case WONKY__CONVERSION_WONKY_TOKEN_POINTER_CALL_STACK:
			{
				struct Token_Pointer *tp=va_arg(args,struct Token_Pointer*);
				_Bool print_line=0;
				wonky_assert(tp);
				wonky_fprintf(s,"%WPc\n",tp->context);
				for(struct Stack_Node *it=tp->call_stack->first;it;it=it->next)
					wonky_fprintf(s,"%WPc\n",it->data);


			}
			break;
		case WONKY__CONVERSION_WONKY_TOKEN_POINTER_CONTEXT:
			{
				struct Token_Pointer_Context *hold=va_arg(args,struct Token_Pointer_Context*);
				wonky_assert(hold);
				wonky_fprintf(s,"ctx=%p",hold);
				if(hold->current_token_node)
				{
					wonky_assert(hold->current_token_node->data!=NULL);
					wonky_fprintf(s,": {\n\tcurrent_token_node = %Wt",hold->current_token_node->data);
				}else
				{
					wonky_fprintf(s,": {\n\tcurrent_token_node = NULL");
				}
				wonky_fprintf(s,"\n\tnum_remain_toks = %zu\n\tline = %zu\n\tcolumn = %zu\n\tbarier=%d\n\tfilename = \"",hold->number_of_remaining_tokens,hold->line,hold->column,hold->barrier);
				wonky_write(s,hold->filename,hold->filename_size);
				wonky_write(s,"\"",sizeof("\"")-1);
				if(hold->executed_macro_id)
				{
					wonky_write(s,"\n\tmacro_id = \"",sizeof(" macro_id = \"")-1);
					wonky_write(s,hold->executed_macro_id->data,hold->executed_macro_id->size);
					wonky_write(s,"\"",sizeof("\"")-1);
				}
				if(hold->has_saved_functionlike_macro_state)
				{
					wonky_write(s,"\n\tmacro_state : \n\t{",sizeof("\n\tmacro_state : \n\t{")-1);
					for(struct Queue_Node *it=hold->functionlike_macro_arguments_save_state->first;it;it=it->prev)
						wonky_fprintf(s,"\n\t\t%WMA",it->data);
					wonky_write(s,"\n\t}",sizeof("\n\t}")-1);
				}
				wonky_write(s,"\n}\n",sizeof("\n}\n")-1);

			}
			break;
		case WONKY__CONVERSION_WONKY_MACRO_ARGUMENT:
			{
				struct functionlike_define_directive_argument *arg=va_arg(args,struct functionlike_define_directive_argument*);
				wonky_fprintf(s,"first_in_argument_substitution_tokens=%p number_of_substitution_tokens=%zu",arg->first_in_argument_substitution_tokens,arg->number_of_substitution_tokens);
			}
			break;
		case WONKY__CONVERSION_WONKY_FUNCTIONLIKE_MACRO:
			{
				struct functionlike_define_directive *arg=va_arg(args,struct functionlike_define_directive*);
				wonky_assert(arg);
				wonky_fprintf(s,"\n\"%WI\" : {\n\tis_variadic=%d",arg->id,(int)arg->is_variadic);
				for(struct Queue_Node *it=arg->arguments->first;it;it=it->prev)
					wonky_fprintf(s,"\n\t%WMA",it->data);
				wonky_fprintf(s,"\n}\n");
			}
			break;
		case WONKY__CONVERSION_WONKY_TOKEN_LINE:
			{
				struct token *token=va_arg(args,struct token*);
				size_t begining_of_real_line=token->delta->location->starting_byte_index;
				size_t ending_of_real_line=token->delta->location->starting_byte_index;
				for(begining_of_real_line ;begining_of_real_line && token->delta->location->src->src[begining_of_real_line]!='\n' ;--begining_of_real_line);
				for(ending_of_real_line ;ending_of_real_line<token->delta->location->src->src_size && token->delta->location->src->src[ending_of_real_line]!='\n' ;++ending_of_real_line);
				begining_of_real_line+=!!(begining_of_real_line);
				wonky_assert(begining_of_real_line<ending_of_real_line);
				wonky_write(s,token->delta->location->src->src+begining_of_real_line,ending_of_real_line-begining_of_real_line);
			}
			break;
		case WONKY__CONVERSION_WONKY_SOURCE_LOCATION:
			{
				struct Source_Location *loc=va_arg(args,struct Source_Location*);
				wonky_write(s,"[ ",2);
				if(loc->src->src_name)
					wonky_write(s,loc->src->src_name->name,loc->src->src_name->name_size);
				else
					wonky_write(s,"null",sizeof("null")-1);
				wonky_fprintf(s," %zu:%zu]",loc->line+1,loc->column);
			}
			break;
		case WONKY__CONVERSION_WONKY_TOKEN_RAW_TEXT:
			{
				struct token *token=va_arg(args,struct token*);
				print_raw_token_text(s,token);
			}
			break;
	}
}

ssize_t wonky__FILE_read(void *state,void *dst,size_t num_bytes)
{
	return fread(dst,1,num_bytes,(FILE*)state);
}
ssize_t wonky__FILE_write(void *state,void *src,size_t num_bytes)
{
	return fwrite(src,1,num_bytes,(FILE*)state);
}
_Bool wonky__FILE_fseek(void *state,size_t where,int whence)
{
	return !fseek((FILE*)state,where,whence);
}
_Bool wonky__FILE_eof(void *state)
{
	return feof((FILE*)state);
}

ssize_t wonky__fail_read(void *state,void *dst,size_t num_bytes)
{
	return -1;
}
ssize_t wonky__fail_write(void *state,void *src,size_t num_bytes)
{
	return -1;
}
_Bool wonky__fail_fseek(void *state,size_t where,int whence)
{
	return 0;
}
_Bool wonky__fail_eof(void *state)
{
	return 0;
}
struct wonky_stream wonky_stream_from_file(FILE *f)
{
	return (struct wonky_stream) {
		.read=wonky__FILE_read,
		.write=wonky__FILE_write,
		.fseek=wonky__FILE_fseek,
		.eof=wonky__FILE_eof,
		.type=WONKY_STREAM_TYPE_FILE,
		.state=f

	};
}
void wonky_stream_delete(struct wonky_stream *s)
{
	switch(s->type)
	{
		case WONKY_STREAM_TYPE_STRING:
			wonky_string_stream_delete(s);
			break;
#warning add FILE stream deletion code here :>
	}
}

/*
	%WE - message
	%Wt  - token
	%Wi  - indentation (short)
	%WI  - id
	%Wd  - denoted
	%WA  - ast
	%WT  - type
	%WAE - ast enum
	%Wo  - object
	%WC  - constant
	%WS  - source name
	%WSl - source location
	%WIC - inclusion chain (takes Token_Pointer )
	%WPC - token pointer context call stack ( takes Token_Pointer *)
	%WPc - token pointer context ( takes Token_Pointer_Context *)
	%WMA - macro argument
	%WMf - functionlike macro
	%Wtl - print line containing token ( takes token*)
	%Wtr - print raw token text ( takes token *)
 */
void wonky__parse_scan_format(const char *begining, struct wonky__scanformat *destination)
{
	destination->forward_crawl=1;
	destination->modifier=WONKY__MOD_END;
	destination->conversion=WONKY__CONVERSION_END;
	destination->alternate_form=0;
	if(begining[destination->forward_crawl]=='W')
	{
		destination->wonky_form=1;
		++destination->forward_crawl;
	}else
	{
		destination->wonky_form=0;
	}

	switch(begining[destination->forward_crawl])
	{
		case 'h':
			++destination->forward_crawl;
			if(begining[destination->forward_crawl]=='h')
			{
				++destination->forward_crawl;
				destination->modifier=WONKY__MOD_SHORT_SHORT;
			}else
			{
				destination->modifier=WONKY__MOD_SHORT;
			}
			break;
		case 'l':
			++destination->forward_crawl;
			if(begining[destination->forward_crawl]=='l')
			{
				++destination->forward_crawl;
				destination->modifier=WONKY__MOD_LONG_LONG;
			}else
			{
				destination->modifier=WONKY__MOD_LONG;
			}
			break;
		case 'L':
			++destination->forward_crawl;
			destination->modifier=WONKY__MOD_LONG_DOUBLE;
			break;
		case 'j':
			++destination->forward_crawl;
			destination->modifier=WONKY__MOD_INTMAX;
			break;
		case 'z':
			++destination->forward_crawl;
			destination->modifier=WONKY__MOD_SIZE_T;
			break;
		case 't':
			++destination->forward_crawl;
			if(destination->wonky_form)
			{
				if(begining[destination->forward_crawl]=='l')
				{
					++destination->forward_crawl;
					destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_LINE;
				} else if(begining[destination->forward_crawl]=='r')
				{
					++destination->forward_crawl;
					destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_RAW_TEXT;
				} else
				{
					destination->conversion=WONKY__CONVERSION_WONKY_TOKEN;
				}
				/*WARNING EARLY RETURN*/
				return;
			}else
			{
				destination->modifier=WONKY__MOD_PTRDIFF;
			}
			break;
	}
	switch(begining[destination->forward_crawl])
	{
		case 'd':
			++destination->forward_crawl;
			if(destination->wonky_form)
				destination->conversion=WONKY__CONVERSION_WONKY_DENOTED;
			else
				destination->conversion=WONKY__CONVERSION_INT_DECIMAL;
			break;
		case 'i':
			++destination->forward_crawl;
			if(destination->wonky_form)
				destination->conversion=WONKY__CONVERSION_WONKY_INDENTATION;
			else
				destination->conversion=WONKY__CONVERSION_INT_DECIMAL;
			break;
		case 'I':
			++destination->forward_crawl;
			if(destination->wonky_form)
			{
				if(begining[destination->forward_crawl]=='C')
				{
					destination->conversion=WONKY__CONVERSION_WONKY_INCLUSION_CHAIN;
					++destination->forward_crawl;
				}else
				{
					destination->conversion=WONKY__CONVERSION_WONKY_ID;
				}
			}
			break;
		case 'o':
			++destination->forward_crawl;
			if(destination->wonky_form)
				destination->conversion=WONKY__CONVERSION_WONKY_OBJECT;
			else
				destination->conversion=WONKY__CONVERSION_INT_OCTAL;
			break;
		case 'u':
			++destination->forward_crawl;
			destination->conversion=WONKY__CONVERSION_INT_UNSIGNED_DECIMAL;
			break;
		case 'x':
		case 'X':
			++destination->forward_crawl;
			destination->conversion=WONKY__CONVERSION_INT_HEXADECIMAL;
			break;
		case 'e':
			++destination->forward_crawl;
			destination->conversion=WONKY__CONVERSION_DOUBLE_EXPONENT;
			break;
		case 'E':
			++destination->forward_crawl;
			if(destination->wonky_form)
			{
				destination->conversion=WONKY__CONVERSION_WONKY_ERROR;
			}else
			{
				destination->conversion=WONKY__CONVERSION_DOUBLE_EXPONENT;
			}
			break;
		case 'f':
		case 'F':
		case 'g':
		case 'G':
			++destination->forward_crawl;
			destination->conversion=WONKY__CONVERSION_DOUBLE_DECIMAL;
			break;
		case 'a':
		case 'A':
			++destination->forward_crawl;
			if(destination->wonky_form)
			{
				if(begining[destination->forward_crawl]=='E')
				{
					destination->conversion=WONKY__CONVERSION_WONKY_AST_ENUM;
					++destination->forward_crawl;
				}else
				{
					destination->conversion=WONKY__CONVERSION_WONKY_AST;
				}
			}else
			{
				destination->conversion=WONKY__CONVERSION_DOUBLE_HEXADECIMAL;
			}
			break;
		case 'c':
			++destination->forward_crawl;
			destination->conversion=WONKY__CONVERSION_CHAR;
			break;
		case 's':
			++destination->forward_crawl;
			destination->conversion=WONKY__CONVERSION_CSTRING;
			break;
		case 'p':
			++destination->forward_crawl;
			destination->conversion=WONKY__CONVERSION_POINTER;
			break;
		case '%':
			++destination->forward_crawl;
			destination->conversion=WONKY__CONVERSION_PERCENT;
			break;
		case 'b':
			++destination->forward_crawl;
			destination->conversion=WONKY__CONVERSION_BITS;
			break;
		case 'T':
			++destination->forward_crawl;
			if(destination->wonky_form)
				destination->conversion=WONKY__CONVERSION_WONKY_TYPE;
			break;
		case 'C':
			++destination->forward_crawl;
			if(destination->wonky_form)
				destination->conversion=WONKY__CONVERSION_WONKY_CONSTANT;
			break;
		case 'S':
			++destination->forward_crawl;
			if(destination->wonky_form)
			{
				if(begining[destination->forward_crawl]=='l')
				{
					destination->conversion=WONKY__CONVERSION_WONKY_SOURCE_LOCATION;
					++destination->forward_crawl;
				}else
				{
					destination->conversion=WONKY__CONVERSION_WONKY_SOURCE_NAME;
				}
			}
			break;
		case 'P':
			++destination->forward_crawl;
			if(destination->wonky_form && begining[destination->forward_crawl]=='C')
			{
				destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_POINTER_CALL_STACK;
				++destination->forward_crawl;
			} else if(destination->wonky_form && begining[destination->forward_crawl]=='c')
			{
				destination->conversion=WONKY__CONVERSION_WONKY_TOKEN_POINTER_CONTEXT;
				++destination->forward_crawl;
			}
			break;
		case 'M':
			++destination->forward_crawl;
			if(destination->wonky_form && begining[destination->forward_crawl]=='A')
			{
				destination->conversion=WONKY__CONVERSION_WONKY_MACRO_ARGUMENT;
				++destination->forward_crawl;
			} else if(destination->wonky_form && begining[destination->forward_crawl]=='f')
			{
				destination->conversion=WONKY__CONVERSION_WONKY_FUNCTIONLIKE_MACRO;
				++destination->forward_crawl;
			}
			break;

	}
}




/*uint32_t takes care of endianness*/
_Bool wonky__float_is_negative(float f)
{
	return (*((uint32_t*)(void*)&f))&0x80000000u;
}

int16_t wonky__float_get_exponent(float f)
{
	return (((*((uint32_t*)(void*)&f))&0x7F800000u)>>23);
}
uint32_t wonky__float_get_mantissa(float f)
{
	return (*((uint32_t*)(void*)&f))&0x007FFFFFu;
}
float wonky__float_set_sign(float f,_Bool is_negative)
{
	uint32_t *as_uint=(void*)&f;
	if(is_negative)
		*as_uint=((*as_uint)|0x80000000u);
	else
		*as_uint=((*as_uint)&0x7FFFFFFFu);
	return *(float*)(void*)as_uint;
}
float wonky__float_set_exponent(float f,int16_t exponent)
{
	uint32_t *as_uint=(void*)&f;
	*as_uint=((*as_uint)&0x807FFFFFu)|((0xFu&(uint32_t)(exponent+0x7F))<<23);
	return *(float*)(void*)as_uint;
}
float wonky__float_set_base(float f,uint32_t base)
{
	uint32_t *as_uint=(void*)&f;
	*as_uint=((*as_uint)&0xFF800000u)|((0x007FFFFFu)&base);
	return *(float*)(void*)as_uint;
}
/*uint64_t takes care of endianness*/
_Bool wonky__double_is_negative(double d)
{
	return (*((uint64_t*)(void*)&d))&0x8000000000000000ull;
}
int16_t wonky__double_get_exponent(double d)
{
	return ((*((uint64_t*)(void*)&d))&0x7FF0000000000000ull)>>52;
}
uint64_t wonky__double_get_mantissa(double d)
{
	return (*((uint64_t*)(void*)&d))&0x000FFFFFFFFFFFFFull;
}
double wonky__double_set_sign(double d,_Bool is_negative)
{
	uint64_t *as_uint=(void*)&d;
	if(is_negative)
		*as_uint=((*as_uint)|0x8000000000000000ull);
	else
		*as_uint=((*as_uint)&0x7FFFFFFFFFFFFFFFull);
	return *(double*)(void*)as_uint;
}
double wonky__double_set_exponent(double d,int16_t exponent)
{
	uint64_t *as_uint=(void*)&d;
	*as_uint=((*as_uint)&0x800FFFFFFFFFFFFFull)|((0x7Fu&(uint64_t)exponent)<<52);
	return *(double*)(void*)as_uint;
}
double wonky__double_set_mantissa(double d,uint64_t mantissa)
{
	uint64_t *as_uint=(void*)&d;
	*as_uint=((*as_uint)&0xFFF0000000000000ull)|((0x000FFFFFFFFFFFFFull)&mantissa);
	return *(double*)(void*)as_uint;
}



#endif