F diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
include_directories(parse)
include_directories(semantics)
include_directories(lex)
+ include_directories(code_generation/js)
set(SOURCES main.c
parse/parse_declaration.c
semantics/scope.c
semantics/semantics.c
semantics/gcc_error.c
+ code_generation/js/transpile_to_js.c
)
add_executable(wonky ${SOURCES})
F diff --git a/README b/README
--- a/README
+++ b/README
prints the tokens after preprocessing
--print-ast
prints 'ast' of the program after parsing
+ --transpile-to-js || -js
+ tries to transpile C code to JS
+ --add-html
+ Encases resulting JS in simple html
+ -o FILENAME
+ specifies output filename
F diff --git a/code_generation/js/transpile_to_js.c b/code_generation/js/transpile_to_js.c
new file mode 100644
--- /dev/null
+++ b/code_generation/js/transpile_to_js.c
+ #ifndef GCC_TRANSPILE_TO_JS_C
+ #define GCC_TRANSPILE_TO_JS_C GCC_TRANSPILE_TO_JS_C
+ #include <transpile_to_js.h>
+
+
+ void transpile_to_javascript(FILE* out,struct Program *program,struct Command_Arguments *command_arguments)
+ {
+ struct Queue_Node *it;
+
+ if(command_arguments->insert_html)
+ {
+ fprintf(out,"<DOCTYPE! html> <html> <head> <title>asdf</title> <script>");
+ }
+ to_js_print_externs(out,program,command_arguments);
+
+ for(it=program->translation_units->first;it!=NULL;it=it->prev)
+ {
+ fprintf(out,"{");
+ to_js_print_translation_unit_tree(out,(struct AST_Translation_Unit*)it->data,program);
+ fprintf(out,"\n}\n");
+ }
+
+ if(command_arguments->insert_html)
+ {
+ fprintf(out,"</script> </head> <body> </body> </html>");
+ }
+
+ }
+
+ void _to_js_print_externs(void *denoted,void *args)
+ {
+ #define ARGS(x) ((struct Command_Arguments*)x)
+ #define DENOTED(x) ((struct Denoted*)x)
+ #define DFUNC(x) ((struct Denoted_Function*)x)
+ #define DOBJ(x) ((struct Denoted_Object*)x)
+ if(DENOTED(denoted)->denotation==DT_Function)
+ {
+ fprintf(ARGS(args)->output_file,"var ");
+ print_token(ARGS(args)->output_file,DFUNC(denoted)->id);
+ fprintf(ARGS(args)->output_file,"; /*FUNCTION*/ ");
+ if(DFUNC(denoted)->body==NULL)
+ {
+ fprintf(ARGS(args)->output_file,"/*UNDEFINED*/");
+ }
+ fprintf(ARGS(args)->output_file,"\n");
+
+ }else if(DENOTED(denoted)->denotation==DT_Object)
+ {
+ fprintf(ARGS(args)->output_file,"var ");
+ print_token(ARGS(args)->output_file,DFUNC(denoted)->id);
+ fprintf(ARGS(args)->output_file,"; /*VARIABLE*/");
+ }
+
+ #undef DOBJ
+ #undef DFUNC
+ #undef ARGS
+ #undef DENOTED
+ }
+ void to_js_print_externs(FILE* out,struct Program *program,struct Command_Arguments *command_arguments)
+ {
+ fprintf(out,"\n/*EXTERNS START*/\n");
+ Map_Map_Extended(
+ &((struct Normal_Scope*)program->externs)->ordinary
+ ,_to_js_print_externs
+ ,command_arguments);
+ fprintf(out,"\n/*EXTERNS END*/\n");
+ }
+ void to_js_print_ast(FILE* out,struct AST *tree,struct Program *program)
+ {
+ if(tree==NULL)
+ {
+ return ;
+ }
+ switch(tree->type)
+ {
+ case OP_MEMBER_TROUGH_PTR:
+ case OP_MEMBER:
+ case OP_BITWISE_AND:
+ case OP_BITWISE_XOR:
+ case OP_BITWISE_NOT:
+ 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:
+ to_js_print_binary_expression_tree(out,(struct AST_Binary_Expression*)tree,program);
+ break;
+ case OP_COND:
+ to_js_print_conditional_expression_tree(out,(struct AST_Conditional_Expression*)tree,program);
+ break;
+ case OP_FUNCTION:
+ to_js_print_function_expression_tree(out,(struct AST_Function_Expression*)tree,program);
+ 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:
+ to_js_print_unary_expression_tree(out,(struct AST_Unary_Expression*)tree,program);
+ break;
+ case OP_LVALUE:
+ to_js_print_lvalue_expression_tree(out,(struct AST_Lvalue_Expression*)tree,program);
+ break;
+ case OP_RVALUE:
+ to_js_print_rvalue_expression_tree(out,(struct AST_Rvalue_Expression*)tree,program);
+ break;
+ case OP_NOP:
+ fprintf(out,"NOP");
+ break;
+
+ case ST_SWITCH:
+ to_js_print_switch_statement_tree(out,(struct AST_Switch_Statement*)tree,program);
+ break;
+ case ST_IF:
+ to_js_print_if_statement_tree(out,(struct AST_If_Statement*)tree,program);
+ break;
+ case ST_WHILE:
+ to_js_print_while_statement_tree(out,(struct AST_While_Statement*)tree,program);
+ break;
+ case ST_DO_WHILE:
+ to_js_print_do_while_statement_tree(out,(struct AST_Do_While_Statement*)tree,program);
+ break;
+ case ST_GOTO:
+ to_js_print_goto_statement_tree(out,(struct AST_Goto_Statement*)tree,program);
+ break;
+ case ST_DEFAULT:
+ case ST_LABEL:
+ case ST_CASE:
+ to_js_print_labeled_statement_tree(out,(struct AST_Labeled_Statement*)tree,program);
+ break;
+ case ST_CONTINUE:
+ fprintf(out,"continue");
+ break;
+ case ST_BREAK:
+ fprintf(out,"break");
+ break;
+ case ST_RETURN:
+ to_js_print_return_statement_tree(out,(struct AST_Return_Statement*)tree,program);
+ break;
+ case ST_FOR:
+ to_js_print_for_statement_tree(out,(struct AST_For_Statement*)tree,program);
+ break;
+ case ST_COMPOUND:
+ to_js_print_compound_statement_tree(out,(struct AST_Compound_Statement*)tree,program);
+ break;
+ case ST_OBJECT_DECLARATION:
+ to_js_print_object_declaration_tree(out,((struct AST_Object_Declaration*)tree),program);
+ if(((struct AST_Object_Declaration*)tree)->initializer!=NULL)
+ {
+ fprintf(out,"=");
+ to_js_print_ast(out,((struct AST_Object_Declaration*)tree)->initializer,program);
+ }
+ break;
+ case ST_FUNCTION_DECLARATION:
+ to_js_print_function_declaration_tree(out,((struct AST_Function_Declaration*)tree),program);
+ break;
+ case ST_FUNCTION_DEFINITION:
+ to_js_print_function_definition(out,((struct AST_Function_Definition*)tree),program);
+ break;
+ case TRANSLATION_UNIT:
+ to_js_print_translation_unit_tree(out,(struct AST_Translation_Unit*)tree,program);
+ break;
+ case ERROR:
+ default:
+ /*TODO error*/
+ return;
+ }
+ }
+ void to_js_print_translation_unit_tree(FILE* out,struct AST_Translation_Unit *translation_unit,struct Program *program)
+ {
+ struct Queue_Node *it;
+ struct AST* hold;
+ for(it=translation_unit->components.first;it!=NULL;it=it->prev)
+ {
+ hold=(struct AST*)(it->data);
+ to_js_print_ast(out,hold,program);
+
+ fprintf(out,";\n");
+ }
+ }
+ void to_js_print_binary_expression_tree(FILE* out,struct AST_Binary_Expression *bin,struct Program *program)
+ {
+ if(bin->type==OP_ARR_SUBSCRIPT)
+ {
+ to_js_print_ast(out,bin->left,program);
+ fprintf(out,"[");
+ to_js_print_ast(out,bin->right,program);
+ fprintf(out,"]");
+ }else
+ {
+ fprintf(out,"(");
+ to_js_print_ast(out,bin->left,program);
+ print_ast_enum(out,bin->type);
+ to_js_print_ast(out,bin->right,program);
+ fprintf(out,")");
+ }
+ }
+
+ void to_js_print_conditional_expression_tree(FILE* out,struct AST_Conditional_Expression *cond,struct Program *program)
+ {
+ fprintf(out,"(");
+ to_js_print_ast(out,cond->left,program);
+ fprintf(out,"?");
+ to_js_print_ast(out,cond->center,program);
+ fprintf(out,":");
+ to_js_print_ast(out,cond->right,program);
+ fprintf(out,")");
+ }
+ void to_js_print_function_expression_tree(FILE* out,struct AST_Function_Expression *function_call,struct Program *program)
+ {
+ struct Queue_Node *it;
+ to_js_print_ast(out,function_call->id,program);
+ fprintf(out,"(");
+ if(function_call->arguments.size>0)
+ {
+ fprintf(out,"\n");
+ for(it=function_call->arguments.first;it!=function_call->arguments.last;it=it->prev)
+ {
+ to_js_print_ast(out,(struct AST*)(it->data),program);
+ fprintf(out,",\n");
+ }
+ if(it!=NULL)
+ {
+ to_js_print_ast(out,(struct AST*)(it->data),program);
+ }
+
+ }
+ fprintf(out,")");
+ }
+ void to_js_print_rvalue_expression_tree(FILE* out,struct AST_Rvalue_Expression *rval,struct Program *program)
+ {
+ print_token(out,rval->id);
+ }
+ void to_js_print_lvalue_expression_tree(FILE* out,struct AST_Lvalue_Expression *lval,struct Program *program)
+ {
+ print_token(out,lval->id);
+ }
+ void to_js_print_unary_expression_tree(FILE* out,struct AST_Unary_Expression *unary,struct Program *program)
+ {
+ print_ast_enum(out,unary->type);
+ to_js_print_ast(out,unary->operand,program);
+ }
+ void to_js_print_labeled_statement_tree(FILE* out,struct AST_Labeled_Statement *label,struct Program *program)
+ {
+ if(label->type!=ST_LABEL)
+ print_ast_enum(out,label->type);
+ if(label->label!=NULL)
+ {
+ fprintf(out,"case");
+ print_token(out,label->label);
+ }
+ fprintf(out,":\n");
+ to_js_print_ast(out,label->statement,program);
+ }
+ void to_js_print_compound_statement_tree(FILE* out,struct AST_Compound_Statement *compound,struct Program *program)
+ {
+ struct Queue_Node *it;
+ fprintf(out,"{");
+ for(it=compound->components.first;it!=NULL;it=it->prev)
+ {
+ fprintf(out,"\n");
+ to_js_print_ast(out,(struct AST*)it->data,program);
+ fprintf(out,";");
+ }
+ fprintf(out,"\n}");
+ }
+ void to_js_print_for_statement_tree(FILE* out,struct AST_For_Statement *for_statement,struct Program *program)
+ {
+ fprintf(out,"for(\n");
+ if(for_statement->initialisation!=NULL)
+ to_js_print_ast(out,for_statement->initialisation,program);
+ fprintf(out,";\n");
+ if(for_statement->condition!=NULL)
+ to_js_print_ast(out,for_statement->condition,program);
+ fprintf(out,";\n");
+ if(for_statement->update!=NULL)
+ to_js_print_ast(out,for_statement->update,program);
+ fprintf(out,")\n");
+ print_ast(out,for_statement->body_statement);
+ }
+ void to_js_print_while_statement_tree(FILE* out,struct AST_While_Statement *while_statement,struct Program *program)
+ {
+ fprintf(out,"while(");
+ to_js_print_ast(out,while_statement->condition,program);
+ fprintf(out,")\n");
+ to_js_print_ast(out,while_statement->body_statement,program);
+ }
+ void to_js_print_do_while_statement_tree(FILE* out,struct AST_Do_While_Statement *do_while_statement,struct Program *program)
+ {
+ fprintf(out,"do\n");
+ to_js_print_ast(out,do_while_statement->body_statement,program);
+ fprintf(out,"while(");
+ to_js_print_ast(out,do_while_statement->condition,program);
+ fprintf(out,")\n");
+ }
+ void to_js_print_if_statement_tree(FILE* out,struct AST_If_Statement *if_statement,struct Program *program)
+ {
+ fprintf(out,"if(");
+ to_js_print_ast(out,if_statement->condition,program);
+ fprintf(out,")\n");
+ to_js_print_ast(out,if_statement->body_statement,program);
+
+ if(if_statement->else_statement!=NULL)
+ {
+ fprintf(out,"\nelse");
+ to_js_print_ast(out,if_statement->else_statement,program);
+ }
+ }
+ void to_js_print_goto_statement_tree(FILE* out,struct AST_Goto_Statement *goto_statement,struct Program *program)
+ {
+ /*TODO something here, be it error or not*/
+ }
+ void to_js_print_switch_statement_tree(FILE* out,struct AST_Switch_Statement *switch_statement,struct Program *program)
+ {
+ fprintf(out,"switch(");
+ to_js_print_ast(out,switch_statement->condition,program);
+ fprintf(out,")\n");
+ to_js_print_ast(out,switch_statement->body_statement,program);
+ }
+ void to_js_print_return_statement_tree(FILE* out,struct AST_Return_Statement *return_statement,struct Program *program)
+ {
+ fprintf(out,"return ");
+ to_js_print_ast(out,return_statement->return_expression,program);
+ }
+ void to_js_print_object_declaration_tree(FILE* out,struct AST_Object_Declaration *object_declaration,struct Program *program)
+ {
+ if(object_declaration->object->object->storage_class!=SC_EXTERN)
+ {
+ fprintf(out,"let ");
+ print_token(out,object_declaration->object->id);
+ }
+
+ }
+ void to_js_print_function_definition(FILE* out,struct AST_Function_Definition *function_definition,struct Program *program)
+ {
+ size_t i;
+ struct Type_Function *cache_type;
+
+ cache_type=(struct Type_Function*)function_definition->function->type;
+
+ if((struct Type_Function*)function_definition->function->storage_class==SC_EXTERN)
+ {
+ // fprintf(out,"var ");
+ print_token(out,function_definition->function->id);
+ fprintf(out,"= function");
+ }else
+ {
+ fprintf(out,"function ");
+ print_token(out,function_definition->function->id);
+ }
+
+ /*print parameters*/
+ fprintf(out,"(");
+ print_token(out,cache_type->arguments[0]->id);
+ for(i=1;i<cache_type->number_of_arguments;++i)
+ {
+ fprintf(out,",");
+ print_token(out,cache_type->arguments[i]->id);
+ }
+
+ fprintf(out,")");
+
+ /*print body*/
+ to_js_print_compound_statement_tree(out,function_definition->function->body,program);
+
+
+ }
+ void to_js_print_function_declaration_tree(FILE* out,struct AST_Function_Declaration *function_declaration,struct Program *program)
+ {
+ /*TODO probably leave it empty*/
+ }
+
+
+
+ #endif
F diff --git a/code_generation/js/transpile_to_js.h b/code_generation/js/transpile_to_js.h
new file mode 100644
--- /dev/null
+++ b/code_generation/js/transpile_to_js.h
+ #ifndef GCC_TRANSPILE_TO_JS_H
+ #define GCC_TRANSPILE_TO_JS_H GCC_TRANSPILE_TO_JS_H
+ #include <program.h>
+ #include <gcc_arguments.h>
+ #include <stdio.h>
+ #include <print.h>
+
+
+ void transpile_to_javascript(FILE* out,struct Program *program,struct Command_Arguments *command_arguments);
+ void to_js_print_externs(FILE* out,struct Program *program,struct Command_Arguments *command_arguments);
+
+ void to_js_print_ast(FILE* out,struct AST *tree,struct Program *program);
+ void to_js_print_translation_unit_tree(FILE* out,struct AST_Translation_Unit *translation_unit,struct Program *program);
+ void to_js_print_binary_expression_tree(FILE* out,struct AST_Binary_Expression *bin,struct Program *program);
+ void to_js_print_conditional_expression_tree(FILE* out,struct AST_Conditional_Expression *cond,struct Program *program);
+ void to_js_print_function_expression_tree(FILE* out,struct AST_Function_Expression *function_call,struct Program *program);
+ void to_js_print_rvalue_expression_tree(FILE* out,struct AST_Rvalue_Expression *rval,struct Program *program);
+ void to_js_print_lvalue_expression_tree(FILE* out,struct AST_Lvalue_Expression *lval,struct Program *program);
+ void to_js_print_unary_expression_tree(FILE* out,struct AST_Unary_Expression *unary,struct Program *program);
+ void to_js_print_labeled_statement_tree(FILE* out,struct AST_Labeled_Statement *label,struct Program *program);
+ void to_js_print_compound_statement_tree(FILE* out,struct AST_Compound_Statement *compound,struct Program *program);
+ void to_js_print_for_statement_tree(FILE* out,struct AST_For_Statement *for_statement,struct Program *program);
+ void to_js_print_while_statement_tree(FILE* out,struct AST_While_Statement *while_statement,struct Program *program);
+ void to_js_print_do_while_statement_tree(FILE* out,struct AST_Do_While_Statement *do_while_statement,struct Program *program);
+ void to_js_print_if_statement_tree(FILE* out,struct AST_If_Statement *if_statement,struct Program *program);
+ void to_js_print_goto_statement_tree(FILE* out,struct AST_Goto_Statement *goto_statement,struct Program *program);
+ void to_js_print_switch_statement_tree(FILE* out,struct AST_Switch_Statement *switch_statement,struct Program *program);
+ void to_js_print_return_statement_tree(FILE* out,struct AST_Return_Statement *return_statement,struct Program *program);
+ void to_js_print_object_declaration_tree(FILE* out,struct AST_Object_Declaration *object_declaration,struct Program *program);
+ void to_js_print_function_definition(FILE* out,struct AST_Function_Definition *function_definition,struct Program *program);
+ void to_js_print_function_declaration_tree(FILE* out,struct AST_Function_Declaration *function_declaration,struct Program *program);
+ void to_js_print_denoted(FILE* out,struct Denoted* denoted,struct Program *program);
+
+
+
+ #endif
F diff --git a/lex/preprocessing.c b/lex/preprocessing.c
--- a/lex/preprocessing.c
+++ b/lex/preprocessing.c
if(hold_macro!=NULL)
{
delete_macro(hold_macro);
+ Map_Remove(translation_data->macros,id->data,id->data_size);
}
}
chase_new_line(src,translation_data);
F diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
struct Program *program;
command_arguments=parse_command_arguments(argv);
+ if(command_arguments->error_message!=NULL)
+ {
+ fprintf(stderr,command_arguments->error_message);
+ return 1;
+ }
if(command_arguments->print_tokens && !command_arguments->is_quiet)
{
return print_tokens_of_program(stdout,command_arguments->source_names);
}else if(command_arguments->print_ast && !command_arguments->is_quiet)
{
print_program_ast(stdout,program);
+ }else if(command_arguments->transpile_to_js)
+ {
+ transpile_to_javascript(command_arguments->output_file,program,command_arguments);
}
}
F diff --git a/misc/all.h b/misc/all.h
--- a/misc/all.h
+++ b/misc/all.h
#include <scope.h>
#include <semantics.h>
#include <type.h>
+ #include <transpile_to_js.h>
#include <queue.h>
#include <map.h>
F diff --git a/misc/gcc_arguments.c b/misc/gcc_arguments.c
--- a/misc/gcc_arguments.c
+++ b/misc/gcc_arguments.c
struct Queue *source_names;
ret=malloc(sizeof(struct Command_Arguments));
- ret->print_ast=ret->print_tokens=0;
+ ret->print_ast=ret->print_tokens=ret->transpile_to_js=0;
+ ret->output_file=ret->javascript_extern_file=NULL;
source_names=malloc(sizeof(struct Queue));
Queue_Init(source_names);
+ ret->error_message=NULL;
/*we skip the first element(the program name)*/
for(++argv;*argv;++argv)
}else if(gstr_cmp(*argv,"--quiet") || gstr_cmp(*argv,"-q"))
{
ret->is_quiet=1;
+ if(ret->print_ast || ret->print_tokens)
+ {
+ ret->error_message="print and quiet conflict. Aborting";
+ break;
+ }
+ }else if(gstr_cmp(*argv,"--transpile_to_js") || gstr_cmp(*argv,"-js"))
+ {
+ ret->transpile_to_js=1;
+ }else if(gstr_cmp(*argv,"-o"))
+ {
+ ++argv;
+ if(*argv==NULL)
+ {
+ ret->error_message="expected a filename after -o. Aborting";
+ break;
+ }else
+ {
+ ret->output_file=fopen(*argv,"w");
+ if(ret->output_file==NULL)
+ {
+ ret->error_message="Couldn't open file for output. Aborting";
+ break;
+ }
+ }
+ }else if(gstr_cmp(*argv,"--make-extern-file"))
+ {
+ ret->javascript_extern_file=fopen(*argv,"w");
+ if(ret->javascript_extern_file==NULL)
+ {
+ ret->error_message="Couldn't open file for extern dump. Aborting";
+ break;
+ }
+ }else if(gstr_cmp(*argv,"--add-html"))
+ {
+ ret->insert_html=1;
}else
{
Queue_Push(source_names,*argv);
Queue_Pop(source_names);
}
free(source_names);
+ if(ret->transpile_to_js && ret->output_file==NULL)
+ {
+ ret->output_file=fopen("a.js","w");
+ if(ret==NULL)
+ ret->error_message="Couldn't open file for output. Aborting";
+ }
return ret;
}
F diff --git a/misc/gcc_arguments.h b/misc/gcc_arguments.h
--- a/misc/gcc_arguments.h
+++ b/misc/gcc_arguments.h
#include <gcc_arguments.hh>
#include <queue.h>
#include <gcc_string.h>
+ #include <stdio.h>
struct Command_Arguments
char print_tokens:1;
char print_ast:1;
char is_quiet:1;
+ char transpile_to_js:1;
+ char insert_html:1;
+
+
+ FILE* output_file;
+ FILE* javascript_extern_file;
+
+
+ char *error_message;
};
struct Command_Arguments* parse_command_arguments(char **argv);
F diff --git a/misc/map.c b/misc/map.c
--- a/misc/map.c
+++ b/misc/map.c
}
}
+ /*first argument of map is the node id , the second is pass_data*/
+ void Map_Map_Extended(Map *tree,void (*map)(void*,void*),void* pass_data)
+ {
+ if(tree->is_final==1)map(tree->ID,pass_data);
+ for(int i=0;i<256;++i)
+ {
+ if(tree->delta[i]!=NULL)
+ {
+ Map_Map_Extended(tree->delta[i],map,pass_data);
+ }
+ }
+ }
/*this does not destroy(free) any memory pointed to by a node in the Map. This does not free() the root (Map *tree) */
F diff --git a/misc/map.h b/misc/map.h
--- a/misc/map.h
+++ b/misc/map.h
void* Map_Check(Map *tree, void *str,size_t size);
void Map_Remove(Map *tree, void *str,size_t size);
void Map_Map(Map *tree,void (*map)(void*));
+ void Map_Map_Extended(Map *tree,void (*map)(void*,void*),void* pass_data);
void Map_Destroy(Map *tree);
struct Condensed_Map* Map_Condense(Map* tree);
F diff --git a/misc/print.c b/misc/print.c
--- a/misc/print.c
+++ b/misc/print.c
case OP_ASSIGN:
fprintf(out,"=");break;
case OP_ADD_ASSIGN:
- fprintf(out,"&=");break;
+ fprintf(out,"+=");break;
case OP_SUBTRACT_ASSIGN:
fprintf(out,"-=");break;
case OP_MULTIPLY_ASSIGN:
fprintf(out,"denotation error");return;
case DT_Prototype:
fprintf(out,"denotation prototyep");return;
+ default:
+ assert(0);
}
}
if(func->number_of_arguments==0)
return;
- print_type(out,func->arguments[0],0);
+ print_denoted(out,(struct Denoted*)func->arguments[0]);
for(i=1;i<func->number_of_arguments;++i)
{
fprintf(out,", ");
- print_type(out,func->arguments[i],0);
+ print_denoted(out,(struct Denoted*)func->arguments[i]);
}
}
#undef TOK
F diff --git a/parse/parse_declaration.c b/parse/parse_declaration.c
--- a/parse/parse_declaration.c
+++ b/parse/parse_declaration.c
if(get_and_check(translation_data,KW_OPEN_CURLY))
{
((struct Denoted_Function*)hold)->body=(struct AST_Compound_Statement*)parse_finish_compound_statement(translation_data,scope);
+ ((struct Denoted_Function*)hold)->storage_class=(prototype->storage_class==SC_NONE?
+ SC_EXTERN:
+ prototype->storage_class);
+
+
+
+
Queue_Push(where_to_push,get_function_definition_tree(scope,(struct Denoted_Function*)hold));
Scope_Push(scope,hold);
free(prototype);
hold=extract_denoted(base,prototype,1);
Scope_Push((struct Scope*)function_prototype_scope,hold);
- Queue_Push(parameters,((struct Denoted_Object*)hold)->object->type);
+ Queue_Push(parameters,((struct Denoted_Object*)hold));
- delete_denoted(hold);
delete_denoted_prototype(prototype);
delete_denoted_base(base);
F diff --git a/semantics/denoted.c b/semantics/denoted.c
--- a/semantics/denoted.c
+++ b/semantics/denoted.c
ret->type=return_type;
ret->function_specifier=fs;
ret->body=NULL;
+ ret->storage_class=SC_NONE;
return (struct Denoted*)ret;
}
{
delete_denoted(denoted);
}
+
+
+
+
+
#endif
F diff --git a/semantics/denoted.h b/semantics/denoted.h
--- a/semantics/denoted.h
+++ b/semantics/denoted.h
enum Function_Specifier function_specifier;
+ enum Storage_Class storage_class;
+
struct AST_Compound_Statement *body;
};
struct Denoted_Object
void delete_denoted_base(struct Denoted_Base *base);
+ enum Storage_Class get_denoted_function_storage_class(struct Denoted_Function *function);
#endif
F diff --git a/semantics/scope.c b/semantics/scope.c
--- a/semantics/scope.c
+++ b/semantics/scope.c
return 1;
*/
case DT_Function:
- case DT_Typedef:
+ if(((struct Denoted_Function*)declarator)->storage_class==SC_EXTERN)
+ {
+ while(scope->type!=EXTERN_SCOPE)
+ scope=scope->parent;
+ }
+ goto hack;
case DT_Object:
+ if(((struct Denoted_Object*)declarator)->object->storage_class==SC_EXTERN)
+ {
+ while(scope->type!=EXTERN_SCOPE)
+ scope=scope->parent;
+ }
+ goto hack;
+ case DT_Typedef:
case DT_Enum_Constant:
case DT_Struct_Union_Member:
+ hack:
push_ordinary(scope,((struct Denoted_Object*)declarator)->id,declarator);
return;
case DT_Enum:
F diff --git a/semantics/type.c b/semantics/type.c
--- a/semantics/type.c
+++ b/semantics/type.c
ret->number_of_arguments=parameters->size;
- ret->arguments=malloc(sizeof(struct Type*)*ret->number_of_arguments);
+ ret->arguments=malloc(sizeof(struct Denoted_Object*)*ret->number_of_arguments);
for(i=0;parameters->size>0;++i)
{
- ret->arguments[i]=(struct Type*)Queue_Pop(parameters);
+ ret->arguments[i]=(struct Denoted_Object*)Queue_Pop(parameters);
}
ret=(struct Type_Function*)type_check_and_push((struct Type*)ret,return_type->node,sizeof(struct Type_Function));
F diff --git a/semantics/type.h b/semantics/type.h
--- a/semantics/type.h
+++ b/semantics/type.h
struct Type *return_type;
/*types*/
size_t number_of_arguments;
- /*array of pointers to Type*/
- struct Type** arguments;
+
+ struct Denoted_Object** arguments;
struct Normal_Scope *function_prototype_scope;
};
F diff --git a/tests/test3.c b/tests/test3.c
--- a/tests/test3.c
+++ b/tests/test3.c
int err;
#endif
+ #undef VERSION
#ifdef VERSION
- char charimander;
+ char asdf;
#endif
+
+ extern int external_int;
+ static int fib(int n)
+ {
+ int a=1,b=1,c;
+ for(n;n>0;--n)
+ {
+ c=a;
+ a+=b;
+ b=c;
+ }
+ return a;
+
+ }
+ int main(int argc,char *argv[])
+ {
+ int k[10*10];
+ a=b=c=d;
+ external_int++;
+ fib(10);
+ return 0;
+ }