F diff --git a/code_generation/js/transpile_to_js.c b/code_generation/js/transpile_to_js.c --- a/code_generation/js/transpile_to_js.c +++ b/code_generation/js/transpile_to_js.cfor(it=program->translation_units->first;it!=NULL;it=it->prev){fprintf(out,"{");+ to_js_print_statics(out,(struct AST_Translation_Unit*)it->data,command_arguments);+ fprintf(out,"\n");to_js_print_translation_unit_tree(out,(struct AST_Translation_Unit*)it->data,program);fprintf(out,"\n}\n");}#define DOBJ(x) ((struct Denoted_Object*)x)if(DENOTED(denoted)->denotation==DT_Function){+ if(DFUNC(denoted)->body==NULL)+ {+ fprintf(ARGS(args)->output_file,"/*UNDEFINED*/");+ }fprintf(ARGS(args)->output_file,"var ");print_token(ARGS(args)->output_file,DFUNC(denoted)->id);- fprintf(ARGS(args)->output_file,"; /*FUNCTION*/ ");+ fprintf(ARGS(args)->output_file,";");+ 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,";\n");+ }++ #undef DOBJ+ #undef DFUNC+ #undef ARGS+ #undef DENOTED+ }+ void _to_js_print_statics(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)+ {if(DFUNC(denoted)->body==NULL){fprintf(ARGS(args)->output_file,"/*UNDEFINED*/");}+ fprintf(ARGS(args)->output_file,"let ");+ print_token(ARGS(args)->output_file,DFUNC(denoted)->id);+ fprintf(ARGS(args)->output_file,";");fprintf(ARGS(args)->output_file,"\n");}else if(DENOTED(denoted)->denotation==DT_Object){- fprintf(ARGS(args)->output_file,"var ");+ fprintf(ARGS(args)->output_file,"let ");print_token(ARGS(args)->output_file,DFUNC(denoted)->id);- fprintf(ARGS(args)->output_file,"; /*VARIABLE*/");+ fprintf(ARGS(args)->output_file,";");}#undef DOBJ,command_arguments);fprintf(out,"\n/*EXTERNS END*/\n");}++ void to_js_print_statics(FILE* out,struct AST_Translation_Unit *translation_unit,struct Command_Arguments* command_arguments)+ {++ Map_Map_Extended(+ &((struct Normal_Scope*)translation_unit->scope)->ordinary+ ,_to_js_print_statics+ ,command_arguments);+ }void to_js_print_ast(FILE* out,struct AST *tree,struct Program *program){if(tree==NULL)F diff --git a/code_generation/js/transpile_to_js.h b/code_generation/js/transpile_to_js.h --- a/code_generation/js/transpile_to_js.h +++ b/code_generation/js/transpile_to_js.hvoid transpile_to_javascript(FILE* out,struct Program *program,struct Command_Arguments *command_arguments);++ void _to_js_print_externs(void *denoted,void *args);void to_js_print_externs(FILE* out,struct Program *program,struct Command_Arguments *command_arguments);+ void _to_js_print_statics(void *denoted,void *args);+ void to_js_print_statics(FILE* out,struct AST_Translation_Unit *translation_unit,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);F diff --git a/misc/print.c b/misc/print.c --- a/misc/print.c +++ b/misc/print.ccase DT_Label:fprintf(out,"label ");return;case DT_Object:+ switch(((struct Denoted_Object*)denoted)->object->storage_class)+ {+ case SC_EXTERN:+ fprintf(out,"extern ");+ break;+ case SC_STATIC:+ fprintf(out,"static ");+ break;+ }fprintf(out,"denoted object ");print_token(out,((struct Denoted_Object*)denoted)->id);fprintf(out," is a ");print_type(out,((struct Denoted_Typedef*)denoted)->type,0);return;case DT_Function:+ switch(((struct Denoted_Function*)denoted)->storage_class)+ {+ case SC_EXTERN:+ fprintf(out,"extern ");+ break;+ case SC_STATIC:+ fprintf(out,"static ");+ break;+ }print_token(out,((struct Denoted_Function*)denoted)->id);fprintf(out," is ");print_type(out,((struct Denoted_Function*)denoted)->type,1);F diff --git a/parse/parse_declaration.c b/parse/parse_declaration.c --- a/parse/parse_declaration.c +++ b/parse/parse_declaration.cif(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);F diff --git a/semantics/scope.c b/semantics/scope.c --- a/semantics/scope.c +++ b/semantics/scope.creturn 1;*/case DT_Function:- if(((struct Denoted_Function*)declarator)->storage_class==SC_EXTERN)+ if(scope->type==FILE_SCOPE){- while(scope->type!=EXTERN_SCOPE)- scope=scope->parent;+ ((struct Denoted_Function*)declarator)->storage_class=SC_EXTERN;+ }+ switch(((struct Denoted_Function*)declarator)->storage_class)+ {+ case SC_EXTERN:+ while(scope->type!=EXTERN_SCOPE)+ scope=scope->parent;+ break;+ case SC_STATIC:+ assert(scope->type!=EXTERN_SCOPE);++ while(scope->type!=FILE_SCOPE)+ scope=scope->parent;+ break;}goto hack;case DT_Object:- if(((struct Denoted_Object*)declarator)->object->storage_class==SC_EXTERN)+ switch(((struct Denoted_Object*)declarator)->object->storage_class){- while(scope->type!=EXTERN_SCOPE)- scope=scope->parent;+ case SC_EXTERN:+ while(scope->type!=EXTERN_SCOPE)+ scope=scope->parent;+ break;+ case SC_STATIC:+ assert(scope->type!=EXTERN_SCOPE);++ while(scope->type!=FILE_SCOPE)+ scope=scope->parent;+ break;}goto hack;case DT_Typedef:F diff --git a/tests/test3.c b/tests/test3.c --- a/tests/test3.c +++ b/tests/test3.c#endifextern int external_int;+ static int static_int;static int fib(int n){int a=1,b=1,c;}extern void alert(int a);- int main()+ extern int main(){- int k[10*10];+ int k[10*10][3][5];external_int++;alert(fib(10));return 0;