WONKY



LOG | FILES | OVERVIEW


#ifndef WONKY_TRANSLATION_UNIT_H
#define WONKY_TRANSLATION_UNIT_H WONKY_TRANSLATION_UNIT_H
#include <translation_unit.hh>

#include <queue.h>
#include <source_file.h>
#include <wonky_malloc.h>
#include <wonky_assert.h>
#include <queue.h>
#include <source_file.h>
#include <macro.h>

struct Preprocessing_Translation_Unit
{
	struct Queue *tokens;
};
struct Token_Pointer_Context
{
	struct Queue_Node *current_token_node;
	size_t number_of_remaining_tokens;

	struct Queue *ungeted_tokens;
	size_t line;
	size_t column;
	char *filename;
	size_t filename_size;

	/*
		Blocks popping of context. This is useful
		when parsing expressions in preprocessing directives
		and in similar line oriented situations.
	*/
	_Bool barrier;

	/*
		points to the macro id if this context is the replacement tokens
		are what this context is iterating over.
		NULL otherwise
		NOTE: very english
	 */
	struct identifier *executed_macro_id; 

	/*
		MEGAHACK!	
	 */
	_Bool has_saved_functionlike_macro_state;
	struct Queue *functionlike_macro_arguments_save_state;
	struct functionlike_define_directive *saved_macro;

	/*
		bool to separate #include contexts from macro et al. ones 
	 */
	_Bool is_file_inclusion;
};
struct Token_Pointer
{
	struct Stack *call_stack;
	struct Token_Pointer_Context *context;
	struct Program *program;

	enum Token_Pointer_State state;
	_Bool is_in_conditional_directive;/*TODO move this into the state*/
	
	unsigned int next_barrier_number;

};

struct Preprocessing_Translation_Unit* get_preprocessing_translation_unit(struct Source_File *source);
void delete_preprocessing_translation_unit(struct Preprocessing_Translation_Unit *unit);
void delete_preprocessing_translation_unit_but_not_the_tokens(struct Preprocessing_Translation_Unit *unit);

void push_token_into_preprocessing_translation_unit(struct Preprocessing_Translation_Unit *unit,struct token *token);
struct token* token_ptr_get_token_under_pointer_in_preprocessing_directive(struct Token_Pointer *token_pointer);
struct token* token_ptr_get_token_under_pointer(struct Token_Pointer *token_pointer);
struct token* token_ptr_get_token_under_pointer_inner(struct Token_Pointer *token_pointer);
struct token* token_ptr_check_next_normal_token(struct Token_Pointer *token_pointer);
void token_ptr_goto_next_token(struct Token_Pointer *token_pointer);
void token_ptr_goto_next_normal_token(struct Token_Pointer *token_pointer);

struct Token_Pointer* get_token_ptr(struct Preprocessing_Translation_Unit *unit,struct Program *program);
void delete_token_ptr(struct Token_Pointer *ptr);
struct Token_Pointer_Context* get_token_ptr_context(struct Queue_Node *start,size_t number_of_remaining_tokens,_Bool is_file_inclusion);
void token_ptr_pop_context(struct Token_Pointer *ptr);

_Bool token_ptr_has_remaining_tokens(struct Token_Pointer *ptr);
_Bool token_ptr_has_remaining_tokens_in_current_context(struct Token_Pointer *ptr);

size_t token_ptr_get_functionlike_macro_number(struct Token_Pointer *ptr);

void token_ptr_unget_token(struct Token_Pointer *ptr,struct token *token);
void token_ptr_execute_include_directive(struct Token_Pointer *ptr,struct token_include_directive *include_directive);
void token_ptr_execute_if_directive(struct Token_Pointer *ptr,struct token_if_directive *if_directive);
void token_ptr_execute_ifdef_directive(struct Token_Pointer *ptr,struct token_ifdefndef_directive *ifdef_directive);
void token_ptr_execute_ifndef_directive(struct Token_Pointer *ptr,struct token_ifdefndef_directive *ifndef_directive);
void token_ptr_execute_normal_define_directive(struct Token_Pointer *ptr,struct token_normal_define_directive *define_directive);
void token_ptr_execute_functionlike_define_directive(struct Token_Pointer *ptr,struct token_functionlike_define_directive *define_directive);
void token_ptr_execute_undef_directive(struct Token_Pointer *ptr,struct token_undef_directive *undef_directive);
void token_ptr_execute_line_directive(struct Token_Pointer *ptr,struct token_line_directive *line_directive);
void token_ptr_execute_error_directive(struct Token_Pointer *ptr,struct token_error_directive *error_directive);
void token_ptr_execute_pragma_directive(struct Token_Pointer *ptr,struct token_pragma_directive *pragma_directive);
void token_ptr_execute_defined_unary_operator(struct Token_Pointer *ptr,struct token_defined_unary_operator *operator);
void token_ptr_execute_file_special_macro(struct Token_Pointer *ptr,struct token *directive);
void token_ptr_execute_line_special_macro(struct Token_Pointer *ptr,struct token *directive);
void token_ptr_execute_stdc_special_macro(struct Token_Pointer *ptr,struct token *directive);
void token_ptr_execute_stdc_hosted_special_macro(struct Token_Pointer *ptr,struct token *directive);
void token_ptr_execute_stdc_version_special_macro(struct Token_Pointer *ptr,struct token *directive);
void token_ptr_execute_macro(struct Token_Pointer *ptr,struct identifier *id);
void token_ptr_execute_normal_macro(struct Token_Pointer *ptr,struct normal_define_directive *macro);
void token_ptr_execute_functionlike_macro(struct Token_Pointer *ptr,struct functionlike_define_directive *macro);
void token_ptr_execute_functionlike_macro_argument(struct Token_Pointer *ptr,struct functionlike_define_directive_argument *argument);

void token_ptr_store_functionlike_macro_state_into_context(struct Token_Pointer_Context *ctx,struct functionlike_define_directive *macro);
void token_ptr_load_functionlike_macro_state_from_context(struct Token_Pointer_Context *ctx);



void token_ptr_execute_stringify_functionlike_macro_argument(struct Token_Pointer *ptr,struct token_hashtag_unary_operator *op);
void token_ptr_execute_concat_functionlike_macro_arguments(struct Token_Pointer *ptr,struct token_hashtag_hastag_operator *op);



void token_ptr_load_functionlike_macro_arguments_with_tokens(struct Token_Pointer *ptr,struct functionlike_define_directive *macro);
_Bool token_ptr_do_preprocessing_stuff(struct Token_Pointer *ptr,struct token *token);

void token_ptr_assume_location_of_token(struct Token_Pointer *ptr,struct token *token);

_Bool token_ptr_has_buffered_tokens(struct Token_Pointer *ptr);
struct token* token_ptr_get_buffered_token(struct Token_Pointer *ptr);
struct token* token_ptr_check_buffered_token(struct Token_Pointer *ptr);

struct Queue_Node* token_ptr_get_current_queue_node(struct Token_Pointer *ptr);

/*0 means no barrier in current context*/
unsigned int token_ptr_get_current_barrier_number(struct Token_Pointer *ptr);
/*returns set barrier number*/
void token_ptr_set_barrier(struct Token_Pointer *ptr);
void token_ptr_clear_barrier(struct Token_Pointer *ptr);

void token_ptr_jump_to(struct Token_Pointer *ptr,struct Queue_Node *where_to,size_t number_of_remaining_tokens,_Bool is_file_inclusion);
void token_ptr_jump_to_functionlike_macro_argument(struct Token_Pointer *ptr,struct functionlike_define_directive_argument *arg);
void token_ptr_jump_to_first(struct Token_Pointer *ptr,struct Queue *queue,_Bool is_file_inclusion);
void delete_token_ptr_context(struct Token_Pointer_Context *context);
#endif