Skip to content

Pointers / links in ASDL #1167

@certik

Description

@certik

@czgdp1807 had a great idea here how to improve GoTo / GoToTarget: #1163 (comment)

Change GoTo(int target_id, identifier name) to GoTo(stmt_t goto_target). Then one can do ASR::down_cast<ASR::GoToTarget>(goto_object->goto_target)->m_name. So it would look like this:

diff --git a/src/libasr/ASR.asdl b/src/libasr/ASR.asdl
index 2f120d29e..2e71a694e 100644
--- a/src/libasr/ASR.asdl
+++ b/src/libasr/ASR.asdl
@@ -169,10 +169,10 @@ stmt
         -- GoTo points to a GoToTarget with the corresponding target_id within
         -- the same procedure. We currently use `int` IDs to link GoTo with
         -- GoToTarget to avoid issues with serialization.
-    | GoTo(int target_id)
+    | GoTo(stmt goto_target)
         -- An empty statement, a target of zero or more GoTo statements
         -- the `id` is only unique within a procedure
-    | GoToTarget(int id)
+    | GoToTarget(int id, identifier name)
     | If(expr test, stmt* body, stmt* orelse)
     | IfArithmetic(expr test, int lt_label, int eq_label, int gt_label)
     | Print(expr? fmt, expr* values, expr? separator, expr? end)

Except that this would not work, as GoTo would contain a new (copy) of GoToTarget, not related to the actual target.

The reason is that we can't represent links/pointers in ASDL. For the symbol table we implemented pointers implicitly: the ASDL->C++ translation script recognizes heuristically when the value is needed, and when a pointer is needed.

The way out of this could be to create an addition to ASDL, that when _ptr is appended after a type, it will be a pointer to this type, not the value.

So the final change would look something like this:

diff --git a/src/libasr/ASR.asdl b/src/libasr/ASR.asdl
index 2f120d29e..e10350585 100644
--- a/src/libasr/ASR.asdl
+++ b/src/libasr/ASR.asdl
@@ -89,20 +89,20 @@ symbol
         access access, deftype deftype, string? bindc_name, bool elemental,
         bool pure, bool module, bool inline)
     | GenericProcedure(symbol_table parent_symtab, identifier name,
-        symbol* procs, access access)
+        symbol_ptr* procs, access access)
     | CustomOperator(symbol_table parent_symtab, identifier name,
-        symbol* procs, access access)
+        symbol_ptr* procs, access access)
     | ExternalSymbol(symbol_table parent_symtab, identifier name,
-        symbol external, identifier module_name, identifier* scope_names,
+        symbol_ptr external, identifier module_name, identifier* scope_names,
         identifier original_name, access access)
     | DerivedType(symbol_table symtab, identifier name, identifier* members,
-        abi abi, access access, symbol? parent)
+        abi abi, access access, symbol_ptr? parent)
     | Variable(symbol_table parent_symtab, identifier name, intent intent,
         expr? symbolic_value, expr? value, storage_type storage, ttype type,
         abi abi, access access, presence presence, bool value_attr)
     | ClassType(symbol_table symtab, identifier name, abi abi, access access)
     | ClassProcedure(symbol_table parent_symtab, identifier name, identifier
-        proc_name, symbol proc, abi abi)
+        proc_name, symbol_ptr proc, abi abi)
     | AssociateBlock(symbol_table symtab, identifier name, stmt* body)
     | Block(symbol_table symtab, identifier name, stmt* body)
 
@@ -158,9 +158,9 @@ stmt
     | Associate(expr target, expr value)
     | Cycle()
     -- deallocates if allocated otherwise throws a runtime error
-    | ExplicitDeallocate(symbol* vars)
+    | ExplicitDeallocate(symbol_ptr* vars)
     -- deallocates if allocated otherwise does nothing
-    | ImplicitDeallocate(symbol* vars)
+    | ImplicitDeallocate(symbol_ptr* vars)
     | DoConcurrentLoop(do_loop_head head, stmt* body)
     | DoLoop(do_loop_head head, stmt* body)
     | ErrorStop(expr? code)
@@ -169,10 +169,10 @@ stmt
         -- GoTo points to a GoToTarget with the corresponding target_id within
         -- the same procedure. We currently use `int` IDs to link GoTo with
         -- GoToTarget to avoid issues with serialization.
-    | GoTo(int target_id)
+    | GoTo(stmt_ptr goto_target)
         -- An empty statement, a target of zero or more GoTo statements
         -- the `id` is only unique within a procedure
-    | GoToTarget(int id)
+    | GoToTarget(int id, identifier name)
     | If(expr test, stmt* body, stmt* orelse)
     | IfArithmetic(expr test, int lt_label, int eq_label, int gt_label)
     | Print(expr? fmt, expr* values, expr? separator, expr? end)
@@ -193,15 +193,15 @@ 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(symbol_ptr name, symbol_ptr? original_name, call_arg* args, expr? dt)
     | Where(expr test, stmt* body, stmt* orelse)
     | WhileLoop(expr test, stmt* body)
-    | Nullify(symbol* vars)
+    | Nullify(symbol_ptr* vars)
     | Flush(int label, expr unit, expr? err, expr? iomsg, expr? iostat)
     | ListAppend(expr a, expr ele)
-    | AssociateBlockCall(symbol m)
+    | AssociateBlockCall(symbol_ptr m)
     | CPtrToPointer(expr cptr, expr ptr, expr? shape)
-    | BlockCall(int label, symbol m)
+    | BlockCall(int label, symbol_ptr m)
     | SetInsert(expr a, expr ele)
     | SetRemove(expr a, expr ele)
     | ListInsert(expr a, expr pos, expr ele)
@@ -215,9 +215,9 @@ 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,
+    | FunctionCall(symbol_ptr name, symbol_ptr? original_name,
             call_arg* args, ttype type, expr? value, expr? dt)
-    | DerivedTypeConstructor(symbol dt_sym, expr* args, ttype type, expr? value)
+    | DerivedTypeConstructor(symbol_ptr dt_sym, expr* args, ttype type, expr? value)
     | ImpliedDoLoop(expr* values, expr var, expr start, expr end,
                     expr? increment, ttype type, expr? value)
     | IntegerConstant(int n, ttype type)
@@ -263,7 +263,7 @@ expr
     | DictConstant(expr* keys, expr* values, ttype type)
     | DictLen(expr arg, ttype type, expr? value)
 
-    | Var(symbol v)
+    | Var(symbol_ptr v)
 
     | ArrayConstant(expr* args, ttype type)
     | ArrayItem(expr v, array_index* args, ttype type, expr? value)
@@ -277,7 +277,7 @@ expr
     | ArrayReshape(expr array, expr shape, ttype type, expr? value)
 
     | BitCast(expr source, expr mold, expr? size, ttype type, expr? value)
-    | DerivedRef(expr v, symbol m, ttype type, expr? value)
+    | DerivedRef(expr v, symbol_ptr m, ttype type, expr? value)
     | OverloadedCompare(expr left, cmpop op, expr right, ttype type, expr? value, expr overloaded)
     | OverloadedBinOp(expr left, binop op, expr right, ttype type, expr? value, expr overloaded)
     | Cast(expr arg, cast_kind kind, ttype type, expr? value)
@@ -325,8 +325,8 @@ ttype
     | Set(ttype type)
     | List(ttype type)
     | Tuple(ttype* type)
-    | Derived(symbol derived_type, dimension* dims)
-    | Class(symbol class_type, dimension* dims)
+    | Derived(symbol_ptr derived_type, dimension* dims)
+    | Class(symbol_ptr class_type, dimension* dims)
     | Dict(ttype key_type, ttype value_type)
     | Pointer(ttype type)
     | CPtr()
@@ -370,7 +370,7 @@ cast_kind
 
 dimension = (expr? start, expr? length)
 
-alloc_arg = (symbol a, dimension* dims)
+alloc_arg = (symbol_ptr a, dimension* dims)
 
 attribute = Attribute(identifier name, attribute_arg *args)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions