Skip to content

Fix issue with dynamic codegen of first.aps#154

Open
amir734jj wants to merge 1 commit intoboyland:masterfrom
amir734jj:user/amir734jj/fix-issue-with-dynamic-codegen-in-first
Open

Fix issue with dynamic codegen of first.aps#154
amir734jj wants to merge 1 commit intoboyland:masterfrom
amir734jj:user/amir734jj/fix-issue-with-dynamic-codegen-in-first

Conversation

@amir734jj
Copy link
Copy Markdown
Contributor

@amir734jj amir734jj commented Mar 6, 2026

Given this APS code of first.aps:

  match ?self:Item=nonterminal(?s:Symbol) begin
    case DeclarationTable$select(firstTable, s) begin
      match DeclarationTable$table_entry(?,?item_first_objs) begin
        self.item_first :> item_first_objs;
      end;
    end;
  end;

In static code generation we get the following and it runs correctly. All good.

  def visit_1_2_1(anchor : T_Item, changed : AtomicBoolean) : Unit = anchor match {
    case p_nonterminal(v_self,v_s) => {
      val node = t_DeclarationTable.v_select(v_firstTable,v_s);
      node match {
        case t_DeclarationTable.p_table_entry(_,v_0,v_item_first_objs) => {
          a_item_first.set(v_self,v_item_first_objs, changed);
        }
        case _ => {
          a_item_first.set(v_self,t_SymbolLattice.v_none(), changed);
        }}
    }
  }

But in dynamic code generation we get the following which results in runtime match error crash

  def c_item_first(anode : T_Item) : T_SymbolLattice = {
    var collection : T_SymbolLattice = t_SymbolLattice.v_none();
    for (anchor <- t_Result.t_Item.nodes) anchor match {
      case p_terminal(v_self,v_s) => {
        if (anode eq v_self) collection = t_SymbolLattice.v_combine(collection,t_SymbolLattice.v_single(v_s));
      }
      case _ => {}
    }
    for (anchor <- t_Result.t_Item.nodes) anchor match {
      case p_nonterminal(v_self,v_s) => {
        t_DeclarationTable.v_select(v_firstTable,v_s) match {
          case t_DeclarationTable.p_table_entry(_,v_0,v_item_first_objs) => {
            if (anode eq v_self) collection = t_SymbolLattice.v_combine(collection,v_item_first_objs);
          }
        }
      }
      case _ => {}
    }
    return collection;
  }
Caused by: scala.MatchError: TreeMap() (of class scala.collection.immutable.TreeMap)
	at M_FIRST.$anonfun$c_item_first$2(first.scala:178)
	at M_FIRST.$anonfun$c_item_first$2$adapted(first.scala:176)
	at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:619)
	at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:617)
	at scala.collection.AbstractIterable.foreach(Iterable.scala:935)
	at M_FIRST.c_item_first(first.scala:176)
	at M_FIRST$E_item_first.compute(first.scala:104)
	at M_FIRST$E_item_first.compute(first.scala:99)

The root of the problem is this PR #147

But after this APS fix, this will be the dynamic codegen output (notice else case was added):

  def c_item_first(anode : T_Item) : T_SymbolLattice = {
    var collection : T_SymbolLattice = t_SymbolLattice.v_none();
    for (anchor <- t_Result.t_Item.nodes) anchor match {
      case p_terminal(v_self,v_s) => {
        if (anode eq v_self) collection = t_SymbolLattice.v_combine(collection,t_SymbolLattice.v_single(v_s));
      }
      case _ => {}
    }
    for (anchor <- t_Result.t_Item.nodes) anchor match {
      case p_nonterminal(v_self,v_s) => {
        t_DeclarationTable.v_select(v_firstTable,v_s) match {
          case t_DeclarationTable.p_table_entry(_,v_0,v_item_first_objs) => {
            if (anode eq v_self) collection = t_SymbolLattice.v_combine(collection,v_item_first_objs);
          }
          case _ => {
            if (anode eq v_self) collection = t_SymbolLattice.v_combine(collection,t_SymbolLattice.v_none());
          }
        }
      }
      case _ => {}
    }
    return collection;
  }

Static code generated output is the same, no change.

Not sure if the right approach is fixing the first.aps or fixing the dynamic codegen to also dump default assignment.

Copy link
Copy Markdown
Owner

@boyland boyland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Collection assignments should not require an else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants