F diff --git a/build/cmake/include_directories.txt b/build/cmake/include_directories.txt --- a/build/cmake/include_directories.txt +++ b/build/cmake/include_directories.txtinclude_directories(src/backend)include_directories(src/backend/asm)include_directories(src/backend/asm/intel)- include_directories(src/backend/js)include_directories(src/backend/text)include_directories(src/backend/text/print)+ include_directories(src/backend/js)include_directories(src/debug)include_directories(src/debug/wobler)include_directories(src/environment)F diff --git a/build/cmake/libs/innards.txt b/build/cmake/libs/innards.txt --- a/build/cmake/libs/innards.txt +++ b/build/cmake/libs/innards.txtsrc/backend/asm/intel/intel_instruction.csrc/backend/asm/intel/intel_location.csrc/backend/compile.c- src/backend/text/lines.c- src/backend/text/print/print.csrc/debug/debug_ast.csrc/debug/debug_ast.csrc/debug/debug_denoted.cF diff --git a/build/cmake/libs/misc.txt b/build/cmake/libs/misc.txt --- a/build/cmake/libs/misc.txt +++ b/build/cmake/libs/misc.txtsrc/misc/stack.csrc/misc/wonky_malloc.csrc/misc/wonky_array.c+ src/misc/wonky_string.c+ src/misc/wonky_stream.c+ src/misc/print.c)F diff --git a/src/backend/asm/intel/intel_asm.c b/src/backend/asm/intel/intel_asm.c --- a/src/backend/asm/intel/intel_asm.c +++ b/src/backend/asm/intel/intel_asm.creturn ret;}- void save_compiled_intel_asm(struct Compiled_Object_Intel_Asm *object,FILE *out)+ void save_compiled_intel_asm(struct Compiled_Object_Intel_Asm *object,struct wonky_stream *out){struct Queue_Node *it;for(it=object->exports->first;it!=NULL;it=it->prev)for(it=object->instructions->first;it!=NULL;it=it->prev)save_intel_asm_instruction(it->data,out);}- void save_compiled_intel_asm_as_nasm(struct Compiled_Object_Intel_Asm *object,FILE *out)+ void save_compiled_intel_asm_as_nasm(struct Compiled_Object_Intel_Asm *object,struct wonky_stream *out){struct Queue_Node *it;- fprintf(out,"[BITS 64]\n\n");+ wonky_fprintf(out,"[BITS 64]\n\n");for(it=object->exports->first;it!=NULL;it=it->prev)save_intel_asm_instruction(it->data,out);for(it=object->imports->first;it!=NULL;it=it->prev)save_intel_asm_instruction(it->data,out);- fprintf(out,"\nsection .data\n");+ wonky_fprintf(out,"\nsection .data\n");for(it=object->data_block->first;it!=NULL;it=it->prev)save_intel_asm_instruction(it->data,out);- fprintf(out,"\nsection .text\n");+ wonky_fprintf(out,"\nsection .text\n");for(it=object->instructions->first;it!=NULL;it=it->prev)save_intel_asm_instruction(it->data,out);}F diff --git a/src/backend/asm/intel/intel_asm.h b/src/backend/asm/intel/intel_asm.h --- a/src/backend/asm/intel/intel_asm.h +++ b/src/backend/asm/intel/intel_asm.h#include <value.h>#include <constant.h>#include <wonky_malloc.h>+ #include <wonky_stream.h>struct Compile_Data_Intel_Asm{struct Compiled_Object_Intel_Asm* compile_program_to_intel_asm(struct Program *program);void compile_program_static_objects(struct Compile_Data *obj,struct Program *program);- void save_compiled_intel_asm(struct Compiled_Object_Intel_Asm *object,FILE *out);- void save_compiled_intel_asm_as_nasm(struct Compiled_Object_Intel_Asm *object,FILE *out);+ void save_compiled_intel_asm(struct Compiled_Object_Intel_Asm *object,struct wonky_stream *out);+ void save_compiled_intel_asm_as_nasm(struct Compiled_Object_Intel_Asm *object,struct wonky_stream *out);struct Compile_Data_Intel_Asm* get_compile_data_for_intel_asm();F diff --git a/src/backend/asm/intel/intel_instruction.c b/src/backend/asm/intel/intel_instruction.c --- a/src/backend/asm/intel/intel_instruction.c +++ b/src/backend/asm/intel/intel_instruction.c{return get_intel_asm_unary_instruction(get_intel_asm_register(reg),INTEL_ASM_OP_PUSH);}- void save_intel_asm_instruction(struct Intel_Asm_Instruction *instruction,FILE *out)+ void save_intel_asm_instruction(struct Intel_Asm_Instruction *instruction,struct wonky_stream *out){- typedef void (*map_entry)(void *,FILE *out);+ typedef void (*map_entry)(void *,struct wonky_stream *out);static const map_entry map[INTEL_ASM_OP_END]={wonky_assert(map[instruction->type]!=NULL);map[instruction->type](instruction,out);}- void save_intel_asm_label(struct Intel_Asm_Label *label,FILE *out)+ void save_intel_asm_label(struct Intel_Asm_Label *label,struct wonky_stream *out){- fprintf(out,"%s:\n",label->label_name);+ wonky_fprintf(out,"%s:\n",label->label_name);}- void save_intel_asm_import(struct Intel_Asm_Label *im,FILE *out)+ void save_intel_asm_import(struct Intel_Asm_Label *im,struct wonky_stream *out){- fprintf(out,"extern %s\n",im->label_name);+ wonky_fprintf(out,"extern %s\n",im->label_name);}- void save_intel_asm_export(struct Intel_Asm_Label *ex,FILE *out)+ void save_intel_asm_export(struct Intel_Asm_Label *ex,struct wonky_stream *out){- fprintf(out,"global %s\n",ex->label_name);+ wonky_fprintf(out,"global %s\n",ex->label_name);}- void save_intel_asm_binary_instruction(struct Intel_Asm_Instruction_Binary *bin,FILE *out)+ void save_intel_asm_binary_instruction(struct Intel_Asm_Instruction_Binary *bin,struct wonky_stream *out){const char *map[INTEL_ASM_OP_END]=[INTEL_ASM_OP_SAR]="SAR",};wonky_assert(map[bin->type]!=NULL);- fprintf(out,"%s ",map[bin->type]);+ wonky_fprintf(out,"%s ",map[bin->type]);save_intel_asm_location(bin->left,out);- fprintf(out,", ");+ wonky_fprintf(out,", ");save_intel_asm_location(bin->right,out);- fprintf(out,"\n");+ wonky_fprintf(out,"\n");}- void save_intel_asm_unary_instruction(struct Intel_Asm_Instruction_Unary *unary,FILE *out)+ void save_intel_asm_unary_instruction(struct Intel_Asm_Instruction_Unary *unary,struct wonky_stream *out){const char *map[INTEL_ASM_OP_END]=[INTEL_ASM_OP_NOT]="NOT",};wonky_assert(map[unary->type]!=NULL);- fprintf(out,"%s ",map[unary->type]);+ wonky_fprintf(out,"%s ",map[unary->type]);save_intel_asm_location(unary->operand,out);- fprintf(out,"\n");+ wonky_fprintf(out,"\n");}- void save_intel_asm_jump_instruction(struct Intel_Asm_Instruction_Jump *jmp,FILE *out)+ void save_intel_asm_jump_instruction(struct Intel_Asm_Instruction_Jump *jmp,struct wonky_stream *out){const char *map[INTEL_ASM_OP_END]=[INTEL_ASM_OP_JZ]="JZ",};wonky_assert(map[jmp->type]!=NULL);- fprintf(out,"%s %s",map[jmp->type],jmp->where_to->label_name);- fprintf(out,"\n");+ wonky_fprintf(out,"%s %s",map[jmp->type],jmp->where_to->label_name);+ wonky_fprintf(out,"\n");}- void save_intel_asm_simple_instruction(struct Intel_Asm_Instruction *instruction,FILE *out)+ void save_intel_asm_simple_instruction(struct Intel_Asm_Instruction *instruction,struct wonky_stream *out){static const char *map[INTEL_ASM_OP_END]=[INTEL_ASM_OP_NOP]="NOP",};wonky_assert(map[instruction->type]!=NULL);- fprintf(out,"%s\n",map[instruction->type]);+ wonky_fprintf(out,"%s\n",map[instruction->type]);}- void save_intel_asm_define_bytes(struct Intel_Asm_Instruction_Define_Bytes *instruction,FILE *out)+ void save_intel_asm_define_bytes(struct Intel_Asm_Instruction_Define_Bytes *instruction,struct wonky_stream *out){int i;- fprintf(out,"db ");+ wonky_fprintf(out,"db ");for(i=0;i<instruction->number_of_bytes;++i){- fprintf(out,"0x%x",instruction->bytes[i]);+ wonky_fprintf(out,"0x%x",instruction->bytes[i]);if(i<instruction->number_of_bytes-1)- fprintf(out,", ");+ wonky_fprintf(out,", ");}- fprintf(out,"\n");+ wonky_fprintf(out,"\n");}#endifF diff --git a/src/backend/asm/intel/intel_instruction.h b/src/backend/asm/intel/intel_instruction.h --- a/src/backend/asm/intel/intel_instruction.h +++ b/src/backend/asm/intel/intel_instruction.h#include <stdio.h>#include <stdlib.h>#include <wonky_malloc.h>+ #include <wonky_stream.h>struct Intel_Asm_Instruction{struct Intel_Asm_Instruction* intel_asm_get_pop(enum Intel_Asm_Memory_Location_Type reg);struct Intel_Asm_Instruction* intel_asm_get_push(enum Intel_Asm_Memory_Location_Type reg);- void save_intel_asm_instruction(struct Intel_Asm_Instruction *instruction,FILE *out);- void save_intel_asm_label(struct Intel_Asm_Label *label,FILE *out);- void save_intel_asm_import(struct Intel_Asm_Label *im,FILE *out);- void save_intel_asm_export(struct Intel_Asm_Label *ex,FILE *out);- void save_intel_asm_binary_instruction(struct Intel_Asm_Instruction_Binary *bin,FILE *out);- void save_intel_asm_unary_instruction(struct Intel_Asm_Instruction_Unary *unary,FILE *out);- void save_intel_asm_jump_instruction(struct Intel_Asm_Instruction_Jump *jmp,FILE *out);- void save_intel_asm_simple_instruction(struct Intel_Asm_Instruction *instruction,FILE *out);- void save_intel_asm_define_bytes(struct Intel_Asm_Instruction_Define_Bytes *instruction,FILE *out);+ void save_intel_asm_instruction(struct Intel_Asm_Instruction *instruction,struct wonky_stream *out);+ void save_intel_asm_label(struct Intel_Asm_Label *label,struct wonky_stream *out);+ void save_intel_asm_import(struct Intel_Asm_Label *im,struct wonky_stream *out);+ void save_intel_asm_export(struct Intel_Asm_Label *ex,struct wonky_stream *out);+ void save_intel_asm_binary_instruction(struct Intel_Asm_Instruction_Binary *bin,struct wonky_stream *out);+ void save_intel_asm_unary_instruction(struct Intel_Asm_Instruction_Unary *unary,struct wonky_stream *out);+ void save_intel_asm_jump_instruction(struct Intel_Asm_Instruction_Jump *jmp,struct wonky_stream *out);+ void save_intel_asm_simple_instruction(struct Intel_Asm_Instruction *instruction,struct wonky_stream *out);+ void save_intel_asm_define_bytes(struct Intel_Asm_Instruction_Define_Bytes *instruction,struct wonky_stream *out);#endifF diff --git a/src/backend/asm/intel/intel_location.c b/src/backend/asm/intel/intel_location.c --- a/src/backend/asm/intel/intel_location.c +++ b/src/backend/asm/intel/intel_location.c{return get_intel_asm_register(INTEL_ASM_REGISTER_DX);}- void save_intel_asm_label_location(struct Intel_Asm_Memory_Location_By_Label *label,FILE *out)+ void save_intel_asm_label_location(struct Intel_Asm_Memory_Location_By_Label *label,struct wonky_stream *out){- fprintf(out,"%s",label->label->label_name);+ wonky_fprintf(out,"%s",label->label->label_name);}- void save_intel_asm_by_stack_offset_location(struct Intel_Asm_Memory_Location_By_Stack_Offset *sp,FILE *out)+ void save_intel_asm_by_stack_offset_location(struct Intel_Asm_Memory_Location_By_Stack_Offset *sp,struct wonky_stream *out){if(sp->offset>=0)- fprintf(out,"%s [RBP-%d]",memory_size_map[sp->size],sp->offset);+ wonky_fprintf(out,"%s [RBP-%d]",memory_size_map[sp->size],sp->offset);else- fprintf(out,"%s [RBP+%d]",memory_size_map[sp->size],sp->offset);+ wonky_fprintf(out,"%s [RBP+%d]",memory_size_map[sp->size],sp->offset);}- void save_intel_asm_stack_offset_location(struct Intel_Asm_Memory_Location_Stack_Offset *sp,FILE *out)+ void save_intel_asm_stack_offset_location(struct Intel_Asm_Memory_Location_Stack_Offset *sp,struct wonky_stream *out){if(sp->offset>=0)- fprintf(out,"RBP-%d",sp->offset);+ wonky_fprintf(out,"RBP-%d",sp->offset);else- fprintf(out,"RBP+%d",sp->offset);+ wonky_fprintf(out,"RBP+%d",sp->offset);}- void save_intel_asm_by_register_location(struct Intel_Asm_Memory_Location_By_Register *reg,FILE *out)+ void save_intel_asm_by_register_location(struct Intel_Asm_Memory_Location_By_Register *reg,struct wonky_stream *out){wonky_assert(register_map[reg->reg]!=NULL);- fprintf(out,"%s [%s]",memory_size_map[reg->size],register_map[reg->reg]);+ wonky_fprintf(out,"%s [%s]",memory_size_map[reg->size],register_map[reg->reg]);}- void save_intel_asm_register_location(struct Intel_Asm_Memory_Location_Register *reg,FILE *out)+ void save_intel_asm_register_location(struct Intel_Asm_Memory_Location_Register *reg,struct wonky_stream *out){wonky_assert(register_map[reg->reg]!=NULL);- fprintf(out,"%s",register_map[reg->reg]);+ wonky_fprintf(out,"%s",register_map[reg->reg]);}- void save_intel_asm_location(struct Intel_Asm_Memory_Location *location,FILE *out)+ void save_intel_asm_location(struct Intel_Asm_Memory_Location *location,struct wonky_stream *out){- typedef void (*map_entry)(void *,FILE *out);+ typedef void (*map_entry)(void *,struct wonky_stream *out);static const map_entry map[INTEL_ASM_MEMORY_LOCATION_END]={wonky_assert(map[location->type]!=NULL);map[location->type](location,out);}- void save_intel_asm_number_in_instruction(struct Intel_Asm_Memory_Location_In_Instruction_Number *num,FILE *out)+ void save_intel_asm_number_in_instruction(struct Intel_Asm_Memory_Location_In_Instruction_Number *num,struct wonky_stream *out){- fprintf(out,"%d",num->number);+ wonky_fprintf(out,"%d",num->number);}#endifF diff --git a/src/backend/asm/intel/intel_location.h b/src/backend/asm/intel/intel_location.h --- a/src/backend/asm/intel/intel_location.h +++ b/src/backend/asm/intel/intel_location.h#include <stdio.h>#include <stdlib.h>#include <wonky_malloc.h>-+ #include <wonky_stream.h>int number;};- void save_intel_asm_location(struct Intel_Asm_Memory_Location *location,FILE *out);- void save_intel_asm_label_location(struct Intel_Asm_Memory_Location_By_Label *label,FILE *out);- void save_intel_asm_stack_offset_location(struct Intel_Asm_Memory_Location_Stack_Offset *sp,FILE *out);- void save_intel_asm_by_stack_offset_location(struct Intel_Asm_Memory_Location_By_Stack_Offset *sp,FILE *out);- void save_intel_asm_by_register_location(struct Intel_Asm_Memory_Location_By_Register *reg,FILE *out);- void save_intel_asm_register_location(struct Intel_Asm_Memory_Location_Register *reg,FILE *out);- void save_intel_asm_number_in_instruction(struct Intel_Asm_Memory_Location_In_Instruction_Number *num,FILE *out);+ void save_intel_asm_location(struct Intel_Asm_Memory_Location *location,struct wonky_stream *out);+ void save_intel_asm_label_location(struct Intel_Asm_Memory_Location_By_Label *label,struct wonky_stream *out);+ void save_intel_asm_stack_offset_location(struct Intel_Asm_Memory_Location_Stack_Offset *sp,struct wonky_stream *out);+ void save_intel_asm_by_stack_offset_location(struct Intel_Asm_Memory_Location_By_Stack_Offset *sp,struct wonky_stream *out);+ void save_intel_asm_by_register_location(struct Intel_Asm_Memory_Location_By_Register *reg,struct wonky_stream *out);+ void save_intel_asm_register_location(struct Intel_Asm_Memory_Location_Register *reg,struct wonky_stream *out);+ void save_intel_asm_number_in_instruction(struct Intel_Asm_Memory_Location_In_Instruction_Number *num,struct wonky_stream *out);struct Intel_Asm_Memory_Location* get_intel_asm_register(enum Intel_Asm_Registers reg);struct Intel_Asm_Memory_Location* get_intel_asm_by_register(enum Intel_Asm_Registers reg,size_t size);F diff --git a/src/backend/compile.c b/src/backend/compile.c --- a/src/backend/compile.c +++ b/src/backend/compile.c{switch(compile_to_what){- case COMPILE_TO_PRINT:- compile_program_for_print(program);- break;default:wonky_assert(SHOULD_NOT_REACH_HERE);}wonky_assert(SHOULD_NOT_REACH_HERE);}- void save_compiled_object(struct Compiled_Object *object,FILE *out)+ void save_compiled_object(struct Compiled_Object *object,struct wonky_stream *out){switch(object->type){- case COMPILE_TO_PRINT:- save_compiled_object_for_print((struct Compiled_Object_Print*)object,out);- break;default:wonky_assert(SHOULD_NOT_REACH_HERE);}F diff --git a/src/backend/compile.h b/src/backend/compile.h --- a/src/backend/compile.h +++ b/src/backend/compile.h#include <print.h>#include <stdio.h>#include <queue.h>+ #include <wonky_stream.h>struct Compile_Data{struct Compiled_Object* compile_program(struct Program *program,enum Compilation_Type compile_to_what);- void save_compiled_object(struct Compiled_Object *object,FILE *out);+ void save_compiled_object(struct Compiled_Object *object,struct wonky_stream *out);#endifF diff --git a/src/backend/text/lines.c b/src/backend/text/lines.c deleted file mode 100644 --- a/src/backend/text/lines.c +++ /dev/null- #ifndef WONKY_LINES_C- #define WONKY_LINES_C WONKY_LINES_C- #include <lines.h>-- void push_line(char *string,int indent,struct Queue *where_to_push_the_line)- {- struct Line *line;- line=wonky_malloc(sizeof(struct Line));- line->data=string;- line->indent=indent;-- Queue_Push(where_to_push_the_line,line);- }-- void append_to_last_line(char *string,struct Queue *line_queue)- {- struct Line *last_line;-- wonky_assert(line_queue->size>0);-- last_line=line_queue->last->data;-- last_line->data=gstr_append_and_consume(last_line->data,string);- }- #endifF diff --git a/src/backend/text/lines.h b/src/backend/text/lines.h deleted file mode 100644 --- a/src/backend/text/lines.h +++ /dev/null- #ifndef WONKY_LINES_H- #define WONKY_LINES_H WONKY_LINES_H- #include <lines.hh>- #include <queue.h>- #include <gcc_string.h>- #include <wonky_assert.h>- #include <wonky_malloc.h>--- struct Line- {- char *data;- int indent;- };-- /*consumes string*/- void push_line(char *string,int indent,struct Queue *where_to_push_the_line);- void append_to_last_line(char *string,struct Queue *line_queue);-- #endifF diff --git a/src/backend/text/lines.hh b/src/backend/text/lines.hh deleted file mode 100644 --- a/src/backend/text/lines.hh +++ /dev/null- #ifndef WONKY_LINES_HH- #define WONKY_LINES_HH WONKY_LINES_HH-- struct Line;-- #endifF diff --git a/src/backend/text/print/print.c b/src/backend/text/print/print.c deleted file mode 100644 --- a/src/backend/text/print/print.c +++ /dev/null- #ifndef WONKY_PRINT- #define WONKY_PRINT WONKY_PRINT- #include <print.h>-- struct Compiled_Object_Print* get_print_compile_object(struct Queue *lines)- {- struct Compiled_Object_Print *ret;-- ret=wonky_malloc(sizeof(struct Compiled_Object_Print));- ret->type=COMPILE_TO_PRINT;- ret->lines=lines;-- return ret;- }- struct Compile_Data_Print* get_print_compile_data()- {- struct Compile_Data_Print *ret;-- ret=wonky_malloc(sizeof(struct Compile_Data_Print));- ret->type=COMPILE_TO_PRINT;- ret->indent=0;-- ret->lines=wonky_malloc(sizeof(struct Queue));- Queue_Init(ret->lines);-- ret->errors=wonky_malloc(sizeof(struct Queue));- Queue_Init(ret->errors);-- return ret;-- }- struct Compiled_Object_Print* compile_program_for_print(struct Program *program)- {- struct Compile_Data_Print *compile_data;- struct Compiled_Object_Print *ret;-- compile_data=get_print_compile_data();- print_program_ast(compile_data,program);-- ret=get_print_compile_object(compile_data->lines);-- wonky_free(compile_data);-- return ret;- }- void save_compiled_object_for_print(struct Compiled_Object_Print *object,FILE *out)- {- struct Queue_Node *it;- struct Line *current_line;- int i;- for(it=object->lines->first;it!=NULL;it=it->prev)- {- current_line=it->data; /*TODO add assert is valid line*/-- for(i=0;i<current_line->indent;++i)- fprintf(out,"\t");- fputs(current_line->data,out);- fputs("\n",out);- }- }-- void print_token(struct Compile_Data_Print *compile_data,struct token *token)- {- push_line(gstr_to_heap("[ "),compile_data->indent,compile_data->lines);- switch(token->type)- {- case KW_AUTO:- append_to_last_line("AUTO",compile_data->lines);- break;- case KW_DO:- append_to_last_line("DO",compile_data->lines);- break;- case KW_DOUBLE:- append_to_last_line("DOUBLE",compile_data->lines);- break;- case KW_INT:- append_to_last_line("INT",compile_data->lines);- break;- case KW_STRUCT:- append_to_last_line("STRUCT",compile_data->lines);- break;- case KW_BREAK:- append_to_last_line("BREAK",compile_data->lines);- break;- case KW_ELSE:- append_to_last_line("ELSE",compile_data->lines);- break;- case KW_LONG:- append_to_last_line("LONG",compile_data->lines);- break;- case KW_SWITCH:- append_to_last_line("SWITCH",compile_data->lines);- break;- case KW_CASE:- append_to_last_line("CASE",compile_data->lines);- break;- case KW_ENUM:- append_to_last_line("ENUM",compile_data->lines);- break;- case KW_REGISTER:- append_to_last_line("REGISTER",compile_data->lines);- break;- case KW_TYPEDEF:- append_to_last_line("TYPEDEF",compile_data->lines);- break;- case KW_CHAR:- append_to_last_line("CHAR",compile_data->lines);- break;- case KW_EXTERN:- append_to_last_line("EXTERN",compile_data->lines);- break;- case KW_RETURN:- append_to_last_line("RETURN",compile_data->lines);- break;- case KW_UNION:- append_to_last_line("UNION",compile_data->lines);- break;- case KW_CONST:- append_to_last_line("CONST",compile_data->lines);- break;- case KW_FLOAT:- append_to_last_line("FLOAT",compile_data->lines);- break;- case KW_SHORT:- append_to_last_line("SHORT",compile_data->lines);- break;- case KW_UNSIGNED:- append_to_last_line("UNSIGNED",compile_data->lines);- break;- case KW_CONTINUE:- append_to_last_line("CONTINUE",compile_data->lines);- break;- case KW_FOR:- append_to_last_line("FOR",compile_data->lines);- break;- case KW_SIGNED:- append_to_last_line("SIGNED",compile_data->lines);- break;- case KW_VOID:- append_to_last_line("VOID",compile_data->lines);- break;- case KW_DEFAULT:- append_to_last_line("DEFAULT",compile_data->lines);- break;- case KW_GOTO:- append_to_last_line("GOTO",compile_data->lines);- break;- case KW_SIZEOF:- append_to_last_line("SIZEOF",compile_data->lines);- break;- case KW_VOLATILE:- append_to_last_line("VOLATILE",compile_data->lines);- break;- case KW_IF:- append_to_last_line("IF",compile_data->lines);- break;- case KW_STATIC:- append_to_last_line("STATIC",compile_data->lines);- break;- case KW_WHILE:- append_to_last_line("WHILE",compile_data->lines);- break;- case KW_EXCLAMATION:- append_to_last_line("!",compile_data->lines);- break;- case KW_PERCENT:- append_to_last_line("%",compile_data->lines);- break;- case KW_AND:- append_to_last_line("&",compile_data->lines);- break;- case KW_AND_AND:- append_to_last_line("&&",compile_data->lines);- break;- case KW_OPEN_NORMAL:- append_to_last_line("(",compile_data->lines);- break;- case KW_CLOSE_NORMAL:- append_to_last_line(")",compile_data->lines);- break;- case KW_STAR:- append_to_last_line("*",compile_data->lines);- break;- case KW_PLUS:- append_to_last_line("+",compile_data->lines);- break;- case KW_COMMA:- append_to_last_line(",",compile_data->lines);- break;- case KW_MINUS:- append_to_last_line("-",compile_data->lines);- break;- case KW_DOT:- append_to_last_line(".",compile_data->lines);- break;- case KW_ARROW:- append_to_last_line("->",compile_data->lines);- break;- case KW_COLUMN:- append_to_last_line(":",compile_data->lines);- break;- case KW_SEMICOLON:- append_to_last_line(";",compile_data->lines);- break;- case KW_LESS:- append_to_last_line("<",compile_data->lines);- break;- case KW_EQ:- append_to_last_line("=",compile_data->lines);- break;- case KW_EQEQ:- append_to_last_line("==",compile_data->lines);- break;- case KW_MORE:- append_to_last_line(">",compile_data->lines);- break;- case KW_QUESTION:- append_to_last_line("?",compile_data->lines);- break;- case KW_HAT:- append_to_last_line("^",compile_data->lines);- break;- case KW_PIPE:- append_to_last_line("|",compile_data->lines);- break;- case KW_PIPE_PIPE:- append_to_last_line("||",compile_data->lines);- break;- case KW_TILDE:- append_to_last_line("~",compile_data->lines);- break;- case KW_PLUSPLUS:- append_to_last_line("++",compile_data->lines);- break;- case KW_MINUSMINUS:- append_to_last_line("--",compile_data->lines);- break;- case KW_SHIFT_RIGHT:- append_to_last_line(">>",compile_data->lines);- break;- case KW_SHIFT_LEFT:- append_to_last_line("<<",compile_data->lines);- break;- case KW_LESS_EQ:- append_to_last_line("<=",compile_data->lines);- break;- case KW_MORE_EQ:- append_to_last_line(">=",compile_data->lines);- break;- case KW_NOT_EQ:- append_to_last_line("!=",compile_data->lines);- break;- case KW_PLUS_EQ:- append_to_last_line("+=",compile_data->lines);- break;- case KW_MINUS_EQ:- append_to_last_line("-=",compile_data->lines);- break;- case KW_STAR_EQ:- append_to_last_line("*=",compile_data->lines);- break;- case KW_PERCENT_EQ:- append_to_last_line("%=",compile_data->lines);- break;- case KW_SHIFT_LEFT_EQ:- append_to_last_line("<<=",compile_data->lines);- break;- case KW_SHIFT_RIGHT_EQ:- append_to_last_line(">>=",compile_data->lines);- break;- case KW_AND_EQ:- append_to_last_line("&=",compile_data->lines);- break;- case KW_HAT_EQ:- append_to_last_line("^=",compile_data->lines);- break;- case KW_PIPE_EQ:- append_to_last_line("|=",compile_data->lines);- break;- case KW_HASHTAG:- append_to_last_line("#",compile_data->lines);- break;- case KW_HASHTAG_HASHTAG:- append_to_last_line("##",compile_data->lines);- break;- case KW_ELIPSIS:- append_to_last_line("...",compile_data->lines);- break;- case KW_DIV:- append_to_last_line("/",compile_data->lines);- break;- case KW_INLINE:- append_to_last_line("INLINE",compile_data->lines);- break;- case KW_RESTRICT:- append_to_last_line("RESTRICT",compile_data->lines);- break;- case KW_BOOL:- append_to_last_line("_BOOL",compile_data->lines);- break;- case KW_COMPLEX:- append_to_last_line("_COMPLEX",compile_data->lines);- break;- case KW_IMAGINARY:- append_to_last_line("_IMAGINARY",compile_data->lines);- break;- case KW_OPEN_SQUARE:- append_to_last_line("[",compile_data->lines);- break;- case KW_CLOSE_SQUARE:- append_to_last_line("]",compile_data->lines);- break;- case KW_CLOSE_CURLY:- append_to_last_line("}",compile_data->lines);- break;- case KW_OPEN_CURLY:- append_to_last_line("{",compile_data->lines);- break;- case KW_DIV_EQ:- append_to_last_line("/=",compile_data->lines);- break;- case KW_FORWARD_SLASH:- append_to_last_line("/",compile_data->lines);- break;- case KW_NOTYPE:- append_to_last_line("NOTYPE",compile_data->lines);- 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:- append_to_last_line("CONSTANT",compile_data->lines);- break;- case KW_ID:- append_to_last_line("ID ",compile_data->lines);- print_id(compile_data,((struct token_identifier*)token)->id);- break;- case KW_STRING:- case KW_WIDE_STRING:- append_to_last_line("STRING",compile_data->lines);- break;-- default:- append_to_last_line("NOTYPE",compile_data->lines);-- }- append_to_last_line(" ]",compile_data->lines);- }-- char print_tokens_of_program(FILE *out,char **base_source_names)- {-- struct Source_File *src;- struct Program *program;- struct Token_Pointer *ptr;- struct Compile_Data_Print *data;- struct Compiled_Object_Print *obj;- 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();- data=get_print_compile_data();-- 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)- {- ret=1;- print_errors(out,program->errors);- break;- }-- fprintf(out,"\nTOKENS OF %s {\n",base_source_names[0]);-- ptr=get_token_ptr(hold_unit,program);- print_tokens(out,ptr,data);-- obj=get_print_compile_object(data->lines);- save_compiled_object_for_print(obj,out);-- fprintf(out,"\n} END OF TOKENS\n");- ++program->current_translation_unit_number;- }while(*(++base_source_names));--- return ret;- }- void print_tokens(FILE *out,struct Token_Pointer *ptr,struct Compile_Data_Print *data)- {- while(token_ptr_has_remaining_tokens(ptr))- {- print_token(data,token_ptr_get_token_under_pointer(ptr));- }- }-- void print_ast_enum(struct Compile_Data_Print *compile_data,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));- if(map[op]==NULL)- {-- }else- {- char *hold;- hold=gstr_to_heap(map[op]);- append_to_last_line(hold,compile_data->lines);- }- }-- void print_error_tree(struct Compile_Data_Print *compile_data,struct AST_Error *error)- {- append_to_last_line(gstr_to_heap("ERROR"),compile_data->lines);- if(error->error!=NULL)- {- print_ast(compile_data,error->error);- }- }- void print_designator_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Designator *designator)- {- print_id(compile_data,designator->id);- }- void print_binary_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Binary_Expression *bin)- {- if(bin->type==OP_ARR_SUBSCRIPT)- {- print_ast(compile_data,(struct AST*)bin->left);- append_to_last_line(gstr_to_heap("["),compile_data->lines);- print_ast(compile_data,(struct AST*)bin->right);- append_to_last_line(gstr_to_heap("]"),compile_data->lines);- }else- {- append_to_last_line(gstr_to_heap("("),compile_data->lines);- print_ast(compile_data,(struct AST*)bin->left);- print_ast_enum(compile_data,bin->type);- print_ast(compile_data,(struct AST*)bin->right);- append_to_last_line(gstr_to_heap(")"),compile_data->lines);- }- }- void print_conditional_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Conditional_Expression *cond)- {- append_to_last_line(gstr_to_heap("("),compile_data->lines);- print_ast(compile_data,(struct AST*)cond->left);- append_to_last_line(gstr_to_heap("?"),compile_data->lines);- print_ast(compile_data,(struct AST*)cond->center);- append_to_last_line(gstr_to_heap(":"),compile_data->lines);- print_ast(compile_data,(struct AST*)cond->right);- append_to_last_line(gstr_to_heap(")"),compile_data->lines);- }- void print_function_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Function_Expression *function_call)- {- size_t i;- print_ast(compile_data,(struct AST*)function_call->id);- append_to_last_line(gstr_to_heap("("),compile_data->lines);-- if(function_call->number_of_arguments>0)- {- for(i=0;i<function_call->number_of_arguments;++i)- {- print_ast(compile_data,(struct AST*)function_call->arg_list[i]);- if(i!=function_call->number_of_arguments-1)- append_to_last_line(gstr_to_heap(","),compile_data->lines);- }- }- append_to_last_line(gstr_to_heap(")"),compile_data->lines);- }- void print_unary_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Unary_Expression *unary_expression)- {- if(unary_expression->type==OP_CAST)- {- append_to_last_line(gstr_to_heap("("),compile_data->lines);- print_expression_value_type(compile_data,unary_expression->value);- append_to_last_line(gstr_to_heap(")("),compile_data->lines);-- print_ast(compile_data,(struct AST*)unary_expression->operand);- append_to_last_line(gstr_to_heap(")"),compile_data->lines);- }else- {- print_ast_enum(compile_data,unary_expression->type);- print_ast(compile_data,(struct AST*)unary_expression->operand);- }- }- void print_labeled_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Labeled_Statement *lab)- {- if(lab->type!=ST_LABEL)- print_ast_enum(compile_data,lab->type);- if(lab->label!=NULL)- print_denoted(compile_data,(struct Denoted*)lab->label);- }- void print_compound_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Compound_Statement *comp)- {- struct Queue_Node *it;- push_line(gstr_to_heap("{"),compile_data->indent,compile_data->lines);- ++compile_data->indent;- for(it=comp->components->first;it!=NULL;it=it->prev)- {- push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)(struct AST*)(it->data));- append_to_last_line(gstr_to_heap(";"),compile_data->lines);- }- --compile_data->indent;- push_line(gstr_to_heap("}"),compile_data->indent,compile_data->lines);- }- void print_if_statement_tree(struct Compile_Data_Print *compile_data,struct AST_If_Statement *ifs)- {- push_line(gstr_to_heap("if("),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)ifs->condition);- append_to_last_line(gstr_to_heap(")"),compile_data->lines);-- push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)ifs->body_statement);-- if(ifs->else_statement!=NULL)- {- push_line(gstr_to_heap("else"),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)ifs->else_statement);- }-- }- void print_switch_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Switch_Statement *swi)- {- push_line(gstr_to_heap("switch("),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)swi->condition);- append_to_last_line(gstr_to_heap(")"),compile_data->lines);-- push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)swi->body_statement);- }- void print_while_statement_tree(struct Compile_Data_Print *compile_data,struct AST_While_Statement *whi)- {- push_line(gstr_to_heap("while("),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)whi->condition);- append_to_last_line(gstr_to_heap(")"),compile_data->lines);-- push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)whi->body_statement);- }- void print_do_while_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Do_While_Statement *whi)- {- push_line(gstr_to_heap("do"),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)whi->body_statement);-- push_line(gstr_to_heap("while("),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)whi->condition);- append_to_last_line(gstr_to_heap(")"),compile_data->lines);- }- void print_for_statement_tree(struct Compile_Data_Print *compile_data,struct AST_For_Statement *fo)- {- push_line(gstr_to_heap("for("),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)fo->initialisation);-- push_line(gstr_to_heap(";"),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)fo->condition);-- push_line(gstr_to_heap(";"),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)fo->update);-- push_line(gstr_to_heap(")"),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)fo->body_statement);- }- void print_return_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Return_Statement *return_expression)- {- push_line(gstr_to_heap("return "),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)return_expression->return_expression);- }- void print_goto_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Goto_Statement *got)- {- push_line(gstr_to_heap("goto"),compile_data->indent,compile_data->lines);- print_denoted(compile_data,(struct Denoted*)got->label);- }-- void print_type(struct Compile_Data_Print *compile_data,struct Type *type,char should_print_struct_union)- {- print_type_qualifier(compile_data,type);- print_type_sign(compile_data,type);- print_type_constraint(compile_data,type);-- switch(type->specifier)- {- case TS_VOID:- append_to_last_line(gstr_to_heap(" void"),compile_data->lines);- return;- case TS_CHAR:- append_to_last_line(gstr_to_heap(" char"),compile_data->lines);- return;- case TS_INT:- append_to_last_line(gstr_to_heap(" int"),compile_data->lines);- return;- case TS_FLOAT:- append_to_last_line(gstr_to_heap(" float"),compile_data->lines);- return;- case TS_DOUBLE:- append_to_last_line(gstr_to_heap(" double"),compile_data->lines);- return;- case TS_UNION:- case TS_STRUCT:- if(should_print_struct_union)- {- print_struct_union(compile_data,((struct Type_Struct_Union*)type)->struct_union);- }else- {- append_to_last_line( gstr_to_heap((type->specifier==TS_STRUCT?"struct":"union")),- compile_data->lines- );- }- return;- case TS_ENUM:- print_enumeration(compile_data,((struct Type_Enum*)type)->enumeration);- return;- case TS_POINTER:- append_to_last_line(gstr_to_heap(" pointer to"),compile_data->lines);- print_type(compile_data,((struct Type_Pointer*)type)->points_to,0);- return;- case TS_ARRAY:- {- char *number_of_elements;- number_of_elements=wonky_calloc(1,1024);-- if(snprintf(number_of_elements,1024," array [%zu] of ",((struct Type_Array*)type)->number_of_elements)==1024)- number_of_elements[1023]='\0';- append_to_last_line(number_of_elements,compile_data->lines);-- print_type(compile_data,((struct Type_Array*)type)->is_array_of,should_print_struct_union);- return;- }- case TS_FUNC:- append_to_last_line(gstr_to_heap(" function taking arguments ("),compile_data->lines);- print_function_args(compile_data,(struct Type_Function*)type);- append_to_last_line(gstr_to_heap(") returning"),compile_data->lines);- print_type(compile_data,((struct Type_Function*)type)->return_type,should_print_struct_union);- return;- case TS_NONE:- append_to_last_line(gstr_to_heap(" NONE "),compile_data->lines);- return;- case TS_ERROR:- append_to_last_line(gstr_to_heap(" ERROR! "),compile_data->lines);- return;-- }- wonky_assert(SHOULD_NOT_REACH_HERE);- }- void print_denoted(struct Compile_Data_Print *compile_data,struct Denoted *denoted)- {-- switch(denoted->denotation)- {- case DT_Macro:- append_to_last_line(gstr_to_heap("macro"),compile_data->lines);- return;- case DT_Macro_Parameter:- append_to_last_line(gstr_to_heap("macro parameter"),compile_data->lines);- return;- case DT_Statement:- append_to_last_line(gstr_to_heap("label"),compile_data->lines);- return;- case DT_Object:- switch(((struct Denoted_Object*)denoted)->linkage)- {- case LINKAGE_INTERNAL:- append_to_last_line(gstr_to_heap("internally linked "),compile_data->lines);- break;- case LINKAGE_EXTERNAL:- append_to_last_line(gstr_to_heap("externally linked "),compile_data->lines);- break;- case LINKAGE_NONE:- break;- default:- wonky_assert(SHOULD_NOT_REACH_HERE);- }- append_to_last_line(gstr_to_heap("denoted object "),compile_data->lines);- print_id(compile_data,((struct Denoted_Object*)denoted)->id);- print_object(compile_data,((struct Denoted_Object*)denoted)->object);- append_to_last_line(gstr_to_heap(" is a"),compile_data->lines);- print_type(compile_data,((struct Denoted_Object*)denoted)->object->type,1);- return;- case DT_Typedef:- append_to_last_line(gstr_to_heap("typedef "),compile_data->lines);- print_id(compile_data,((struct Denoted_Type*)denoted)->id);- append_to_last_line(gstr_to_heap(" to "),compile_data->lines);- print_type(compile_data,((struct Denoted_Type*)denoted)->type,0);- return;- case DT_Function:- print_id(compile_data,((struct Denoted_Function*)denoted)->id);- append_to_last_line(gstr_to_heap(" is "),compile_data->lines);- switch(((struct Denoted_Function*)denoted)->linkage)- {- case LINKAGE_INTERNAL:- append_to_last_line(gstr_to_heap("an internally linked"),compile_data->lines);- break;- case LINKAGE_EXTERNAL:- append_to_last_line(gstr_to_heap("an externally linked"),compile_data->lines);- break;- case LINKAGE_NONE:- break;- default:- wonky_assert(SHOULD_NOT_REACH_HERE);- }- print_type(compile_data,((struct Denoted_Function*)denoted)->type,1);- return;- case DT_Enum:- print_id(compile_data,((struct Denoted_Enum*)denoted)->enumeration->id);- append_to_last_line(gstr_to_heap(" is "),compile_data->lines);- print_enumeration(compile_data,((struct Denoted_Enum*)denoted)->enumeration);- return;- case DT_Enum_Constant:- {- char *value;- value=wonky_malloc(1024);- if(snprintf(value,1024,"%d ",((struct Denoted_Enum_Const*)denoted)->value)==1024)- value[1023]='\0';- append_to_last_line(value,compile_data->lines);- return;- }- case DT_Struct_Union_Tag:- print_id(compile_data,((struct Denoted_Struct_Union*)denoted)->struct_union->id);- append_to_last_line(gstr_to_heap(" is "),compile_data->lines);- print_struct_union(compile_data,((struct Denoted_Struct_Union*)denoted)->struct_union);- return;- case DT_Error:- append_to_last_line(gstr_to_heap("denotation error"),compile_data->lines);- return;- case DT_Prototype:- append_to_last_line(gstr_to_heap("denotation prototype"),compile_data->lines);- return;- default:- wonky_assert(SHOULD_NOT_REACH_HERE);-- }- }- void print_list_of_denoted(struct Compile_Data_Print *compile_data,struct Queue *denoted)- {- struct Queue_Node *it;- for(it=denoted->first;it!=NULL;it=it->prev)- {- print_denoted(compile_data,(struct Denoted*)it->data);- if(it->prev!=NULL)- append_to_last_line(gstr_to_heap(","),compile_data->lines);- }- }- void print_enumeration(struct Compile_Data_Print *compile_data,struct Enum *enumeration)- {- append_to_last_line(gstr_to_heap("enum "),compile_data->lines);- print_list_of_denoted(compile_data,enumeration->consts);- }- void print_struct_union(struct Compile_Data_Print *compile_data,struct Struct_Union *struct_union)- {- switch(struct_union->specifier)- {- case TS_UNION:- append_to_last_line(gstr_to_heap("union "),compile_data->lines);- break;- case TS_STRUCT:- append_to_last_line(gstr_to_heap("struct "),compile_data->lines);- break;- default:- wonky_assert(SHOULD_NOT_REACH_HERE);- }- append_to_last_line(gstr_to_heap("{"),compile_data->lines);- print_list_of_denoted(compile_data,struct_union->members);- append_to_last_line(gstr_to_heap("}"),compile_data->lines);-- }- void print_object(struct Compile_Data_Print *compile_data,struct Object *object)- {- if(object->kind==OBJECT_KIND_NORMAL)- {- print_normal_object(compile_data,object);- }else- {- print_bitfield_object(compile_data,(struct Object_Bitfield*)object);- }- }- void print_normal_object(struct Compile_Data_Print *compile_data,struct Object *object)- {- append_to_last_line(gstr_to_heap(" normal object that"),compile_data->lines);- }- void print_bitfield_object(struct Compile_Data_Print *compile_data,struct Object_Bitfield *object)- {- char *str;-- str=wonky_calloc(1,1024);-- if(snprintf(str,1024," bitfield object with %zu bits ",object->number_of_bits)==1024)- str[1023]='\0';- append_to_last_line(str,compile_data->lines);- }- void print_translation_unit_tree(struct Compile_Data_Print *compile_data,struct AST_Translation_Unit *unit)- {- 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(compile_data,(struct AST*)hold);- if(hold->type!=ST_FUNCTION_DEFINITION)- {- append_to_last_line(gstr_to_heap(";"),compile_data->lines);- push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);- }- }- }- void print_ast(struct Compile_Data_Print *compile_data,struct AST* tree)- {- if(tree==NULL)- {- append_to_last_line(gstr_to_heap("NULL"),compile_data->lines);- return;- }- switch(tree->type)- {- case OP_DESIGNATOR:- print_designator_expression_tree(compile_data,(struct AST_Designator*)tree);- 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(compile_data,(struct AST_Binary_Expression*)tree);- break;- case OP_COND:- print_conditional_expression_tree(compile_data,(struct AST_Conditional_Expression*)tree);- break;- case OP_FUNCTION:- print_function_expression_tree(compile_data,(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(compile_data,(struct AST_Unary_Expression*)tree);- break;- case OP_STRING_LITERAL:- print_string_literal(compile_data,(struct AST_String_Literal*)tree);- break;- case OP_CONSTANT:- print_constant_tree(compile_data,(struct AST_Constant*)tree);- break;- case OP_NOP:- append_to_last_line(gstr_to_heap("NOP"),compile_data->lines);- break;- case ST_SWITCH:- print_switch_statement_tree(compile_data,(struct AST_Switch_Statement*)tree);- break;- case ST_IF:- print_if_statement_tree(compile_data,(struct AST_If_Statement*)tree);- break;- case ST_WHILE:- print_while_statement_tree(compile_data,(struct AST_While_Statement*)tree);- break;- case ST_DO_WHILE:- print_do_while_statement_tree(compile_data,(struct AST_Do_While_Statement*)tree);- break;- case ST_GOTO:- print_goto_statement_tree(compile_data,(struct AST_Goto_Statement*)tree);- break;- case ST_DEFAULT:- case ST_LABEL:- case ST_CASE:- print_labeled_statement_tree(compile_data,(struct AST_Labeled_Statement*)tree);- break;- case ST_CONTINUE:- append_to_last_line(gstr_to_heap("continue"),compile_data->lines);- break;- case ST_BREAK:- append_to_last_line(gstr_to_heap("break"),compile_data->lines);- break;- case ST_RETURN:- print_return_statement_tree(compile_data,(struct AST_Return_Statement*)tree);- break;- case ST_FOR:- print_for_statement_tree(compile_data,(struct AST_For_Statement*)tree);- break;- case ST_COMPOUND:- print_compound_statement_tree(compile_data,(struct AST_Compound_Statement*)tree);- break;- case ST_OBJECT_DECLARATION:- print_denoted(compile_data,(struct Denoted*)((struct AST_Object_Declaration*)tree)->object);- break;- case ST_TYPE_DEFINITION:- print_denoted(compile_data,(struct Denoted*)((struct AST_Type_Definition*)tree)->definition);- break;- case ST_FUNCTION_DECLARATION:- print_denoted(compile_data,(struct Denoted*)((struct AST_Function_Declaration*)tree)->function);- break;- case ST_FUNCTION_DEFINITION:- print_function_definition(compile_data,(struct AST_Function_Definition*)tree);- break;- case TRANSLATION_UNIT:- print_translation_unit_tree(compile_data,(struct AST_Translation_Unit*)tree);- break;- case ERROR:- print_error_tree(compile_data,(struct AST_Error*)tree);- break;- default:- append_to_last_line(gstr_to_heap("NOT_POSSIBLE"),compile_data->lines);- }-- }-- void print_function_definition(struct Compile_Data_Print *compile_data,struct AST_Function_Definition *function)- {- print_id(compile_data,function->function->id);- append_to_last_line(gstr_to_heap(" is"),compile_data->lines);-- switch(function->function->linkage)- {- case LINKAGE_EXTERNAL:- append_to_last_line(gstr_to_heap(" an externally linked "),compile_data->lines);- break;- case LINKAGE_INTERNAL:- append_to_last_line(gstr_to_heap(" an internally linked "),compile_data->lines);- break;- default:- wonky_assert(SHOULD_NOT_REACH_HERE);- }- print_type(compile_data,function->function->type,1);- print_compound_statement_tree(compile_data,function->body);- }- void print_program_ast(struct Compile_Data_Print *compile_data,struct Program *program)- {- size_t i;- struct Queue_Node *it;-- push_line(gstr_to_heap("EXTERNALLY DEFINED {"),compile_data->indent,compile_data->lines);-- ++compile_data->indent;- push_line(gstr_to_heap("FUNCTIONS {"),compile_data->indent,compile_data->lines);- ++compile_data->indent;- for(it=program->functions_without_a_definition->first;it!=NULL;it=it->prev)- {- push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);- print_ast(compile_data,it->data);- }- --compile_data->indent;- push_line(gstr_to_heap("}"),compile_data->indent,compile_data->lines);- --compile_data->indent;-- ++compile_data->indent;- push_line(gstr_to_heap("OBJECTS {"),compile_data->indent,compile_data->lines);- ++compile_data->indent;- for(it=program->external_objects_without_an_initialiser->first;it!=NULL;it=it->prev)- {- push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);- print_ast(compile_data,it->data);- }- --compile_data->indent;- push_line(gstr_to_heap("}"),compile_data->indent,compile_data->lines);- --compile_data->indent;-- push_line(gstr_to_heap("}"),compile_data->indent,compile_data->lines);-- for(it=program->translation_units->first;it!=NULL;it=it->prev)- {- push_line(gstr_to_heap("TRANSLATION_UNIT {"),compile_data->indent,compile_data->lines);- ++compile_data->indent;-- push_line(gstr_to_heap(""),compile_data->indent,compile_data->lines);- print_ast(compile_data,(struct AST*)(struct AST*)it->data);-- --compile_data->indent;- push_line(gstr_to_heap("} TRANSLATION_UNIT_END"),compile_data->indent,compile_data->lines);- }- }- void print_keyword_enum(FILE *out,enum LEXER_TYPE kw)- {- switch(kw)- {- case KW_AUTO:- fprintf(out,"KW_AUTO");- break;- case KW_DO:- fprintf(out,"KW_DO");- break;- case KW_DOUBLE:- fprintf(out,"KW_DOUBLE");- break;- case KW_INT:- fprintf(out,"KW_INT");- break;- case KW_STRUCT:- fprintf(out,"KW_STRUCT");- break;- case KW_BREAK:- fprintf(out,"KW_BREAK");- break;- case KW_ELSE:- fprintf(out,"KW_ELSE");- break;- case PKW_DEFINED:- fprintf(out,"KW_DEFINED");- break;- case KW_LONG:- fprintf(out,"KW_LONG");- break;- case KW_SWITCH:- fprintf(out,"KW_SWITCH");- break;- case KW_CASE:- fprintf(out,"KW_CASE");- break;- case KW_ENUM:- fprintf(out,"KW_ENUM");- break;- case KW_REGISTER:- fprintf(out,"KW_REGISTER");- break;- case KW_TYPEDEF:- fprintf(out,"KW_TYPEDEF");- break;- case KW_CHAR:- fprintf(out,"KW_CHAR");- break;- case KW_EXTERN:- fprintf(out,"KW_EXTERN");- break;- case KW_RETURN:- fprintf(out,"KW_RETURN");- break;- case KW_UNION:- fprintf(out,"KW_UNION");- break;- case KW_CONST:- fprintf(out,"KW_CONST");- break;- case KW_FLOAT:- fprintf(out,"KW_FLOAT");- break;- case KW_SHORT:- fprintf(out,"KW_SHORT");- break;- case KW_UNSIGNED:- fprintf(out,"KW_UNSIGNED");- break;- case KW_CONTINUE:- fprintf(out,"KW_CONTINUE");- break;- case KW_FOR:- fprintf(out,"KW_FOR");- break;- case KW_SIGNED:- fprintf(out,"KW_SIGNED");- break;- case KW_VOID:- fprintf(out,"KW_VOID");- break;- case KW_DEFAULT:- fprintf(out,"KW_DEFAULT");- break;- case KW_GOTO:- fprintf(out,"KW_GOTO");- break;- case KW_SIZEOF:- fprintf(out,"KW_SIZEOF");- break;- case KW_VOLATILE:- fprintf(out,"KW_VOLATILE");- break;- case KW_IF:- fprintf(out,"KW_IF");- break;- case KW_STATIC:- fprintf(out,"KW_STATIC");- break;- case KW_WHILE:- fprintf(out,"KW_WHILE");- break;- case KW_EXCLAMATION:- fprintf(out,"KW_EXCLAMATION");- break;- case KW_PERCENT:- fprintf(out,"KW_PERCENT");- break;- case KW_AND:- fprintf(out,"KW_AND");- break;- case KW_AND_AND:- fprintf(out,"KW_AND_AND");- break;- case KW_OPEN_NORMAL:- fprintf(out,"KW_OPEN_NORMAL");- break;- case KW_CLOSE_NORMAL:- fprintf(out,"KW_CLOSE_NORMAL");- break;- case KW_STAR:- fprintf(out,"KW_STAR");- break;- case KW_PLUS:- fprintf(out,"KW_PLUS");- break;- case KW_COMMA:- fprintf(out,"KW_COMMA");- break;- case KW_MINUS:- fprintf(out,"KW_MINUS");- break;- case KW_DOT:- fprintf(out,"KW_DOT");- break;- case KW_ARROW:- fprintf(out,"KW_ARROW");- break;- case KW_COLUMN:- fprintf(out,"KW_COLUMN");- break;- case KW_SEMICOLON:- fprintf(out,"KW_SEMICOLON");- break;- case KW_LESS:- fprintf(out,"KW_LESS");- break;- case KW_EQ:- fprintf(out,"KW_EQ");- break;- case KW_EQEQ:- fprintf(out,"KW_EQEQ");- break;- case KW_MORE:- fprintf(out,"KW_MORE");- break;- case KW_QUESTION:- fprintf(out,"KW_QUESTION");- break;- case KW_HAT:- fprintf(out,"KW_HAT");- break;- case KW_PIPE:- fprintf(out,"KW_PIPE");- break;- case KW_PIPE_PIPE:- fprintf(out,"KW_PIPE_PIPE");- break;- case KW_TILDE:- fprintf(out,"KW_TILDE");- break;- case KW_PLUSPLUS:- fprintf(out,"KW_PLUSPLUS");- break;- case KW_MINUSMINUS:- fprintf(out,"KW_MINUSMINUS");- break;- case KW_SHIFT_RIGHT:- fprintf(out,"KW_SHIFT_RIGHT");- break;- case KW_SHIFT_LEFT:- fprintf(out,"KW_SHIFT_LEFT");- break;- case KW_LESS_EQ:- fprintf(out,"KW_LESS_EQ");- break;- case KW_MORE_EQ:- fprintf(out,"KW_MORE_EQ");- break;- case KW_NOT_EQ:- fprintf(out,"KW_NOT_EQ");- break;- case KW_PLUS_EQ:- fprintf(out,"KW_PLUS_EQ");- break;- case KW_MINUS_EQ:- fprintf(out,"KW_MINUS_EQ");- break;- case KW_STAR_EQ:- fprintf(out,"KW_STAR_EQ");- break;- case KW_PERCENT_EQ:- fprintf(out,"KW_PERCENT_EQ");- break;- case KW_SHIFT_LEFT_EQ:- fprintf(out,"KW_SHIFT_LEFT_EQ");- break;- case KW_SHIFT_RIGHT_EQ:- fprintf(out,"KW_SHIFT_RIGHT_EQ");- break;- case KW_AND_EQ:- fprintf(out,"KW_AND_EQ");- break;- case KW_HAT_EQ:- fprintf(out,"KW_HAT_EQ");- break;- case KW_PIPE_EQ:- fprintf(out,"KW_PIPE_EQ");- break;- case KW_HASHTAG:- fprintf(out,"KW_HASHTAG");- break;- case KW_HASHTAG_HASHTAG:- fprintf(out,"KW_HASHTAG_HASHTAG");- break;- case KW_ELIPSIS:- fprintf(out,"KW_ELIPSIS");- break;- case KW_DIV:- fprintf(out,"KW_DIV");- break;- case KW_INLINE:- fprintf(out,"KW_INLINE");- break;- case KW_RESTRICT:- fprintf(out,"KW_RESTRICT");- break;- case KW_BOOL:- fprintf(out,"KW_BOOL");- break;- case KW_COMPLEX:- fprintf(out,"KW_COMPLEX");- break;- case KW_IMAGINARY:- fprintf(out,"KW_IMAGINARY");- break;- case KW_OPEN_SQUARE:- fprintf(out,"KW_OPEN_SQUARE");- break;- case KW_CLOSE_SQUARE:- fprintf(out,"KW_CLOSE_SQUARE");- break;- case KW_CLOSE_CURLY:- fprintf(out,"KW_CLOSE_CURLY");- break;- case KW_OPEN_CURLY:- fprintf(out,"KW_OPEN_CURLY");- break;- case KW_DIV_EQ:- fprintf(out,"KW_DIV_EQ");- break;- case KW_FORWARD_SLASH:- fprintf(out,"KW_FORWARD_SLASH");- break;- case KW_NOTYPE:- fprintf(out,"KW_NOTYPE");- break;- case KW_HEXADECIMAL_CONSTANT:- fprintf(out,"KW_HEXADECIMAL_CONSTANT");- break;- case KW_DECIMAL_CONSTANT:- fprintf(out,"KW_DECIMAL_CONSTANT");- break;- case KW_OCTAL_CONSTANT:- fprintf(out,"KW_OCTAL_CONSTANT");- break;- case KW_UNSIGNED_DECIMAL_CONSTANT:- fprintf(out,"KW_UNSIGNED_DECIMAL_CONSTANT");- break;- case KW_UNSIGNED_OCTAL_CONSTANT:- fprintf(out,"KW_UNSIGNED_OCTAL_CONSTANT");- break;- case KW_UNSIGNED_HEXADECIMAL_CONSTANT:- fprintf(out,"KW_UNSIGNED_HEXADECIMAL_CONSTANT");- break;- case KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT:- fprintf(out,"KW_UNSIGNED_LONG_HEXADECIMAL_CONSTANT");- break;- case KW_UNSIGNED_LONG_OCTAL_CONSTANT:- fprintf(out,"KW_UNSIGNED_LONG_OCTAL_CONSTANT");- break;- case KW_UNSIGNED_LONG_DECIMAL_CONSTANT:- fprintf(out,"KW_UNSIGNED_LONG_DECIMAL_CONSTANT");- break;- case KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT:- fprintf(out,"KW_UNSIGNED_LONG_LONG_DECIMAL_CONSTANT");- break;- case KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT:- fprintf(out,"KW_UNSIGNED_LONG_LONG_HEXADECIMAL_CONSTANT");- break;- case KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT:- fprintf(out,"KW_UNSIGNED_LONG_LONG_OCTAL_CONSTANT");- break;- case KW_LONG_HEXADECIMAL_CONSTANT:- fprintf(out,"KW_LONG_HEXADECIMAL_CONSTANT");- break;- case KW_LONG_OCTAL_CONSTANT:- fprintf(out,"KW_LONG_OCTAL_CONSTANT");- break;- case KW_LONG_DECIMAL_CONSTANT:- fprintf(out,"KW_LONG_DECIMAL_CONSTANT");- break;- case KW_LONG_LONG_HEXADECIMAL_CONSTANT:- fprintf(out,"KW_LONG_LONG_HEXADECIMAL_CONSTANT");- break;- case KW_LONG_LONG_OCTAL_CONSTANT:- fprintf(out,"KW_LONG_LONG_OCTAL_CONSTANT");- break;- case KW_LONG_LONG_DECIMAL_CONSTANT:- fprintf(out,"KW_LONG_LONG_DECIMAL_CONSTANT");- break;- case KW_DOUBLE_DECIMAL_CONSTANT:- fprintf(out,"KW_DOUBLE_DECIMAL_CONSTANT");- break;- case KW_LONG_DOUBLE_DECIMAL_CONSTANT:- fprintf(out,"KW_LONG_DOUBLE_DECIMAL_CONSTANT");- break;- case KW_FLOAT_DECIMAL_CONSTANT:- fprintf(out,"KW_FLOAT_DECIMAL_CONSTANT");- break;- case KW_DOUBLE_HEXADECIMAL_CONSTANT:- fprintf(out,"KW_DOUBLE_HEXADECIMAL_CONSTANT");- break;- case KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT:- fprintf(out,"KW_LONG_DOUBLE_HEXADECIMAL_CONSTANT");- break;- case KW_FLOAT_HEXADECIMAL_CONSTANT:- fprintf(out,"KW_FLOAT_HEXADECIMAL_CONSTANT");- break;- case KW_COMMENT:- fprintf(out,"KW_COMMENT");- break;- case KW_ID:- fprintf(out,"KW_ID");- break;- case KW_CHAR_CONSTANT:- fprintf(out,"KW_CHAR_CONSTANT");- break;- case KW_WIDE_CHAR_CONSTANT:- fprintf(out,"KW_WIDE_CHAR_CONSTANT");- break;- case KW_STRING:- fprintf(out,"KW_STRING");- break;- case KW_WIDE_STRING:- fprintf(out,"KW_WIDE_STRING");- break;- case PKW_IF:- fprintf(out,"PKW_IF");- break;- case PKW_IFDEF:- fprintf(out,"PKW_IFDEF");- break;- case PKW_IFNDEF:- fprintf(out,"PKW_IFNDEF");- break;- case PKW_ELIF:- fprintf(out,"PKW_ELIF");- break;- case PKW_ELSE:- fprintf(out,"PKW_ELSE");- break;- case PKW_ENDIF:- fprintf(out,"PKW_ENDIF");- break;- case PKW_INCLUDE:- fprintf(out,"PKW_INCLUDE");- break;- case PKW_DEFINE:- fprintf(out,"PKW_DEFINE");- break;- case PKW_UNDEF:- fprintf(out,"PKW_UNDEF");- break;- case PKW_LINE:- fprintf(out,"PKW_LINE");- break;- case PKW_ERROR:- fprintf(out,"PKW_ERROR");- break;- case PKW_PRAGMA:- fprintf(out,"PKW_PRAGMA");- break;- case PKW_COMMENT:- fprintf(out,"PKW_COMMENT");- break;- case PKW_NOTYPE:- fprintf(out,"PKW_NOTYPE");- break;- default:- fprintf(out,"KW_ERROR");- }- }- void print_errors(FILE *out,struct Queue *errors)- {- struct Queue_Node *it;- for(it=errors->first;it!=NULL;it=it->prev)- {- print_translation_error(out,(struct Translation_Message*)it->data);- }- }- void print_function_args(struct Compile_Data_Print *compile_data,struct Type_Function *func)- {- size_t i;- if(func->number_of_arguments==0)- return;-- print_denoted_argument(compile_data,func->arguments[0]);- for(i=1;i<func->number_of_arguments;++i)- {- append_to_last_line(gstr_to_heap(", "),compile_data->lines);- print_denoted(compile_data,(struct Denoted*)func->arguments[i]);- }- }- void print_denoted_argument(struct Compile_Data_Print *compile_data,struct Denoted_Object *denoted)- {- append_to_last_line(gstr_to_heap("denoted object "),compile_data->lines);- if(denoted->id)- print_id(compile_data,denoted->id);- print_object(compile_data,denoted->object);- append_to_last_line(gstr_to_heap(" is a"),compile_data->lines);- print_type(compile_data,denoted->object->type,1);- return;- }- void print_type_qualifier(struct Compile_Data_Print *compile_data,struct Type *type)- {- if(type_is_constant(type))- append_to_last_line(gstr_to_heap(" constant "),compile_data->lines);- if(type_is_volatile(type))- append_to_last_line(gstr_to_heap(" volatile "),compile_data->lines);- }-- void print_type_constraint_enum(struct Compile_Data_Print *compile_data,enum Type_Specifier specifier)- {- switch(specifier)- {- case TC_LONG:- append_to_last_line(gstr_to_heap("long "),compile_data->lines);- break;- case TC_LONG_LONG:- append_to_last_line(gstr_to_heap("long long "),compile_data->lines);- break;- case TC_SHORT:- append_to_last_line(gstr_to_heap("short "),compile_data->lines);- break;- }- }- void print_type_sign_enum(struct Compile_Data_Print *compile_data,enum Type_Signedness sign)- {- if(sign==TSIGN_UNSIGNED)- append_to_last_line(gstr_to_heap("unsigned "),compile_data->lines);- }-- void print_type_constraint(struct Compile_Data_Print *compile_data,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(compile_data,AS_BASIC_TYPE_PTR(type)->constraint);- }- }- void print_type_sign(struct Compile_Data_Print *compile_data,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(compile_data,AS_BASIC_TYPE_PTR(type)->sign);- break;- }- }-- void print_constant_tree(struct Compile_Data_Print *compile_data,struct AST_Constant *constant)- {- append_to_last_line(gstr_to_heap("CONSTANT of type"),compile_data->lines);- //print_type(out,constant->value_type,1);- }- void print_string_literal(struct Compile_Data_Print *compile_data,struct AST_String_Literal *string)- {- append_to_last_line(gstr_to_heap("STRING LITERAL"),compile_data->lines);- //print_token(out,string->string);- }-- void print_expression_value(struct Compile_Data_Print *compile_data,struct Expression_Value *value)- {- append_to_last_line(gstr_to_heap("EXPRESSION VALUE of type"),compile_data->lines);- print_expression_value_type(compile_data,value);- }- void print_expression_value_type(struct Compile_Data_Print *compile_data,struct Expression_Value *expression_value)- {- switch(expression_value->type)- {- case VALUE_LVALUE:- print_type(compile_data, ((struct Expression_Value_LValue*)expression_value)->object->type,1);- return;- case VALUE_TEMP:- print_type(compile_data,((struct Expression_Value_RValue*)expression_value)->temp_object->type,1);- return;- case VALUE_FUNCTION_DESIGNATOR:- print_type(compile_data,((struct Expression_Value_Function_Designator*)expression_value)->function->type,1);- return;- case VALUE_CONSTANT:- print_type(compile_data, ((struct Expression_Value_Constant*)expression_value)->constant->type,1);- return;- case VALUE_VOID:- append_to_last_line(gstr_to_heap("void"),compile_data->lines);- return;- }- wonky_assert(SHOULD_NOT_REACH_HERE);- }-- void print_id(struct Compile_Data_Print *compile_data,struct identifier *id)- {-- append_to_last_line(id->data,compile_data->lines);-- }- #undef TOK- #undef INDENT-- #endifF diff --git a/src/backend/text/print/print.h b/src/backend/text/print/print.h deleted file mode 100644 --- a/src/backend/text/print/print.h +++ /dev/null- #ifndef WONKY_PRINT_H- #define WONKY_PRINT_H WONKY_PRINT_H-- #include <print.hh>- #include <stdio.h>- #include <wonky_assert.h>- #include <wonky_malloc.h>- #include <wonky.h>- #include <common.h>- #include <compile.h>- #include <lines.h>- #include <queue.h>- #include <object.h>- #include <value.h>- #include <program.h>- #include <translation_unit.h>- #include <gcc_error.h>-- #define ASTPTR(s) ((struct AST*)(s))-- struct Compile_Data_Print- {- enum Compilation_Type type;- struct Queue *errors;-- struct Queue *lines;/*queue of struct Lines*/- int indent;- };- struct Compiled_Object_Print- {- enum Compilation_Type type;- struct Queue *errors;-- struct Queue *lines;-- };-- struct Compiled_Object_Print* compile_program_for_print(struct Program *program);- void save_compiled_object_for_print(struct Compiled_Object_Print *object,FILE *out);-- struct Compiled_Object_Print* get_print_compile_object(struct Queue *lines);- struct Compile_Data_Print* get_print_compile_data();---- void print_token(struct Compile_Data_Print *compile_data,struct token *token);- void print_tokens(FILE *out,struct Token_Pointer *ptr,struct Compile_Data_Print *data);- char print_tokens_of_program(FILE *out,char **base_source_names);- void print_ast_enum(struct Compile_Data_Print *compile_data,enum AST_Type op);- void print_error_tree(struct Compile_Data_Print *compile_data,struct AST_Error *error);- void print_designator_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Designator *designator);- void print_binary_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Binary_Expression *bin);- void print_conditional_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Conditional_Expression *cond);- void print_function_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Function_Expression *function_call);- void print_unary_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Unary_Expression *unary_expression);- void print_constant_tree(struct Compile_Data_Print *compile_data,struct AST_Constant *constant);- void print_string_literal(struct Compile_Data_Print *compile_data,struct AST_String_Literal *string);- //void print_lvalue_expression_tree(struct Compile_Data_Print *compile_data,struct AST_Lvalue_Expression *lval);- void print_labeled_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Labeled_Statement *lab);- void print_compound_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Compound_Statement *comp);- void print_if_statement_tree(struct Compile_Data_Print *compile_data,struct AST_If_Statement *ifs);- void print_switch_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Switch_Statement *swi);- void print_while_statement_tree(struct Compile_Data_Print *compile_data,struct AST_While_Statement *whi);- void print_do_while_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Do_While_Statement *whi);- void print_for_statement_tree(struct Compile_Data_Print *compile_data,struct AST_For_Statement *fo);- void print_return_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Return_Statement *return_expression);- void print_goto_statement_tree(struct Compile_Data_Print *compile_data,struct AST_Goto_Statement *got);- void print_type(struct Compile_Data_Print *compile_data,struct Type *type,char print_struct_union);- void print_denoted(struct Compile_Data_Print *compile_data,struct Denoted *denoted);- void print_denoted_argument(struct Compile_Data_Print *compile_data,struct Denoted_Object *denoted);- void print_list_of_denoted(struct Compile_Data_Print *compile_data,struct Queue *denoted);- void print_enumeration(struct Compile_Data_Print *compile_data,struct Enum *enumeration);- void print_struct_union(struct Compile_Data_Print *compile_data,struct Struct_Union *struct_union);- void print_object(struct Compile_Data_Print *compile_data,struct Object *object);- void print_normal_object(struct Compile_Data_Print *compile_data,struct Object *object);- void print_bitfield_object(struct Compile_Data_Print *compile_data,struct Object_Bitfield *object);- void print_translation_unit_tree(struct Compile_Data_Print *compile_data,struct AST_Translation_Unit *unit);- void print_ast(struct Compile_Data_Print *compile_data,struct AST* tree);- void print_program_tokens(struct Compile_Data_Print *compile_data,struct Program *program);- void print_program_ast(struct Compile_Data_Print *compile_data,struct Program *program);- void print_keyword_enum(FILE *out,enum LEXER_TYPE kw);- void print_function_definition(struct Compile_Data_Print *compile_data,struct AST_Function_Definition *function);- void print_errors(FILE *out,struct Queue *errors);- void print_function_args(struct Compile_Data_Print *compile_data,struct Type_Function *func);- void print_type_qualifier(struct Compile_Data_Print *compile_data,struct Type *type);- void print_type_constraint_enum(struct Compile_Data_Print *compile_data,enum Type_Specifier specifier);- void print_type_sign_enum(struct Compile_Data_Print *compile_data,enum Type_Signedness sign);- void print_type_constraint(struct Compile_Data_Print *compile_data,struct Type *type);- void print_type_sign(struct Compile_Data_Print *compile_data,struct Type *type);- void print_expression_value(struct Compile_Data_Print *compile_data,struct Expression_Value *value);- void print_expression_value_type(struct Compile_Data_Print *compile_data,struct Expression_Value *value);- void print_id(struct Compile_Data_Print *compile_data,struct identifier *id);--- #endifF diff --git a/src/backend/text/print/print.hh b/src/backend/text/print/print.hh deleted file mode 100644 --- a/src/backend/text/print/print.hh +++ /dev/null- #ifndef WONKY_PRINT_HH- #define WONKY_PRINT_HH WONKY_PRINT_HH--- struct Compile_Data_Print;- struct Compiled_Object_Print;-- #endifF diff --git a/src/common.h b/src/common.h --- a/src/common.h +++ b/src/common.h#include <config.h>#include <stddef.h>+ #include <stdint.h>+ #include <stdlib.h>+ #include <stdio.h>+ #include <stdarg.h>#define SHOULD_NOT_REACH_HERE (!"should not reach here")#define FIRST_TOKEN_IN_TOKEN_QUEUE 0F diff --git a/src/environment/error/gcc_error.c b/src/environment/error/gcc_error.c --- a/src/environment/error/gcc_error.c +++ b/src/environment/error/gcc_error.c#include <gcc_error.h>- /*- %T - type- %D - denoted- %I - identifier- */- struct Translation_Message* get_translation_message(const char *message_format,struct Program *program,char *filename,size_t filename_size,size_t line,size_t column,va_list args)+ struct Wonky_Message* get_wonky_message(enum Wonky_Message_Type type,enum Wonky_Message_Source source,ssize_t line,ssize_t column,char *filename,size_t filename_size,const char *msg_fmt,...){+ va_list args;+ struct Wonky_Message *ret;- size_t i;- const char *where_in_return_message=message_format;- const char *hold_return_string;- const char *hold_return_substring;-- struct Translation_Message *ret;-- hold_return_string=get_translation_message_location_prefix(filename,line,column);--- for(i=0;i<1000 && message_format[i]!='\0';++i)- {- if(message_format[i]=='%')- {- switch(message_format[i+1])- {- case 'I':- hold_return_substring=get_string_for_id_error(va_arg(args,struct identifier*));- break;- case 'T':- hold_return_substring=get_string_for_type_error(va_arg(args,struct Type*));- break;- case 'D':- hold_return_substring=get_string_for_denoted_error(va_arg(args,struct Denoted*));- break;- case 't':- hold_return_substring=get_string_for_token_error(va_arg(args,struct token*));- break;- default:- continue; /*goes to top for loop*/- }-- hold_return_substring=gstr_append_and_consume(- gstr_dup(where_in_return_message,message_format+i,i+1),- hold_return_substring);- hold_return_string=gstr_append_and_consume(hold_return_string,hold_return_substring);-- where_in_return_message=message_format+i+2;- ++i;+ va_start(args,msg_fmt);+ ret=get_wonky_message(type,source,line,column,filename,filename_size,msg_fmt,args);+ va_end(args);- }- }+ return ret;+ }+ struct Wonky_Message* get_wonky_message_vargs(enum Wonky_Message_Type type,enum Wonky_Message_Source source,ssize_t line,ssize_t column,char *filename,size_t filename_size,const char *msg_fmt,va_list args)+ {+ struct Wonky_Message *ret;++ ret=wonky_malloc(sizeof(struct Wonky_Message));+ ret->type=type;+ ret->source=source;+ ret->message=wonky_malloc(sizeof(struct wonky_str));+ *ret->message=wonky_string_make();- hold_return_string=gstr_append_and_consume(- hold_return_string,- gstr_dup(where_in_return_message,message_format+i,i+1)- );+ wonky_string_vprintf(ret->message,msg_fmt,args);- ret=wonky_malloc(sizeof(struct Translation_Message));- ret->message=hold_return_string;ret->line=line;ret->column=column;ret->filename=filename;+ ret->filename_size=filename_size;return ret;}- void push_translation_message_into_program_as_error(struct Translation_Message *message,struct Program *program)- {- Queue_Push(program->errors,message);- }- void push_translation_message_inner(const char *prefix,const char *message_format,struct Program *program,char *filename,size_t filename_size,size_t line,size_t column,va_list args)- {- struct Translation_Message *hold_message;- hold_message=get_translation_message(message_format,program,filename,filename_size,line,column,args);- hold_message->message=gstr_append_and_consume(gstr_to_heap(prefix),hold_message->message);- Queue_Push(program->errors,hold_message);- }- void push_translation_error(const char *message_format,struct Translation_Data *translation_data, ...)+ void push_generic_error(struct Program *program,const char *err_fmt,...){va_list args;- va_start(args,translation_data);- push_translation_message_inner("[Error] ",- message_format,- translation_data->program,- translation_data->token_pointer->context->filename,- translation_data->token_pointer->context->filename_size,- translation_data->token_pointer->context->line,- translation_data->token_pointer->context->column,- args);+ va_start(args,err_fmt);+ push_generic_note_vargs(program,err_fmt,args);va_end(args);}- void push_translation_note(const char *note_message,struct Translation_Data *translation_data, ...)+ void push_generic_error_vargs(struct Program *program,const char *err_fmt,va_list args){- va_list args;- va_start(args,translation_data);- push_translation_message_inner("[Note] ",- note_message,- translation_data->program,- translation_data->token_pointer->context->filename,- translation_data->token_pointer->context->filename_size,- translation_data->token_pointer->context->line,- translation_data->token_pointer->context->column,- args);- va_end(args);- }- void push_lexing_error(char *error_message,struct Lexer_Data *lexer_data)- {- wonky_assert(!"REWORK THE ERROR MESSAGE CODE");- }- void push_raw_translation_error(const char *error_message,size_t line,size_t column,const char *filename,struct Translation_Data *translation_data)- {- struct Translation_Message *hold_message;- hold_message=wonky_malloc(sizeof(struct Translation_Message));- hold_message->message=gstr_to_heap(error_message);- hold_message->filename=filename;- hold_message->line=line;- hold_message->column=column;-- Queue_Push(translation_data->program->errors,hold_message);-+ Queue_Push(program->errors,get_wonky_message_vargs(WONKY_MESSAGE_TYPE_ERROR,WONKY_MESSAGE_SOURCE_END,-1,-1,NULL,0,err_fmt,args));}- void push_compile_error(const char *message,struct Compile_Data *compile_data)+ void push_generic_note(struct Program *program,const char *note_fmt,...){- Queue_Push(compile_data->errors,gstr_to_heap(message));+ va_list args;+ va_start(args,note_fmt);+ push_generic_note_vargs(program,note_fmt,args);+ va_end(args);}- void push_compile_note(const char *message,struct Compile_Data *compile_data)+ void push_generic_note_vargs(struct Program *program,const char *note_fmt,va_list args){- Queue_Push(compile_data->errors,gstr_to_heap(message));+ Queue_Push(program->errors,get_wonky_message_vargs(WONKY_MESSAGE_TYPE_NOTE,WONKY_MESSAGE_SOURCE_END,-1,-1,NULL,0,note_fmt,args));}- void push_program_error(const char *message_format,struct Program *program, ...)+ void push_message_struct(struct Program *program,struct Wonky_Message *error){- va_list args;- va_start(args,program);- push_translation_message_inner("[Error] ",- message_format,- program,- "",- 0,- 0,- 0,- args);- va_end(args);+ Queue_Push(program->errors,error);}- void push_token_ptr_error(const char *message_format,struct Token_Pointer *ptr,...)++ void push_translation_error(const char *fmt,struct Translation_Data *translation_data,...){va_list args;- va_start(args,ptr);- push_translation_message_inner("[Error] ",- message_format,- ptr->program,- ptr->context->filename,- ptr->context->filename_size,- ptr->context->line,- ptr->context->column,- args);+ va_start(args,translation_data);+ push_translation_error_vargs(fmt,translation_data,args);va_end(args);- ptr->state=TOKEN_POINTER_STATE_ERROR;}- char* get_string_for_type_error(struct Type *type)+ void push_translation_error_vargs(const char *fmt,struct Translation_Data *translation_data,va_list args){- char *ret;- struct Type *current;-- ret=gstr_to_heap("");+ ssize_t line=-1;+ ssize_t column=-1;+ char *filename=NULL;+ size_t filename_size=0;- current=type;-- while(type_is_derivative(current))+ if(translation_data->token_pointer->context){- switch(current->specifier)- {-- case TS_POINTER:- ret=gstr_append_and_consume(gstr_to_heap("*"),ret);- current=((struct Type_Pointer*)current)->points_to;- break;- case TS_ARRAY:- ret=gstr_append_and_consume(gstr_to_heap("("),ret);- ret=gstr_append_and_consume(ret,gstr_to_heap(")[]"));- current=((struct Type_Array*)current)->is_array_of;- break;- case TS_FUNC: /*TODO*/- goto hack;- default:- wonky_assert(SHOULD_NOT_REACH_HERE);- }+ line=translation_data->token_pointer->context->line;+ column=translation_data->token_pointer->context->column;+ filename=translation_data->token_pointer->context->filename;+ filename_size=translation_data->token_pointer->context->filename_size;}- hack:- switch(current->specifier)- {- case TS_DOUBLE:- ret=gstr_append_and_consume(gstr_to_heap("double"),ret);- break;- case TS_FLOAT:- ret=gstr_append_and_consume(gstr_to_heap("float"),ret);- break;- case TS_INT:- ret=gstr_append_and_consume(gstr_to_heap("int"),ret);- break;- case TS_CHAR:- ret=gstr_append_and_consume(gstr_to_heap("char"),ret);- break;- case TS_STRUCT:- ret=gstr_append_and_consume(gstr_to_heap("struct "),ret);- goto hack2;- case TS_UNION:- ret=gstr_append_and_consume(gstr_to_heap("struct "),ret);- hack2:- {- struct identifier *id;- id=((struct Type_Struct_Union*)current)->struct_union->id;- ret=gstr_append_and_consume(ret,gstr_dup(id->data,id->data+id->size,id->size+1));- }- break;- default:- ret=gstr_append_and_consume(gstr_to_heap("type"),ret);- }- return ret;+ Queue_Push(translation_data->program->errors,get_wonky_message_vargs(WONKY_MESSAGE_TYPE_ERROR,WONKY_MESSAGE_SOURCE_TRANSLATION,line,column,filename,filename_size,fmt,args));}- char* get_string_for_denoted_error(struct Denoted *denoted)- {- char *ret;-- ret=gstr_to_heap("denoted");- return ret;- }- char* get_string_for_token_error(struct token *token)+ void push_translation_note(const char *fmt,struct Translation_Data *translation_data,...){- char *ret;-- ret=gstr_to_heap("token");-- return ret;+ va_list args;+ va_start(args,translation_data);+ push_translation_note_vargs(fmt,translation_data,args);+ va_end(args);}- char* get_string_for_id_error(struct identifier *id)+ void push_translation_note_vargs(const char *fmt,struct Translation_Data *translation_data,va_list args){- char *ret;+ ssize_t line=-1;+ ssize_t column=-1;+ char *filename=NULL;+ size_t filename_size=0;- ret=gstr_dup(id->data,id->data+id->size,id->size+1);+ if(translation_data->token_pointer->context)+ {+ line=translation_data->token_pointer->context->line;+ column=translation_data->token_pointer->context->column;+ filename=translation_data->token_pointer->context->filename;+ filename_size=translation_data->token_pointer->context->filename_size;+ }- return ret;+ Queue_Push(translation_data->program->errors,get_wonky_message_vargs(WONKY_MESSAGE_TYPE_NOTE,WONKY_MESSAGE_SOURCE_TRANSLATION,line,column,filename,filename_size,fmt,args));}- char* get_translation_message_location_prefix(char *filename,size_t line,size_t column)+ void print_message(struct wonky_stream *out,struct Wonky_Message *msg){- char *ret;- size_t filename_length;-- if(filename!=NULL)- filename_length=gstrlen(filename);- else- filename_length=sizeof("NULL")+100;-- ret=wonky_calloc(filename_length+64,1);-- sprintf(ret,"%s %zu:%zu ",filename,line+1,column);- return ret;- }+ wonky_assert(out && msg);+ switch(msg->type)+ {+ case WONKY_MESSAGE_TYPE_ERROR:+ wonky_fprintf(out,"[Error] ");+ break;+ case WONKY_MESSAGE_TYPE_NOTE:+ wonky_fprintf(out,"[Note] ");+ break;+ }+ if(msg->filename && msg->filename_size)+ wonky_write(out,msg->filename,msg->filename_size);+ if(msg->line>0)+ wonky_fprintf(out,"%s%zu:%zu ",(msg->filename?":":" "),(size_t)msg->line,(size_t)msg->column);+ wonky_fprintf(out,"%s\n",msg->message->cs);- void print_translation_error(FILE *out,struct Translation_Message *error)- {- fprintf(out,"%s\n",error->message);- }- void delete_translation_error(struct Translation_Message *translation_error)- {- wonky_free(translation_error);}- void print_compile_errors(FILE *out,struct Queue *errors)+ void delete_error(struct Program *program,struct Wonky_Message *error){- while(errors->size>0)- fputs(Queue_Pop(errors),out);+ /*currently all of wonky's memory is in a big heap an dropped after all use*/}- void hard_error(char *format,...)- {- va_list args;- va_start(args,format);- vfprintf(stderr,format,args);-- abort();- }#endifF diff --git a/src/environment/error/gcc_error.h b/src/environment/error/gcc_error.h --- a/src/environment/error/gcc_error.h +++ b/src/environment/error/gcc_error.h#include <compile.h>#include <type.h>#include <translation_unit.h>+ #include <source_file.h>+ #include <wonky_string.h>+ #include <wonky_stream.h>- struct Translation_Message+ struct Wonky_Message{- const char *message;- size_t line,column;- const char *filename;+ enum Wonky_Message_Type type;+ enum Wonky_Message_Source source;+ struct wonky_str *message;+ ssize_t line; /*negative values means not to print the line and column*/+ ssize_t column;+ char *filename; /*could be NULL*/+ size_t filename_size;};+ struct Wonky_Message* get_wonky_message(enum Wonky_Message_Type type,enum Wonky_Message_Source source,ssize_t line,ssize_t column,char *filename,size_t filename_size,const char *msg_fmt,...);+ struct Wonky_Message* get_wonky_message_vargs(enum Wonky_Message_Type type,enum Wonky_Message_Source source,ssize_t line,ssize_t column,char *filename,size_t filename_size,const char *msg_fmt,va_list args);- /*- %T print type - takes pointer to Type- %D denoted - takes pointer to Denoted- %I identifier - takes pointer to an id- %t token - takes a pointer to a token- */- struct Translation_Message* get_translation_message(const char *message_format,struct Program *program,char *filename,size_t filename_size,size_t line,size_t column,va_list args);- struct Translation_Message* get_translation_message_inner(const char *message,struct Program *program,char *filename,size_t filename_size,size_t line,size_t column);+ void push_generic_error(struct Program *program,const char *err_fmt,...);+ void push_generic_error_vargs(struct Program *program,const char *err_fmt,va_list args);- void push_translation_message_into_program_as_error(struct Translation_Message *message,struct Program *program);+ void push_generic_note(struct Program *program,const char *note_fmt,...);+ void push_generic_note_vargs(struct Program *program,const char *note_fmt,va_list args);- void push_translation_message_inner(const char *prefix,const char *message_format,struct Program *program,char *filename,size_t filename_size,size_t line,size_t column,va_list args);- void push_translation_error(const char *message_format,struct Translation_Data *translation_data, ...);- void push_translation_note(const char *note_message,struct Translation_Data *translation_data, ...);+ void push_message_struct(struct Program *program,struct Wonky_Message *msg);- void push_lexing_error(char *error_message,struct Lexer_Data *lexer_data);+ void push_translation_error(const char *fmt,struct Translation_Data *translation_data,...);+ void push_translation_error_vargs(const char *fmt,struct Translation_Data *translation_data,va_list args);+ void push_translation_note(const char *fmt,struct Translation_Data *translation_data,...);+ void push_translation_note_vargs(const char *fmt,struct Translation_Data *translation_data,va_list args);- void push_raw_translation_error(const char *error_message,size_t line,size_t column,const char *filename,struct Translation_Data *translation_data);+ void print_message(struct wonky_stream *out,struct Wonky_Message *msg);+ void delete_message(struct Program *program,struct Wonky_Message *msg);- void push_compile_error(const char *message,struct Compile_Data *compile_data);- void push_compile_note(const char *message,struct Compile_Data *compile_data);--- void push_program_error(const char *message_format,struct Program *program, ...);- void push_token_ptr_error(const char *message_format,struct Token_Pointer *ptr,...);-- char* get_string_for_type_error(struct Type *type);- char* get_string_for_denoted_error(struct Denoted *denoted);- char* get_string_for_token_error(struct token *token);- char* get_string_for_id_error(struct identifier *id);- char* get_translation_message_location_prefix(char *filename,size_t line,size_t column);-- void print_translation_error(FILE *out,struct Translation_Message *message);- void delete_translation_error(struct Translation_Message *message);--- void print_compile_errors(FILE *out,struct Queue *errors);-- void hard_error(char *format,...);---- /*-- =====================================================================================================================- push_translation_error("Redeclaration of identifier %t",idptr);- push_translation_note("First declared here %L as %T",denoted->id->filename,denoted->id->line,denoted->type);-- |- V-- [Error] file line:column - Redeclaration of identifier a- [Note] file line:column - First declared as Type- =====================================================================================================================- push_translation_error("Usage of undeclared identifier %t at %L",idptr,idptr);-- |- V-- [Error] file line:column - Usage of undeclared identifier a at file:line- =====================================================================================================================- push_translation_error("Addition between incompatible types %T and %T",...);-- |- V-- [Error] file line:column - Addition between incomptatible types int and struct kek- =====================================================================================================================- */#endifF diff --git a/src/environment/error/gcc_error.hh b/src/environment/error/gcc_error.hh --- a/src/environment/error/gcc_error.hh +++ b/src/environment/error/gcc_error.hh- #ifndef WONKY_ERROR_H- #define WONKY_ERROR_H WONKY_ERROR_H+ #ifndef WONKY_ERROR_HH+ #define WONKY_ERROR_HH WONKY_ERROR_HH+ enum Wonky_Message_Type+ {+ WONKY_MESSAGE_TYPE_ERROR,+ WONKY_MESSAGE_TYPE_NOTE,+ WONKY_MESSAGE_TYPE_END+ };+ enum Wonky_Message_Source+ {+ WONKY_MESSAGE_SOURCE_TRANSLATION,+ WONKY_MESSAGE_SOURCE_PREPROCESSING,+ WONKY_MESSAGE_SOURCE_LEXING,+ WONKY_MESSAGE_SOURCE_END+ };+ struct Wonky_Error;+ struct Wonky_Error_Generic;- struct Translation_Error;- struct Output_Message;#endifF diff --git a/src/frontend/lex/lex_preprocessing_directive.c b/src/frontend/lex/lex_preprocessing_directive.c --- a/src/frontend/lex/lex_preprocessing_directive.c +++ b/src/frontend/lex/lex_preprocessing_directive.cif(hold_token==NULL){- push_lexing_error("Expected id in defined unary operator",lexer_data);+ push_generic_error(lexer_data->program,"Expected id in defined unary operator");}else{if(token_is_identifier_in_preprocessing(hold_token))ret->id=hold_token;hold_token=preprocessing_extract_next_token(lexer_data);if(hold_token->type!=KW_CLOSE_NORMAL)- push_lexing_error("Expected ')' in defined unary operator after id",lexer_data);+ push_generic_error(lexer_data->program,"Expected ')' in defined unary operator after id");}else{- push_lexing_error("Expected id in defined unary operator after '('",lexer_data);+ push_generic_error(lexer_data->program,"Expected id in defined unary operator after '('");}}else{- push_lexing_error("Expected id in defined unary operator",lexer_data);+ push_generic_error(lexer_data->program,"Expected id in defined unary operator");}}return (struct token*)ret;hold_token=preprocessing_get_token_for_functionlike_macro_substitution_list(lexer_data,where,directive);if(hold_token==NULL || hold_token->type!=PKW_MACRO_ARGUMENT){- push_lexing_error("Expected macro argument after #",lexer_data);+ push_generic_error(lexer_data->program,"Expected macro argument after #");ret->operand=NULL;return (struct token*)ret;}if(preprocessing_eol(lexer_data)){- push_lexing_error("Expected something after ##",lexer_data);+ push_generic_error(lexer_data->program,"Expected something after ##");return (struct token*)previous_token;}else{hold_token_constant=(struct token_constant*)preprocessing_extract_next_token(lexer_data);if(hold_token_constant->type!=KW_CONSTANT || !type_is_a_plain_signed_int(hold_token_constant->constant->type)){- push_lexing_error("Expected a digit sequence in the #line directive",lexer_data);+ push_generic_error(lexer_data->program,"Expected a digit sequence in the #line directive");ret->line=0;return (struct token*)ret;}else}}else{- push_lexing_error("Expected a digit sequence in the #line directive",lexer_data);+ push_generic_error(lexer_data->program,"Expected a digit sequence in the #line directive");ret->line=0;return (struct token*)ret;}hold_token_string=(struct token_string*)preprocessing_extract_next_token(lexer_data);if(hold_token_string->type!=KW_STRING || !type_is_a_normal_string(hold_token_string->constant->type)){- push_lexing_error("Expected a digit sequence in the #line directive",lexer_data);+ push_generic_error(lexer_data->program,"Expected a digit sequence in the #line directive");ret->line=0;return (struct token*)ret;}elseif(hold_token==NULL || !token_is_identifier_in_preprocessing(hold_token)){- push_lexing_error("Expected id in #ifdef directive",lexer_data);+ push_generic_error(lexer_data->program,"Expected id in #ifdef directive");ret->id=NULL;}else{Queue_Push(if_false,hold_token);}if(hold_token==NULL)- push_lexing_error("Reached end of file before reaching a #endif",lexer_data);+ push_generic_error(lexer_data->program,"Reached end of file before reaching a #endif");delete_token(hold_token);break;if(hold_token==NULL || !token_is_identifier_in_preprocessing(hold_token)){- push_lexing_error("Expected id in #undef directive",lexer_data);+ push_generic_error(lexer_data->program,"Expected id in #undef directive");}else{if(token_is_a_special_macro(hold_token)){- push_lexing_error("Special macro id in #undef directive is not allowed",lexer_data);+ push_generic_error(lexer_data->program,"Special macro id in #undef directive is not allowed");}else{ret->id=hold_token;{if(preprocessing_eol(lexer_data)){- push_lexing_error("## is the last token in the functionlike macro substitution tokens",lexer_data);+ push_generic_error(lexer_data->program,"## is the last token in the functionlike macro substitution tokens");return;}else{break;}else{- push_lexing_error("Expected ')' after '...' in functionlike macro",lexer_data);+ push_generic_error(lexer_data->program,"Expected ')' after '...' in functionlike macro");break;}}else if(hold_token->type==KW_ID)F diff --git a/src/frontend/lex/lexer.c b/src/frontend/lex/lexer.c --- a/src/frontend/lex/lexer.c +++ b/src/frontend/lex/lexer.cdelete_lexer_data(lexer_data);if(lexed_unit->tokens->size==0)- push_program_error("Empty translation unit",program);+ push_generic_error(program,"Empty translation unit");return lexed_unit;}F diff --git a/src/frontend/lex/lexer.h b/src/frontend/lex/lexer.h --- a/src/frontend/lex/lexer.h +++ b/src/frontend/lex/lexer.h#include <translation_unit.h>#include <lex_preprocessing_directive.h>+ #include <gcc_error.h>+struct Lexer_Data{F diff --git a/src/frontend/parse/parse_declaration.c b/src/frontend/parse/parse_declaration.c --- a/src/frontend/parse/parse_declaration.c +++ b/src/frontend/parse/parse_declaration.c{/*TODO error*/Queue_Push(where_to_push_objects,get_declaration_error_tree(hold));- push_translation_error("declaration expected",translation_data);+ push_generic_error(translation_data->program,"declaration expected");/*search for end of erronous declaration*/break;{/*TODO error*/Queue_Push(where_to_push_objects,get_declaration_error_tree(NULL));- push_translation_error("Semicolon expected",translation_data);+ push_generic_error(translation_data->program,"Semicolon expected");break;}}}else{- push_translation_error("unexpected 'signed' in type",translation_data);+ push_generic_error(translation_data->program,"unexpected 'signed' in type");if(ret->sign==TSIGN_SIGNED)- push_translation_note("when it is unsigned",translation_data);+ push_generic_note(translation_data->program,"when it is unsigned");else- push_translation_note("when it is already signed",translation_data);+ push_generic_note(translation_data->program,"when it is already signed");}break;case KW_UNSIGNED:}else{- push_translation_error("unexpected 'unsigned' in type",translation_data);+ push_generic_error(translation_data->program,"unexpected 'unsigned' in type");if(ret->sign==TSIGN_SIGNED)- push_translation_note("when it is signed",translation_data);+ push_generic_note(translation_data->program,"when it is signed");else- push_translation_note("when it is already unsigned",translation_data);+ push_generic_note(translation_data->program,"when it is already unsigned");}break;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_translation_error("more than one type specifier given",translation_data);+ push_generic_error(translation_data->program,"more than one type specifier given");return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_INT;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_translation_error("more than one type specifier given",translation_data);+ push_generic_error(translation_data->program,"more than one type specifier given");return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_VOID;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_translation_error("more than one type specifier given",translation_data);+ push_generic_error(translation_data->program,"more than one type specifier given");return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_CHAR;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_translation_error("more than one type specifier given",translation_data);+ push_generic_error(translation_data->program,"more than one type specifier given");return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_DOUBLE;chomp(translation_data);if(ret->specifier!=TS_NONE){- push_translation_error("more than one type specifier given",translation_data);+ push_generic_error(translation_data->program,"more than one type specifier given");return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}ret->specifier=TS_FLOAT;}else{if(ret->constraint==TC_LONG_LONG)- push_translation_error("yeah ... it's big",translation_data);+ push_generic_error(translation_data->program,"yeah ... it's big");else if(ret->constraint==TC_SHORT)- push_translation_error("long and short constraints contradict",translation_data);+ push_generic_error(translation_data->program,"long and short constraints contradict");elsewonky_assert(SHOULD_NOT_REACH_HERE);return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);switch(ret->constraint){case TC_LONG:- push_translation_error("long and short constraints contradict",translation_data);+ push_generic_error(translation_data->program,"long and short constraints contradict");break;case TC_SHORT:- push_translation_error("it's not about the size, it's about how you use it",translation_data);+ push_generic_error(translation_data->program,"it's not about the size, it's about how you use it");break;case TC_LONG_LONG:- push_translation_error("long long and short constraints contradict",translation_data);+ push_generic_error(translation_data->program,"long long and short constraints contradict");break;default:/*should not be able to enter here*/switch(ret->storage_class){case SCS_EXTERN:- push_translation_error("only one extern allowed >:|",translation_data);+ push_generic_error(translation_data->program,"only one extern allowed >:|");break;case SCS_TYPEDEF:case SCS_STATIC:- push_translation_error("only one storage class allowed >:|",translation_data);+ push_generic_error(translation_data->program,"only one storage class allowed >:|");break;default:wonky_assert(SHOULD_NOT_REACH_HERE);switch(ret->storage_class){case SCS_STATIC:- push_translation_error("only one static allowed >:|",translation_data);+ push_generic_error(translation_data->program,"only one static allowed >:|");break;case SCS_EXTERN:case SCS_TYPEDEF:- push_translation_error("only one storage class allowed >:|",translation_data);+ push_generic_error(translation_data->program,"only one storage class allowed >:|");break;default:wonky_assert(SHOULD_NOT_REACH_HERE);case SCS_STATIC:case SCS_EXTERN:case SCS_TYPEDEF:- push_translation_error("only one storage class allowed >:|",translation_data);+ push_generic_error(translation_data->program,"only one storage class allowed >:|");break;default:wonky_assert(SHOULD_NOT_REACH_HERE);ret->struct_union=tag->struct_union;if(ret->struct_union->specifier!=ret->specifier){- push_translation_error("more than one type specifier",translation_data);+ push_generic_error(translation_data->program,"more than one type specifier");return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}if(ret->struct_union->is_finished==0)parse_struct_union_specifier_finish(translation_data,scope,ret->struct_union);if(ret->struct_union->is_finished==0){- push_translation_error("expected a struct tag or a struct definition",translation_data);+ push_generic_error(translation_data->program,"expected a struct tag or a struct definition");return (struct Denotation_Prototype*)get_denoted_error((struct Denoted*)ret);}}}else{base->type=get_type_error(hold_first_part);- push_translation_error("Expected a ')' at %L",translation_data);+ push_generic_error(translation_data->program,"Expected a ')' at %L");}}else{if(!get_and_check(translation_data,KW_CLOSE_SQUARE)){/*TODO error*/- push_translation_error("']' expected",translation_data);+ push_generic_error(translation_data->program,"']' expected");base->type=(struct Type*)get_type_error(base->type);delete_ast(hold_expression);return;if(get_and_check(translation_data,KW_CLOSE_CURLY))return ;/*TODO error*/- push_translation_error("expected closing curly bracket from struct declaration",translation_data);+ push_generic_error(translation_data->program,"expected closing curly bracket from struct declaration");return;}}base->has_constant_member=1;}else{- push_translation_error("non object declaration in struct definition",translation_data);+ push_generic_error(translation_data->program,"non object declaration in struct definition");}}else{wonky_free(prototype);- push_translation_error("there is a problem with the declarator",translation_data);+ push_generic_error(translation_data->program,"there is a problem with the declarator");return 0;}if(!get_and_check(translation_data,KW_COMMA) && !check(translation_data,KW_SEMICOLON)){wonky_free(prototype);- push_translation_error("semi column expected in struct declaration",translation_data);+ push_generic_error(translation_data->program,"semi column expected in struct declaration");return 0;}}if(hold_denoted_object->denotation!=DT_Object){/*TODO error*/- push_translation_error("expected object type for bitfield",translation_data);+ push_generic_error(translation_data->program,"expected object type for bitfield");return get_denoted_error((struct Denoted*)hold_denoted_object);}if(get_and_check(translation_data,KW_COLUMN))}else{/*TODO error*/- push_translation_error("enum definition error",translation_data);+ push_generic_error(translation_data->program,"enum definition error");Queue_Push(enumeration->consts,get_denoted_error(NULL));return ;}}else{/*TODO error*/- push_translation_error("enum definition error, expected an id",translation_data);+ push_generic_error(translation_data->program,"enum definition error, expected an id");Queue_Push(enumeration->consts,get_denoted_error(NULL));return ;}if(base->denotation!=DT_Object){/*TODO error*/- push_translation_error("expected object declaration in function prototype",translation_data);+ push_generic_error(translation_data->program,"expected object declaration in function prototype");// delete_denoted(hold);delete_denoted_prototype(prototype);delete_denoted_base(base);if(!get_and_check(translation_data,KW_CLOSE_NORMAL)){/*TODO error*/- push_translation_error("expected a ')' finishing the parameter list",translation_data);+ push_generic_error(translation_data->program,"expected a ')' finishing the parameter list");Queue_Push(parameters,get_denoted_error(NULL));}if(base->denotation==DT_Error || base->id!=NULL){/*TODO error*/- push_translation_error("unexpedted id in abstract declarator",translation_data);+ push_generic_error(translation_data->program,"unexpedted id in abstract declarator");delete_denoted_base(base);ret=base->type;return ret;return parse_initialiser_list_for_struct_union(translation_data,scope,(struct Type_Struct_Union*)type_of_initialised);else{- push_translation_error("expected aggregate type in compound initialisation, got %T instead",translation_data,type_of_initialised);+ push_generic_error(translation_data->program,"expected aggregate type in compound initialisation, got %T instead",type_of_initialised);return get_initialiser_error(NULL);}}return parse_initialiser(translation_data,scope,type_of_initialised);else{- push_translation_error("expected '=' in initialiser designation",translation_data);+ push_generic_error(translation_data->program,"expected '=' in initialiser designation");return get_initialiser_error(NULL);}if(!type_is_an_array(type_of_initialised)){- push_translation_error("expected array type in indexed initialiser, instead got a %T",translation_data,type_of_initialised);+ push_generic_error(translation_data->program,"expected array type in indexed initialiser, instead got a %T",type_of_initialised);return get_initialiser_error(NULL);}if(!type_is_struct_union(type_of_initialised)){- push_translation_error("expected struct/union type in initialiser, got %T instead",translation_data,type_of_initialised);+ push_generic_error(translation_data->program,"expected struct/union type in initialiser, got %T instead",type_of_initialised);return get_initialiser_error(NULL);}if(!check(translation_data,KW_ID)){- push_translation_error("expected id in the initialisation of type %T",translation_data,type_of_initialised);+ push_generic_error(translation_data->program,"expected id in the initialisation of type %T",type_of_initialised);return get_initialiser_error(NULL);}if(member==NULL){- push_translation_error("%t is not a member of %T",translation_data,id,type_of_initialised);+ push_generic_error(translation_data->program,"%t is not a member of %T",id,type_of_initialised);push_translation_note("in initialiser",translation_data);return get_initialiser_error(NULL);}F diff --git a/src/misc/galib.c b/src/misc/galib.c --- a/src/misc/galib.c +++ b/src/misc/galib.cif utf8 encoded glyph at byte_index'th byte is invalid this function returns 0*/uint32_t gas_glyph_at_position(const struct ga_str str,size_t byte_index);- struct ga_str_mark* gas_mark_lines(const struct ga_str str); /*returns a ga_array of marks*/+ struct ga_str_mark* gas_mark_lines(const struct ga_str str);elsereturn ga__utf8_glyph_value(str,byte_index,glyph_size);}- struct ga_str_mark* gas_mark_lines(const struct ga_str str)+ struct ga_str_mark* _garray gas_mark_lines(const struct ga_str str){struct ga_str_mark *ret;size_t last_beginning=0;F diff --git a/src/misc/gcc_string.c b/src/misc/gcc_string.c --- a/src/misc/gcc_string.c +++ b/src/misc/gcc_string.creturn ret;}- void gmemmove(void *where_to,void *from_where,size_t how_many_bytes)+ /*where and from must not overlap*/+ #warning rename to gmemcpy+ void gmemmove(void *where_to,const void *from_where,size_t how_many_bytes){size_t i;for(i=0;i<how_many_bytes;++i)- ((char*)where_to)[i]=((char *)from_where)[i];+ ((unsigned char*)where_to)[i]=((const unsigned char *)from_where)[i];}+ int gmemcmp(void *a,void *b,size_t num_bytes)+ {+ size_t i;+ for(i=0;i<num_bytes;++i)+ if(((unsigned char*)a)[i]!=((unsigned char*)b)[i])+ /*holy cast!*/+ return ((int)((unsigned char*)a)[i])-((int)((unsigned char*)b)[i]);+ return 1;+ }#endifF diff --git a/src/misc/gcc_string.h b/src/misc/gcc_string.h --- a/src/misc/gcc_string.h +++ b/src/misc/gcc_string.h#include <common.h>#include <wonky_malloc.h>--size_t gstrlen(const char *str);size_t gstrnlen(const char *str,size_t limit);char* gstr_append(const char *lead,const char *follower);char *gstr_append_and_consume(const char *lead,const char *follower);char* gstr_dup(const char *first,const char *last,size_t limit);char* gstr_to_heap(const char *literal);- void gmemmove(void *where_to,void *from_where,size_t how_many_bytes);+ void gmemmove(void *where_to,const void *from_where,size_t how_many_bytes);+ int gmemcmp(void *a,void *b,size_t num_bytes);char* gstrn_append(char *lead,char *follower,size_t overall_limit);#endifF diff --git a/src/misc/print.c b/src/misc/print.c new file mode 100644 --- /dev/null +++ b/src/misc/print.c+ #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: ");+ 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:+ wonky_fprintf(out,"CONSTANT");+ break;+ case KW_ID:+ wonky_fprintf(out,"ID ");+ print_id(out,((struct token_identifier*)token)->id);+ break;+ case KW_STRING:+ case KW_WIDE_STRING:+ wonky_fprintf(out,"STRING");+ break;++ default:+ wonky_fprintf(out,"NOTYPE");++ }+ wonky_fprintf(out," ]");+ }++ 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)+ {+ 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;+ }+ }+ #endifF diff --git a/src/misc/print.h b/src/misc/print.h new file mode 100644 --- /dev/null +++ b/src/misc/print.h+ #ifndef WONKY_PRINT_H+ #define WONKY_PRINT_H WONKY_PRINT_H++ #include <print.hh>+ #include <stdio.h>+ #include <wonky_assert.h>+ #include <wonky_malloc.h>+ #include <wonky.h>+ #include <common.h>+ #include <compile.h>+ #include <queue.h>+ #include <object.h>+ #include <value.h>+ #include <program.h>+ #include <translation_unit.h>+ #include <gcc_error.h>+ #include <wonky_stream.h>++ #define ASTPTR(s) ((struct AST*)(s))++ void print_token(struct wonky_stream *out,struct token *token);+ void print_tokens(struct wonky_stream *out,struct Token_Pointer *ptr);+ char print_tokens_of_program(struct wonky_stream *out,char **base_source_names);+ void print_ast_enum(struct wonky_stream *out,enum AST_Type op);+ void print_error_tree(struct wonky_stream *out,struct AST_Error *error,short indentation);+ void print_designator_expression_tree(struct wonky_stream *out,struct AST_Designator *designator,short indentation);+ void print_binary_expression_tree(struct wonky_stream *out,struct AST_Binary_Expression *bin);+ void print_conditional_expression_tree(struct wonky_stream *out,struct AST_Conditional_Expression *cond);+ void print_function_expression_tree(struct wonky_stream *out,struct AST_Function_Expression *function_call);+ void print_unary_expression_tree(struct wonky_stream *out,struct AST_Unary_Expression *unary_expression);+ void print_constant_tree(struct wonky_stream *out,struct AST_Constant *constant);+ void print_string_literal(struct wonky_stream *out,struct AST_String_Literal *string);+ //void print_lvalue_expression_tree(struct wonky_stream *out,struct AST_Lvalue_Expression *lval);+ void print_labeled_statement_tree(struct wonky_stream *out,struct AST_Labeled_Statement *lab,short indentation);+ void print_compound_statement_tree(struct wonky_stream *out,struct AST_Compound_Statement *comp,short indentation);+ void print_if_statement_tree(struct wonky_stream *out,struct AST_If_Statement *ifs,short indentation);+ void print_switch_statement_tree(struct wonky_stream *out,struct AST_Switch_Statement *swi,short indentation);+ void print_while_statement_tree(struct wonky_stream *out,struct AST_While_Statement *whi,short indentation);+ void print_do_while_statement_tree(struct wonky_stream *out,struct AST_Do_While_Statement *whi,short indentation);+ void print_for_statement_tree(struct wonky_stream *out,struct AST_For_Statement *fo,short indentation);+ void print_return_statement_tree(struct wonky_stream *out,struct AST_Return_Statement *return_expression,short indentation);+ void print_goto_statement_tree(struct wonky_stream *out,struct AST_Goto_Statement *got,short indentation);+ void print_type(struct wonky_stream *out,struct Type *type,char print_struct_union);+ void print_denoted(struct wonky_stream *out,struct Denoted *denoted);+ void print_denoted_argument(struct wonky_stream *out,struct Denoted_Object *denoted);+ void print_list_of_denoted(struct wonky_stream *out,struct Queue *denoted);+ void print_enumeration(struct wonky_stream *out,struct Enum *enumeration);+ void print_struct_union(struct wonky_stream *out,struct Struct_Union *struct_union);+ void print_object(struct wonky_stream *out,struct Object *object);+ void print_normal_object(struct wonky_stream *out,struct Object *object);+ void print_bitfield_object(struct wonky_stream *out,struct Object_Bitfield *object);+ void print_translation_unit_tree(struct wonky_stream *out,struct AST_Translation_Unit *unit,short indentation);+ void print_ast(struct wonky_stream *out,struct AST* tree,short indentation);+ void print_program_tokens(struct wonky_stream *out,struct Program *program);+ void print_program_ast(struct wonky_stream *out,struct Program *program);+ void print_keyword_enum(struct wonky_stream *out,enum LEXER_TYPE kw);+ void print_function_definition(struct wonky_stream *out,struct AST_Function_Definition *function,short indentation);+ void print_errors(struct wonky_stream *out,struct Queue *errors);+ void print_function_args(struct wonky_stream *out,struct Type_Function *func);+ void print_type_qualifier(struct wonky_stream *out,struct Type *type);+ void print_type_constraint_enum(struct wonky_stream *out,enum Type_Specifier specifier);+ void print_type_sign_enum(struct wonky_stream *out,enum Type_Signedness sign);+ void print_type_constraint(struct wonky_stream *out,struct Type *type);+ void print_type_sign(struct wonky_stream *out,struct Type *type);+ void print_expression_value(struct wonky_stream *out,struct Expression_Value *value);+ void print_expression_value_type(struct wonky_stream *out,struct Expression_Value *value);+ void print_id(struct wonky_stream *out,struct identifier *id);+ void print_indentation(struct wonky_stream *out,short indentation);+ void print_constant(struct wonky_stream *out,struct Constant *constant);+++ #endifF diff --git a/src/misc/print.hh b/src/misc/print.hh new file mode 100644 --- /dev/null +++ b/src/misc/print.hh+ #ifndef WONKY_PRINT_HH+ #define WONKY_PRINT_HH WONKY_PRINT_HH+++ struct Compile_Data_Print;+ struct Compiled_Object_Print;++ #endifF diff --git a/src/misc/wonky_array.c b/src/misc/wonky_array.c --- a/src/misc/wonky_array.c +++ b/src/misc/wonky_array.c{if(arr){- struct wony_array_internals *internals;+ struct wonky_array_internals *internals;internals=wonky_arr_get_internals(arr);if(start_index<internals->size){struct wonky_array_internals *internals;void* ret_arr;- internals=wonky_get_internals(arr);+ internals=wonky_arr_get_internals(arr);ret_arr=wonky_arr_alloc(internals->size,internals->element_size);if(!wonky_arr_oom(ret_arr)){- gmemcpy(ret_arr,internals->bytes,internals->size*internals->element_size);+ gmemmove(ret_arr,internals->bytes,internals->size*internals->element_size);return ret_arr;}else{{return NULL;}- }}struct wonky_array_internals* wonky_arr_get_internals(void * _wonky_arr arr){F diff --git a/src/misc/wonky_array.h b/src/misc/wonky_array.h --- a/src/misc/wonky_array.h +++ b/src/misc/wonky_array.h#include <common.h>#include <wonky_malloc.h>- #define _wonky_arr/*generic resizable array stuff*/struct wonky_array_internalsF diff --git a/src/misc/wonky_array.hh b/src/misc/wonky_array.hh --- a/src/misc/wonky_array.hh +++ b/src/misc/wonky_array.hhstruct wonky_array_internals;+ #ifndef _wonky_arr+ #define _wonky_arr+ #endif+#endifF diff --git a/src/misc/wonky_malloc.c b/src/misc/wonky_malloc.c --- a/src/misc/wonky_malloc.c +++ b/src/misc/wonky_malloc.creturn ret;}+ void* wonky_realloc(void *old_mem,size_t new_size)+ {+ void *ret;+ #warning this should be made into a propper realloc!+ ret=wonky_malloc(new_size);+ #warning we are getting out of bound bytes from old_mem :-(+ gmemmove(ret,old_mem,new_size);+ return ret;+ }void wonky_memfail(){fprintf(stderr,"WONKY MEMFAIL");F diff --git a/src/misc/wonky_stream.c b/src/misc/wonky_stream.c new file mode 100644 --- /dev/null +++ b/src/misc/wonky_stream.c+ #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;++ if(a==0)+ return wonky_write(s,"0",1);+ else if(a<0)+ {+ ret=wonky_write(s,"-",1);+ a=-a;+ }+++ while(a)+ {+ hold[0]=a%10+'0';+ hret=wonky_write(s,hold,1);+ if(hret<0)+ return -ret;+ else+ ret+=hret;+ a/=10;+ }+ 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;++ if(a==0)+ return wonky_write(s,"0",1);++ while(a)+ {+ hold[0]=a%10+'0';+ hret=wonky_write(s,hold,1);+ if(hret<0)+ return -ret;+ else+ ret+=hret;+ a/=10;+ }+ 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;+ if(a==0)+ return wonky_write(s,"0",1);++ while(a)+ {+ if(a%16<10)+ hold[0]=a%16+'0';+ else+ hold[0]=a%16-10+'A';+ hret=wonky_write(s,hold,1);+ if(hret<0)+ return -ret;+ else+ ret+=hret;+ a/=16;+ }+ 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;++ if(a==0)+ return wonky_write(s,"0",1);++ while(a)+ {+ hold[0]=a%8+'0';+ hret=wonky_write(s,hold,1);+ if(hret<0)+ return -ret;+ else+ ret+=hret;+ a/=8;+ }+ 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_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;+ }+ }++ 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+ */+ 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)+ {+ 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)+ 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;+ 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;++ }+ }+++++ /*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;+ }++++ #endifF diff --git a/src/misc/wonky_stream.h b/src/misc/wonky_stream.h new file mode 100644 --- /dev/null +++ b/src/misc/wonky_stream.h+ #ifndef WONKY_STREAM_H+ #define WONKY_STREAM_H WONKY_STREAM_H+ #include <wonky_stream.hh>+ #include <common.h>+ #include <gcc_string.h>+++ struct wonky_stream+ {+ ssize_t (*read)(void *state,void *dst,size_t num_bytes);+ ssize_t (*write)(void *state,void *src,size_t num_bytes);+ _Bool (*fseek)(void *state,size_t where,int whence);+ _Bool (*eof)(void *state);+ enum wonky_stream_type type;++ void *state;+ };++ struct wonky__scanformat+ {+ size_t forward_crawl;+ enum wonky__scanformat_modifier modifier;+ enum wonky__scanformat_conversion conversion;+ _Bool alternate_form;+ _Bool wonky_form;+ };+++ ssize_t wonky_read(struct wonky_stream *s,void *dst,size_t num_bytes);+ ssize_t wonky_write(struct wonky_stream *s,void *src,size_t num_bytes);+ ssize_t wonky_fseek(struct wonky_stream *s,size_t where,int whence);+ ssize_t wonky_eof(struct wonky_stream *s);+ int wonky_printf(const char *format,...);+ int wonky_vprintf(const char *format,va_list args);+ int wonky_fprintf(struct wonky_stream *s,const char *format,...);+ int wonky_vfprintf(struct wonky_stream *s,const char *format,va_list args);+++ ssize_t wonky_stream_int_to_decimal(struct wonky_stream *s,intmax_t a);+ ssize_t wonky_stream_uint_to_decimal(struct wonky_stream *s,uintmax_t a);+ ssize_t wonky_stream_uint_to_hexadecimal(struct wonky_stream *s,uintmax_t a);+ ssize_t wonky_stream_uint_to_octal(struct wonky_stream *s,uintmax_t a);+ ssize_t wonky_stream_double_to_decimal(struct wonky_stream *s,double d);+ ssize_t wonky_stream_from_fraction(struct wonky_stream *s,uint64_t a,uint64_t b,int precision);+ struct wonky_stream wonky_stream_from_file(FILE *f);+ void wonky_stream_delete(struct wonky_stream *s);++ ssize_t wonky__FILE_read(void *state,void *dst,size_t num_bytes);+ ssize_t wonky__FILE_write(void *state,void *src,size_t num_bytes);+ _Bool wonky__FILE_fseek(void *state,size_t where,int whence);+ _Bool wonky__FILE_eof(void *state);++ ssize_t wonky__fail_read(void *state,void *dst,size_t num_bytes);+ ssize_t wonky__fail_write(void *state,void *src,size_t num_bytes);+ _Bool wonky__fail_fseek(void *state,size_t where,int whence);+ _Bool wonky__fail_eof(void *state);+ void wonky__parse_scan_format(const char *begining, struct wonky__scanformat *destination);+ void wonky__from_scanformat(struct wonky__scanformat *fmt,va_list args,struct wonky_stream *destination,short *indentation);++ /*float = 1 bit sign | 8 bit exponent | 23 bit mantissa*/+ _Bool wonky__float_is_negative(float f);+ int16_t wonky__float_get_exponent(float f);+ uint32_t wonky__float_get_mantissa(float f);+ float wonky__float_set_sign(float f,_Bool is_negative);+ float wonky__float_set_exponent(float f,int16_t exponent);+ float wonky__float_set_base(float f,uint32_t mantissa);++ /*double = 1 bit sign | 11 bit exponent | 52 bit mantissa*/+ _Bool wonky__double_is_negative(double d);+ int16_t wonky__double_get_exponent(double d);+ uint64_t wonky__double_get_mantissa(double d);+ double wonky__double_set_sign(double d,_Bool is_negative);+ double wonky__double_set_exponent(double d,int16_t exponent);+ double wonky__double_set_mantissa(double d,uint64_t mantissa);++ #endifF diff --git a/src/misc/wonky_stream.hh b/src/misc/wonky_stream.hh new file mode 100644 --- /dev/null +++ b/src/misc/wonky_stream.hh+ #ifndef WONKY_STREAM_HH+ #define WONKY_STREAM_HH WONKY_STREAM_HH++ struct wonky_stream;+ struct wonky__scanformat;++ enum wonky_stream_type+ {+ WONKY_STREAM_TYPE_OOM,+ WONKY_STREAM_TYPE_STRING,+ WONKY_STREAM_TYPE_FILE,+ WONKY_STREAM_TYPE_END+ };+ enum wonky__scanformat_conversion+ {+ WONKY__CONVERSION_INT_DECIMAL,+ WONKY__CONVERSION_INT_UNSIGNED_DECIMAL,+ WONKY__CONVERSION_INT_OCTAL,+ WONKY__CONVERSION_INT_HEXADECIMAL,+ WONKY__CONVERSION_DOUBLE_EXPONENT,+ WONKY__CONVERSION_DOUBLE_DECIMAL,+ WONKY__CONVERSION_DOUBLE_HEXADECIMAL,+ WONKY__CONVERSION_CHAR,+ WONKY__CONVERSION_CSTRING,+ WONKY__CONVERSION_POINTER,+ WONKY__CONVERSION_PERCENT,+ WONKY__CONVERSION_BITS,+ WONKY__CONVERSION_WONKY_ERROR,+ WONKY__CONVERSION_WONKY_TOKEN,++ WONKY__CONVERSION_WONKY_INDENTATION,+ WONKY__CONVERSION_WONKY_AST,+ WONKY__CONVERSION_WONKY_AST_ENUM,+ WONKY__CONVERSION_WONKY_ID,+ WONKY__CONVERSION_WONKY_DENOTED,+ WONKY__CONVERSION_WONKY_TYPE,+ WONKY__CONVERSION_WONKY_OBJECT,+ WONKY__CONVERSION_WONKY_CONSTANT,+ WONKY__CONVERSION_END+ };+ enum wonky__scanformat_modifier+ {+ WONKY__MOD_NONE,+ WONKY__MOD_SHORT,+ WONKY__MOD_SHORT_SHORT,+ WONKY__MOD_LONG,+ WONKY__MOD_LONG_LONG,+ WONKY__MOD_LONG_DOUBLE,+ WONKY__MOD_INTMAX,+ WONKY__MOD_SIZE_T,+ WONKY__MOD_PTRDIFF,+ WONKY__MOD_END+ };+++ #endifF diff --git a/src/misc/wonky_string.c b/src/misc/wonky_string.c new file mode 100644 --- /dev/null +++ b/src/misc/wonky_string.c+ #ifndef WONKY_STRING_C+ #define WONKY_STRING_C WONKY_STRING_C+ #include <wonky_string.h>++ struct wonky_str wonky_string_make()+ {+ struct wonky_str ret;+ ret.cs=wonky_arr_alloc(1,1);+ if(!wonky_arr_oom(ret.cs))+ {+ ret.cs[0]='\0';+ ret.number_of_glyphs=1;/*\0 is a glyph*/+ }else+ {+ ret.cs=NULL;+ ret.number_of_glyphs=0;+ }+ return ret;+ }+ struct wonky_str wonky_string_copy(const struct wonky_str str)+ {+ struct wonky_str ret=(struct wonky_str){.cs=wonky_arr_copy(str.cs),.number_of_glyphs=str.number_of_glyphs};+ wonky_string_recount_glyphs(&ret);+ return ret;+ }+ struct wonky_str wonky_string_from_cstr(const char *str)+ {+ struct wonky_str ret;+ if(str)+ {+ size_t str_len;+ str_len=gstrlen(str);+ ret.cs=wonky_arr_alloc(str_len+1,1);+ ret.number_of_glyphs=1;+ if(!wonky_arr_oom(ret.cs))+ gmemmove(ret.cs,str,str_len+1);+ wonky_string_recount_glyphs(&ret);+ return ret;+ }else+ {+ ret.cs=NULL;+ ret.number_of_glyphs=0;+ }+ return ret;+ }+ size_t wonky_string_number_of_bytes(const struct wonky_str str)+ {+ if(!wonky_arr_oom(str.cs))+ return wonky_arr_size(str.cs);+ else+ return 0;+ }+ size_t wonky_string_recount_glyphs(struct wonky_str *str)+ {+ size_t glyph_count=0;+ for(size_t i=0,j=1;j!=i && i<wonky_string_number_of_bytes(*str);j=i,i=wonky_string_following_glyph_position(*str,i))+ {+ ++glyph_count;+ }+ str->number_of_glyphs=glyph_count;+ return glyph_count;+ }+ size_t wonky_string_length(const struct wonky_str str)+ {+ return str.number_of_glyphs;+ }+ _Bool wonky_string_oom(struct wonky_str str)+ {+ return wonky_arr_oom(str.cs);+ }++ /*get element(unicode) value from index'th glyph, indices starting from 0*/+ uint32_t wonky_string_glyph(const struct wonky_str str,size_t glyph_index)+ {+ /*get byte index of glyph then extract the value and return it*/+ return wonky_string_glyph_at_position(str,wonky_string_glyph_position(str,glyph_index));+ }+ /*returns the index of the starting byte of the utf8 encoded glyph_indexed glyph*/+ size_t wonky_string_glyph_position(const struct wonky_str str,size_t glyph_index)+ {+ size_t byte_index,i;+ /*walk glyphs till we reach glyph_index or run out of bytes*/+ for(byte_index=0,i=0;i<glyph_index;++i,byte_index=wonky_string_following_glyph_position(str,byte_index));+ /*if this could be last byte index in string*/+ return byte_index;+ }+ /*returns index of starting byte of next valid glyph after byte_index'th byte in string*/+ size_t wonky_string_following_glyph_position(const struct wonky_str str,size_t byte_index)+ {+ short glyph_size=0;+ /*skip invalid bytes*/+ while(byte_index<wonky_string_number_of_bytes(str) && (glyph_size=wonky__utf8_glyph_size(str,byte_index))==0)+ {+ ++byte_index;+ }+ byte_index+=glyph_size;+ return (byte_index<wonky_string_number_of_bytes(str)?byte_index:wonky_arr_last_index(str.cs)+1);+ }+ /*+ returns glyph value of utf8 encoded glyph starting at byte_index'th index'th byte of string+ if utf8 encoded glyph at byte_index'th byte is invalid this function returns 0+ */+ uint32_t wonky_string_glyph_at_position(const struct wonky_str str,size_t byte_index)+ {+ short glyph_size;+ glyph_size=wonky__utf8_glyph_size(str,byte_index);+ if(glyph_size==0)+ return 0;+ else+ return wonky__utf8_glyph_value(str,byte_index,glyph_size);+ }++ _Bool wonky_string_push_codepoint(struct wonky_str *str,uint32_t ch)+ {+ short codepoint_size;++ codepoint_size=wonky__utf8_codepoint_size(ch);+ str->cs=wonky_arr_expand(str->cs,codepoint_size);++ if(wonky_arr_oom(str->cs))+ return 0;+++ str->cs[wonky_arr_last_index(str->cs)]='\0';+ wonky__utf8_encode_codepoint(str->cs+wonky_arr_last_index(str->cs)-codepoint_size,ch,codepoint_size);++ ++str->number_of_glyphs;+ return 1;+ }+ _Bool wonky_string_push_byte(struct wonky_str *str,unsigned char ch)+ {+ if(str==NULL || wonky_arr_oom(str->cs))+ return 0;+ str->cs=wonky_arr_expand(str->cs,1);+ if(wonky_arr_oom(str->cs))+ return 0;++ str->cs[wonky_arr_last_index(str->cs)]='\0';+ str->cs[wonky_arr_last_index(str->cs)-1]=ch;+ return 1;+ }+ _Bool wonky_string_append(struct wonky_str *str,const char *right)+ {+ {+ if(str==NULL || right==NULL)+ return 0;++ size_t right_size;+ right_size=gstrlen(right);+ str->cs=wonky_arr_expand(str->cs,right_size);++ gmemmove(str->cs+wonky_arr_last_index(str->cs)-right_size,right,right_size);+ str->cs[wonky_arr_last_index(str->cs)]='\0';++ wonky_string_recount_glyphs(str);+ return 1;++ }+ }+ _Bool wonky_string_preppend(struct wonky_str *str,char *left)+ {+ if(str==NULL || left==NULL)+ return 0;++ size_t left_size;+ left_size=gstrlen(left);+ str->cs=wonky_arr_expand(str->cs,left_size);+++ gmemmove(str->cs+left_size,str->cs,wonky_string_number_of_bytes(*str)-left_size);+ gmemmove(str->cs,left,left_size);++ wonky_string_recount_glyphs(str);+ return 1;+ }+ _Bool wonky_string_insert(struct wonky_str *str,char *infix,size_t glyph_index)+ {+ if(str==NULL || infix==NULL || glyph_index>wonky_string_length(*str)-1)+ return 0;++ size_t infix_size;+ size_t where;+ infix_size=gstrlen(infix);+ where=wonky_string_glyph_position(*str,glyph_index);+ str->cs=wonky_arr_expand(str->cs,infix_size);++ gmemmove(str->cs+where+infix_size,str->cs+where,wonky_string_number_of_bytes(*str)-where-infix_size);+ gmemmove(str->cs+where,infix,infix_size);++ wonky_string_recount_glyphs(str);+ return 1;+ }+ _Bool wonky_string_delete_chars(struct wonky_str *str,size_t starting_glyph_index,size_t number_of_glyphs)+ {+ if(str==NULL)+ return 0;+ size_t start_offset=wonky_string_glyph_position(*str,starting_glyph_index);+ size_t offset=start_offset;+ for(size_t i=0;i<number_of_glyphs;++i,offset=wonky_string_following_glyph_position(*str,offset));+ if(offset==0 || offset>wonky_string_number_of_bytes(*str))+ return 0;+ gmemmove(str->cs+start_offset,str->cs+offset,wonky_string_number_of_bytes(*str)-offset+start_offset);+ wonky_arr_shrink(str->cs,offset-start_offset);+ wonky_string_recount_glyphs(str);+ return 1;+ }++ _Bool wonky_string_eqal(const struct wonky_str a,const struct wonky_str b)+ {+ if(wonky_string_number_of_bytes(a)!=wonky_string_number_of_bytes(b))+ return 0;+ return !gmemcmp(a.cs,b.cs,wonky_string_number_of_bytes(a));+ }+ _Bool wonky_string_cequal(const struct wonky_str a,const char *b)+ {+ return !gstrn_cmp(a.cs,b,wonky_string_number_of_bytes(a));+ }+++ int wonky_string_printf(struct wonky_str *destination,const char *format,...)+ {+ va_list args;+ int ret;++ va_start(args,format);+ ret=wonky_string_vprintf(destination,format,args);+ va_end(args);++ return ret;+ }+ int wonky_string_vprintf(struct wonky_str *destination,const char *format,va_list args)+ {+ if(format==NULL || destination==NULL)+ return 0;++ struct wonky__scanformat fmt;+ struct wonky_stream s=wonky_string_stream(destination);+ short indentation=0;+ wonky_fseek(&s,0,SEEK_END);++ 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;+ }+ }+ wonky_stream_delete(&s);++ return 0;+ }++ short wonky__utf8_get_glyph_size_from_starting_codepoint(unsigned char leading_byte)+ {+ if(leading_byte<0x7F)+ return 1;+ else if(leading_byte&0xE0==0xC0)+ return 2;+ else if(leading_byte&0xF0==0xE0)+ return 3;+ else if(leading_byte&0xF8==0xF0)+ return 4;+ else if(leading_byte&0xFC==0xF8)+ return 5;+ else if(leading_byte&0xFE==0xFC)+ return 6;+ else+ return 0;+ }+ short wonky__utf8_glyph_size(struct wonky_str str,size_t byte_index)+ {++ if(str.cs[byte_index]<0x7F) /*we were on top of an ascii char*/+ {+ return 1;+ }else if((str.cs[byte_index]&0xE0) == 0xC0)+ {+ if(byte_index+2<wonky_string_number_of_bytes(str)+ && (str.cs[byte_index+1]&0xC0)==0x80)+ return 2;+ else+ return 0;+ }else if( (str.cs[byte_index]&0xF0) == 0xE0)+ {+ if(byte_index+3<wonky_string_number_of_bytes(str)+ && (str.cs[byte_index+1]&0xC0)==0x80+ && (str.cs[byte_index+2]&0xC0)==0x80)+ return 3;+ else+ return 0;+ }else if( (str.cs[byte_index]&0xF8) == 0xF0)+ {+ if(byte_index+4<wonky_string_number_of_bytes(str)+ && (str.cs[byte_index+1]&0xC0)==0x80+ && (str.cs[byte_index+2]&0xC0)==0x80+ && (str.cs[byte_index+3]&0xC0)==0x80)+ return 4;+ else+ return 0;+ }else if( (str.cs[byte_index]&0xFC) == 0xF8)+ {+ if(byte_index+5<wonky_string_number_of_bytes(str)+ && (str.cs[byte_index+1]&0xC0)==0x80+ && (str.cs[byte_index+2]&0xC0)==0x80+ && (str.cs[byte_index+3]&0xC0)==0x80+ && (str.cs[byte_index+4]&0xC0)==0x80)+ return byte_index+5;+ else+ ++byte_index;+ }else if( (str.cs[byte_index]&0xFE) == 0xFC)+ {+ if(byte_index+5<wonky_string_number_of_bytes(str)+ && (str.cs[byte_index+1]&0xC0)==0x80+ && (str.cs[byte_index+2]&0xC0)==0x80+ && (str.cs[byte_index+3]&0xC0)==0x80+ && (str.cs[byte_index+4]&0xC0)==0x80+ && (str.cs[byte_index+5]&0xC0)==0x80)+ return 6;+ else+ return 0;+ }else+ {+ return 0;+ }+ }+ uint32_t wonky__utf8_glyph_value(struct wonky_str str,size_t byte_index,short glyph_size)+ {+ uint32_t ret=str.cs[byte_index]&(0xff>>glyph_size);+ for(short i=1;i<glyph_size;++i)+ {+ ret<<=6;+ ret+=(0x3F&str.cs[byte_index+i]);+ }+ return ret;+ }+ short wonky__utf8_codepoint_size(uint32_t codepoint)+ {+ if(codepoint<=0x7Fu)+ return 1;+ else if(codepoint<=0x7FFu)+ return 2;+ else if(codepoint<=0xFFFFu)+ return 3;+ else if(codepoint<=0x1FFFFFu)+ return 4;+ else if(codepoint<=0x3FFFFFFu)+ return 5;+ else if(codepoint<=0x7FFFFFFFu)+ return 6;+ else+ return 0;++ }+ void wonky__utf8_encode_codepoint(unsigned char *where,uint32_t codepoint,short size)+ {+ if(size==1)+ {+ where[0]=codepoint;+ }else+ {+ where[0]=(0xFF<<(8-size))|(codepoint>>((size-1)*6));+ for(short i=1;i<size;++i)+ where[i]=0x80|((codepoint>>((size-i-1)*6))&0x3F);+ }+ }++ struct wonky_stream wonky_string_stream(struct wonky_str *str)+ {+ struct wonky_string__stream_state *state=wonky_malloc(sizeof(struct wonky_string__stream_state));++ if(state)+ {+ state->str=str;+ state->where=0;+ }+ return (struct wonky_stream){+ .read=wonky_string__stream_read,+ .write=wonky_string__stream_write,+ .fseek=wonky_string__stream_fseek,+ .eof=wonky_string__stream_eof,+ .type=WONKY_STREAM_TYPE_STRING,+ .state=state+ };+ }+ void wonky_string_stream_delete(struct wonky_stream *stream)+ {+ /*currently not much point in freeing anything*/+ }+ ssize_t wonky_string__stream_read(void *state,void *dst,size_t num_bytes)+ {+ if(state==NULL)+ return -1;+ struct wonky_string__stream_state *s=(struct wonky_string__stream_state*)state;+ uint8_t *d=(uint8_t*)dst;+ size_t i;++ if(wonky_string_oom(*s->str))+ return -1;++ for(s->where,i=0;s->where<wonky_arr_size(s->str->cs)-1 && i<num_bytes;++i,++s->where)+ d[i]=s->str->cs[i];++ return i;+ }+ ssize_t wonky_string__stream_write(void *state,void *src,size_t num_bytes)+ {+ if(state==NULL)+ return -1;+ struct wonky_string__stream_state *s=(struct wonky_string__stream_state*)state;+ uint8_t *sr=(uint8_t*)src;+ size_t i;++ if(wonky_string_oom(*s->str))+ return -1;++ for(s->where,i=0;s->where<wonky_arr_size(s->str->cs)-1 && i<num_bytes;++i,++s->where)+ s->str->cs[i]=sr[i];+ for(i;i<num_bytes && !wonky_string_oom(*s->str);++i,++s->where)+ wonky_string_push_byte(s->str,(unsigned char)sr[i]);+ wonky_string_recount_glyphs(s->str);++ return i;+ }+ _Bool wonky_string__stream_fseek(void *state,size_t where,int whence)+ {+ if(state==NULL)+ return 0;++ struct wonky_string__stream_state *s=(struct wonky_string__stream_state*)state;++ if(wonky_string_oom(*s->str))+ return -1;++ switch(whence)+ {+ case SEEK_SET:+ if(where<wonky_arr_size(s->str->cs)-1)+ {+ s->where=where;+ return 1;+ }else+ {+ s->where=wonky_arr_size(s->str->cs)-1;+ return 0;+ }+ case SEEK_CUR:+ if(where<wonky_arr_size(s->str->cs)-s->where-1)+ {+ s->where+=where;+ return 1;+ }else+ {+ s->where=wonky_arr_size(s->str->cs)-1;+ return 0;+ }+ case SEEK_END:+ if(where<wonky_arr_size(s->str->cs)-1)+ {+ s->where=wonky_arr_size(s->str->cs)-1-where;+ return 1;+ }else+ {+ s->where=wonky_arr_size(s->str->cs)-1;+ return 0;+ }+ default:+ return 0;+ }+ return 0;+ }+ _Bool wonky_string__stream_eof(void *state)+ {+ if(state==NULL)+ return 1;++ struct wonky_string__stream_state *s=(struct wonky_string__stream_state*)state;+ return s->where<wonky_arr_size(s->str->cs)-1;+ }+ #endifF diff --git a/src/misc/wonky_string.h b/src/misc/wonky_string.h new file mode 100644 --- /dev/null +++ b/src/misc/wonky_string.h+ #ifndef WONKY_STRING_H+ #define WONKY_STRING_H WONKY_STRING_H+ #include <wonky_string.hh>+ #include <wonky_array.h>++ /*+ utf8 string+ */+ struct wonky_str+ {+ /*cstring*/+ unsigned char * _wonky_arr cs; /*wonky_array that is also \0 terminated*/+ size_t number_of_glyphs;+ };++ struct wonky_string__stream_state+ {+ struct wonky_str *str;+ size_t where;+ };+ struct wonky_str wonky_string_make();+ struct wonky_str wonky_string_copy(const struct wonky_str str);+ struct wonky_str wonky_string_from_cstr(const char *str);+ size_t wonky_string_number_of_bytes(const struct wonky_str str);+ size_t wonky_string_recount_glyphs(struct wonky_str *str);+ size_t wonky_string_length(const struct wonky_str str);+ _Bool wonky_string_oom(struct wonky_str str);++ /*get element(unicode) value from index'th glyph, indices starting from 0*/+ uint32_t wonky_string_glyph(const struct wonky_str str,size_t glyph_index);+ /*returns the index of the starting byte of the utf8 encoded glyph_indexed glyph*/+ size_t wonky_string_glyph_position(const struct wonky_str str,size_t glyph_index);+ /*returns index of starting byte of next valid glyph after byte_index'th byte in string*/+ size_t wonky_string_following_glyph_position(const struct wonky_str str,size_t byte_index);+ /*+ returns index of starting byte of next valid glyph going backwards in string after+ byte_index'th byte in string.+ TODO: currently not implemented and returns byte_index+ */+ size_t wonky_string_previous_glyph_position(const struct wonky_str str,size_t byte_index);+ /*+ returns glyph value of utf8 encoded glyph starting at byte_index'th index'th byte of string+ if utf8 encoded glyph at byte_index'th byte is invalid this function returns 0+ */+ uint32_t wonky_string_glyph_at_position(const struct wonky_str str,size_t byte_index);+ struct wonky_str_mark* wonky_string_mark_lines(const struct wonky_str str); /*returns a ga_array of marks*/++++ _Bool wonky_string_push_codepoint(struct wonky_str *str,uint32_t ch);+ _Bool wonky_string_push_byte(struct wonky_str *str,unsigned char ch);+ _Bool wonky_string_append(struct wonky_str *str,const char *right); /*right is \0 terminated*/+ _Bool wonky_string_preppend(struct wonky_str *str,char *left); /*left is \0 terminated*/+ _Bool wonky_string_insert(struct wonky_str *str,char *infix,size_t glyph_index);/*infix is \0 terminated*/+ _Bool wonky_string_delete_chars(struct wonky_str *str,size_t starting_glyph_index,size_t number_of_glyphs);++ _Bool wonky_string_eqal(const struct wonky_str a,const struct wonky_str b);+ _Bool wonky_string_cequal(const struct wonky_str a,const char *b);+++ int wonky_string_printf(struct wonky_str *destination,const char *format,...);+ int wonky_string_vprintf(struct wonky_str *destination,const char *format,va_list args);+++ short wonky__utf8_get_glyph_size_from_starting_codepoint(unsigned char leading_byte);+ short wonky__utf8_glyph_size(struct wonky_str str,size_t byte_index);+ uint32_t wonky__utf8_glyph_value(struct wonky_str str,size_t byte_index,short glyph_size);+ short wonky__utf8_codepoint_size(uint32_t codepoint);+ void wonky__utf8_encode_codepoint(unsigned char *where,uint32_t codepoint,short size);++ struct wonky_stream wonky_string_stream(struct wonky_str *str);+ void wonky_string_stream_delete(struct wonky_stream *stream);+ ssize_t wonky_string__stream_read(void *state,void *dst,size_t num_bytes);+ ssize_t wonky_string__stream_write(void *state,void *src,size_t num_bytes);+ _Bool wonky_string__stream_fseek(void *state,size_t where,int whence);+ _Bool wonky_string__stream_eof(void *state);++ #endifF diff --git a/src/misc/wonky_string.hh b/src/misc/wonky_string.hh new file mode 100644 --- /dev/null +++ b/src/misc/wonky_string.hh+ #ifndef WONKY_STRING_HH+ #define WONKY_STRING_HH WONKY_STRING_HH++ struct wonky_str;+ struct wonky_string__stream_state;++ #endifF diff --git a/src/semantics/ast.c b/src/semantics/ast.c --- a/src/semantics/ast.c +++ b/src/semantics/ast.chold_denoted=check_ordinary(scope,id);if(hold_denoted==NULL){- push_translation_error("using undeclared id - %t, in expression",translation_data,id);+ push_translation_error("using undeclared id - %WI, in expression",translation_data,id);wonky_free(ret);return (struct AST_Expression*)get_error_tree(NULL);}elseF diff --git a/src/semantics/program/program.c b/src/semantics/program/program.c --- a/src/semantics/program/program.c +++ b/src/semantics/program/program.cwhile(program->errors->size>0)- delete_translation_error(Queue_Pop(program->errors));+ delete_error(program,Queue_Pop(program->errors));wonky_free(program->errors);F diff --git a/src/semantics/program/translation_unit.c b/src/semantics/program/translation_unit.c --- a/src/semantics/program/translation_unit.c +++ b/src/semantics/program/translation_unit.c{if(ptr->context->current_token_node!=NULL){- push_token_ptr_error("Unexpected token at end of include directive",ptr);+ push_generic_error(ptr->program,"Unexpected token at end of include directive");return;}include_name=((struct token_string*)hold_token)->constant->value;include_name=gstrn_append(include_name,((struct token_keyword*)hold_token)->id->data,100);}else{- push_token_ptr_error("Unsupported symbol found inside filename in include directive with angular brackets and macro expansion",ptr);+ push_generic_error(ptr->program,"Unsupported symbol found inside filename in include directive with angular brackets and macro expansion");return;/*NOTICE*/}}if(ptr->context->current_token_node!=NULL){- push_token_ptr_error("Unexpected token at end of include directive",ptr);+ push_generic_error(ptr->program,"Unexpected token at end of include directive");return;}token_ptr_goto_next_token(ptr);}else if(hold_token->type==KW_LESS_EQ) /*implementation defined*/{- push_token_ptr_error("'=' is not supported inside filename in include directive with angular brackets and macro expansion",ptr);+ push_generic_error(ptr->program,"'=' is not supported inside filename in include directive with angular brackets and macro expansion");return;}}void token_ptr_execute_error_directive(struct Token_Pointer *ptr,struct token_error_directive *error_directive){- struct Translation_Message *hold_error;- va_list hack;- hold_error=get_translation_message(- error_directive->error_message,- ptr->program,- ptr->context->filename,- ptr->context->filename_size,- ptr->context->line,- ptr->context->column,- hack);- push_translation_message_into_program_as_error(hold_error,ptr->program);+ push_generic_error(ptr->program,error_directive->error_message);program_stop_parsing(ptr->program);token_ptr_goto_next_token(ptr);}hold_token=token_ptr_get_token_under_pointer(ptr);if(hold_token->type!=KW_OPEN_NORMAL){- push_token_ptr_error("Expected '(' after functionlike macro id",ptr);+ push_generic_error(ptr->program,"Expected '(' after functionlike macro id");return;}{if(hold_argument_node==NULL){- push_token_ptr_error("Too many arguments given to functionlike macro",ptr);+ push_generic_error(ptr->program,"Too many arguments given to functionlike macro");return;}if(number_of_tokens_in_argument==0){- push_token_ptr_error("No tokens in functionlike macro",ptr);+ push_generic_error(ptr->program,"No tokens in functionlike macro");return;}hold_arg=(struct functionlike_define_directive_argument*)hold_argument_node->data;if(hold_argument_node==NULL || hold_argument_node->prev!=NULL){- push_token_ptr_error("Too few arguments given to functionlike macro",ptr);+ push_generic_error(ptr->program,"Too few arguments given to functionlike macro");return;}hold_arg=(struct functionlike_define_directive_argument*)hold_argument_node->data;}break;case LT_ERROR:- push_translation_message_into_program_as_error(((struct token_error*)token)->error,token_pointer->program);+ /*erronous token*/+ push_message_struct(token_pointer->program,((struct token_error*)token)->error);token_ptr_goto_next_token(token_pointer);return 1;case KW_ID:{if(ptr->call_stack->size>1000){- push_token_ptr_error("Preprocessing bounds exceeded",ptr);+ push_generic_error(ptr->program,"Preprocessing bounds exceeded");return;}new_context=get_token_ptr_context(where_to,number_of_remaining_tokens);F diff --git a/src/semantics/value/type.c b/src/semantics/value/type.c --- a/src/semantics/value/type.c +++ b/src/semantics/value/type.cif(is_variadic && ret->number_of_arguments==0){- push_translation_error("variadic function needs atleast one named argument",translation_data);+ push_generic_error(translation_data->program,"variadic function needs atleast one named argument");return (struct Type*)get_type_error((struct Type*)ret);}F diff --git a/src/syntax/source_file.c b/src/syntax/source_file.c --- a/src/syntax/source_file.c +++ b/src/syntax/source_file.cfile=fopen(filename,"r");if(file==NULL){- push_program_error("Could not open filename %s",program,filename);+ push_generic_error(program,"Could not open filename %s",filename);ret->src_name=get_source_name("");return ret;}F diff --git a/src/syntax/token/token.c b/src/syntax/token/token.c --- a/src/syntax/token/token.c +++ b/src/syntax/token/token.c{struct token_error *ret;va_list args;+ struct wonky_str hold_err;++ hold_err=wonky_string_make();va_start(args,program);+ wonky_string_vprintf(&hold_err,msg,args);+ va_end(args);ret=wonky_malloc(sizeof(struct token_error));ret->type=LT_ERROR;ret->delta=get_source_location_delta(previous_location,current_location);- ret->error=get_translation_message(- msg,- program,- current_location->src->src_name->name,- current_location->src->src_name->name_size,- current_location->line,- current_location->column,- args);+ ret->error=get_wonky_message(WONKY_MESSAGE_TYPE_ERROR,WONKY_MESSAGE_SOURCE_PREPROCESSING,current_location,"%s:%zu:%zu %s",current_location->src->src_name->name,current_location->line,current_location->column,hold_err.cs);return (struct token*)ret;}F diff --git a/src/syntax/token/token.h b/src/syntax/token/token.h --- a/src/syntax/token/token.h +++ b/src/syntax/token/token.h{enum LEXER_TYPE type;struct Source_Location_Delta *delta;- struct Translation_Message *error;+ struct Wonky_Message *error;};/*F diff --git a/src/wonky.c b/src/wonky.c --- a/src/wonky.c +++ b/src/wonky.c*/struct Command_Arguments *command_arguments;struct Program *program;+ struct wonky_stream out;wonky_memory_init();+ #warning out is not being 'freed' :-(+ out=wonky_stream_from_file(stdout);command_arguments=parse_command_arguments(argv);}if(command_arguments->print_tokens && !command_arguments->is_quiet){- if(print_tokens_of_program(stdout,command_arguments->source_names))+ if(print_tokens_of_program(&out,command_arguments->source_names)){return 0;wonky_memory_delete();{if(!command_arguments->is_quiet){- print_errors(stdout,program->errors);+ print_errors(&out,program->errors);}delete_command_arguments(command_arguments);delete_program(program);return 1;}else if(command_arguments->print_ast && !command_arguments->is_quiet){- struct Compiled_Object_Print *object;- object=compile_program_for_print(program);- save_compiled_object_for_print(object,stdout);+ print_program_ast(&out,program);}else if(command_arguments->transpile_to_js){//transpile_to_javascript(command_arguments->output_file,program,command_arguments);{struct Compiled_Object_Intel_Asm *object;object=compile_program_to_intel_asm(program);- save_compiled_intel_asm_as_nasm(object,stdout);+ save_compiled_intel_asm_as_nasm(object,&out);}else if(command_arguments->compile_to_intel_asm){struct Compiled_Object_Intel_Asm *object;object=compile_program_to_intel_asm(program);- save_compiled_intel_asm(object,stdout);+ save_compiled_intel_asm(object,&out);}}