#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