@@ -48,6 +48,9 @@ KaosIR* compile(ASTRoot* ast_root)
4848 // Declare functions in all parsed files
4949 declare_functions (ast_root , program );
5050
51+ // Determine whether the functions should be inlined or not
52+ determine_inline_functions (ast_root );
53+
5154 // Compile functions in all parsed files
5255 compile_functions (ast_root , program );
5356
@@ -652,6 +655,12 @@ unsigned short compileExpr(KaosIR* program, Expr* expr)
652655 enum ValueType value_type = compileExpr (program , expr ) - 1 ;
653656 Symbol * parameter = function -> parameters [i - 1 ];
654657
658+ if (function -> should_inline ) {
659+ Symbol * symbol_upper = getSymbol (expr_list -> exprs [i - 1 ]-> v .ident -> name );
660+ Symbol * symbol_new = createCloneFromSymbol (parameter -> name , symbol_upper -> type , symbol_upper , symbol_upper -> type );
661+ symbol_new -> addr = symbol_upper -> addr ;
662+ }
663+
655664 strongly_type (parameter , NULL , function , expr , value_type );
656665
657666 enum Type type = parameter -> type ;
@@ -857,16 +866,23 @@ unsigned short compileExpr(KaosIR* program, Expr* expr)
857866 } else {
858867 }
859868
860- push_inst_ (program , PREPARE );
861- for (size_t i = 0 ; i < putargr_stack_p ; i ++ )
862- push_inst_r (program , PUTARGR , putargr_stack [i ]);
869+ if (function -> should_inline ) {
870+ Decl * decl = function -> ast ;
871+ compileStmt (program , decl -> v .func_decl -> body );
872+ if (decl -> v .func_decl -> decision != NULL )
873+ compileSpec (program , decl -> v .func_decl -> decision );
874+ } else {
875+ push_inst_ (program , PREPARE );
876+ for (size_t i = 0 ; i < putargr_stack_p ; i ++ )
877+ push_inst_r (program , PUTARGR , putargr_stack [i ]);
863878
864- push_inst_i_i (program , CALL , function -> addr , op_counter ++ );
879+ push_inst_i_i (program , CALL , function -> addr , op_counter ++ );
865880
866- function -> call_patches [function -> call_patches_size ++ ] = op_counter - 1 ;
881+ function -> call_patches [function -> call_patches_size ++ ] = op_counter - 1 ;
867882
868- push_inst_r (program , RETVAL , R1 );
869- push_inst_r_i (program , MOVI , R0 , 1 ); // TODO: temp, set it according to function return type
883+ push_inst_r (program , RETVAL , R1 );
884+ push_inst_r_i (program , MOVI , R0 , 1 ); // TODO: temp, set it according to function return type
885+ }
870886
871887 return function -> value_type + 1 ;
872888 break ;
@@ -1042,6 +1058,14 @@ void compileDecl(KaosIR* program, Decl* decl)
10421058 }
10431059 case FuncDecl_kind : {
10441060 _Function * function = startFunctionNew (decl -> v .func_decl -> name -> v .ident -> name );
1061+ if (function -> should_inline ) {
1062+ function -> ast = decl ;
1063+ function_mode -> is_compiled = true;
1064+ endFunction ();
1065+ break ;
1066+ }
1067+
1068+ function -> ast = decl ;
10451069
10461070 if (function -> is_compiled )
10471071 break ;
@@ -2145,6 +2169,111 @@ void compile_functions(ASTRoot* ast_root, KaosIR* program)
21452169 }
21462170}
21472171
2172+ void determine_inline_functions (ASTRoot * ast_root )
2173+ {
2174+ for (unsigned long i = 0 ; i < ast_root -> file_count ; i ++ ) {
2175+ File * file = ast_root -> files [i ];
2176+ current_file_index = i ;
2177+ StmtList * stmt_list = file -> stmt_list ;
2178+ pushModuleStack (file -> module_path , file -> module );
2179+
2180+ // Foreach function look for other functions' decision blocks for calls
2181+ for (unsigned long j = stmt_list -> stmt_count ; 0 < j ; j -- ) {
2182+ Stmt * stmt = stmt_list -> stmts [j - 1 ];
2183+ if (stmt -> kind == DeclStmt_kind && stmt -> v .decl_stmt -> decl -> kind == FuncDecl_kind ) {
2184+ Decl * decl = stmt -> v .decl_stmt -> decl ;
2185+ _Function * function = startFunctionNew (decl -> v .func_decl -> name -> v .ident -> name );
2186+ function -> should_inline = determine_inline_function (ast_root , function );
2187+ endFunction ();
2188+ }
2189+ }
2190+
2191+ popModuleStack ();
2192+ }
2193+ }
2194+
2195+ bool determine_inline_function (ASTRoot * ast_root , _Function * function )
2196+ {
2197+ unsigned long call_counter = 0 ;
2198+ // Look for all functions' decision blocks for all the files compiled
2199+ for (unsigned long i = 0 ; i < ast_root -> file_count ; i ++ ) {
2200+ File * file = ast_root -> files [i ];
2201+ current_file_index = i ;
2202+ StmtList * stmt_list = file -> stmt_list ;
2203+ pushModuleStack (file -> module_path , file -> module );
2204+
2205+ for (unsigned long j = stmt_list -> stmt_count ; 0 < j ; j -- ) {
2206+ Stmt * stmt = stmt_list -> stmts [j - 1 ];
2207+ if (stmt -> kind == DeclStmt_kind && stmt -> v .decl_stmt -> decl -> kind == FuncDecl_kind ) {
2208+ Decl * decl = stmt -> v .decl_stmt -> decl ;
2209+ _Function * _function = startFunctionNew (decl -> v .func_decl -> name -> v .ident -> name );
2210+ if (function == _function )
2211+ continue ;
2212+ if (decl -> v .func_decl -> decision != NULL ) {
2213+ ExprList * expr_list = decl -> v .func_decl -> decision -> v .decision_block -> decisions ;
2214+ for (unsigned long i = expr_list -> expr_count ; 0 < i ; i -- ) {
2215+ Expr * expr = expr_list -> exprs [i - 1 ];
2216+ if (does_decision_have_a_call (expr , function )) {
2217+ call_counter ++ ;
2218+ }
2219+ }
2220+ }
2221+ endFunction ();
2222+ }
2223+ }
2224+
2225+ popModuleStack ();
2226+ }
2227+
2228+ if (call_counter == 1 )
2229+ return true;
2230+ else
2231+ return false;
2232+ }
2233+
2234+ bool does_decision_have_a_call (Expr * expr , _Function * function )
2235+ {
2236+ Stmt * stmt = NULL ;
2237+ switch (expr -> kind ) {
2238+ case DecisionExpr_kind :
2239+ stmt = expr -> v .decision_expr -> outcome ;
2240+ break ;
2241+ case DefaultExpr_kind :
2242+ stmt = expr -> v .default_expr -> outcome ;
2243+ break ;
2244+ default :
2245+ break ;
2246+ }
2247+
2248+ return does_stmt_have_a_call (stmt , function );
2249+ }
2250+
2251+ bool does_stmt_have_a_call (Stmt * stmt , _Function * function )
2252+ {
2253+ if (stmt -> kind == ExprStmt_kind && stmt -> v .expr_stmt -> x -> kind == CallExpr_kind ) {
2254+ Expr * expr = stmt -> v .expr_stmt -> x ;
2255+ _Function * _function = NULL ;
2256+ switch (expr -> v .call_expr -> fun -> kind ) {
2257+ case Ident_kind :
2258+ _function = getFunction (expr -> v .call_expr -> fun -> v .ident -> name , NULL );
2259+ break ;
2260+ case SelectorExpr_kind :
2261+ _function = getFunction (
2262+ expr -> v .call_expr -> fun -> v .selector_expr -> sel -> v .ident -> name ,
2263+ expr -> v .call_expr -> fun -> v .selector_expr -> x -> v .ident -> name
2264+ );
2265+ break ;
2266+ default :
2267+ break ;
2268+ }
2269+
2270+ if (function == _function )
2271+ return true;
2272+ }
2273+
2274+ return false;
2275+ }
2276+
21482277void strongly_type (Symbol * symbol_x , Symbol * symbol_y , _Function * function , Expr * expr , enum ValueType value_type )
21492278{
21502279 if (expr != NULL ) {
0 commit comments