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.txt
include_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.txt
src/backend/asm/intel/intel_instruction.c
src/backend/asm/intel/intel_location.c
src/backend/compile.c
- src/backend/text/lines.c
- src/backend/text/print/print.c
src/debug/debug_ast.c
src/debug/debug_ast.c
src/debug/debug_denoted.c
F 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.txt
src/misc/stack.c
src/misc/wonky_malloc.c
src/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.c
return 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");
}
#endif
F 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);
#endif
F 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);
}
#endif
F 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);
#endif
F 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);
- }
- #endif
F 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);
-
- #endif
F 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;
-
- #endif
F 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
-
- #endif
F 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);
-
-
- #endif
F 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;
-
- #endif
F 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 0
F 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();
- }
#endif
F 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
- =====================================================================================================================
- */
#endif
F 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;
#endif
F 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.c
if(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;
}else
if(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.c
delete_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");
else
wonky_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.c
if 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);
else
return 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.c
return 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;
+ }
#endif
F 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);
#endif
F 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;
+ }
+ }
+ #endif
F 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);
+
+
+ #endif
F 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;
+
+ #endif
F 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_internals
F 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.hh
struct wonky_array_internals;
+ #ifndef _wonky_arr
+ #define _wonky_arr
+ #endif
+
#endif
F 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.c
return 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;
+ }
+
+
+
+ #endif
F 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);
+
+ #endif
F 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
+ };
+
+
+ #endif
F 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;
+ }
+ #endif
F 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);
+
+ #endif
F 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;
+
+ #endif
F diff --git a/src/semantics/ast.c b/src/semantics/ast.c
--- a/src/semantics/ast.c
+++ b/src/semantics/ast.c
hold_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);
}else
F 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.c
while(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.c
if(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.c
file=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);
}
}