Skip to content

Commit

Permalink
MATLAB switch statement support (#634)
Browse files Browse the repository at this point in the history
## MATLAB switch statement support
This PR adds Tree-sitter coverage of MATLAB switch statements. CI tests
are also included.

``` matlab
switch x
    case 1
        n = 1;
        j = 1;
    case {3, three, 'three'}
        n = 3;
    case {{1, 2, 3,}, {7, 8, 9}}
        n = 6;
    otherwise
        n = 0;
end
```

## Relevant features
- Switch statements are translated into CAST conditional logic
- Multiple argument cases are reduced to single list inclusion test
- Case arguments may be of differing datatypes (string, number,
identifier)

## Related issues

- Resolves issue #561

---------

Co-authored-by: Joseph Astier <jastier@arizona.edu> 391786e
  • Loading branch information
github-actions[bot] committed Nov 13, 2023
1 parent 0284c9c commit 1cf0b48
Show file tree
Hide file tree
Showing 1,109 changed files with 123,986 additions and 123,380 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ <h3>Instance variables</h3>
<h3>Methods</h3>
<dl>
<dt id="skema.img2mml.models.decoders.xfmer_decoder.Transformer_Decoder.create_pad_mask"><code class="name flex">
<span>def <span class="ident">create_pad_mask</span></span>(<span>self, matrix: <built-in method tensor of type object at 0x7f273bb5b500>, pad_token: int) ‑> <built-in method tensor of type object at 0x7f273bb5b500></span>
<span>def <span class="ident">create_pad_mask</span></span>(<span>self, matrix: <built-in method tensor of type object at 0x7fa979f5b500>, pad_token: int) ‑> <built-in method tensor of type object at 0x7fa979f5b500></span>
</code></dt>
<dd>
<div class="desc"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ <h3>Class variables</h3>
<h3>Methods</h3>
<dl>
<dt id="skema.img2mml.models.encoding.positional_encoding_for_xfmer.PositionalEncoding.forward"><code class="name flex">
<span>def <span class="ident">forward</span></span>(<span>self, x: <built-in method tensor of type object at 0x7f273bb5b500>) ‑> <built-in method tensor of type object at 0x7f273bb5b500></span>
<span>def <span class="ident">forward</span></span>(<span>self, x: <built-in method tensor of type object at 0x7fa979f5b500>) ‑> <built-in method tensor of type object at 0x7fa979f5b500></span>
</code></dt>
<dd>
<div class="desc"><p>Defines the computation performed at every call.</p>
Expand Down
735 changes: 406 additions & 329 deletions api/python/skema/program_analysis/CAST/matlab/matlab_to_cast.html

Large diffs are not rendered by default.

61 changes: 52 additions & 9 deletions api/python/skema/program_analysis/CAST/matlab/node_helper.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ <h1 class="title">Module <code>skema.program_analysis.CAST.matlab.node_helper</c

class NodeHelper():
def __init__(self, source: str, source_file_name: str):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.source = source
self.source_file_name = source_file_name

Expand Down Expand Up @@ -118,6 +117,19 @@ <h1 class="title">Module <code>skema.program_analysis.CAST.matlab.node_helper</c
if child.type == type:
return i

def get_all(node, types):
&#34;&#34;&#34; return all nodes with type in types from the entire node tree &#34;&#34;&#34;
def search(node, types, ret):
if node.type in types:
ret += [node]
for child in node.children:
search(child, types, ret)
return ret
return search(node, types, [])

def valid(nodes):
&#34;&#34;&#34; return the node list without any None elements &#34;&#34;&#34;
return [node for node in nodes if node]

def remove_comments(node: Node):
&#34;&#34;&#34;Remove comment nodes from tree-sitter parse tree&#34;&#34;&#34;
Expand All @@ -143,12 +155,10 @@ <h1 class="title">Module <code>skema.program_analysis.CAST.matlab.node_helper</c


def get_control_children(node: Node):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
return get_children_by_types(node, CONTROL_CHARACTERS)


def get_non_control_children(node: Node):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
children = []
for child in node.children:
if child.type not in CONTROL_CHARACTERS:
Expand All @@ -164,6 +174,26 @@ <h1 class="title">Module <code>skema.program_analysis.CAST.matlab.node_helper</c
<section>
<h2 class="section-title" id="header-functions">Functions</h2>
<dl>
<dt id="skema.program_analysis.CAST.matlab.node_helper.get_all"><code class="name flex">
<span>def <span class="ident">get_all</span></span>(<span>node, types)</span>
</code></dt>
<dd>
<div class="desc"><p>return all nodes with type in types from the entire node tree</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def get_all(node, types):
&#34;&#34;&#34; return all nodes with type in types from the entire node tree &#34;&#34;&#34;
def search(node, types, ret):
if node.type in types:
ret += [node]
for child in node.children:
search(child, types, ret)
return ret
return search(node, types, [])</code></pre>
</details>
</dd>
<dt id="skema.program_analysis.CAST.matlab.node_helper.get_children_by_types"><code class="name flex">
<span>def <span class="ident">get_children_by_types</span></span>(<span>node: tree_sitter.Node, types: List[~T])</span>
</code></dt>
Expand All @@ -182,13 +212,12 @@ <h2 class="section-title" id="header-functions">Functions</h2>
<span>def <span class="ident">get_control_children</span></span>(<span>node: tree_sitter.Node)</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def get_control_children(node: Node):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
return get_children_by_types(node, CONTROL_CHARACTERS)</code></pre>
</details>
</dd>
Expand Down Expand Up @@ -256,13 +285,12 @@ <h2 class="section-title" id="header-functions">Functions</h2>
<span>def <span class="ident">get_non_control_children</span></span>(<span>node: tree_sitter.Node)</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def get_non_control_children(node: Node):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
children = []
for child in node.children:
if child.type not in CONTROL_CHARACTERS:
Expand Down Expand Up @@ -294,6 +322,20 @@ <h2 class="section-title" id="header-functions">Functions</h2>
return node</code></pre>
</details>
</dd>
<dt id="skema.program_analysis.CAST.matlab.node_helper.valid"><code class="name flex">
<span>def <span class="ident">valid</span></span>(<span>nodes)</span>
</code></dt>
<dd>
<div class="desc"><p>return the node list without any None elements</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def valid(nodes):
&#34;&#34;&#34; return the node list without any None elements &#34;&#34;&#34;
return [node for node in nodes if node]</code></pre>
</details>
</dd>
</dl>
</section>
<section>
Expand All @@ -304,14 +346,13 @@ <h2 class="section-title" id="header-classes">Classes</h2>
<span>(</span><span>source: str, source_file_name: str)</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class NodeHelper():
def __init__(self, source: str, source_file_name: str):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.source = source
self.source_file_name = source_file_name

Expand Down Expand Up @@ -415,13 +456,15 @@ <h1>Index</h1>
</li>
<li><h3><a href="#header-functions">Functions</a></h3>
<ul class="">
<li><code><a title="skema.program_analysis.CAST.matlab.node_helper.get_all" href="#skema.program_analysis.CAST.matlab.node_helper.get_all">get_all</a></code></li>
<li><code><a title="skema.program_analysis.CAST.matlab.node_helper.get_children_by_types" href="#skema.program_analysis.CAST.matlab.node_helper.get_children_by_types">get_children_by_types</a></code></li>
<li><code><a title="skema.program_analysis.CAST.matlab.node_helper.get_control_children" href="#skema.program_analysis.CAST.matlab.node_helper.get_control_children">get_control_children</a></code></li>
<li><code><a title="skema.program_analysis.CAST.matlab.node_helper.get_first_child_by_type" href="#skema.program_analysis.CAST.matlab.node_helper.get_first_child_by_type">get_first_child_by_type</a></code></li>
<li><code><a title="skema.program_analysis.CAST.matlab.node_helper.get_first_child_index" href="#skema.program_analysis.CAST.matlab.node_helper.get_first_child_index">get_first_child_index</a></code></li>
<li><code><a title="skema.program_analysis.CAST.matlab.node_helper.get_last_child_index" href="#skema.program_analysis.CAST.matlab.node_helper.get_last_child_index">get_last_child_index</a></code></li>
<li><code><a title="skema.program_analysis.CAST.matlab.node_helper.get_non_control_children" href="#skema.program_analysis.CAST.matlab.node_helper.get_non_control_children">get_non_control_children</a></code></li>
<li><code><a title="skema.program_analysis.CAST.matlab.node_helper.remove_comments" href="#skema.program_analysis.CAST.matlab.node_helper.remove_comments">remove_comments</a></code></li>
<li><code><a title="skema.program_analysis.CAST.matlab.node_helper.valid" href="#skema.program_analysis.CAST.matlab.node_helper.valid">valid</a></code></li>
</ul>
</li>
<li><h3><a href="#header-classes">Classes</a></h3>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ <h1 class="title">Module <code>skema.program_analysis.CAST.matlab.variable_conte

class VariableContext(object):
def __init__(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.context = [{}] # Stack of context dictionaries
self.context_return_values = [set()] # Stack of context return values
self.all_symbols = {}
Expand Down Expand Up @@ -107,11 +106,9 @@ <h1 class="title">Module <code>skema.program_analysis.CAST.matlab.variable_conte
return symbol in self.all_symbols

def get_node(self, symbol: str) -&gt; Dict:
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
return self.all_symbols[symbol][&#34;node&#34;]

def get_type(self, symbol: str) -&gt; str:
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
return self.all_symbols[symbol][&#34;type&#34;]

def update_type(self, symbol: str, type: str):
Expand All @@ -121,22 +118,18 @@ <h1 class="title">Module <code>skema.program_analysis.CAST.matlab.variable_conte
self.all_symbols[full_symbol_name][&#34;type&#34;] = type

def add_return_value(self, symbol):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.context_return_values[-1].add(symbol)

def remove_return_value(self, symbol):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.context_return_values[-1].discard(symbol)

def generate_iterator(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
symbol = f&#34;generated_iter_{self.iterator_id}&#34;
self.iterator_id += 1

return self.add_variable(symbol, &#34;iterator&#34;, None)

def generate_stop_condition(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
symbol = f&#34;sc_{self.stop_condition_id}&#34;
self.stop_condition_id += 1

Expand All @@ -155,7 +148,6 @@ <h1 class="title">Module <code>skema.program_analysis.CAST.matlab.variable_conte
self.internal = True

def unset_internal(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.internal = False</code></pre>
</details>
</section>
Expand All @@ -172,14 +164,13 @@ <h2 class="section-title" id="header-classes">Classes</h2>
<span>class <span class="ident">VariableContext</span></span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class VariableContext(object):
def __init__(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.context = [{}] # Stack of context dictionaries
self.context_return_values = [set()] # Stack of context return values
self.all_symbols = {}
Expand Down Expand Up @@ -251,11 +242,9 @@ <h2 class="section-title" id="header-classes">Classes</h2>
return symbol in self.all_symbols

def get_node(self, symbol: str) -&gt; Dict:
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
return self.all_symbols[symbol][&#34;node&#34;]

def get_type(self, symbol: str) -&gt; str:
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
return self.all_symbols[symbol][&#34;type&#34;]

def update_type(self, symbol: str, type: str):
Expand All @@ -265,22 +254,18 @@ <h2 class="section-title" id="header-classes">Classes</h2>
self.all_symbols[full_symbol_name][&#34;type&#34;] = type

def add_return_value(self, symbol):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.context_return_values[-1].add(symbol)

def remove_return_value(self, symbol):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.context_return_values[-1].discard(symbol)

def generate_iterator(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
symbol = f&#34;generated_iter_{self.iterator_id}&#34;
self.iterator_id += 1

return self.add_variable(symbol, &#34;iterator&#34;, None)

def generate_stop_condition(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
symbol = f&#34;sc_{self.stop_condition_id}&#34;
self.stop_condition_id += 1

Expand All @@ -299,7 +284,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
self.internal = True

def unset_internal(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.internal = False</code></pre>
</details>
<h3>Methods</h3>
Expand All @@ -308,13 +292,12 @@ <h3>Methods</h3>
<span>def <span class="ident">add_return_value</span></span>(<span>self, symbol)</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def add_return_value(self, symbol):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.context_return_values[-1].add(symbol)</code></pre>
</details>
</dd>
Expand Down Expand Up @@ -383,13 +366,12 @@ <h3>Methods</h3>
<span>def <span class="ident">generate_iterator</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def generate_iterator(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
symbol = f&#34;generated_iter_{self.iterator_id}&#34;
self.iterator_id += 1

Expand All @@ -400,13 +382,12 @@ <h3>Methods</h3>
<span>def <span class="ident">generate_stop_condition</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def generate_stop_condition(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
symbol = f&#34;sc_{self.stop_condition_id}&#34;
self.stop_condition_id += 1

Expand All @@ -417,27 +398,25 @@ <h3>Methods</h3>
<span>def <span class="ident">get_node</span></span>(<span>self, symbol: str) ‑> Dict[~KT, ~VT]</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def get_node(self, symbol: str) -&gt; Dict:
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
return self.all_symbols[symbol][&#34;node&#34;]</code></pre>
</details>
</dd>
<dt id="skema.program_analysis.CAST.matlab.variable_context.VariableContext.get_type"><code class="name flex">
<span>def <span class="ident">get_type</span></span>(<span>self, symbol: str) ‑> str</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def get_type(self, symbol: str) -&gt; str:
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
return self.all_symbols[symbol][&#34;type&#34;]</code></pre>
</details>
</dd>
Expand Down Expand Up @@ -505,13 +484,12 @@ <h3>Methods</h3>
<span>def <span class="ident">remove_return_value</span></span>(<span>self, symbol)</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def remove_return_value(self, symbol):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.context_return_values[-1].discard(symbol)</code></pre>
</details>
</dd>
Expand All @@ -533,13 +511,12 @@ <h3>Methods</h3>
<span>def <span class="ident">unset_internal</span></span>(<span>self)</span>
</code></dt>
<dd>
<div class="desc"><p>Docstring</p></div>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def unset_internal(self):
&#34;&#34;&#34;Docstring&#34;&#34;&#34;
self.internal = False</code></pre>
</details>
</dd>
Expand Down
Loading

0 comments on commit 1cf0b48

Please sign in to comment.