lcompilers / lpython

Python compiler
https://lpython.org/
Other
1.47k stars 157 forks source link

Unify FunctionCall and SubroutineCall #947

Open certik opened 1 year ago

certik commented 1 year ago

Since we now only have a Function, we should only have FunctionCall. The idea is to unify the almost duplicate code that we currently have to have in almost all visitors regarding function/subroutine calls.

Also we will be adding generics/templates, so we want both functions and subroutines to be handled the same way.

The different between SubroutineCall and FunctionCall is that one is a statement and the other is not. How to unify?

One option is to just have FunctionCall, an expr. Then change SubroutineCall to just point to a FunctionCall:

--- a/src/libasr/ASR.asdl
+++ b/src/libasr/ASR.asdl
@@ -193,7 +193,7 @@ stmt
     | Select(expr test, case_stmt* body, stmt* default)
     | Stop(expr? code)
     | Assert(expr test, expr? msg)
-    | SubroutineCall(symbol name, symbol? original_name, call_arg* args, expr? dt)
+    | SubroutineCall(expr function_call)
     | Where(expr test, stmt* body, stmt* orelse)
     | WhileLoop(expr test, stmt* body)
     | Nullify(symbol* vars)

But the extra indirection is a bit unfortunate. Another option is:

--- a/src/libasr/ASR.asdl
+++ b/src/libasr/ASR.asdl
@@ -193,7 +193,7 @@ stmt
     | Select(expr test, case_stmt* body, stmt* default)
     | Stop(expr? code)
     | Assert(expr test, expr? msg)
-    | SubroutineCall(symbol name, symbol? original_name, call_arg* args, expr? dt)
+    | SubroutineCall(function_call call)
     | Where(expr test, stmt* body, stmt* orelse)
     | WhileLoop(expr test, stmt* body)
     | Nullify(symbol* vars)
@@ -214,8 +214,7 @@ expr
         -- Such as: (x, y+z), (3.0, 2.0) generally not known at compile time
     | ComplexConstructor(expr re, expr im, ttype type, expr? value)
     | NamedExpr(expr target, expr value, ttype type)
-    | FunctionCall(symbol name, symbol? original_name,
-            call_arg* args, ttype type, expr? value, expr? dt)
+    | FunctionCall(function_call call, ttype type, expr? value)
     | DerivedTypeConstructor(symbol dt_sym, expr* args, ttype type, expr? value)
     | ImpliedDoLoop(expr* values, expr var, expr start, expr end,
                     expr? increment, ttype type, expr? value)
@@ -377,4 +376,6 @@ do_loop_head = (expr? v, expr? start, expr? end, expr? increment)

 case_stmt = CaseStmt(expr* test, stmt* body) | CaseStmt_Range(expr? start, expr? end, stmt* body)

+function_call = (symbol name, symbol? original_name, call_arg* args, expr? dt)
+
 }
czgdp1807 commented 1 year ago

The second option makes more sense to me.