New project structure
This commit is contained in:
1
Project-02-03-04-05/README.md
Normal file
1
Project-02-03-04-05/README.md
Normal file
@@ -0,0 +1 @@
|
||||
Author: Jan-Niclas Loosen (1540907)
|
||||
117
Project-02-03-04-05/cfg/CFG.py
Normal file
117
Project-02-03-04-05/cfg/CFG.py
Normal file
@@ -0,0 +1,117 @@
|
||||
from typing import Any, Callable, Set
|
||||
from .CFG_Node import *
|
||||
|
||||
class CFG:
|
||||
def __init__(self, ast):
|
||||
start = CFG_START()
|
||||
start.dot_style = 'style=filled, color=gray'
|
||||
end = CFG_END()
|
||||
end.dot_style = 'style=filled, color=gray'
|
||||
|
||||
last = ast.cfa(start, end)
|
||||
if last is not None:
|
||||
last.add_child(end)
|
||||
|
||||
self.START = start
|
||||
self.END = end
|
||||
self.ast = ast
|
||||
|
||||
# Remove empty nodes and rewire edges
|
||||
all_nodes = self.nodes()
|
||||
nodes_to_remove = [node for node in all_nodes if node.is_empty()]
|
||||
for node in nodes_to_remove:
|
||||
self.__remove_and_rewire(node)
|
||||
|
||||
def nodes(self):
|
||||
all_nodes = set()
|
||||
self.__collect_nodes(self.START, all_nodes)
|
||||
return all_nodes
|
||||
|
||||
def __collect_nodes(self, node, node_set):
|
||||
if node in node_set:
|
||||
return
|
||||
node_set.add(node)
|
||||
for child in node.children:
|
||||
self.__collect_nodes(child, node_set)
|
||||
|
||||
def __remove_and_rewire(self, node):
|
||||
original_children = list(node.children)
|
||||
|
||||
for parent in list(node.parents):
|
||||
if node in parent.children:
|
||||
# For diamond nodes, preserve the true and false bodies
|
||||
if isinstance(node, CFG_DIAMOND):
|
||||
targets = []
|
||||
if len(original_children) >= 1:
|
||||
true_target = self.__first_filled_child(original_children[0])
|
||||
if true_target:
|
||||
targets.append(true_target)
|
||||
if len(original_children) >= 2:
|
||||
false_target = self.__first_filled_child(original_children[1])
|
||||
if false_target:
|
||||
targets.append(false_target)
|
||||
# For regular nodes, find all non-empty targets
|
||||
else:
|
||||
targets = []
|
||||
for child in original_children:
|
||||
target = self.__first_filled_child(child)
|
||||
if target and target not in targets:
|
||||
targets.append(target)
|
||||
|
||||
# Remove edge from parent to node
|
||||
parent.remove_child(node, propagate=False)
|
||||
|
||||
# Add edges from parent to targets
|
||||
for target in targets:
|
||||
parent.add_child(target, propagate=False)
|
||||
|
||||
# Clear the node's connections
|
||||
node.parents.clear()
|
||||
node.children.clear()
|
||||
|
||||
def __first_filled_child(self, node):
|
||||
if not node.is_empty():
|
||||
return node
|
||||
# Recursively check children
|
||||
for child in sorted(node.children, key=lambda n: n.id):
|
||||
result = self.__first_filled_child(child)
|
||||
if result is not None:
|
||||
return result
|
||||
return None
|
||||
|
||||
def to_dot(self) -> str:
|
||||
lines = ["digraph CFG {", ' node [fontname="Helvetica"];']
|
||||
|
||||
def emit(node: CFG_Node):
|
||||
label = node.dot_label()
|
||||
shape = node.dot_shape
|
||||
style = node.dot_style
|
||||
style_str = f", {style}" if style else ""
|
||||
lines.append(f' n{node.id} [label="{label}", shape={shape}{style_str}];')
|
||||
|
||||
for i, child in enumerate(sorted(node.children, key=lambda n: n.id)):
|
||||
edge_label = ""
|
||||
if isinstance(node, CFG_DIAMOND):
|
||||
if i == 0:
|
||||
edge_label = ' [label="T"]'
|
||||
elif i == 1:
|
||||
edge_label = ' [label="F"]'
|
||||
lines.append(f" n{node.id} -> n{child.id}{edge_label};")
|
||||
|
||||
self.traverse(emit, start=self.START)
|
||||
lines.append("}")
|
||||
return "\n".join(lines)
|
||||
|
||||
# Reusable traversal function
|
||||
def traverse(self, fn: Callable[[CFG_Node], Any], start: CFG_Node | None = None) -> None:
|
||||
start = start or self.START
|
||||
visited: Set[int] = set()
|
||||
|
||||
def visit(node: CFG_Node):
|
||||
if node.id in visited:
|
||||
return
|
||||
visited.add(node.id)
|
||||
fn(node)
|
||||
for child in sorted(node.children, key=lambda n: n.id):
|
||||
visit(child)
|
||||
visit(start)
|
||||
96
Project-02-03-04-05/cfg/CFG_Node.py
Normal file
96
Project-02-03-04-05/cfg/CFG_Node.py
Normal file
@@ -0,0 +1,96 @@
|
||||
class CFG_Node:
|
||||
__counter = 1
|
||||
|
||||
def __init__(self, ast_node=None):
|
||||
self.ast_node = ast_node
|
||||
self.children = set()
|
||||
self.parents = set()
|
||||
|
||||
self.label = None
|
||||
self.dot_shape = 'box'
|
||||
self.dot_style = ''
|
||||
|
||||
self.id = CFG_Node.__counter
|
||||
CFG_Node.__counter += 1
|
||||
|
||||
def get_children(self):
|
||||
return self.children
|
||||
|
||||
def get_parents(self):
|
||||
return self.parents
|
||||
|
||||
def add_child(self, child: 'CFG_Node', propagate=True):
|
||||
if propagate:
|
||||
child.parents.add(self)
|
||||
self.children.add(child)
|
||||
|
||||
def add_parent(self, parent: 'CFG_Node', propagate=True):
|
||||
if propagate:
|
||||
parent.add_child(self)
|
||||
self.parents.add(parent)
|
||||
|
||||
def remove_child(self, child: 'CFG_Node', propagate=True):
|
||||
if propagate:
|
||||
child.parents.remove(self)
|
||||
self.children.remove(child)
|
||||
|
||||
def remove_parent(self, parent: 'CFG_Node', propagate=True):
|
||||
if propagate:
|
||||
parent.children.remove(self)
|
||||
self.parents.remove(parent)
|
||||
|
||||
def dot_label(self):
|
||||
# Prioritize custom label
|
||||
if self.label is not None:
|
||||
return self.label
|
||||
|
||||
# Build label from AST node
|
||||
if self.ast_node is not None:
|
||||
return str(self.ast_node)
|
||||
|
||||
return None
|
||||
|
||||
def is_filled(self):
|
||||
return not self.is_empty()
|
||||
|
||||
def is_empty(self):
|
||||
# Node is empty if it has no label and no related AST node
|
||||
if self.label is None or self.label == "None":
|
||||
if self.ast_node is not None:
|
||||
# Node belongs to a ast node
|
||||
return False
|
||||
return True
|
||||
# Node is required for the control flow
|
||||
return False
|
||||
|
||||
class CFG_START(CFG_Node):
|
||||
def __init__(self, ast_node=None):
|
||||
super().__init__(ast_node)
|
||||
self.dot_shape = "ellipse"
|
||||
self.dot_style = 'style=filled, color=green'
|
||||
self.label = "START"
|
||||
|
||||
class CFG_END(CFG_Node):
|
||||
def __init__(self, ast_node=None):
|
||||
super().__init__(ast_node)
|
||||
self.dot_shape = "ellipse"
|
||||
self.dot_style = 'style=filled, color=green'
|
||||
self.label = "END"
|
||||
|
||||
class CFG_DIAMOND(CFG_Node):
|
||||
def __init__(self, ast_node=None):
|
||||
super().__init__(ast_node)
|
||||
self.dot_shape = "diamond"
|
||||
self.label = "<?>"
|
||||
|
||||
class CFG_CALL(CFG_Node):
|
||||
def __init__(self, ast_node=None):
|
||||
super().__init__(ast_node)
|
||||
self.dot_style = 'style=filled, color=orange'
|
||||
self.dot_shape = "box"
|
||||
|
||||
class CFG_RETURN(CFG_Node):
|
||||
def __init__(self, ast_node=None):
|
||||
super().__init__(ast_node)
|
||||
self.dot_style = 'style=filled, color=orange'
|
||||
self.dot_shape = "box"
|
||||
0
Project-02-03-04-05/cfg/__init__.py
Normal file
0
Project-02-03-04-05/cfg/__init__.py
Normal file
306
Project-02-03-04-05/cfg_build.py
Normal file
306
Project-02-03-04-05/cfg_build.py
Normal file
@@ -0,0 +1,306 @@
|
||||
from cfg.CFG_Node import (
|
||||
CFG_Node,
|
||||
CFG_CALL,
|
||||
CFG_RETURN,
|
||||
CFG_DIAMOND,
|
||||
CFG_START,
|
||||
CFG_END,
|
||||
)
|
||||
|
||||
import compiler
|
||||
import syntax
|
||||
|
||||
# Global registry for function start/end nodes
|
||||
FUNCTIONS = {}
|
||||
|
||||
# Global variable to track the current function being processed
|
||||
CURRENT_FUNCTION = None
|
||||
|
||||
class CONST(compiler.CONST):
|
||||
def cfa(self, pred, end = None):
|
||||
node = CFG_Node(self)
|
||||
pred.add_child(node)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if end is not None:
|
||||
node.add_child(end)
|
||||
return node
|
||||
|
||||
class ID(compiler.ID):
|
||||
def cfa(self, pred, end = None):
|
||||
node = CFG_Node(self)
|
||||
pred.add_child(node)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if end is not None:
|
||||
node.add_child(end)
|
||||
return node
|
||||
|
||||
class AOP(compiler.AOP):
|
||||
def cfa(self, pred, end = None):
|
||||
# Create nodes for the used expressions and attach
|
||||
left_node = self.arg1.cfa(pred)
|
||||
right_node = self.arg2.cfa(left_node)
|
||||
|
||||
# Create the operator node and attach
|
||||
op_node = CFG_Node(self)
|
||||
op_node.label = f"{str(self.arg1)} {self.operator} {str(self.arg2)}"
|
||||
right_node.add_child(op_node)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if end is not None:
|
||||
op_node.add_child(end)
|
||||
return op_node
|
||||
|
||||
class COMP(compiler.COMP):
|
||||
def cfa(self, pred, end = None):
|
||||
# Create nodes for the used expressions and attach
|
||||
left_node = self.arg1.cfa(pred)
|
||||
right_node = self.arg2.cfa(left_node)
|
||||
|
||||
# Create the comparison node and attach
|
||||
comp_node = CFG_Node(self)
|
||||
comp_node.label = f"{str(self.arg1)} {self.operator} {str(self.arg2)}"
|
||||
right_node.add_child(comp_node)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if end is not None:
|
||||
comp_node.add_child(end)
|
||||
return comp_node
|
||||
|
||||
class EQOP(compiler.EQOP):
|
||||
def cfa(self, pred, end = None):
|
||||
# Create nodes for the used expressions and attach
|
||||
left_node = self.arg1.cfa(pred)
|
||||
right_node = self.arg2.cfa(left_node)
|
||||
|
||||
# Create the comparison node and attach
|
||||
eqop_node = CFG_Node(self)
|
||||
eqop_node.label = f"{str(self.arg1)} {self.operator} {str(self.arg2)}"
|
||||
right_node.add_child(eqop_node)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if end is not None:
|
||||
eqop_node.add_child(end)
|
||||
return eqop_node
|
||||
|
||||
class LOP(compiler.LOP):
|
||||
def cfa(self, pred, end = None):
|
||||
# Create nodes for each operand separately
|
||||
left_node = self.arg1.cfa(pred)
|
||||
right_node = self.arg2.cfa(left_node)
|
||||
|
||||
# Create the logical operation node with just the operator
|
||||
lop_node = CFG_Node(self)
|
||||
lop_node.label = f"{str(self.arg1)} {self.operator} {str(self.arg2)}"
|
||||
right_node.add_child(lop_node)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if end is not None:
|
||||
lop_node.add_child(end)
|
||||
return lop_node
|
||||
|
||||
class ASSIGN(compiler.ASSIGN):
|
||||
def cfa(self, pred, end = None):
|
||||
# Unwraps expressions needed for assignment
|
||||
expr_node = self.expr.cfa(pred)
|
||||
|
||||
# Assignment node
|
||||
assign_node = CFG_Node(self)
|
||||
expr_node.add_child(assign_node)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if end is not None:
|
||||
assign_node.add_child(end)
|
||||
return assign_node
|
||||
|
||||
class SEQ(compiler.SEQ):
|
||||
def cfa(self, pred, end = None):
|
||||
mid = self.exp1.cfa(pred)
|
||||
if mid is None:
|
||||
return None
|
||||
return self.exp2.cfa(mid, end)
|
||||
|
||||
class IF(compiler.IF):
|
||||
def cfa(self, pred, end = None):
|
||||
# Unwraps expressions needed for the condition
|
||||
cond_node = self.cond.cfa(pred, None)
|
||||
|
||||
# Attach junction node
|
||||
diamond = CFG_DIAMOND(self.cond)
|
||||
cond_node.add_child(diamond)
|
||||
|
||||
# Define start and end entry and unwraps expressions
|
||||
then_entry = CFG_Node()
|
||||
diamond.add_child(then_entry)
|
||||
else_entry = CFG_Node()
|
||||
diamond.add_child(else_entry)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
join = CFG_Node()
|
||||
if end is not None:
|
||||
join.add_child(end)
|
||||
|
||||
# Connect the extracted expressions with the join
|
||||
then_end = self.exp1.cfa(then_entry, join)
|
||||
else_end = self.exp2.cfa(else_entry, join)
|
||||
return join
|
||||
|
||||
class WHILE(compiler.WHILE):
|
||||
def cfa(self, pred, end = None):
|
||||
if hasattr(self.cond, 'arg1') and hasattr(self.cond, 'arg2'):
|
||||
# This is a comparison operation (e.g., a > b)
|
||||
|
||||
# Create the condition evaluation nodes
|
||||
left_node = self.cond.arg1.cfa(pred)
|
||||
right_node = self.cond.arg2.cfa(left_node)
|
||||
|
||||
# Create the comparison node and attach
|
||||
comp_node = CFG_Node(self.cond)
|
||||
comp_node.label = f"{str(self.cond.arg1)} {self.cond.operator} {str(self.cond.arg2)}"
|
||||
right_node.add_child(comp_node)
|
||||
else:
|
||||
# This is a simple condition (e.g., constant true/false)
|
||||
cond_node = self.cond.cfa(pred)
|
||||
comp_node = cond_node
|
||||
|
||||
# Attach junction node
|
||||
diamond = CFG_DIAMOND(self.cond)
|
||||
comp_node.add_child(diamond)
|
||||
|
||||
# Unwrap the loop body
|
||||
body_entry = CFG_Node()
|
||||
diamond.add_child(body_entry)
|
||||
|
||||
# The body should connect back to the start of condition evaluation
|
||||
body_end = self.body.cfa(body_entry)
|
||||
if body_end is not None:
|
||||
# Connect the body end back to the condition evaluation
|
||||
if hasattr(self.cond, 'arg1') and hasattr(self.cond, 'arg2'):
|
||||
body_end.add_child(left_node)
|
||||
else:
|
||||
body_end.add_child(pred)
|
||||
|
||||
# Attach joining node
|
||||
after = CFG_Node()
|
||||
diamond.add_child(after)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if end is not None:
|
||||
after.add_child(end)
|
||||
return after
|
||||
|
||||
class CALL(compiler.CALL):
|
||||
def cfa(self, pred, end = None):
|
||||
# Create nodes for all argument values
|
||||
current_arg_node = pred
|
||||
for i, arg in enumerate(self.arg):
|
||||
current_arg_node = arg.cfa(current_arg_node)
|
||||
|
||||
# Create and attach the call node
|
||||
call_node = CFG_CALL(self)
|
||||
call_node.label = f"CALL {self.f_name}"
|
||||
current_arg_node.add_child(call_node)
|
||||
|
||||
# Create and attach the exit node
|
||||
cont = CFG_Node()
|
||||
if end is not None:
|
||||
cont.add_child(end)
|
||||
|
||||
# Find the functions in the function list
|
||||
if self.f_name not in FUNCTIONS:
|
||||
raise RuntimeError(f"Call to undefined function '{self.f_name}'")
|
||||
# Determine the start and exit node of the function
|
||||
f_start, f_end = FUNCTIONS[self.f_name]
|
||||
|
||||
# Create return node from function
|
||||
return_node = CFG_RETURN(self)
|
||||
return_node.label = f"RET {self.f_name}"
|
||||
f_end.add_child(return_node)
|
||||
return_node.add_child(cont)
|
||||
|
||||
# Span the start and exit nodes to the method body
|
||||
call_node.add_child(f_start)
|
||||
call_node.add_child(return_node)
|
||||
|
||||
# Return value flow for recursive calls
|
||||
if CURRENT_FUNCTION is not None and self.f_name == CURRENT_FUNCTION:
|
||||
return_node.add_child(cont)
|
||||
return cont
|
||||
|
||||
class DECL(compiler.DECL):
|
||||
def cfa(self, pred, end):
|
||||
# Check if a function is already registered
|
||||
if self.f_name in FUNCTIONS:
|
||||
f_start, f_end = FUNCTIONS[self.f_name]
|
||||
else:
|
||||
# Span the method body into a start and end node
|
||||
f_start = CFG_START(self)
|
||||
f_start.label = f"START {self.f_name}({', '.join(self.params)})"
|
||||
f_end = CFG_END(self)
|
||||
f_end.label = f"END {self.f_name}({', '.join(self.params)})"
|
||||
FUNCTIONS[self.f_name] = (f_start, f_end)
|
||||
|
||||
# Set the current function context for recursion detection
|
||||
global CURRENT_FUNCTION
|
||||
previous_function = CURRENT_FUNCTION
|
||||
CURRENT_FUNCTION = self.f_name
|
||||
|
||||
try:
|
||||
# Unwrap the method body
|
||||
body_end = self.body.cfa(f_start, f_end)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if body_end is not None:
|
||||
body_end.add_child(f_end)
|
||||
finally:
|
||||
# Restore the previous function context
|
||||
CURRENT_FUNCTION = previous_function
|
||||
|
||||
return pred
|
||||
|
||||
class LET(compiler.LET):
|
||||
def cfa(self, pred, end = None):
|
||||
# First pass: Register all function declarations
|
||||
decls = self.decl if isinstance(self.decl, list) else [self.decl]
|
||||
for d in decls:
|
||||
if isinstance(d, compiler.DECL):
|
||||
# Register function without building CFG yet
|
||||
f_start = CFG_START(d)
|
||||
f_start.label = f"START {d.f_name}({', '.join(d.params)})"
|
||||
f_end = CFG_END(d)
|
||||
f_end.label = f"END {d.f_name}({', '.join(d.params)})"
|
||||
FUNCTIONS[d.f_name] = (f_start, f_end)
|
||||
|
||||
# Create a global entry node for the function
|
||||
global_entry = CFG_Node()
|
||||
global_entry.label = "None"
|
||||
pred.add_child(global_entry)
|
||||
current = global_entry
|
||||
|
||||
# Generate function declarations
|
||||
for d in decls:
|
||||
current = d.cfa(current, None)
|
||||
if current is None:
|
||||
return None
|
||||
|
||||
# Unwrap the body
|
||||
body_result = self.body.cfa(current, end)
|
||||
|
||||
# Create global exit node
|
||||
global_exit = CFG_Node()
|
||||
global_exit.label = "None"
|
||||
if body_result is not None:
|
||||
body_result.add_child(global_exit)
|
||||
|
||||
# Attach the end node if it is provided
|
||||
if end is not None:
|
||||
global_exit.add_child(end)
|
||||
return global_exit
|
||||
|
||||
class RETURN(syntax.EXPRESSION):
|
||||
def cfa(self, pred, end):
|
||||
n = CFG_RETURN(self)
|
||||
pred.add_child(n)
|
||||
n.add_child(end)
|
||||
return None
|
||||
23
Project-02-03-04-05/cfgdots/argsParamsExample.dot
Normal file
23
Project-02-03-04-05/cfgdots/argsParamsExample.dot
Normal file
@@ -0,0 +1,23 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n1 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n1 -> n7;
|
||||
n7 [label="1", shape=box];
|
||||
n7 -> n8;
|
||||
n8 [label="2", shape=box];
|
||||
n8 -> n9;
|
||||
n9 [label="3", shape=box];
|
||||
n9 -> n10;
|
||||
n10 [label="CALL a", shape=box, style=filled, color=orange];
|
||||
n10 -> n3;
|
||||
n10 -> n12;
|
||||
n3 [label="START a(x, y, z)", shape=ellipse, style=filled, color=green];
|
||||
n3 -> n6;
|
||||
n6 [label="x", shape=box];
|
||||
n6 -> n4;
|
||||
n4 [label="END a(x, y, z)", shape=ellipse, style=filled, color=green];
|
||||
n4 -> n12;
|
||||
n12 [label="RET a", shape=box, style=filled, color=orange];
|
||||
n12 -> n2;
|
||||
n2 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
127
Project-02-03-04-05/cfgdots/complex.dot
Normal file
127
Project-02-03-04-05/cfgdots/complex.dot
Normal file
@@ -0,0 +1,127 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n14 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n14 -> n65;
|
||||
n65 [label="10", shape=box];
|
||||
n65 -> n66;
|
||||
n66 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n66 -> n16;
|
||||
n66 -> n68;
|
||||
n16 [label="START f1(b)", shape=ellipse, style=filled, color=green];
|
||||
n16 -> n21;
|
||||
n21 [label="b", shape=box];
|
||||
n21 -> n22;
|
||||
n22 [label="0", shape=box];
|
||||
n22 -> n23;
|
||||
n23 [label="b == 0", shape=box];
|
||||
n23 -> n24;
|
||||
n24 [label="<?>", shape=diamond];
|
||||
n24 -> n28 [label="T"];
|
||||
n24 -> n29 [label="F"];
|
||||
n28 [label="0", shape=box];
|
||||
n28 -> n17;
|
||||
n17 [label="END f1(b)", shape=ellipse, style=filled, color=green];
|
||||
n17 -> n34;
|
||||
n17 -> n45;
|
||||
n17 -> n49;
|
||||
n17 -> n68;
|
||||
n34 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n34 -> n17;
|
||||
n45 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n45 -> n58;
|
||||
n58 [label="a", shape=box];
|
||||
n58 -> n59;
|
||||
n59 [label="b", shape=box];
|
||||
n59 -> n60;
|
||||
n60 [label="a * b", shape=box];
|
||||
n60 -> n61;
|
||||
n61 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n61 -> n50;
|
||||
n61 -> n63;
|
||||
n50 [label="START g(c)", shape=ellipse, style=filled, color=green];
|
||||
n50 -> n53;
|
||||
n53 [label="a", shape=box];
|
||||
n53 -> n54;
|
||||
n54 [label="b", shape=box];
|
||||
n54 -> n55;
|
||||
n55 [label="a * b", shape=box];
|
||||
n55 -> n56;
|
||||
n56 [label="c", shape=box];
|
||||
n56 -> n57;
|
||||
n57 [label="(a * b) * c", shape=box];
|
||||
n57 -> n51;
|
||||
n51 [label="END g(c)", shape=ellipse, style=filled, color=green];
|
||||
n51 -> n63;
|
||||
n63 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n63 -> n19;
|
||||
n19 [label="END f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n19 -> n91;
|
||||
n91 [label="RET f2", shape=box, style=filled, color=orange];
|
||||
n91 -> n15;
|
||||
n15 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n49 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n49 -> n58;
|
||||
n68 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n68 -> n70;
|
||||
n70 [label="10", shape=box];
|
||||
n70 -> n83;
|
||||
n83 [label="20", shape=box];
|
||||
n83 -> n84;
|
||||
n84 [label="30", shape=box];
|
||||
n84 -> n85;
|
||||
n85 [label="CALL max", shape=box, style=filled, color=orange];
|
||||
n85 -> n71;
|
||||
n85 -> n87;
|
||||
n71 [label="START max(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n71 -> n74;
|
||||
n74 [label="a", shape=box];
|
||||
n74 -> n75;
|
||||
n75 [label="b", shape=box];
|
||||
n75 -> n76;
|
||||
n76 [label="a > b", shape=box];
|
||||
n76 -> n77;
|
||||
n77 [label="<?>", shape=diamond];
|
||||
n77 -> n81 [label="T"];
|
||||
n77 -> n82 [label="F"];
|
||||
n81 [label="a", shape=box];
|
||||
n81 -> n72;
|
||||
n72 [label="END max(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n72 -> n87;
|
||||
n87 [label="RET max", shape=box, style=filled, color=orange];
|
||||
n87 -> n89;
|
||||
n89 [label="CALL f2", shape=box, style=filled, color=orange];
|
||||
n89 -> n18;
|
||||
n89 -> n91;
|
||||
n18 [label="START f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n18 -> n35;
|
||||
n35 [label="a", shape=box];
|
||||
n35 -> n36;
|
||||
n36 [label="b", shape=box];
|
||||
n36 -> n37;
|
||||
n37 [label="a > b", shape=box];
|
||||
n37 -> n38;
|
||||
n38 [label="<?>", shape=diamond];
|
||||
n38 -> n42 [label="T"];
|
||||
n38 -> n46 [label="F"];
|
||||
n42 [label="a", shape=box];
|
||||
n42 -> n43;
|
||||
n43 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n43 -> n16;
|
||||
n43 -> n45;
|
||||
n46 [label="b", shape=box];
|
||||
n46 -> n47;
|
||||
n47 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n47 -> n16;
|
||||
n47 -> n49;
|
||||
n82 [label="b", shape=box];
|
||||
n82 -> n72;
|
||||
n29 [label="b", shape=box];
|
||||
n29 -> n30;
|
||||
n30 [label="1", shape=box];
|
||||
n30 -> n31;
|
||||
n31 [label="b - 1", shape=box];
|
||||
n31 -> n32;
|
||||
n32 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n32 -> n16;
|
||||
n32 -> n34;
|
||||
}
|
||||
27
Project-02-03-04-05/cfgdots/condition.dot
Normal file
27
Project-02-03-04-05/cfgdots/condition.dot
Normal file
@@ -0,0 +1,27 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n92 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n92 -> n94;
|
||||
n94 [label="2", shape=box];
|
||||
n94 -> n95;
|
||||
n95 [label="x", shape=box];
|
||||
n95 -> n96;
|
||||
n96 [label="2 < x", shape=box];
|
||||
n96 -> n97;
|
||||
n97 [label="x", shape=box];
|
||||
n97 -> n98;
|
||||
n98 [label="9", shape=box];
|
||||
n98 -> n99;
|
||||
n99 [label="x > 9", shape=box];
|
||||
n99 -> n100;
|
||||
n100 [label="(2 < x) && (x > 9)", shape=box];
|
||||
n100 -> n101;
|
||||
n101 [label="<?>", shape=diamond];
|
||||
n101 -> n105 [label="T"];
|
||||
n101 -> n106 [label="F"];
|
||||
n105 [label="1", shape=box];
|
||||
n105 -> n93;
|
||||
n93 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n106 [label="0", shape=box];
|
||||
n106 -> n93;
|
||||
}
|
||||
45
Project-02-03-04-05/cfgdots/defSemiExample.dot
Normal file
45
Project-02-03-04-05/cfgdots/defSemiExample.dot
Normal file
@@ -0,0 +1,45 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n107 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n107 -> n119;
|
||||
n119 [label="1", shape=box];
|
||||
n119 -> n120;
|
||||
n120 [label="CALL a", shape=box, style=filled, color=orange];
|
||||
n120 -> n109;
|
||||
n120 -> n122;
|
||||
n109 [label="START a(x)", shape=ellipse, style=filled, color=green];
|
||||
n109 -> n116;
|
||||
n116 [label="x", shape=box];
|
||||
n116 -> n110;
|
||||
n110 [label="END a(x)", shape=ellipse, style=filled, color=green];
|
||||
n110 -> n122;
|
||||
n122 [label="RET a", shape=box, style=filled, color=orange];
|
||||
n122 -> n124;
|
||||
n124 [label="2", shape=box];
|
||||
n124 -> n125;
|
||||
n125 [label="CALL b", shape=box, style=filled, color=orange];
|
||||
n125 -> n111;
|
||||
n125 -> n127;
|
||||
n111 [label="START b(y)", shape=ellipse, style=filled, color=green];
|
||||
n111 -> n117;
|
||||
n117 [label="y", shape=box];
|
||||
n117 -> n112;
|
||||
n112 [label="END b(y)", shape=ellipse, style=filled, color=green];
|
||||
n112 -> n127;
|
||||
n127 [label="RET b", shape=box, style=filled, color=orange];
|
||||
n127 -> n128;
|
||||
n128 [label="3", shape=box];
|
||||
n128 -> n129;
|
||||
n129 [label="CALL c", shape=box, style=filled, color=orange];
|
||||
n129 -> n113;
|
||||
n129 -> n131;
|
||||
n113 [label="START c(z)", shape=ellipse, style=filled, color=green];
|
||||
n113 -> n118;
|
||||
n118 [label="z", shape=box];
|
||||
n118 -> n114;
|
||||
n114 [label="END c(z)", shape=ellipse, style=filled, color=green];
|
||||
n114 -> n131;
|
||||
n131 [label="RET c", shape=box, style=filled, color=orange];
|
||||
n131 -> n108;
|
||||
n108 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
69
Project-02-03-04-05/cfgdots/example.dot
Normal file
69
Project-02-03-04-05/cfgdots/example.dot
Normal file
@@ -0,0 +1,69 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n132 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n132 -> n167;
|
||||
n167 [label="2", shape=box];
|
||||
n167 -> n168;
|
||||
n168 [label="3", shape=box];
|
||||
n168 -> n169;
|
||||
n169 [label="CALL f", shape=box, style=filled, color=orange];
|
||||
n169 -> n134;
|
||||
n169 -> n171;
|
||||
n134 [label="START f(x, y, z)", shape=ellipse, style=filled, color=green];
|
||||
n134 -> n137;
|
||||
n137 [label="2", shape=box];
|
||||
n137 -> n138;
|
||||
n138 [label="y = 2", shape=box];
|
||||
n138 -> n139;
|
||||
n139 [label="3", shape=box];
|
||||
n139 -> n140;
|
||||
n140 [label="z = 3", shape=box];
|
||||
n140 -> n160;
|
||||
n160 [label="x", shape=box];
|
||||
n160 -> n161;
|
||||
n161 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n161 -> n141;
|
||||
n161 -> n163;
|
||||
n141 [label="START g(x)", shape=ellipse, style=filled, color=green];
|
||||
n141 -> n144;
|
||||
n144 [label="7", shape=box];
|
||||
n144 -> n145;
|
||||
n145 [label="x = 7", shape=box];
|
||||
n145 -> n146;
|
||||
n146 [label="y", shape=box];
|
||||
n146 -> n147;
|
||||
n147 [label="0", shape=box];
|
||||
n147 -> n148;
|
||||
n148 [label="y > 0", shape=box];
|
||||
n148 -> n149;
|
||||
n149 [label="<?>", shape=diamond];
|
||||
n149 -> n153 [label="T"];
|
||||
n149 -> n157 [label="F"];
|
||||
n153 [label="y", shape=box];
|
||||
n153 -> n154;
|
||||
n154 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n154 -> n141;
|
||||
n154 -> n156;
|
||||
n156 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n156 -> n159;
|
||||
n159 [label="x", shape=box];
|
||||
n159 -> n142;
|
||||
n142 [label="END g(x)", shape=ellipse, style=filled, color=green];
|
||||
n142 -> n156;
|
||||
n142 -> n163;
|
||||
n163 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n163 -> n164;
|
||||
n164 [label="x", shape=box];
|
||||
n164 -> n165;
|
||||
n165 [label="g(x) + x", shape=box];
|
||||
n165 -> n135;
|
||||
n135 [label="END f(x, y, z)", shape=ellipse, style=filled, color=green];
|
||||
n135 -> n171;
|
||||
n171 [label="RET f", shape=box, style=filled, color=orange];
|
||||
n171 -> n133;
|
||||
n133 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n157 [label="8", shape=box];
|
||||
n157 -> n158;
|
||||
n158 [label="x = 8", shape=box];
|
||||
n158 -> n159;
|
||||
}
|
||||
268
Project-02-03-04-05/cfgdots/factorial.dot
Normal file
268
Project-02-03-04-05/cfgdots/factorial.dot
Normal file
@@ -0,0 +1,268 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n173 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n173 -> n338;
|
||||
n338 [label="3", shape=box];
|
||||
n338 -> n339;
|
||||
n339 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n339 -> n191;
|
||||
n339 -> n341;
|
||||
n191 [label="START fac(x)", shape=ellipse, style=filled, color=green];
|
||||
n191 -> n194;
|
||||
n191 -> n210;
|
||||
n191 -> n226;
|
||||
n191 -> n242;
|
||||
n191 -> n258;
|
||||
n191 -> n274;
|
||||
n191 -> n290;
|
||||
n191 -> n306;
|
||||
n191 -> n322;
|
||||
n194 [label="x", shape=box];
|
||||
n194 -> n195;
|
||||
n195 [label="1", shape=box];
|
||||
n195 -> n196;
|
||||
n196 [label="x == 1", shape=box];
|
||||
n196 -> n197;
|
||||
n197 [label="<?>", shape=diamond];
|
||||
n197 -> n201 [label="T"];
|
||||
n197 -> n202 [label="F"];
|
||||
n201 [label="1", shape=box];
|
||||
n201 -> n192;
|
||||
n192 [label="END fac(x)", shape=ellipse, style=filled, color=green];
|
||||
n192 -> n207;
|
||||
n192 -> n223;
|
||||
n192 -> n239;
|
||||
n192 -> n255;
|
||||
n192 -> n271;
|
||||
n192 -> n287;
|
||||
n192 -> n303;
|
||||
n192 -> n319;
|
||||
n192 -> n335;
|
||||
n192 -> n341;
|
||||
n207 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n207 -> n208;
|
||||
n208 [label="x", shape=box];
|
||||
n208 -> n209;
|
||||
n209 [label="fac((x - 1)) * x", shape=box];
|
||||
n209 -> n192;
|
||||
n223 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n223 -> n224;
|
||||
n224 [label="x", shape=box];
|
||||
n224 -> n225;
|
||||
n225 [label="fac((x - 1)) * x", shape=box];
|
||||
n225 -> n192;
|
||||
n239 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n239 -> n240;
|
||||
n240 [label="x", shape=box];
|
||||
n240 -> n241;
|
||||
n241 [label="fac((x - 1)) * x", shape=box];
|
||||
n241 -> n192;
|
||||
n255 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n255 -> n256;
|
||||
n256 [label="x", shape=box];
|
||||
n256 -> n257;
|
||||
n257 [label="fac((x - 1)) * x", shape=box];
|
||||
n257 -> n192;
|
||||
n271 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n271 -> n272;
|
||||
n272 [label="x", shape=box];
|
||||
n272 -> n273;
|
||||
n273 [label="fac((x - 1)) * x", shape=box];
|
||||
n273 -> n192;
|
||||
n287 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n287 -> n288;
|
||||
n288 [label="x", shape=box];
|
||||
n288 -> n289;
|
||||
n289 [label="fac((x - 1)) * x", shape=box];
|
||||
n289 -> n192;
|
||||
n303 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n303 -> n304;
|
||||
n304 [label="x", shape=box];
|
||||
n304 -> n305;
|
||||
n305 [label="fac((x - 1)) * x", shape=box];
|
||||
n305 -> n192;
|
||||
n319 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n319 -> n320;
|
||||
n320 [label="x", shape=box];
|
||||
n320 -> n321;
|
||||
n321 [label="fac((x - 1)) * x", shape=box];
|
||||
n321 -> n192;
|
||||
n335 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n335 -> n336;
|
||||
n336 [label="x", shape=box];
|
||||
n336 -> n337;
|
||||
n337 [label="fac((x - 1)) * x", shape=box];
|
||||
n337 -> n192;
|
||||
n341 [label="RET fac", shape=box, style=filled, color=orange];
|
||||
n341 -> n174;
|
||||
n174 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n202 [label="x", shape=box];
|
||||
n202 -> n203;
|
||||
n203 [label="1", shape=box];
|
||||
n203 -> n204;
|
||||
n204 [label="x - 1", shape=box];
|
||||
n204 -> n205;
|
||||
n205 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n205 -> n191;
|
||||
n205 -> n207;
|
||||
n210 [label="x", shape=box];
|
||||
n210 -> n211;
|
||||
n211 [label="1", shape=box];
|
||||
n211 -> n212;
|
||||
n212 [label="x == 1", shape=box];
|
||||
n212 -> n213;
|
||||
n213 [label="<?>", shape=diamond];
|
||||
n213 -> n217 [label="T"];
|
||||
n213 -> n218 [label="F"];
|
||||
n217 [label="1", shape=box];
|
||||
n217 -> n192;
|
||||
n218 [label="x", shape=box];
|
||||
n218 -> n219;
|
||||
n219 [label="1", shape=box];
|
||||
n219 -> n220;
|
||||
n220 [label="x - 1", shape=box];
|
||||
n220 -> n221;
|
||||
n221 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n221 -> n191;
|
||||
n221 -> n223;
|
||||
n226 [label="x", shape=box];
|
||||
n226 -> n227;
|
||||
n227 [label="1", shape=box];
|
||||
n227 -> n228;
|
||||
n228 [label="x == 1", shape=box];
|
||||
n228 -> n229;
|
||||
n229 [label="<?>", shape=diamond];
|
||||
n229 -> n233 [label="T"];
|
||||
n229 -> n234 [label="F"];
|
||||
n233 [label="1", shape=box];
|
||||
n233 -> n192;
|
||||
n234 [label="x", shape=box];
|
||||
n234 -> n235;
|
||||
n235 [label="1", shape=box];
|
||||
n235 -> n236;
|
||||
n236 [label="x - 1", shape=box];
|
||||
n236 -> n237;
|
||||
n237 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n237 -> n191;
|
||||
n237 -> n239;
|
||||
n242 [label="x", shape=box];
|
||||
n242 -> n243;
|
||||
n243 [label="1", shape=box];
|
||||
n243 -> n244;
|
||||
n244 [label="x == 1", shape=box];
|
||||
n244 -> n245;
|
||||
n245 [label="<?>", shape=diamond];
|
||||
n245 -> n249 [label="T"];
|
||||
n245 -> n250 [label="F"];
|
||||
n249 [label="1", shape=box];
|
||||
n249 -> n192;
|
||||
n250 [label="x", shape=box];
|
||||
n250 -> n251;
|
||||
n251 [label="1", shape=box];
|
||||
n251 -> n252;
|
||||
n252 [label="x - 1", shape=box];
|
||||
n252 -> n253;
|
||||
n253 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n253 -> n191;
|
||||
n253 -> n255;
|
||||
n258 [label="x", shape=box];
|
||||
n258 -> n259;
|
||||
n259 [label="1", shape=box];
|
||||
n259 -> n260;
|
||||
n260 [label="x == 1", shape=box];
|
||||
n260 -> n261;
|
||||
n261 [label="<?>", shape=diamond];
|
||||
n261 -> n265 [label="T"];
|
||||
n261 -> n266 [label="F"];
|
||||
n265 [label="1", shape=box];
|
||||
n265 -> n192;
|
||||
n266 [label="x", shape=box];
|
||||
n266 -> n267;
|
||||
n267 [label="1", shape=box];
|
||||
n267 -> n268;
|
||||
n268 [label="x - 1", shape=box];
|
||||
n268 -> n269;
|
||||
n269 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n269 -> n191;
|
||||
n269 -> n271;
|
||||
n274 [label="x", shape=box];
|
||||
n274 -> n275;
|
||||
n275 [label="1", shape=box];
|
||||
n275 -> n276;
|
||||
n276 [label="x == 1", shape=box];
|
||||
n276 -> n277;
|
||||
n277 [label="<?>", shape=diamond];
|
||||
n277 -> n281 [label="T"];
|
||||
n277 -> n282 [label="F"];
|
||||
n281 [label="1", shape=box];
|
||||
n281 -> n192;
|
||||
n282 [label="x", shape=box];
|
||||
n282 -> n283;
|
||||
n283 [label="1", shape=box];
|
||||
n283 -> n284;
|
||||
n284 [label="x - 1", shape=box];
|
||||
n284 -> n285;
|
||||
n285 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n285 -> n191;
|
||||
n285 -> n287;
|
||||
n290 [label="x", shape=box];
|
||||
n290 -> n291;
|
||||
n291 [label="1", shape=box];
|
||||
n291 -> n292;
|
||||
n292 [label="x == 1", shape=box];
|
||||
n292 -> n293;
|
||||
n293 [label="<?>", shape=diamond];
|
||||
n293 -> n297 [label="T"];
|
||||
n293 -> n298 [label="F"];
|
||||
n297 [label="1", shape=box];
|
||||
n297 -> n192;
|
||||
n298 [label="x", shape=box];
|
||||
n298 -> n299;
|
||||
n299 [label="1", shape=box];
|
||||
n299 -> n300;
|
||||
n300 [label="x - 1", shape=box];
|
||||
n300 -> n301;
|
||||
n301 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n301 -> n191;
|
||||
n301 -> n303;
|
||||
n306 [label="x", shape=box];
|
||||
n306 -> n307;
|
||||
n307 [label="1", shape=box];
|
||||
n307 -> n308;
|
||||
n308 [label="x == 1", shape=box];
|
||||
n308 -> n309;
|
||||
n309 [label="<?>", shape=diamond];
|
||||
n309 -> n313 [label="T"];
|
||||
n309 -> n314 [label="F"];
|
||||
n313 [label="1", shape=box];
|
||||
n313 -> n192;
|
||||
n314 [label="x", shape=box];
|
||||
n314 -> n315;
|
||||
n315 [label="1", shape=box];
|
||||
n315 -> n316;
|
||||
n316 [label="x - 1", shape=box];
|
||||
n316 -> n317;
|
||||
n317 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n317 -> n191;
|
||||
n317 -> n319;
|
||||
n322 [label="x", shape=box];
|
||||
n322 -> n323;
|
||||
n323 [label="1", shape=box];
|
||||
n323 -> n324;
|
||||
n324 [label="x == 1", shape=box];
|
||||
n324 -> n325;
|
||||
n325 [label="<?>", shape=diamond];
|
||||
n325 -> n329 [label="T"];
|
||||
n325 -> n330 [label="F"];
|
||||
n329 [label="1", shape=box];
|
||||
n329 -> n192;
|
||||
n330 [label="x", shape=box];
|
||||
n330 -> n331;
|
||||
n331 [label="1", shape=box];
|
||||
n331 -> n332;
|
||||
n332 [label="x - 1", shape=box];
|
||||
n332 -> n333;
|
||||
n333 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||
n333 -> n191;
|
||||
n333 -> n335;
|
||||
}
|
||||
8
Project-02-03-04-05/cfgdots/faulty_if.dot
Normal file
8
Project-02-03-04-05/cfgdots/faulty_if.dot
Normal file
@@ -0,0 +1,8 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n356 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n356 -> n358;
|
||||
n358 [label="0", shape=box];
|
||||
n358 -> n357;
|
||||
n357 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
52
Project-02-03-04-05/cfgdots/func.dot
Normal file
52
Project-02-03-04-05/cfgdots/func.dot
Normal file
@@ -0,0 +1,52 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n359 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n359 -> n382;
|
||||
n382 [label="10", shape=box];
|
||||
n382 -> n383;
|
||||
n383 [label="8", shape=box];
|
||||
n383 -> n384;
|
||||
n384 [label="CALL func", shape=box, style=filled, color=orange];
|
||||
n384 -> n361;
|
||||
n384 -> n386;
|
||||
n361 [label="START func(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n361 -> n364;
|
||||
n364 [label="a", shape=box];
|
||||
n364 -> n365;
|
||||
n365 [label="0", shape=box];
|
||||
n365 -> n366;
|
||||
n366 [label="a > 0", shape=box];
|
||||
n366 -> n367;
|
||||
n367 [label="b", shape=box];
|
||||
n367 -> n368;
|
||||
n368 [label="a", shape=box];
|
||||
n368 -> n369;
|
||||
n369 [label="b != a", shape=box];
|
||||
n369 -> n370;
|
||||
n370 [label="(a > 0) && (b != a)", shape=box];
|
||||
n370 -> n371;
|
||||
n371 [label="<?>", shape=diamond];
|
||||
n371 -> n362 [label="T"];
|
||||
n371 -> n373 [label="F"];
|
||||
n362 [label="END func(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n362 -> n386;
|
||||
n386 [label="RET func", shape=box, style=filled, color=orange];
|
||||
n386 -> n360;
|
||||
n360 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n373 [label="b", shape=box];
|
||||
n373 -> n374;
|
||||
n374 [label="1", shape=box];
|
||||
n374 -> n375;
|
||||
n375 [label="b + 1", shape=box];
|
||||
n375 -> n376;
|
||||
n376 [label="b = (b + 1)", shape=box];
|
||||
n376 -> n377;
|
||||
n377 [label="a", shape=box];
|
||||
n377 -> n378;
|
||||
n378 [label="1", shape=box];
|
||||
n378 -> n379;
|
||||
n379 [label="a - 1", shape=box];
|
||||
n379 -> n380;
|
||||
n380 [label="a = (a - 1)", shape=box];
|
||||
n380 -> n366;
|
||||
}
|
||||
19
Project-02-03-04-05/cfgdots/geq.dot
Normal file
19
Project-02-03-04-05/cfgdots/geq.dot
Normal file
@@ -0,0 +1,19 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n388 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n388 -> n390;
|
||||
n390 [label="1", shape=box];
|
||||
n390 -> n391;
|
||||
n391 [label="0", shape=box];
|
||||
n391 -> n392;
|
||||
n392 [label="1 >= 0", shape=box];
|
||||
n392 -> n393;
|
||||
n393 [label="<?>", shape=diamond];
|
||||
n393 -> n397 [label="T"];
|
||||
n393 -> n398 [label="F"];
|
||||
n397 [label="1", shape=box];
|
||||
n397 -> n389;
|
||||
n389 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n398 [label="0", shape=box];
|
||||
n398 -> n389;
|
||||
}
|
||||
67
Project-02-03-04-05/cfgdots/ggT_euclid_rec.dot
Normal file
67
Project-02-03-04-05/cfgdots/ggT_euclid_rec.dot
Normal file
@@ -0,0 +1,67 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n405 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n405 -> n439;
|
||||
n439 [label="2", shape=box];
|
||||
n439 -> n440;
|
||||
n440 [label="8", shape=box];
|
||||
n440 -> n441;
|
||||
n441 [label="CALL ggT", shape=box, style=filled, color=orange];
|
||||
n441 -> n407;
|
||||
n441 -> n443;
|
||||
n407 [label="START ggT(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n407 -> n410;
|
||||
n410 [label="a", shape=box];
|
||||
n410 -> n411;
|
||||
n411 [label="b", shape=box];
|
||||
n411 -> n412;
|
||||
n412 [label="a == b", shape=box];
|
||||
n412 -> n413;
|
||||
n413 [label="<?>", shape=diamond];
|
||||
n413 -> n417 [label="T"];
|
||||
n413 -> n418 [label="F"];
|
||||
n417 [label="a", shape=box];
|
||||
n417 -> n408;
|
||||
n408 [label="END ggT(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n408 -> n431;
|
||||
n408 -> n438;
|
||||
n408 -> n443;
|
||||
n431 [label="RET ggT", shape=box, style=filled, color=orange];
|
||||
n431 -> n408;
|
||||
n438 [label="RET ggT", shape=box, style=filled, color=orange];
|
||||
n438 -> n408;
|
||||
n443 [label="RET ggT", shape=box, style=filled, color=orange];
|
||||
n443 -> n406;
|
||||
n406 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n418 [label="a", shape=box];
|
||||
n418 -> n419;
|
||||
n419 [label="b", shape=box];
|
||||
n419 -> n420;
|
||||
n420 [label="a > b", shape=box];
|
||||
n420 -> n421;
|
||||
n421 [label="<?>", shape=diamond];
|
||||
n421 -> n425 [label="T"];
|
||||
n421 -> n432 [label="F"];
|
||||
n425 [label="a", shape=box];
|
||||
n425 -> n426;
|
||||
n426 [label="b", shape=box];
|
||||
n426 -> n427;
|
||||
n427 [label="a - b", shape=box];
|
||||
n427 -> n428;
|
||||
n428 [label="b", shape=box];
|
||||
n428 -> n429;
|
||||
n429 [label="CALL ggT", shape=box, style=filled, color=orange];
|
||||
n429 -> n407;
|
||||
n429 -> n431;
|
||||
n432 [label="b", shape=box];
|
||||
n432 -> n433;
|
||||
n433 [label="a", shape=box];
|
||||
n433 -> n434;
|
||||
n434 [label="b - a", shape=box];
|
||||
n434 -> n435;
|
||||
n435 [label="a", shape=box];
|
||||
n435 -> n436;
|
||||
n436 [label="CALL ggT", shape=box, style=filled, color=orange];
|
||||
n436 -> n407;
|
||||
n436 -> n438;
|
||||
}
|
||||
111
Project-02-03-04-05/cfgdots/homework.dot
Normal file
111
Project-02-03-04-05/cfgdots/homework.dot
Normal file
@@ -0,0 +1,111 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n445 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n445 -> n499;
|
||||
n499 [label="1", shape=box];
|
||||
n499 -> n500;
|
||||
n500 [label="2", shape=box];
|
||||
n500 -> n501;
|
||||
n501 [label="CALL f", shape=box, style=filled, color=orange];
|
||||
n501 -> n447;
|
||||
n501 -> n503;
|
||||
n447 [label="START f(x, y)", shape=ellipse, style=filled, color=green];
|
||||
n447 -> n452;
|
||||
n452 [label="x", shape=box];
|
||||
n452 -> n453;
|
||||
n453 [label="0", shape=box];
|
||||
n453 -> n454;
|
||||
n454 [label="x == 0", shape=box];
|
||||
n454 -> n455;
|
||||
n455 [label="<?>", shape=diamond];
|
||||
n455 -> n467 [label="T"];
|
||||
n455 -> n475 [label="F"];
|
||||
n467 [label="2", shape=box];
|
||||
n467 -> n468;
|
||||
n468 [label="y", shape=box];
|
||||
n468 -> n469;
|
||||
n469 [label="2 * y", shape=box];
|
||||
n469 -> n470;
|
||||
n470 [label="x", shape=box];
|
||||
n470 -> n471;
|
||||
n471 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n471 -> n459;
|
||||
n471 -> n473;
|
||||
n459 [label="START g(x, z)", shape=ellipse, style=filled, color=green];
|
||||
n459 -> n462;
|
||||
n459 -> n478;
|
||||
n462 [label="x", shape=box];
|
||||
n462 -> n463;
|
||||
n463 [label="y", shape=box];
|
||||
n463 -> n464;
|
||||
n464 [label="x * y", shape=box];
|
||||
n464 -> n465;
|
||||
n465 [label="z", shape=box];
|
||||
n465 -> n466;
|
||||
n466 [label="(x * y) + z", shape=box];
|
||||
n466 -> n460;
|
||||
n460 [label="END g(x, z)", shape=ellipse, style=filled, color=green];
|
||||
n460 -> n473;
|
||||
n460 -> n509;
|
||||
n473 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n473 -> n448;
|
||||
n448 [label="END f(x, y)", shape=ellipse, style=filled, color=green];
|
||||
n448 -> n488;
|
||||
n448 -> n503;
|
||||
n488 [label="RET f", shape=box, style=filled, color=orange];
|
||||
n488 -> n489;
|
||||
n489 [label="a * f(a,i)", shape=box];
|
||||
n489 -> n490;
|
||||
n490 [label="a = (a * f(a,i))", shape=box];
|
||||
n490 -> n491;
|
||||
n491 [label="i", shape=box];
|
||||
n491 -> n492;
|
||||
n492 [label="1", shape=box];
|
||||
n492 -> n493;
|
||||
n493 [label="i - 1", shape=box];
|
||||
n493 -> n494;
|
||||
n494 [label="i = (i - 1)", shape=box];
|
||||
n494 -> n478;
|
||||
n478 [label="i", shape=box];
|
||||
n478 -> n479;
|
||||
n479 [label="0", shape=box];
|
||||
n479 -> n480;
|
||||
n480 [label="i > 0", shape=box];
|
||||
n480 -> n481;
|
||||
n481 [label="<?>", shape=diamond];
|
||||
n481 -> n483 [label="T"];
|
||||
n481 -> n496 [label="F"];
|
||||
n483 [label="a", shape=box];
|
||||
n483 -> n484;
|
||||
n484 [label="a", shape=box];
|
||||
n484 -> n485;
|
||||
n485 [label="i", shape=box];
|
||||
n485 -> n486;
|
||||
n486 [label="CALL f", shape=box, style=filled, color=orange];
|
||||
n486 -> n447;
|
||||
n486 -> n488;
|
||||
n496 [label="a", shape=box];
|
||||
n496 -> n497;
|
||||
n497 [label="42", shape=box];
|
||||
n497 -> n498;
|
||||
n498 [label="a + 42", shape=box];
|
||||
n498 -> n460;
|
||||
n503 [label="RET f", shape=box, style=filled, color=orange];
|
||||
n503 -> n505;
|
||||
n505 [label="3", shape=box];
|
||||
n505 -> n506;
|
||||
n506 [label="3", shape=box];
|
||||
n506 -> n507;
|
||||
n507 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n507 -> n459;
|
||||
n507 -> n509;
|
||||
n509 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n509 -> n446;
|
||||
n446 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n475 [label="x", shape=box];
|
||||
n475 -> n476;
|
||||
n476 [label="1", shape=box];
|
||||
n476 -> n477;
|
||||
n477 [label="x + 1", shape=box];
|
||||
n477 -> n448;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n512 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n512 -> n518;
|
||||
n518 [label="5", shape=box];
|
||||
n518 -> n519;
|
||||
n519 [label="CALL m", shape=box, style=filled, color=orange];
|
||||
n519 -> n514;
|
||||
n519 -> n521;
|
||||
n514 [label="START m(a)", shape=ellipse, style=filled, color=green];
|
||||
n514 -> n517;
|
||||
n517 [label="a", shape=box];
|
||||
n517 -> n515;
|
||||
n515 [label="END m(a)", shape=ellipse, style=filled, color=green];
|
||||
n515 -> n521;
|
||||
n521 [label="RET m", shape=box, style=filled, color=orange];
|
||||
n521 -> n529;
|
||||
n529 [label="5", shape=box];
|
||||
n529 -> n530;
|
||||
n530 [label="CALL m", shape=box, style=filled, color=orange];
|
||||
n530 -> n523;
|
||||
n530 -> n532;
|
||||
n523 [label="START m(b)", shape=ellipse, style=filled, color=green];
|
||||
n523 -> n526;
|
||||
n526 [label="b", shape=box];
|
||||
n526 -> n527;
|
||||
n527 [label="1", shape=box];
|
||||
n527 -> n528;
|
||||
n528 [label="b + 1", shape=box];
|
||||
n528 -> n524;
|
||||
n524 [label="END m(b)", shape=ellipse, style=filled, color=green];
|
||||
n524 -> n532;
|
||||
n532 [label="RET m", shape=box, style=filled, color=orange];
|
||||
n532 -> n513;
|
||||
n513 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
46
Project-02-03-04-05/cfgdots/multiple-let.dot
Normal file
46
Project-02-03-04-05/cfgdots/multiple-let.dot
Normal file
@@ -0,0 +1,46 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n534 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n534 -> n540;
|
||||
n540 [label="5", shape=box];
|
||||
n540 -> n541;
|
||||
n541 [label="CALL n", shape=box, style=filled, color=orange];
|
||||
n541 -> n536;
|
||||
n541 -> n543;
|
||||
n536 [label="START n(a)", shape=ellipse, style=filled, color=green];
|
||||
n536 -> n539;
|
||||
n539 [label="a", shape=box];
|
||||
n539 -> n537;
|
||||
n537 [label="END n(a)", shape=ellipse, style=filled, color=green];
|
||||
n537 -> n543;
|
||||
n537 -> n554;
|
||||
n543 [label="RET n", shape=box, style=filled, color=orange];
|
||||
n543 -> n551;
|
||||
n551 [label="5", shape=box];
|
||||
n551 -> n552;
|
||||
n552 [label="CALL n", shape=box, style=filled, color=orange];
|
||||
n552 -> n536;
|
||||
n552 -> n554;
|
||||
n554 [label="RET n", shape=box, style=filled, color=orange];
|
||||
n554 -> n555;
|
||||
n555 [label="5", shape=box];
|
||||
n555 -> n556;
|
||||
n556 [label="CALL m", shape=box, style=filled, color=orange];
|
||||
n556 -> n545;
|
||||
n556 -> n558;
|
||||
n545 [label="START m(a)", shape=ellipse, style=filled, color=green];
|
||||
n545 -> n548;
|
||||
n548 [label="a", shape=box];
|
||||
n548 -> n549;
|
||||
n549 [label="1", shape=box];
|
||||
n549 -> n550;
|
||||
n550 [label="a + 1", shape=box];
|
||||
n550 -> n546;
|
||||
n546 [label="END m(a)", shape=ellipse, style=filled, color=green];
|
||||
n546 -> n558;
|
||||
n558 [label="RET m", shape=box, style=filled, color=orange];
|
||||
n558 -> n559;
|
||||
n559 [label="n(5) + m(5)", shape=box];
|
||||
n559 -> n535;
|
||||
n535 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
23
Project-02-03-04-05/cfgdots/or.dot
Normal file
23
Project-02-03-04-05/cfgdots/or.dot
Normal file
@@ -0,0 +1,23 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n561 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n561 -> n563;
|
||||
n563 [label="True", shape=box];
|
||||
n563 -> n564;
|
||||
n564 [label="True", shape=box];
|
||||
n564 -> n565;
|
||||
n565 [label="True", shape=box];
|
||||
n565 -> n566;
|
||||
n566 [label="True == True", shape=box];
|
||||
n566 -> n567;
|
||||
n567 [label="True || (True == True)", shape=box];
|
||||
n567 -> n568;
|
||||
n568 [label="<?>", shape=diamond];
|
||||
n568 -> n572 [label="T"];
|
||||
n568 -> n573 [label="F"];
|
||||
n572 [label="1", shape=box];
|
||||
n572 -> n562;
|
||||
n562 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n573 [label="0", shape=box];
|
||||
n573 -> n562;
|
||||
}
|
||||
23
Project-02-03-04-05/cfgdots/p1.dot
Normal file
23
Project-02-03-04-05/cfgdots/p1.dot
Normal file
@@ -0,0 +1,23 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n574 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n574 -> n582;
|
||||
n582 [label="5", shape=box];
|
||||
n582 -> n583;
|
||||
n583 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n583 -> n576;
|
||||
n583 -> n585;
|
||||
n576 [label="START g(a)", shape=ellipse, style=filled, color=green];
|
||||
n576 -> n579;
|
||||
n579 [label="a", shape=box];
|
||||
n579 -> n580;
|
||||
n580 [label="a", shape=box];
|
||||
n580 -> n581;
|
||||
n581 [label="a * a", shape=box];
|
||||
n581 -> n577;
|
||||
n577 [label="END g(a)", shape=ellipse, style=filled, color=green];
|
||||
n577 -> n585;
|
||||
n585 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n585 -> n575;
|
||||
n575 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
40
Project-02-03-04-05/cfgdots/p2.dot
Normal file
40
Project-02-03-04-05/cfgdots/p2.dot
Normal file
@@ -0,0 +1,40 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n587 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n587 -> n606;
|
||||
n606 [label="10", shape=box];
|
||||
n606 -> n607;
|
||||
n607 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n607 -> n589;
|
||||
n607 -> n609;
|
||||
n589 [label="START f1(b)", shape=ellipse, style=filled, color=green];
|
||||
n589 -> n592;
|
||||
n592 [label="b", shape=box];
|
||||
n592 -> n593;
|
||||
n593 [label="0", shape=box];
|
||||
n593 -> n594;
|
||||
n594 [label="b == 0", shape=box];
|
||||
n594 -> n595;
|
||||
n595 [label="<?>", shape=diamond];
|
||||
n595 -> n599 [label="T"];
|
||||
n595 -> n600 [label="F"];
|
||||
n599 [label="0", shape=box];
|
||||
n599 -> n590;
|
||||
n590 [label="END f1(b)", shape=ellipse, style=filled, color=green];
|
||||
n590 -> n605;
|
||||
n590 -> n609;
|
||||
n605 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n605 -> n590;
|
||||
n609 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n609 -> n588;
|
||||
n588 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n600 [label="b", shape=box];
|
||||
n600 -> n601;
|
||||
n601 [label="1", shape=box];
|
||||
n601 -> n602;
|
||||
n602 [label="b - 1", shape=box];
|
||||
n602 -> n603;
|
||||
n603 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n603 -> n589;
|
||||
n603 -> n605;
|
||||
}
|
||||
127
Project-02-03-04-05/cfgdots/p3.dot
Normal file
127
Project-02-03-04-05/cfgdots/p3.dot
Normal file
@@ -0,0 +1,127 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n611 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n611 -> n662;
|
||||
n662 [label="10", shape=box];
|
||||
n662 -> n663;
|
||||
n663 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n663 -> n613;
|
||||
n663 -> n665;
|
||||
n613 [label="START f1(b)", shape=ellipse, style=filled, color=green];
|
||||
n613 -> n618;
|
||||
n618 [label="b", shape=box];
|
||||
n618 -> n619;
|
||||
n619 [label="0", shape=box];
|
||||
n619 -> n620;
|
||||
n620 [label="b == 0", shape=box];
|
||||
n620 -> n621;
|
||||
n621 [label="<?>", shape=diamond];
|
||||
n621 -> n625 [label="T"];
|
||||
n621 -> n626 [label="F"];
|
||||
n625 [label="0", shape=box];
|
||||
n625 -> n614;
|
||||
n614 [label="END f1(b)", shape=ellipse, style=filled, color=green];
|
||||
n614 -> n631;
|
||||
n614 -> n642;
|
||||
n614 -> n646;
|
||||
n614 -> n665;
|
||||
n631 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n631 -> n614;
|
||||
n642 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n642 -> n655;
|
||||
n655 [label="a", shape=box];
|
||||
n655 -> n656;
|
||||
n656 [label="b", shape=box];
|
||||
n656 -> n657;
|
||||
n657 [label="a * b", shape=box];
|
||||
n657 -> n658;
|
||||
n658 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n658 -> n647;
|
||||
n658 -> n660;
|
||||
n647 [label="START g(c)", shape=ellipse, style=filled, color=green];
|
||||
n647 -> n650;
|
||||
n650 [label="a", shape=box];
|
||||
n650 -> n651;
|
||||
n651 [label="b", shape=box];
|
||||
n651 -> n652;
|
||||
n652 [label="a * b", shape=box];
|
||||
n652 -> n653;
|
||||
n653 [label="c", shape=box];
|
||||
n653 -> n654;
|
||||
n654 [label="(a * b) * c", shape=box];
|
||||
n654 -> n648;
|
||||
n648 [label="END g(c)", shape=ellipse, style=filled, color=green];
|
||||
n648 -> n660;
|
||||
n660 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n660 -> n616;
|
||||
n616 [label="END f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n616 -> n688;
|
||||
n688 [label="RET f2", shape=box, style=filled, color=orange];
|
||||
n688 -> n612;
|
||||
n612 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n646 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n646 -> n655;
|
||||
n665 [label="RET f1", shape=box, style=filled, color=orange];
|
||||
n665 -> n667;
|
||||
n667 [label="10", shape=box];
|
||||
n667 -> n680;
|
||||
n680 [label="20", shape=box];
|
||||
n680 -> n681;
|
||||
n681 [label="30", shape=box];
|
||||
n681 -> n682;
|
||||
n682 [label="CALL max", shape=box, style=filled, color=orange];
|
||||
n682 -> n668;
|
||||
n682 -> n684;
|
||||
n668 [label="START max(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n668 -> n671;
|
||||
n671 [label="a", shape=box];
|
||||
n671 -> n672;
|
||||
n672 [label="b", shape=box];
|
||||
n672 -> n673;
|
||||
n673 [label="a > b", shape=box];
|
||||
n673 -> n674;
|
||||
n674 [label="<?>", shape=diamond];
|
||||
n674 -> n678 [label="T"];
|
||||
n674 -> n679 [label="F"];
|
||||
n678 [label="a", shape=box];
|
||||
n678 -> n669;
|
||||
n669 [label="END max(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n669 -> n684;
|
||||
n684 [label="RET max", shape=box, style=filled, color=orange];
|
||||
n684 -> n686;
|
||||
n686 [label="CALL f2", shape=box, style=filled, color=orange];
|
||||
n686 -> n615;
|
||||
n686 -> n688;
|
||||
n615 [label="START f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n615 -> n632;
|
||||
n632 [label="a", shape=box];
|
||||
n632 -> n633;
|
||||
n633 [label="b", shape=box];
|
||||
n633 -> n634;
|
||||
n634 [label="a > b", shape=box];
|
||||
n634 -> n635;
|
||||
n635 [label="<?>", shape=diamond];
|
||||
n635 -> n639 [label="T"];
|
||||
n635 -> n643 [label="F"];
|
||||
n639 [label="a", shape=box];
|
||||
n639 -> n640;
|
||||
n640 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n640 -> n613;
|
||||
n640 -> n642;
|
||||
n643 [label="b", shape=box];
|
||||
n643 -> n644;
|
||||
n644 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n644 -> n613;
|
||||
n644 -> n646;
|
||||
n679 [label="b", shape=box];
|
||||
n679 -> n669;
|
||||
n626 [label="b", shape=box];
|
||||
n626 -> n627;
|
||||
n627 [label="1", shape=box];
|
||||
n627 -> n628;
|
||||
n628 [label="b - 1", shape=box];
|
||||
n628 -> n629;
|
||||
n629 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||
n629 -> n613;
|
||||
n629 -> n631;
|
||||
}
|
||||
27
Project-02-03-04-05/cfgdots/p4.dot
Normal file
27
Project-02-03-04-05/cfgdots/p4.dot
Normal file
@@ -0,0 +1,27 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n689 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n689 -> n698;
|
||||
n698 [label="10", shape=box];
|
||||
n698 -> n699;
|
||||
n699 [label="8", shape=box];
|
||||
n699 -> n700;
|
||||
n700 [label="CALL func", shape=box, style=filled, color=orange];
|
||||
n700 -> n691;
|
||||
n700 -> n702;
|
||||
n691 [label="START func(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n691 -> n694;
|
||||
n694 [label="b", shape=box];
|
||||
n694 -> n695;
|
||||
n695 [label="1", shape=box];
|
||||
n695 -> n696;
|
||||
n696 [label="b + 1", shape=box];
|
||||
n696 -> n697;
|
||||
n697 [label="a = (b + 1)", shape=box];
|
||||
n697 -> n692;
|
||||
n692 [label="END func(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n692 -> n702;
|
||||
n702 [label="RET func", shape=box, style=filled, color=orange];
|
||||
n702 -> n690;
|
||||
n690 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
31
Project-02-03-04-05/cfgdots/p5.dot
Normal file
31
Project-02-03-04-05/cfgdots/p5.dot
Normal file
@@ -0,0 +1,31 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n704 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n704 -> n706;
|
||||
n706 [label="10", shape=box];
|
||||
n706 -> n707;
|
||||
n707 [label="8", shape=box];
|
||||
n707 -> n708;
|
||||
n708 [label="CALL func", shape=box, style=filled, color=orange];
|
||||
n708 -> n691;
|
||||
n708 -> n710;
|
||||
n691 [label="START func(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n691 -> n694;
|
||||
n694 [label="b", shape=box];
|
||||
n694 -> n695;
|
||||
n695 [label="1", shape=box];
|
||||
n695 -> n696;
|
||||
n696 [label="b + 1", shape=box];
|
||||
n696 -> n697;
|
||||
n697 [label="a = (b + 1)", shape=box];
|
||||
n697 -> n692;
|
||||
n692 [label="END func(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n692 -> n702;
|
||||
n692 -> n710;
|
||||
n702 [label="RET func", shape=box, style=filled, color=orange];
|
||||
n702 -> n690;
|
||||
n690 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n710 [label="RET func", shape=box, style=filled, color=orange];
|
||||
n710 -> n705;
|
||||
n705 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
105
Project-02-03-04-05/cfgdots/p6.dot
Normal file
105
Project-02-03-04-05/cfgdots/p6.dot
Normal file
@@ -0,0 +1,105 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n711 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n711 -> n763;
|
||||
n763 [label="2", shape=box];
|
||||
n763 -> n764;
|
||||
n764 [label="3", shape=box];
|
||||
n764 -> n765;
|
||||
n765 [label="CALL f", shape=box, style=filled, color=orange];
|
||||
n765 -> n713;
|
||||
n765 -> n767;
|
||||
n713 [label="START f(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n713 -> n718;
|
||||
n718 [label="a", shape=box];
|
||||
n718 -> n719;
|
||||
n719 [label="0", shape=box];
|
||||
n719 -> n720;
|
||||
n720 [label="a == 0", shape=box];
|
||||
n720 -> n721;
|
||||
n721 [label="<?>", shape=diamond];
|
||||
n721 -> n725 [label="T"];
|
||||
n721 -> n736 [label="F"];
|
||||
n725 [label="2", shape=box];
|
||||
n725 -> n726;
|
||||
n726 [label="b", shape=box];
|
||||
n726 -> n727;
|
||||
n727 [label="2 + b", shape=box];
|
||||
n727 -> n714;
|
||||
n714 [label="END f(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n714 -> n761;
|
||||
n714 -> n767;
|
||||
n761 [label="RET f", shape=box, style=filled, color=orange];
|
||||
n761 -> n762;
|
||||
n762 [label="c * f((c - 1),d)", shape=box];
|
||||
n762 -> n729;
|
||||
n729 [label="END g(a, c)", shape=ellipse, style=filled, color=green];
|
||||
n729 -> n741;
|
||||
n729 -> n773;
|
||||
n741 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n741 -> n742;
|
||||
n742 [label="2 + g(a,b)", shape=box];
|
||||
n742 -> n714;
|
||||
n773 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n773 -> n712;
|
||||
n712 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n767 [label="RET f", shape=box, style=filled, color=orange];
|
||||
n767 -> n769;
|
||||
n769 [label="3", shape=box];
|
||||
n769 -> n770;
|
||||
n770 [label="2", shape=box];
|
||||
n770 -> n771;
|
||||
n771 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n771 -> n728;
|
||||
n771 -> n773;
|
||||
n728 [label="START g(a, c)", shape=ellipse, style=filled, color=green];
|
||||
n728 -> n731;
|
||||
n728 -> n744;
|
||||
n731 [label="a", shape=box];
|
||||
n731 -> n732;
|
||||
n732 [label="c", shape=box];
|
||||
n732 -> n733;
|
||||
n733 [label="a + c", shape=box];
|
||||
n733 -> n734;
|
||||
n734 [label="b", shape=box];
|
||||
n734 -> n735;
|
||||
n735 [label="(a + c) + b", shape=box];
|
||||
n735 -> n729;
|
||||
n744 [label="c", shape=box];
|
||||
n744 -> n745;
|
||||
n745 [label="0", shape=box];
|
||||
n745 -> n746;
|
||||
n746 [label="c == 0", shape=box];
|
||||
n746 -> n747;
|
||||
n747 [label="<?>", shape=diamond];
|
||||
n747 -> n751 [label="T"];
|
||||
n747 -> n754 [label="F"];
|
||||
n751 [label="1", shape=box];
|
||||
n751 -> n752;
|
||||
n752 [label="d", shape=box];
|
||||
n752 -> n753;
|
||||
n753 [label="1 + d", shape=box];
|
||||
n753 -> n729;
|
||||
n754 [label="c", shape=box];
|
||||
n754 -> n755;
|
||||
n755 [label="c", shape=box];
|
||||
n755 -> n756;
|
||||
n756 [label="1", shape=box];
|
||||
n756 -> n757;
|
||||
n757 [label="c - 1", shape=box];
|
||||
n757 -> n758;
|
||||
n758 [label="d", shape=box];
|
||||
n758 -> n759;
|
||||
n759 [label="CALL f", shape=box, style=filled, color=orange];
|
||||
n759 -> n713;
|
||||
n759 -> n761;
|
||||
n736 [label="2", shape=box];
|
||||
n736 -> n737;
|
||||
n737 [label="a", shape=box];
|
||||
n737 -> n738;
|
||||
n738 [label="b", shape=box];
|
||||
n738 -> n739;
|
||||
n739 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n739 -> n728;
|
||||
n739 -> n741;
|
||||
}
|
||||
42
Project-02-03-04-05/cfgdots/side_effect.dot
Normal file
42
Project-02-03-04-05/cfgdots/side_effect.dot
Normal file
@@ -0,0 +1,42 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n774 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n774 -> n793;
|
||||
n793 [label="1", shape=box];
|
||||
n793 -> n794;
|
||||
n794 [label="2", shape=box];
|
||||
n794 -> n795;
|
||||
n795 [label="CALL f", shape=box, style=filled, color=orange];
|
||||
n795 -> n776;
|
||||
n795 -> n797;
|
||||
n776 [label="START f(x, y)", shape=ellipse, style=filled, color=green];
|
||||
n776 -> n786;
|
||||
n786 [label="5", shape=box];
|
||||
n786 -> n787;
|
||||
n787 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n787 -> n779;
|
||||
n787 -> n789;
|
||||
n779 [label="START g(x)", shape=ellipse, style=filled, color=green];
|
||||
n779 -> n782;
|
||||
n782 [label="x", shape=box];
|
||||
n782 -> n783;
|
||||
n783 [label="7", shape=box];
|
||||
n783 -> n784;
|
||||
n784 [label="x + 7", shape=box];
|
||||
n784 -> n785;
|
||||
n785 [label="y = (x + 7)", shape=box];
|
||||
n785 -> n780;
|
||||
n780 [label="END g(x)", shape=ellipse, style=filled, color=green];
|
||||
n780 -> n789;
|
||||
n789 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n789 -> n790;
|
||||
n790 [label="x = g(5)", shape=box];
|
||||
n790 -> n792;
|
||||
n792 [label="y", shape=box];
|
||||
n792 -> n777;
|
||||
n777 [label="END f(x, y)", shape=ellipse, style=filled, color=green];
|
||||
n777 -> n797;
|
||||
n797 [label="RET f", shape=box, style=filled, color=orange];
|
||||
n797 -> n775;
|
||||
n775 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
61
Project-02-03-04-05/cfgdots/simpleSequence.dot
Normal file
61
Project-02-03-04-05/cfgdots/simpleSequence.dot
Normal file
@@ -0,0 +1,61 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n799 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n799 -> n830;
|
||||
n830 [label="3", shape=box];
|
||||
n830 -> n831;
|
||||
n831 [label="CALL f", shape=box, style=filled, color=orange];
|
||||
n831 -> n801;
|
||||
n831 -> n833;
|
||||
n801 [label="START f(x)", shape=ellipse, style=filled, color=green];
|
||||
n801 -> n804;
|
||||
n804 [label="2", shape=box];
|
||||
n804 -> n805;
|
||||
n805 [label="x", shape=box];
|
||||
n805 -> n806;
|
||||
n806 [label="2 * x", shape=box];
|
||||
n806 -> n807;
|
||||
n807 [label="x = (2 * x)", shape=box];
|
||||
n807 -> n808;
|
||||
n808 [label="x", shape=box];
|
||||
n808 -> n809;
|
||||
n809 [label="0", shape=box];
|
||||
n809 -> n810;
|
||||
n810 [label="x > 0", shape=box];
|
||||
n810 -> n811;
|
||||
n811 [label="<?>", shape=diamond];
|
||||
n811 -> n815 [label="T"];
|
||||
n811 -> n819 [label="F"];
|
||||
n815 [label="x", shape=box];
|
||||
n815 -> n816;
|
||||
n816 [label="1", shape=box];
|
||||
n816 -> n817;
|
||||
n817 [label="x - 1", shape=box];
|
||||
n817 -> n818;
|
||||
n818 [label="x = (x - 1)", shape=box];
|
||||
n818 -> n820;
|
||||
n820 [label="x", shape=box];
|
||||
n820 -> n821;
|
||||
n821 [label="0", shape=box];
|
||||
n821 -> n822;
|
||||
n822 [label="x > 0", shape=box];
|
||||
n822 -> n823;
|
||||
n823 [label="<?>", shape=diamond];
|
||||
n823 -> n802 [label="T"];
|
||||
n823 -> n825 [label="F"];
|
||||
n802 [label="END f(x)", shape=ellipse, style=filled, color=green];
|
||||
n802 -> n833;
|
||||
n833 [label="RET f", shape=box, style=filled, color=orange];
|
||||
n833 -> n800;
|
||||
n800 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n825 [label="x", shape=box];
|
||||
n825 -> n826;
|
||||
n826 [label="1", shape=box];
|
||||
n826 -> n827;
|
||||
n827 [label="x - 1", shape=box];
|
||||
n827 -> n828;
|
||||
n828 [label="x = (x - 1)", shape=box];
|
||||
n828 -> n820;
|
||||
n819 [label="x", shape=box];
|
||||
n819 -> n820;
|
||||
}
|
||||
23
Project-02-03-04-05/cfgdots/simple_dfa.dot
Normal file
23
Project-02-03-04-05/cfgdots/simple_dfa.dot
Normal file
@@ -0,0 +1,23 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n835 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n835 -> n843;
|
||||
n843 [label="2", shape=box];
|
||||
n843 -> n844;
|
||||
n844 [label="CALL g", shape=box, style=filled, color=orange];
|
||||
n844 -> n837;
|
||||
n844 -> n846;
|
||||
n837 [label="START g(x, y)", shape=ellipse, style=filled, color=green];
|
||||
n837 -> n840;
|
||||
n840 [label="3", shape=box];
|
||||
n840 -> n841;
|
||||
n841 [label="y = 3", shape=box];
|
||||
n841 -> n842;
|
||||
n842 [label="x", shape=box];
|
||||
n842 -> n838;
|
||||
n838 [label="END g(x, y)", shape=ellipse, style=filled, color=green];
|
||||
n838 -> n846;
|
||||
n846 [label="RET g", shape=box, style=filled, color=orange];
|
||||
n846 -> n836;
|
||||
n836 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
15
Project-02-03-04-05/cfgdots/simple_if.dot
Normal file
15
Project-02-03-04-05/cfgdots/simple_if.dot
Normal file
@@ -0,0 +1,15 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n848 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n848 -> n850;
|
||||
n850 [label="True", shape=box];
|
||||
n850 -> n851;
|
||||
n851 [label="<?>", shape=diamond];
|
||||
n851 -> n855 [label="T"];
|
||||
n851 -> n856 [label="F"];
|
||||
n855 [label="1", shape=box];
|
||||
n855 -> n849;
|
||||
n849 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n856 [label="0", shape=box];
|
||||
n856 -> n849;
|
||||
}
|
||||
19
Project-02-03-04-05/cfgdots/simple_if_2.dot
Normal file
19
Project-02-03-04-05/cfgdots/simple_if_2.dot
Normal file
@@ -0,0 +1,19 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n857 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n857 -> n859;
|
||||
n859 [label="True", shape=box];
|
||||
n859 -> n860;
|
||||
n860 [label="False", shape=box];
|
||||
n860 -> n861;
|
||||
n861 [label="True && False", shape=box];
|
||||
n861 -> n862;
|
||||
n862 [label="<?>", shape=diamond];
|
||||
n862 -> n866 [label="T"];
|
||||
n862 -> n867 [label="F"];
|
||||
n866 [label="1", shape=box];
|
||||
n866 -> n858;
|
||||
n858 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n867 [label="0", shape=box];
|
||||
n867 -> n858;
|
||||
}
|
||||
19
Project-02-03-04-05/cfgdots/simple_if_3.dot
Normal file
19
Project-02-03-04-05/cfgdots/simple_if_3.dot
Normal file
@@ -0,0 +1,19 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n868 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n868 -> n870;
|
||||
n870 [label="True", shape=box];
|
||||
n870 -> n871;
|
||||
n871 [label="False", shape=box];
|
||||
n871 -> n872;
|
||||
n872 [label="True || False", shape=box];
|
||||
n872 -> n873;
|
||||
n873 [label="<?>", shape=diamond];
|
||||
n873 -> n877 [label="T"];
|
||||
n873 -> n878 [label="F"];
|
||||
n877 [label="1", shape=box];
|
||||
n877 -> n869;
|
||||
n869 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n878 [label="0", shape=box];
|
||||
n878 -> n869;
|
||||
}
|
||||
19
Project-02-03-04-05/cfgdots/simple_if_4.dot
Normal file
19
Project-02-03-04-05/cfgdots/simple_if_4.dot
Normal file
@@ -0,0 +1,19 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n879 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n879 -> n881;
|
||||
n881 [label="1", shape=box];
|
||||
n881 -> n882;
|
||||
n882 [label="2", shape=box];
|
||||
n882 -> n883;
|
||||
n883 [label="1 > 2", shape=box];
|
||||
n883 -> n884;
|
||||
n884 [label="<?>", shape=diamond];
|
||||
n884 -> n888 [label="T"];
|
||||
n884 -> n889 [label="F"];
|
||||
n888 [label="1", shape=box];
|
||||
n888 -> n880;
|
||||
n880 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n889 [label="0", shape=box];
|
||||
n889 -> n880;
|
||||
}
|
||||
23
Project-02-03-04-05/cfgdots/simple_if_5.dot
Normal file
23
Project-02-03-04-05/cfgdots/simple_if_5.dot
Normal file
@@ -0,0 +1,23 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n890 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n890 -> n892;
|
||||
n892 [label="2", shape=box];
|
||||
n892 -> n893;
|
||||
n893 [label="3", shape=box];
|
||||
n893 -> n894;
|
||||
n894 [label="5", shape=box];
|
||||
n894 -> n895;
|
||||
n895 [label="3 + 5", shape=box];
|
||||
n895 -> n896;
|
||||
n896 [label="2 > (3 + 5)", shape=box];
|
||||
n896 -> n897;
|
||||
n897 [label="<?>", shape=diamond];
|
||||
n897 -> n901 [label="T"];
|
||||
n897 -> n902 [label="F"];
|
||||
n901 [label="1", shape=box];
|
||||
n901 -> n891;
|
||||
n891 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n902 [label="0", shape=box];
|
||||
n902 -> n891;
|
||||
}
|
||||
27
Project-02-03-04-05/cfgdots/simple_if_6.dot
Normal file
27
Project-02-03-04-05/cfgdots/simple_if_6.dot
Normal file
@@ -0,0 +1,27 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n903 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n903 -> n905;
|
||||
n905 [label="1", shape=box];
|
||||
n905 -> n906;
|
||||
n906 [label="2", shape=box];
|
||||
n906 -> n907;
|
||||
n907 [label="1 > 2", shape=box];
|
||||
n907 -> n908;
|
||||
n908 [label="3", shape=box];
|
||||
n908 -> n909;
|
||||
n909 [label="5", shape=box];
|
||||
n909 -> n910;
|
||||
n910 [label="3 < 5", shape=box];
|
||||
n910 -> n911;
|
||||
n911 [label="(1 > 2) || (3 < 5)", shape=box];
|
||||
n911 -> n912;
|
||||
n912 [label="<?>", shape=diamond];
|
||||
n912 -> n916 [label="T"];
|
||||
n912 -> n917 [label="F"];
|
||||
n916 [label="1", shape=box];
|
||||
n916 -> n904;
|
||||
n904 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n917 [label="0", shape=box];
|
||||
n917 -> n904;
|
||||
}
|
||||
23
Project-02-03-04-05/cfgdots/simple_if_7.dot
Normal file
23
Project-02-03-04-05/cfgdots/simple_if_7.dot
Normal file
@@ -0,0 +1,23 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n918 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n918 -> n920;
|
||||
n920 [label="2", shape=box];
|
||||
n920 -> n921;
|
||||
n921 [label="0", shape=box];
|
||||
n921 -> n922;
|
||||
n922 [label="2 == 0", shape=box];
|
||||
n922 -> n923;
|
||||
n923 [label="False", shape=box];
|
||||
n923 -> n924;
|
||||
n924 [label="(2 == 0) == False", shape=box];
|
||||
n924 -> n925;
|
||||
n925 [label="<?>", shape=diamond];
|
||||
n925 -> n929 [label="T"];
|
||||
n925 -> n930 [label="F"];
|
||||
n929 [label="1", shape=box];
|
||||
n929 -> n919;
|
||||
n919 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n930 [label="0", shape=box];
|
||||
n930 -> n919;
|
||||
}
|
||||
23
Project-02-03-04-05/cfgdots/square.dot
Normal file
23
Project-02-03-04-05/cfgdots/square.dot
Normal file
@@ -0,0 +1,23 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n931 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n931 -> n939;
|
||||
n939 [label="10", shape=box];
|
||||
n939 -> n940;
|
||||
n940 [label="CALL square", shape=box, style=filled, color=orange];
|
||||
n940 -> n933;
|
||||
n940 -> n942;
|
||||
n933 [label="START square(x)", shape=ellipse, style=filled, color=green];
|
||||
n933 -> n936;
|
||||
n936 [label="x", shape=box];
|
||||
n936 -> n937;
|
||||
n937 [label="x", shape=box];
|
||||
n937 -> n938;
|
||||
n938 [label="x * x", shape=box];
|
||||
n938 -> n934;
|
||||
n934 [label="END square(x)", shape=ellipse, style=filled, color=green];
|
||||
n934 -> n942;
|
||||
n942 [label="RET square", shape=box, style=filled, color=orange];
|
||||
n942 -> n932;
|
||||
n932 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
}
|
||||
94
Project-02-03-04-05/cfgdots/validProgram.dot
Normal file
94
Project-02-03-04-05/cfgdots/validProgram.dot
Normal file
@@ -0,0 +1,94 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n944 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n944 -> n984;
|
||||
n984 [label="2", shape=box];
|
||||
n984 -> n985;
|
||||
n985 [label="3", shape=box];
|
||||
n985 -> n986;
|
||||
n986 [label="CALL mult", shape=box, style=filled, color=orange];
|
||||
n986 -> n946;
|
||||
n986 -> n988;
|
||||
n946 [label="START mult(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n946 -> n951;
|
||||
n951 [label="a", shape=box];
|
||||
n951 -> n952;
|
||||
n952 [label="b", shape=box];
|
||||
n952 -> n953;
|
||||
n953 [label="a * b", shape=box];
|
||||
n953 -> n947;
|
||||
n947 [label="END mult(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n947 -> n978;
|
||||
n947 -> n988;
|
||||
n978 [label="RET mult", shape=box, style=filled, color=orange];
|
||||
n978 -> n955;
|
||||
n955 [label="END inc(a)", shape=ellipse, style=filled, color=green];
|
||||
n955 -> n973;
|
||||
n955 -> n982;
|
||||
n973 [label="RET inc", shape=box, style=filled, color=orange];
|
||||
n973 -> n955;
|
||||
n982 [label="RET inc", shape=box, style=filled, color=orange];
|
||||
n982 -> n949;
|
||||
n949 [label="END add(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n949 -> n993;
|
||||
n949 -> n996;
|
||||
n993 [label="RET add", shape=box, style=filled, color=orange];
|
||||
n993 -> n994;
|
||||
n994 [label="CALL add", shape=box, style=filled, color=orange];
|
||||
n994 -> n948;
|
||||
n994 -> n996;
|
||||
n948 [label="START add(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n948 -> n979;
|
||||
n979 [label="a", shape=box];
|
||||
n979 -> n980;
|
||||
n980 [label="CALL inc", shape=box, style=filled, color=orange];
|
||||
n980 -> n954;
|
||||
n980 -> n982;
|
||||
n954 [label="START inc(a)", shape=ellipse, style=filled, color=green];
|
||||
n954 -> n957;
|
||||
n957 [label="b", shape=box];
|
||||
n957 -> n958;
|
||||
n958 [label="0", shape=box];
|
||||
n958 -> n959;
|
||||
n959 [label="b != 0", shape=box];
|
||||
n959 -> n960;
|
||||
n960 [label="<?>", shape=diamond];
|
||||
n960 -> n964 [label="T"];
|
||||
n960 -> n974 [label="F"];
|
||||
n964 [label="b", shape=box];
|
||||
n964 -> n965;
|
||||
n965 [label="1", shape=box];
|
||||
n965 -> n966;
|
||||
n966 [label="b - 1", shape=box];
|
||||
n966 -> n967;
|
||||
n967 [label="b = (b - 1)", shape=box];
|
||||
n967 -> n968;
|
||||
n968 [label="a", shape=box];
|
||||
n968 -> n969;
|
||||
n969 [label="1", shape=box];
|
||||
n969 -> n970;
|
||||
n970 [label="a + 1", shape=box];
|
||||
n970 -> n971;
|
||||
n971 [label="CALL inc", shape=box, style=filled, color=orange];
|
||||
n971 -> n954;
|
||||
n971 -> n973;
|
||||
n974 [label="a", shape=box];
|
||||
n974 -> n975;
|
||||
n975 [label="1", shape=box];
|
||||
n975 -> n976;
|
||||
n976 [label="CALL mult", shape=box, style=filled, color=orange];
|
||||
n976 -> n946;
|
||||
n976 -> n978;
|
||||
n996 [label="RET add", shape=box, style=filled, color=orange];
|
||||
n996 -> n945;
|
||||
n945 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n988 [label="RET mult", shape=box, style=filled, color=orange];
|
||||
n988 -> n989;
|
||||
n989 [label="4", shape=box];
|
||||
n989 -> n990;
|
||||
n990 [label="5", shape=box];
|
||||
n990 -> n991;
|
||||
n991 [label="CALL add", shape=box, style=filled, color=orange];
|
||||
n991 -> n948;
|
||||
n991 -> n993;
|
||||
}
|
||||
52
Project-02-03-04-05/cfgdots/while.dot
Normal file
52
Project-02-03-04-05/cfgdots/while.dot
Normal file
@@ -0,0 +1,52 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n998 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n998 -> n1021;
|
||||
n1021 [label="10", shape=box];
|
||||
n1021 -> n1022;
|
||||
n1022 [label="8", shape=box];
|
||||
n1022 -> n1023;
|
||||
n1023 [label="CALL func", shape=box, style=filled, color=orange];
|
||||
n1023 -> n1000;
|
||||
n1023 -> n1025;
|
||||
n1000 [label="START func(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n1000 -> n1003;
|
||||
n1003 [label="a", shape=box];
|
||||
n1003 -> n1004;
|
||||
n1004 [label="0", shape=box];
|
||||
n1004 -> n1005;
|
||||
n1005 [label="a > 0", shape=box];
|
||||
n1005 -> n1006;
|
||||
n1006 [label="b", shape=box];
|
||||
n1006 -> n1007;
|
||||
n1007 [label="a", shape=box];
|
||||
n1007 -> n1008;
|
||||
n1008 [label="b != a", shape=box];
|
||||
n1008 -> n1009;
|
||||
n1009 [label="(a > 0) && (b != a)", shape=box];
|
||||
n1009 -> n1010;
|
||||
n1010 [label="<?>", shape=diamond];
|
||||
n1010 -> n1001 [label="T"];
|
||||
n1010 -> n1012 [label="F"];
|
||||
n1001 [label="END func(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n1001 -> n1025;
|
||||
n1025 [label="RET func", shape=box, style=filled, color=orange];
|
||||
n1025 -> n999;
|
||||
n999 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n1012 [label="b", shape=box];
|
||||
n1012 -> n1013;
|
||||
n1013 [label="1", shape=box];
|
||||
n1013 -> n1014;
|
||||
n1014 [label="b + 1", shape=box];
|
||||
n1014 -> n1015;
|
||||
n1015 [label="b = (b + 1)", shape=box];
|
||||
n1015 -> n1016;
|
||||
n1016 [label="a", shape=box];
|
||||
n1016 -> n1017;
|
||||
n1017 [label="1", shape=box];
|
||||
n1017 -> n1018;
|
||||
n1018 [label="a - 1", shape=box];
|
||||
n1018 -> n1019;
|
||||
n1019 [label="a = (a - 1)", shape=box];
|
||||
n1019 -> n1005;
|
||||
}
|
||||
13
Project-02-03-04-05/cfgdots/while_2.dot
Normal file
13
Project-02-03-04-05/cfgdots/while_2.dot
Normal file
@@ -0,0 +1,13 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n1027 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n1027 -> n1029;
|
||||
n1029 [label="True", shape=box];
|
||||
n1029 -> n1030;
|
||||
n1030 [label="<?>", shape=diamond];
|
||||
n1030 -> n1028 [label="T"];
|
||||
n1030 -> n1032 [label="F"];
|
||||
n1028 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n1032 [label="3", shape=box];
|
||||
n1032 -> n1027;
|
||||
}
|
||||
78
Project-02-03-04-05/cfgdots/wrapped-ggT.dot
Normal file
78
Project-02-03-04-05/cfgdots/wrapped-ggT.dot
Normal file
@@ -0,0 +1,78 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n1034 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n1034 -> n1076;
|
||||
n1076 [label="21", shape=box];
|
||||
n1076 -> n1077;
|
||||
n1077 [label="49", shape=box];
|
||||
n1077 -> n1078;
|
||||
n1078 [label="CALL wrapper", shape=box, style=filled, color=orange];
|
||||
n1078 -> n1036;
|
||||
n1078 -> n1080;
|
||||
n1036 [label="START wrapper(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n1036 -> n1071;
|
||||
n1071 [label="0", shape=box];
|
||||
n1071 -> n1072;
|
||||
n1072 [label="CALL ggt", shape=box, style=filled, color=orange];
|
||||
n1072 -> n1039;
|
||||
n1072 -> n1074;
|
||||
n1039 [label="START ggt(noneSense)", shape=ellipse, style=filled, color=green];
|
||||
n1039 -> n1042;
|
||||
n1042 [label="a", shape=box];
|
||||
n1042 -> n1043;
|
||||
n1043 [label="b", shape=box];
|
||||
n1043 -> n1044;
|
||||
n1044 [label="a == b", shape=box];
|
||||
n1044 -> n1045;
|
||||
n1045 [label="<?>", shape=diamond];
|
||||
n1045 -> n1049 [label="T"];
|
||||
n1045 -> n1050 [label="F"];
|
||||
n1049 [label="a", shape=box];
|
||||
n1049 -> n1040;
|
||||
n1040 [label="END ggt(noneSense)", shape=ellipse, style=filled, color=green];
|
||||
n1040 -> n1074;
|
||||
n1074 [label="RET ggt", shape=box, style=filled, color=orange];
|
||||
n1074 -> n1037;
|
||||
n1037 [label="END wrapper(a, b)", shape=ellipse, style=filled, color=green];
|
||||
n1037 -> n1063;
|
||||
n1037 -> n1070;
|
||||
n1037 -> n1080;
|
||||
n1063 [label="RET wrapper", shape=box, style=filled, color=orange];
|
||||
n1063 -> n1040;
|
||||
n1070 [label="RET wrapper", shape=box, style=filled, color=orange];
|
||||
n1070 -> n1040;
|
||||
n1080 [label="RET wrapper", shape=box, style=filled, color=orange];
|
||||
n1080 -> n1035;
|
||||
n1035 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n1050 [label="a", shape=box];
|
||||
n1050 -> n1051;
|
||||
n1051 [label="b", shape=box];
|
||||
n1051 -> n1052;
|
||||
n1052 [label="a > b", shape=box];
|
||||
n1052 -> n1053;
|
||||
n1053 [label="<?>", shape=diamond];
|
||||
n1053 -> n1057 [label="T"];
|
||||
n1053 -> n1064 [label="F"];
|
||||
n1057 [label="a", shape=box];
|
||||
n1057 -> n1058;
|
||||
n1058 [label="b", shape=box];
|
||||
n1058 -> n1059;
|
||||
n1059 [label="a - b", shape=box];
|
||||
n1059 -> n1060;
|
||||
n1060 [label="b", shape=box];
|
||||
n1060 -> n1061;
|
||||
n1061 [label="CALL wrapper", shape=box, style=filled, color=orange];
|
||||
n1061 -> n1036;
|
||||
n1061 -> n1063;
|
||||
n1064 [label="b", shape=box];
|
||||
n1064 -> n1065;
|
||||
n1065 [label="a", shape=box];
|
||||
n1065 -> n1066;
|
||||
n1066 [label="b - a", shape=box];
|
||||
n1066 -> n1067;
|
||||
n1067 [label="a", shape=box];
|
||||
n1067 -> n1068;
|
||||
n1068 [label="CALL wrapper", shape=box, style=filled, color=orange];
|
||||
n1068 -> n1036;
|
||||
n1068 -> n1070;
|
||||
}
|
||||
51
Project-02-03-04-05/cfgdots/wrapper.dot
Normal file
51
Project-02-03-04-05/cfgdots/wrapper.dot
Normal file
@@ -0,0 +1,51 @@
|
||||
digraph CFG {
|
||||
node [fontname="Helvetica"];
|
||||
n1082 [label="START", shape=ellipse, style=filled, color=gray];
|
||||
n1082 -> n1108;
|
||||
n1108 [label="4", shape=box];
|
||||
n1108 -> n1109;
|
||||
n1109 [label="10", shape=box];
|
||||
n1109 -> n1110;
|
||||
n1110 [label="CALL wrapper", shape=box, style=filled, color=orange];
|
||||
n1110 -> n1084;
|
||||
n1110 -> n1112;
|
||||
n1084 [label="START wrapper(number, threshold)", shape=ellipse, style=filled, color=green];
|
||||
n1084 -> n1103;
|
||||
n1103 [label="number", shape=box];
|
||||
n1103 -> n1104;
|
||||
n1104 [label="CALL square", shape=box, style=filled, color=orange];
|
||||
n1104 -> n1087;
|
||||
n1104 -> n1106;
|
||||
n1087 [label="START square(x)", shape=ellipse, style=filled, color=green];
|
||||
n1087 -> n1090;
|
||||
n1090 [label="x", shape=box];
|
||||
n1090 -> n1091;
|
||||
n1091 [label="x", shape=box];
|
||||
n1091 -> n1092;
|
||||
n1092 [label="x * x", shape=box];
|
||||
n1092 -> n1093;
|
||||
n1093 [label="threshold", shape=box];
|
||||
n1093 -> n1094;
|
||||
n1094 [label="(x * x) > threshold", shape=box];
|
||||
n1094 -> n1095;
|
||||
n1095 [label="<?>", shape=diamond];
|
||||
n1095 -> n1099 [label="T"];
|
||||
n1095 -> n1100 [label="F"];
|
||||
n1099 [label="x", shape=box];
|
||||
n1099 -> n1088;
|
||||
n1088 [label="END square(x)", shape=ellipse, style=filled, color=green];
|
||||
n1088 -> n1106;
|
||||
n1106 [label="RET square", shape=box, style=filled, color=orange];
|
||||
n1106 -> n1085;
|
||||
n1085 [label="END wrapper(number, threshold)", shape=ellipse, style=filled, color=green];
|
||||
n1085 -> n1112;
|
||||
n1112 [label="RET wrapper", shape=box, style=filled, color=orange];
|
||||
n1112 -> n1083;
|
||||
n1083 [label="END", shape=ellipse, style=filled, color=gray];
|
||||
n1100 [label="x", shape=box];
|
||||
n1100 -> n1101;
|
||||
n1101 [label="x", shape=box];
|
||||
n1101 -> n1102;
|
||||
n1102 [label="x * x", shape=box];
|
||||
n1102 -> n1088;
|
||||
}
|
||||
175
Project-02-03-04-05/compiler.py
Normal file
175
Project-02-03-04-05/compiler.py
Normal file
@@ -0,0 +1,175 @@
|
||||
import syntax
|
||||
from vistram.tram import *
|
||||
|
||||
label_counter = 0
|
||||
|
||||
def new_label():
|
||||
global label_counter
|
||||
label_counter += 1
|
||||
return Label(text=f"L{label_counter}")
|
||||
|
||||
# Rules E1, E2
|
||||
def elab_def(decls, rho, nl):
|
||||
r = dict(rho)
|
||||
for d in decls:
|
||||
r = d.elab(r, nl)
|
||||
return r
|
||||
|
||||
# Rule K6
|
||||
class CONST(syntax.CONST):
|
||||
def code(self, rho, nl):
|
||||
return [const(self.value)]
|
||||
|
||||
# Rule K3
|
||||
class ID(syntax.ID):
|
||||
def code(self, rho, nl):
|
||||
k, nl_def = rho[self.name]
|
||||
return [load(k, nl - nl_def)]
|
||||
|
||||
# Rule K7
|
||||
class AOP(syntax.AOP):
|
||||
def code(self, rho, nl):
|
||||
c1 = self.arg1.code(rho, nl)
|
||||
c2 = self.arg2.code(rho, nl)
|
||||
|
||||
match self.operator:
|
||||
case "+":
|
||||
return c1 + c2 + [add()]
|
||||
case "-":
|
||||
return c1 + c2 + [sub()]
|
||||
case "*":
|
||||
return c1 + c2 + [mul()]
|
||||
case "/":
|
||||
return c1 + c2 + [div()]
|
||||
case _:
|
||||
raise Exception(f"Unknown AOP operator.")
|
||||
|
||||
# Rule K5
|
||||
class COMP(syntax.COMP):
|
||||
def code(self, rho, nl):
|
||||
c1 = self.arg1.code(rho, nl)
|
||||
c2 = self.arg2.code(rho, nl)
|
||||
|
||||
match self.operator:
|
||||
case "<":
|
||||
return c1 + c2 + [lt()]
|
||||
case ">":
|
||||
return c1 + c2 + [gt()]
|
||||
case "<=":
|
||||
# leq is not implemented in vistra.tram
|
||||
return LOP("||", COMP("<", self.arg1, self.arg2), EQOP("==", self.arg1, self.arg2)).code(rho, nl)
|
||||
case ">=":
|
||||
# geq is not implemented in vistra.tram
|
||||
return LOP("||", COMP(">", self.arg1, self.arg2), EQOP("==", self.arg1, self.arg2)).code(rho, nl)
|
||||
case _:
|
||||
raise ValueError(f"Unknown COMP operator.")
|
||||
|
||||
# Rule K5
|
||||
class EQOP(syntax.EQOP):
|
||||
def code(self, rho, nl):
|
||||
c1 = self.arg1.code(rho, nl)
|
||||
c2 = self.arg2.code(rho, nl)
|
||||
|
||||
match self.operator:
|
||||
case "==":
|
||||
return c1 + c2 + [eq()]
|
||||
case "!=":
|
||||
return c1 + c2 + [neq()]
|
||||
case _:
|
||||
raise ValueError(f"Unknown EQOP operator.")
|
||||
|
||||
# see lecture code generation AND/OR
|
||||
class LOP(syntax.LOP):
|
||||
def code(self, rho, nl):
|
||||
c1 = self.arg1.code(rho, nl)
|
||||
c2 = self.arg2.code(rho, nl)
|
||||
|
||||
l1 = new_label()
|
||||
l2 = new_label()
|
||||
match self.operator:
|
||||
case "&&":
|
||||
return c1 + [ifzero(l1)] + [const(1)] + c2 + [mul()] + [goto(l2)] + [nop(l1)] + [const(0)] + [nop(l2)]
|
||||
case "||":
|
||||
return c1 + [ifzero(l1)] + [const(1)] + [goto(l2)] + [nop(l1)] + c2 + [nop(l2)]
|
||||
case _:
|
||||
raise ValueError("Unknown LOP operator.")
|
||||
|
||||
# Rule K4
|
||||
class ASSIGN(syntax.ASSIGN):
|
||||
def code(self, rho, nl):
|
||||
c = self.expr.code(rho, nl)
|
||||
k, nl_def = rho[self.var.name]
|
||||
dif = nl - nl_def
|
||||
return c + [store(k, dif), load(k, dif)]
|
||||
|
||||
# Rule K9
|
||||
class SEQ(syntax.SEQ):
|
||||
def code(self, rho, nl):
|
||||
c1 = self.exp1.code(rho, nl)
|
||||
c2 = self.exp2.code(rho, nl)
|
||||
return c1 + [pop()] + c2
|
||||
|
||||
# Rule K10
|
||||
class IF(syntax.IF):
|
||||
def code(self, rho, nl):
|
||||
l1 = new_label()
|
||||
l2 = new_label()
|
||||
|
||||
c1 = self.cond.code(rho, nl)
|
||||
c2 = self.exp1.code(rho, nl)
|
||||
c3 = self.exp2.code(rho, nl)
|
||||
|
||||
return c1 + [ifzero(l1)] + c2 + [goto(l2)] + [nop(assigned_label=l1)] + c3 + [nop(assigned_label=l2)]
|
||||
|
||||
# Rule K11
|
||||
class WHILE(syntax.WHILE):
|
||||
def code(self, rho, nl):
|
||||
l1 = new_label()
|
||||
l2 = new_label()
|
||||
l3 = new_label()
|
||||
l4 = new_label()
|
||||
|
||||
c1 = self.cond.code(rho, nl)
|
||||
c2 = self.body.code(rho, nl)
|
||||
|
||||
return c1 + [ifzero(l3), goto(l4)] + [nop(l1)] + c1 + [ifzero(l2), pop()] + [nop(l4)] + c2 + [goto(l1)] + [nop(l3), const(None), nop(l2)]
|
||||
|
||||
# Rule K2
|
||||
class LET(syntax.LET):
|
||||
def code(self, rho, nl):
|
||||
l = new_label()
|
||||
|
||||
# Normalize to list
|
||||
decls = self.decl if isinstance(self.decl, list) else [self.decl]
|
||||
|
||||
shared_rho = elab_def(decls, rho, nl)
|
||||
ds = []
|
||||
for d in decls:
|
||||
ds += d.code(shared_rho, nl)
|
||||
|
||||
es = self.body.code(shared_rho, nl)
|
||||
return [goto(l)] + ds + [nop(assigned_label=l)] + es
|
||||
|
||||
# Rule K13
|
||||
class DECL(syntax.DECL):
|
||||
def elab(self, rho, nl):
|
||||
nested_rho = dict(rho)
|
||||
nested_rho[self.f_name] = (new_label(), nl)
|
||||
return nested_rho
|
||||
|
||||
def code(self, rho, nl):
|
||||
l, _ = rho[self.f_name]
|
||||
nested_rho = dict(rho)
|
||||
for i, p in enumerate(self.params):
|
||||
nested_rho[p] = (i, nl + 1)
|
||||
c = self.body.code(nested_rho, nl + 1)
|
||||
return [nop(assigned_label=l)] + c + [ireturn()]
|
||||
|
||||
# Rule K12
|
||||
class CALL(syntax.CALL):
|
||||
def code(self, rho, nl):
|
||||
c = []
|
||||
for a in self.arg:
|
||||
c += a.code(rho, nl)
|
||||
l, nl_def = rho[self.f_name]
|
||||
return c + [invoke(len(self.arg), l, nl - nl_def)]
|
||||
0
Project-02-03-04-05/lib/__init__.py
Normal file
0
Project-02-03-04-05/lib/__init__.py
Normal file
22
Project-02-03-04-05/lib/console.py
Normal file
22
Project-02-03-04-05/lib/console.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from pathlib import Path
|
||||
|
||||
def prompt_choice(prompt: str, options: list) -> int:
|
||||
print(prompt)
|
||||
for i, opt in enumerate(options, 1):
|
||||
print(f" {i}. {opt}")
|
||||
|
||||
while True:
|
||||
try:
|
||||
s = input(f"Enter choice (1-{len(options)}): ").strip()
|
||||
idx = int(s) - 1
|
||||
if 0 <= idx < len(options):
|
||||
return idx
|
||||
except Exception:
|
||||
pass
|
||||
print(f"Invalid. Enter a number between 1-{len(options)}.")
|
||||
|
||||
def prompt_confirmation(question: str, default="y"):
|
||||
s = input(f"{question} (y/n) [{default}]: ").strip().lower()
|
||||
if not s:
|
||||
s = default
|
||||
return s.startswith("y")
|
||||
171
Project-02-03-04-05/main.py
Normal file
171
Project-02-03-04-05/main.py
Normal file
@@ -0,0 +1,171 @@
|
||||
import os
|
||||
import tkinter as tk
|
||||
from pathlib import Path
|
||||
|
||||
import matplotlib
|
||||
import matplotlib.image as mpimg
|
||||
import matplotlib.pyplot as plt
|
||||
from graphviz import Source
|
||||
|
||||
import lib.console as cnsl
|
||||
import syntax
|
||||
import triplayacc as yacc
|
||||
from cfg.CFG import CFG
|
||||
from vistram.tram import *
|
||||
from vistram.vistram import MachineUI
|
||||
|
||||
matplotlib.use("TkAgg")
|
||||
|
||||
# Assembles the AST into TRAM code
|
||||
def assemble(ast):
|
||||
code = ast.code({}, 0)
|
||||
return code + [halt()]
|
||||
|
||||
def make_cfg(ast):
|
||||
return CFG(ast)
|
||||
|
||||
# Renders a diagram of the AST
|
||||
def render_diagram(dot_string: str):
|
||||
# Set DPI for PNG
|
||||
os.environ["GV_FILE_DPI"] = "300"
|
||||
|
||||
src = Source(dot_string, format="png", engine="dot")
|
||||
png_path = src.render(cleanup=True)
|
||||
|
||||
img = mpimg.imread(png_path)
|
||||
|
||||
fig = plt.figure(figsize=(12, 12))
|
||||
fig.canvas.manager.window.wm_title("TRIPLA AST Viewer")
|
||||
|
||||
plt.imshow(img)
|
||||
plt.axis("off")
|
||||
plt.show()
|
||||
|
||||
# Pretty prints the AST
|
||||
def pretty_print(node, indent=0):
|
||||
prefix = " " * indent
|
||||
print(f"{prefix}{type(node).__name__}:")
|
||||
|
||||
for key, value in node.__dict__.items():
|
||||
if isinstance(value, syntax.EXPRESSION):
|
||||
pretty_print(value, indent + 4)
|
||||
|
||||
elif isinstance(value, list):
|
||||
print(f"{prefix} {key}: [")
|
||||
for element in value:
|
||||
if isinstance(element, syntax.EXPRESSION):
|
||||
pretty_print(element, indent + 4)
|
||||
else:
|
||||
print(" " * (indent + 4) + str(element))
|
||||
print(f"{prefix} ]")
|
||||
|
||||
else:
|
||||
print(f"{prefix} {key}: {value}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("\nTRIPLA Parser and TRIPLA to TRAM Compiler")
|
||||
|
||||
while True:
|
||||
mode = cnsl.prompt_choice("\nSelect action:", ["Parse .tripla", "Compile .tripla", "CFG for .tripla", "Exit"])
|
||||
|
||||
if mode == 3:
|
||||
print("\nBye Bye.")
|
||||
break
|
||||
|
||||
base = Path(__file__).parent / "triplaprograms"
|
||||
programs = sorted([f for f in base.glob("*.tripla")])
|
||||
if not programs:
|
||||
print("\nNo .tripla files found.")
|
||||
continue
|
||||
|
||||
idx = cnsl.prompt_choice("\nSelect TRIPLA program:", [p.name for p in programs])
|
||||
path = programs[idx]
|
||||
|
||||
source = path.read_text()
|
||||
ast = yacc.parser.parse(source)
|
||||
|
||||
if mode == 0:
|
||||
# Pretty print
|
||||
if cnsl.prompt_confirmation("\nPretty-print AST?"):
|
||||
print("")
|
||||
pretty_print(ast)
|
||||
|
||||
# Export DOT
|
||||
dot_str = ast.to_dot()
|
||||
if cnsl.prompt_confirmation("Export AST as .dot file?"):
|
||||
default = f"{path.stem}.dot"
|
||||
filename = input(f"Filename [{default}]: ").strip()
|
||||
if not filename:
|
||||
filename = default
|
||||
try:
|
||||
base_dir = Path(__file__).parent
|
||||
out_path = base_dir / filename
|
||||
with open(out_path, "w") as f:
|
||||
f.write(dot_str)
|
||||
print(f"Saved DOT file as: {out_path}")
|
||||
except Exception as e:
|
||||
print(f"Could not save DOT file: {e}")
|
||||
|
||||
# Display AST diagram
|
||||
if cnsl.prompt_confirmation("Display AST diagram?"):
|
||||
render_diagram(dot_str)
|
||||
print("Rendered AST diagram.")
|
||||
|
||||
elif mode == 1:
|
||||
tram_code = assemble(ast)
|
||||
|
||||
# Print TRAM code
|
||||
if cnsl.prompt_confirmation("\nPrint TRAM code to console?"):
|
||||
print("\nGenerated TRAM code:\n")
|
||||
for instr in tram_code:
|
||||
print(instr.toString())
|
||||
|
||||
# Save TRAM code
|
||||
if cnsl.prompt_confirmation("Save TRAM code as .tram file?"):
|
||||
base_dir = Path(__file__).parent / "tramcodes"
|
||||
base_dir.mkdir(exist_ok=True)
|
||||
|
||||
default = f"{path.stem}.tram"
|
||||
filename = input(f"Filename [{default}]: ").strip()
|
||||
if not filename:
|
||||
filename = default
|
||||
|
||||
out_path = base_dir / filename
|
||||
with open(out_path, "w") as f:
|
||||
for instr in tram_code:
|
||||
f.write(instr.toString() + "\n")
|
||||
|
||||
print(f"Saved TRAM code to: {out_path}")
|
||||
|
||||
# Display TRAM code in Visual TRAM UI
|
||||
if cnsl.prompt_confirmation("Display TRAM code in Visual TRAM UI?"):
|
||||
root = tk.Tk()
|
||||
ui = MachineUI(root)
|
||||
ui.machine.initial_program = tram_code
|
||||
ui.machine.reset()
|
||||
root.mainloop()
|
||||
|
||||
elif mode == 2:
|
||||
cfg = make_cfg(ast)
|
||||
|
||||
dot_str = cfg.to_dot()
|
||||
if cnsl.prompt_confirmation("\nExport CFG as .dot file?"):
|
||||
default = f"{path.stem}_cfg.dot"
|
||||
filename = input(f"Filename [{default}]: ").strip()
|
||||
if not filename:
|
||||
filename = default
|
||||
|
||||
out_path = Path(__file__).parent / 'cfgdots' / filename
|
||||
with open(out_path, "w") as f:
|
||||
f.write(dot_str)
|
||||
|
||||
print(f"Saved CFG DOT file as: {out_path}")
|
||||
|
||||
if cnsl.prompt_confirmation("Display CFG diagram?"):
|
||||
render_diagram(dot_str)
|
||||
print("Rendered CFG diagram.")
|
||||
|
||||
|
||||
|
||||
|
||||
1129
Project-02-03-04-05/parser.out
Normal file
1129
Project-02-03-04-05/parser.out
Normal file
File diff suppressed because it is too large
Load Diff
53
Project-02-03-04-05/parsetab.py
Normal file
53
Project-02-03-04-05/parsetab.py
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
# parsetab.py
|
||||
# This file is automatically generated. Do not edit.
|
||||
# pylint: disable=W,C,R
|
||||
_tabversion = '3.10'
|
||||
|
||||
_lr_method = 'LALR'
|
||||
|
||||
_lr_signature = 'EleftSEMICOLONleftINleftELSEleftCOMMArightASSIGNleftCOMPleftEQOPleftAOPleftCOMPleftEQOPAOP ASSIGN COMMA COMP CONST DO ELSE EQOP FALSE ID IF IN LBRACE LET LOP LPAREN RBRACE RPAREN SEMICOLON THEN TRUE WHILEE : LET D IN EE : IDE : ID LPAREN A RPARENE : E AOP EE : LPAREN E RPARENE : CONSTE : ID ASSIGN EE : E SEMICOLON EE : IF B THEN E ELSE EE : WHILE B DO LBRACE E RBRACEA : EA : A COMMA ED : ID LPAREN V RPAREN LBRACE E RBRACED : D DV : IDV : V COMMA VB : E EQOP EB : E COMP EB : B EQOP BB : B LOP BB : TRUEB : FALSEB : LPAREN B RPAREN'
|
||||
|
||||
_lr_action_items = {'LET':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,]),'ID':([0,2,4,6,7,8,9,10,12,13,19,23,24,25,30,31,32,33,34,42,49,51,53,55,60,],[3,11,3,3,3,3,3,11,3,3,3,11,3,39,3,3,3,3,3,3,3,39,3,3,-13,]),'LPAREN':([0,3,4,6,7,8,9,11,12,13,19,24,30,31,32,33,34,42,49,53,55,],[4,12,4,19,19,4,4,25,4,4,19,4,4,19,19,4,4,4,4,4,4,]),'CONST':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,]),'IF':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,]),'WHILE':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,]),'$end':([1,3,5,21,22,28,29,38,41,57,58,],[0,-2,-6,-4,-8,-7,-5,-1,-3,-9,-10,]),'AOP':([1,3,5,14,16,21,22,27,28,29,36,38,41,43,46,47,52,54,57,58,59,],[8,-2,-6,8,8,-4,8,8,8,-5,8,8,-3,8,8,8,8,8,8,-10,8,]),'SEMICOLON':([1,3,5,14,16,21,22,27,28,29,36,38,41,43,46,47,52,54,57,58,59,],[9,-2,-6,9,9,-4,-8,9,-7,-5,9,-1,-3,9,9,9,9,9,-9,-10,9,]),'RPAREN':([3,5,14,17,18,21,22,26,27,28,29,35,36,38,39,40,41,44,45,46,47,48,52,56,57,58,],[-2,-6,29,-21,-22,-4,-8,41,-11,-7,-5,48,29,-1,-15,50,-3,-19,-20,-17,-18,-23,-12,-16,-9,-10,]),'EQOP':([3,5,15,16,17,18,20,21,22,28,29,35,36,38,41,44,45,46,47,48,57,58,],[-2,-6,31,33,-21,-22,31,-4,-8,-7,-5,31,33,-1,-3,-19,31,-17,-18,-23,-9,-10,]),'COMP':([3,5,16,21,22,28,29,36,38,41,57,58,],[-2,-6,34,-4,-8,-7,-5,34,-1,-3,-9,-10,]),'COMMA':([3,5,21,22,26,27,28,29,38,39,40,41,52,56,57,58,],[-2,-6,-4,-8,42,-11,-7,-5,-1,-15,51,-3,-12,-16,-9,-10,]),'ELSE':([3,5,21,22,28,29,38,41,43,57,58,],[-2,-6,-4,-8,-7,-5,-1,-3,53,-9,-10,]),'THEN':([3,5,15,17,18,21,22,28,29,38,41,44,45,46,47,48,57,58,],[-2,-6,30,-21,-22,-4,-8,-7,-5,-1,-3,-19,-20,-17,-18,-23,-9,-10,]),'LOP':([3,5,15,17,18,20,21,22,28,29,35,38,41,44,45,46,47,48,57,58,],[-2,-6,32,-21,-22,32,-4,-8,-7,-5,32,-1,-3,-19,32,-17,-18,-23,-9,-10,]),'DO':([3,5,17,18,20,21,22,28,29,38,41,44,45,46,47,48,57,58,],[-2,-6,-21,-22,37,-4,-8,-7,-5,-1,-3,-19,-20,-17,-18,-23,-9,-10,]),'RBRACE':([3,5,21,22,28,29,38,41,54,57,58,59,],[-2,-6,-4,-8,-7,-5,-1,-3,58,-9,-10,60,]),'ASSIGN':([3,],[13,]),'TRUE':([6,7,19,31,32,],[17,17,17,17,17,]),'FALSE':([6,7,19,31,32,],[18,18,18,18,18,]),'IN':([10,23,60,],[24,-14,-13,]),'LBRACE':([37,50,],[49,55,]),}
|
||||
|
||||
_lr_action = {}
|
||||
for _k, _v in _lr_action_items.items():
|
||||
for _x,_y in zip(_v[0],_v[1]):
|
||||
if not _x in _lr_action: _lr_action[_x] = {}
|
||||
_lr_action[_x][_k] = _y
|
||||
del _lr_action_items
|
||||
|
||||
_lr_goto_items = {'E':([0,4,6,7,8,9,12,13,19,24,30,31,32,33,34,42,49,53,55,],[1,14,16,16,21,22,27,28,36,38,43,16,16,46,47,52,54,57,59,]),'D':([2,10,23,],[10,23,23,]),'B':([6,7,19,31,32,],[15,20,35,44,45,]),'A':([12,],[26,]),'V':([25,51,],[40,56,]),}
|
||||
|
||||
_lr_goto = {}
|
||||
for _k, _v in _lr_goto_items.items():
|
||||
for _x, _y in zip(_v[0], _v[1]):
|
||||
if not _x in _lr_goto: _lr_goto[_x] = {}
|
||||
_lr_goto[_x][_k] = _y
|
||||
del _lr_goto_items
|
||||
_lr_productions = [
|
||||
("S' -> E","S'",1,None,None,None),
|
||||
('E -> LET D IN E','E',4,'p_E_let','triplayacc.py',30),
|
||||
('E -> ID','E',1,'p_E_id','triplayacc.py',34),
|
||||
('E -> ID LPAREN A RPAREN','E',4,'p_E_call','triplayacc.py',38),
|
||||
('E -> E AOP E','E',3,'p_E_aop','triplayacc.py',43),
|
||||
('E -> LPAREN E RPAREN','E',3,'p_E_paren','triplayacc.py',47),
|
||||
('E -> CONST','E',1,'p_E_const','triplayacc.py',52),
|
||||
('E -> ID ASSIGN E','E',3,'p_E_assign','triplayacc.py',56),
|
||||
('E -> E SEMICOLON E','E',3,'p_E_seq','triplayacc.py',60),
|
||||
('E -> IF B THEN E ELSE E','E',6,'p_E_if','triplayacc.py',64),
|
||||
('E -> WHILE B DO LBRACE E RBRACE','E',6,'p_E_while','triplayacc.py',68),
|
||||
('A -> E','A',1,'p_A_single','triplayacc.py',77),
|
||||
('A -> A COMMA E','A',3,'p_A_multiple','triplayacc.py',81),
|
||||
('D -> ID LPAREN V RPAREN LBRACE E RBRACE','D',7,'p_D_single','triplayacc.py',89),
|
||||
('D -> D D','D',2,'p_D_concat','triplayacc.py',93),
|
||||
('V -> ID','V',1,'p_V_single','triplayacc.py',101),
|
||||
('V -> V COMMA V','V',3,'p_V_multiple','triplayacc.py',105),
|
||||
('B -> E EQOP E','B',3,'p_B_eqop_E','triplayacc.py',113),
|
||||
('B -> E COMP E','B',3,'p_B_comp','triplayacc.py',117),
|
||||
('B -> B EQOP B','B',3,'p_B_eqop_B','triplayacc.py',121),
|
||||
('B -> B LOP B','B',3,'p_B_lop','triplayacc.py',125),
|
||||
('B -> TRUE','B',1,'p_B_true','triplayacc.py',129),
|
||||
('B -> FALSE','B',1,'p_B_false','triplayacc.py',133),
|
||||
('B -> LPAREN B RPAREN','B',3,'p_B_paren','triplayacc.py',137),
|
||||
]
|
||||
183
Project-02-03-04-05/syntax.py
Normal file
183
Project-02-03-04-05/syntax.py
Normal file
@@ -0,0 +1,183 @@
|
||||
class EXPRESSION:
|
||||
pp_count = 0
|
||||
|
||||
def __init__(self):
|
||||
self.pp = EXPRESSION.pp_count
|
||||
EXPRESSION.pp_count += 1
|
||||
|
||||
@staticmethod
|
||||
def copy():
|
||||
return EXPRESSION()
|
||||
|
||||
# Returns a list of tuples (edge_name, child_expression)
|
||||
def children(self):
|
||||
out = []
|
||||
for key, value in self.__dict__.items():
|
||||
if key == "pp":
|
||||
continue
|
||||
if isinstance(value, EXPRESSION):
|
||||
out.append((key, value))
|
||||
elif isinstance(value, list):
|
||||
for i, elem in enumerate(value):
|
||||
if isinstance(elem, EXPRESSION):
|
||||
out.append((f"{key}{i}", elem))
|
||||
return out
|
||||
|
||||
# Export AST to dot format
|
||||
def to_dot(self, visited=None, root=True):
|
||||
if visited is None:
|
||||
visited = set()
|
||||
|
||||
# Prevent infinite recursion
|
||||
if id(self) in visited:
|
||||
return ""
|
||||
visited.add(id(self))
|
||||
|
||||
parts = []
|
||||
|
||||
# Add a header at the root node
|
||||
if root:
|
||||
parts.append("digraph AST {\n")
|
||||
|
||||
# Append to label
|
||||
label = type(self).__name__
|
||||
if hasattr(self, "operator"):
|
||||
label += f"({self.operator})"
|
||||
if hasattr(self, "name"):
|
||||
label += f"({self.name})"
|
||||
if hasattr(self, "value"):
|
||||
label += f"({self.value})"
|
||||
|
||||
parts.append(f' node{self.pp} [label="{label}"];\n')
|
||||
|
||||
# Draw edges
|
||||
for edge_name, child in self.children():
|
||||
parts.append(f' node{self.pp} -> node{child.pp} [label="{edge_name}"];\n')
|
||||
parts.append(child.to_dot(visited, root=False))
|
||||
|
||||
# Add footer at the root node
|
||||
if root:
|
||||
parts.append("}\n")
|
||||
|
||||
return "".join(parts)
|
||||
|
||||
class LET(EXPRESSION):
|
||||
def __init__(self, decls, body):
|
||||
super().__init__()
|
||||
self.decl = decls
|
||||
self.body = body
|
||||
|
||||
def __str__(self):
|
||||
return "let " + ", ".join(str(d) for d in self.decl) + " in " + str(self.body)
|
||||
|
||||
class DECL(EXPRESSION):
|
||||
def __init__(self, f_name, params, body):
|
||||
super().__init__()
|
||||
self.f_name = f_name
|
||||
self.params = params
|
||||
self.body = body
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.f_name}({self.params}) {{ {self.body} }}"
|
||||
|
||||
class CALL(EXPRESSION):
|
||||
def __init__(self, f_name, args):
|
||||
super().__init__()
|
||||
self.f_name = f_name
|
||||
self.arg = args
|
||||
|
||||
def __str__(self):
|
||||
return self.f_name + "(" + ",".join(str(a) for a in self.arg) + ")"
|
||||
|
||||
class ID(EXPRESSION):
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self.name = name
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class CONST(EXPRESSION):
|
||||
def __init__(self, value):
|
||||
super().__init__()
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
return str(self.value)
|
||||
|
||||
class AOP(EXPRESSION):
|
||||
def __init__(self, operator, arg1, arg2):
|
||||
super().__init__()
|
||||
self.operator = operator
|
||||
self.arg1 = arg1
|
||||
self.arg2 = arg2
|
||||
|
||||
def __str__(self):
|
||||
return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")"
|
||||
|
||||
class EQOP(EXPRESSION):
|
||||
def __init__(self, operator, arg1, arg2):
|
||||
super().__init__()
|
||||
self.operator = operator
|
||||
self.arg1 = arg1
|
||||
self.arg2 = arg2
|
||||
|
||||
def __str__(self):
|
||||
return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")"
|
||||
|
||||
class COMP(EXPRESSION):
|
||||
def __init__(self, operator, arg1, arg2):
|
||||
super().__init__()
|
||||
self.operator = operator
|
||||
self.arg1 = arg1
|
||||
self.arg2 = arg2
|
||||
|
||||
def __str__(self):
|
||||
return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")"
|
||||
|
||||
class LOP(EXPRESSION):
|
||||
def __init__(self, operator, arg1, arg2):
|
||||
super().__init__()
|
||||
self.operator = operator
|
||||
self.arg1 = arg1
|
||||
self.arg2 = arg2
|
||||
|
||||
def __str__(self):
|
||||
return "(" + str(self.arg1) + " " + str(self.operator) + " " + str(self.arg2) + ")"
|
||||
|
||||
class ASSIGN(EXPRESSION):
|
||||
def __init__(self, var, expr):
|
||||
super().__init__()
|
||||
self.var = var
|
||||
self.expr = expr
|
||||
|
||||
def __str__(self):
|
||||
return self.var.name + " = " + str(self.expr)
|
||||
|
||||
class SEQ(EXPRESSION):
|
||||
def __init__(self, exp1, exp2):
|
||||
super().__init__()
|
||||
self.exp1 = exp1
|
||||
self.exp2 = exp2
|
||||
|
||||
def __str__(self):
|
||||
return str(self.exp1) + "; " + str(self.exp2)
|
||||
|
||||
class IF(EXPRESSION):
|
||||
def __init__(self, cond, exp1, exp2):
|
||||
super().__init__()
|
||||
self.cond = cond
|
||||
self.exp1 = exp1
|
||||
self.exp2 = exp2
|
||||
|
||||
def __str__(self):
|
||||
return "if (" + str(self.cond) + ") then { " + str(self.exp1) + " } else { " + str(self.exp2) + " }"
|
||||
|
||||
class WHILE(EXPRESSION):
|
||||
def __init__(self, cond, body):
|
||||
super().__init__()
|
||||
self.cond = cond
|
||||
self.body = body
|
||||
|
||||
def __str__(self):
|
||||
return "while (" + str(self.cond) + ") do { " + str(self.body) + " }"
|
||||
10
Project-02-03-04-05/tramcodes/argsParamsExample.tram
Normal file
10
Project-02-03-04-05/tramcodes/argsParamsExample.tram
Normal file
@@ -0,0 +1,10 @@
|
||||
GOTO L1
|
||||
L2: NOP
|
||||
LOAD 0 0
|
||||
RETURN
|
||||
L1: NOP
|
||||
CONST 1
|
||||
CONST 2
|
||||
CONST 3
|
||||
INVOKE 3 L2 0
|
||||
HALT
|
||||
65
Project-02-03-04-05/tramcodes/complex.tram
Normal file
65
Project-02-03-04-05/tramcodes/complex.tram
Normal file
@@ -0,0 +1,65 @@
|
||||
GOTO L1
|
||||
L2: NOP
|
||||
LOAD 0 0
|
||||
CONST 0
|
||||
EQ
|
||||
IFZERO L4
|
||||
CONST 0
|
||||
GOTO L5
|
||||
L4: NOP
|
||||
LOAD 0 0
|
||||
CONST 1
|
||||
SUB
|
||||
INVOKE 1 L2 1
|
||||
L5: NOP
|
||||
RETURN
|
||||
L3: NOP
|
||||
LOAD 0 0
|
||||
LOAD 1 0
|
||||
GT
|
||||
IFZERO L6
|
||||
LOAD 0 0
|
||||
INVOKE 1 L2 1
|
||||
GOTO L7
|
||||
L6: NOP
|
||||
LOAD 1 0
|
||||
INVOKE 1 L2 1
|
||||
POP
|
||||
GOTO L8
|
||||
L9: NOP
|
||||
LOAD 0 1
|
||||
LOAD 1 1
|
||||
MUL
|
||||
LOAD 0 0
|
||||
MUL
|
||||
RETURN
|
||||
L8: NOP
|
||||
LOAD 0 0
|
||||
LOAD 1 0
|
||||
MUL
|
||||
INVOKE 1 L9 0
|
||||
L7: NOP
|
||||
RETURN
|
||||
L1: NOP
|
||||
CONST 10
|
||||
INVOKE 1 L2 0
|
||||
POP
|
||||
CONST 10
|
||||
GOTO L10
|
||||
L11: NOP
|
||||
LOAD 0 0
|
||||
LOAD 1 0
|
||||
GT
|
||||
IFZERO L12
|
||||
LOAD 0 0
|
||||
GOTO L13
|
||||
L12: NOP
|
||||
LOAD 1 0
|
||||
L13: NOP
|
||||
RETURN
|
||||
L10: NOP
|
||||
CONST 20
|
||||
CONST 30
|
||||
INVOKE 2 L11 0
|
||||
INVOKE 2 L3 0
|
||||
HALT
|
||||
42
Project-02-03-04-05/tramcodes/example.tram
Normal file
42
Project-02-03-04-05/tramcodes/example.tram
Normal file
@@ -0,0 +1,42 @@
|
||||
GOTO L1
|
||||
L2: NOP
|
||||
CONST 2
|
||||
STORE 1 0
|
||||
LOAD 1 0
|
||||
POP
|
||||
CONST 3
|
||||
STORE 2 0
|
||||
LOAD 2 0
|
||||
POP
|
||||
GOTO L3
|
||||
L4: NOP
|
||||
CONST 7
|
||||
STORE 0 0
|
||||
LOAD 0 0
|
||||
POP
|
||||
LOAD 1 1
|
||||
CONST 0
|
||||
GT
|
||||
IFZERO L5
|
||||
LOAD 1 1
|
||||
INVOKE 1 L4 1
|
||||
GOTO L6
|
||||
L5: NOP
|
||||
CONST 8
|
||||
STORE 0 0
|
||||
LOAD 0 0
|
||||
L6: NOP
|
||||
POP
|
||||
LOAD 0 0
|
||||
RETURN
|
||||
L3: NOP
|
||||
LOAD 0 0
|
||||
INVOKE 1 L4 0
|
||||
LOAD 0 0
|
||||
ADD
|
||||
RETURN
|
||||
L1: NOP
|
||||
CONST 2
|
||||
CONST 3
|
||||
INVOKE 2 L2 0
|
||||
HALT
|
||||
18
Project-02-03-04-05/tramcodes/geq.tram
Normal file
18
Project-02-03-04-05/tramcodes/geq.tram
Normal file
@@ -0,0 +1,18 @@
|
||||
CONST 1
|
||||
CONST 0
|
||||
GT
|
||||
IFZERO L3
|
||||
CONST 1
|
||||
GOTO L4
|
||||
L3: NOP
|
||||
CONST 1
|
||||
CONST 0
|
||||
EQ
|
||||
L4: NOP
|
||||
IFZERO L1
|
||||
CONST 1
|
||||
GOTO L2
|
||||
L1: NOP
|
||||
CONST 0
|
||||
L2: NOP
|
||||
HALT
|
||||
71
Project-02-03-04-05/tramcodes/homework.tram
Normal file
71
Project-02-03-04-05/tramcodes/homework.tram
Normal file
@@ -0,0 +1,71 @@
|
||||
GOTO L1
|
||||
L2: NOP
|
||||
LOAD 0 0
|
||||
CONST 0
|
||||
EQ
|
||||
IFZERO L4
|
||||
GOTO L6
|
||||
L7: NOP
|
||||
LOAD 0 0
|
||||
LOAD 1 1
|
||||
MUL
|
||||
LOAD 1 0
|
||||
ADD
|
||||
RETURN
|
||||
L6: NOP
|
||||
CONST 2
|
||||
LOAD 1 0
|
||||
MUL
|
||||
LOAD 0 0
|
||||
INVOKE 2 L7 0
|
||||
GOTO L5
|
||||
L4: NOP
|
||||
LOAD 0 0
|
||||
CONST 1
|
||||
ADD
|
||||
L5: NOP
|
||||
RETURN
|
||||
L3: NOP
|
||||
LOAD 1 0
|
||||
CONST 0
|
||||
GT
|
||||
IFZERO L10
|
||||
GOTO L11
|
||||
L8: NOP
|
||||
LOAD 1 0
|
||||
CONST 0
|
||||
GT
|
||||
IFZERO L9
|
||||
POP
|
||||
L11: NOP
|
||||
LOAD 0 0
|
||||
LOAD 0 0
|
||||
LOAD 1 0
|
||||
INVOKE 2 L2 1
|
||||
MUL
|
||||
STORE 0 0
|
||||
LOAD 0 0
|
||||
POP
|
||||
LOAD 1 0
|
||||
CONST 1
|
||||
SUB
|
||||
STORE 1 0
|
||||
LOAD 1 0
|
||||
GOTO L8
|
||||
L10: NOP
|
||||
CONST None
|
||||
L9: NOP
|
||||
POP
|
||||
LOAD 0 0
|
||||
CONST 42
|
||||
ADD
|
||||
RETURN
|
||||
L1: NOP
|
||||
CONST 1
|
||||
CONST 2
|
||||
INVOKE 2 L2 0
|
||||
POP
|
||||
CONST 3
|
||||
CONST 3
|
||||
INVOKE 2 L3 0
|
||||
HALT
|
||||
92
Project-02-03-04-05/triplalex.py
Normal file
92
Project-02-03-04-05/triplalex.py
Normal file
@@ -0,0 +1,92 @@
|
||||
# ------------------------------------------------------------
|
||||
# Tokenizer for the TRIPLA parser
|
||||
# ------------------------------------------------------------
|
||||
|
||||
import ply.lex as lex
|
||||
|
||||
reserved = {
|
||||
'let': 'LET',
|
||||
'in': 'IN',
|
||||
'if': 'IF',
|
||||
'then': 'THEN',
|
||||
'else': 'ELSE',
|
||||
'while': 'WHILE',
|
||||
'do': 'DO',
|
||||
'true': 'TRUE',
|
||||
'false': 'FALSE'
|
||||
}
|
||||
|
||||
# List of token names.
|
||||
tokens = [
|
||||
'ID',
|
||||
'CONST',
|
||||
'AOP',
|
||||
'COMP',
|
||||
'EQOP',
|
||||
'LOP',
|
||||
'ASSIGN',
|
||||
'LPAREN', 'RPAREN',
|
||||
'LBRACE', 'RBRACE',
|
||||
'COMMA',
|
||||
'SEMICOLON',
|
||||
] + list(reserved.values())
|
||||
|
||||
# Simple tokens
|
||||
t_LPAREN = r'\('
|
||||
t_RPAREN = r'\)'
|
||||
t_LBRACE = r'\{'
|
||||
t_RBRACE = r'\}'
|
||||
t_COMMA = r','
|
||||
t_SEMICOLON = r';'
|
||||
t_ASSIGN = r'='
|
||||
|
||||
# Arithmetic operators
|
||||
t_AOP = r'\+|\-|\*|/'
|
||||
|
||||
# Comparison operators
|
||||
t_COMP = r'<=|>=|<|>'
|
||||
|
||||
# Equality operators
|
||||
t_EQOP = r'==|!='
|
||||
|
||||
# Logical operators
|
||||
t_LOP = r'\|\||&&'
|
||||
|
||||
# IDs
|
||||
def t_ID(t):
|
||||
r'[A-Za-z_][A-Za-z0-9_]*'
|
||||
t.type = reserved.get(t.value, 'ID')
|
||||
return t
|
||||
|
||||
# Constants
|
||||
def t_CONST(t):
|
||||
r'0|[1-9][0-9]*'
|
||||
t.value = int(t.value)
|
||||
return t
|
||||
|
||||
# Linebreaks
|
||||
def t_newline(t):
|
||||
r'\n+'
|
||||
t.lexer.lineno += len(t.value)
|
||||
|
||||
# Ignore whitespace
|
||||
t_ignore = ' \t'
|
||||
|
||||
# Single-line comment
|
||||
def t_comment_single(t):
|
||||
r'//.*'
|
||||
pass
|
||||
|
||||
# Multi-line comment
|
||||
def t_comment_multi(t):
|
||||
r'/\*([^*]|\*+[^*/])*\*/'
|
||||
t.lexer.lineno += t.value.count('\n')
|
||||
pass
|
||||
|
||||
# Error handling
|
||||
def t_error(t):
|
||||
print("Illegal character '%s'" % t.value[0])
|
||||
t.lexer.skip(1)
|
||||
|
||||
# Build the lexer
|
||||
lexer = lex.lex()
|
||||
@@ -0,0 +1,2 @@
|
||||
let a(x,y,z) {x}
|
||||
in a(1,2,3)
|
||||
15
Project-02-03-04-05/triplaprograms/complex.tripla
Normal file
15
Project-02-03-04-05/triplaprograms/complex.tripla
Normal file
@@ -0,0 +1,15 @@
|
||||
let
|
||||
f1(b) {
|
||||
if(b==0) then 0 else f1(b-1)
|
||||
}
|
||||
f2(a, b) {
|
||||
if(a > b) then f1(a) else f1(b);
|
||||
let g(c) {
|
||||
a*b*c
|
||||
} in g(a*b)
|
||||
}
|
||||
in
|
||||
f1(10); f2(10, let max(a, b) {
|
||||
if(a > b) then a else b
|
||||
}
|
||||
in max(20, 30))
|
||||
1
Project-02-03-04-05/triplaprograms/condition.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/condition.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if 2 < x && x > 9 then 1 else 0
|
||||
4
Project-02-03-04-05/triplaprograms/defSemiExample.tripla
Normal file
4
Project-02-03-04-05/triplaprograms/defSemiExample.tripla
Normal file
@@ -0,0 +1,4 @@
|
||||
let a(x) {x}
|
||||
b(y) {y}
|
||||
c(z) {z}
|
||||
in a(1); b(2); c(3)
|
||||
11
Project-02-03-04-05/triplaprograms/example.tripla
Normal file
11
Project-02-03-04-05/triplaprograms/example.tripla
Normal file
@@ -0,0 +1,11 @@
|
||||
let f(x,y,z) {
|
||||
y=2;
|
||||
z=3;
|
||||
let g(x) {
|
||||
x=7;
|
||||
if (y>0)
|
||||
then g(y)
|
||||
else x=8;
|
||||
x
|
||||
} in g(x)+x
|
||||
} in f(2,3)
|
||||
38
Project-02-03-04-05/triplaprograms/factorial.tripla
Normal file
38
Project-02-03-04-05/triplaprograms/factorial.tripla
Normal file
@@ -0,0 +1,38 @@
|
||||
let
|
||||
fac(x) {
|
||||
if (x == 1) then 1
|
||||
else fac(x-1)*x
|
||||
}
|
||||
fac(x) {
|
||||
if (x == 1) then 1
|
||||
else fac(x-1)*x
|
||||
}
|
||||
fac(x) {
|
||||
if (x == 1) then 1
|
||||
else fac(x-1)*x
|
||||
}
|
||||
fac(x) {
|
||||
if (x == 1) then 1
|
||||
else fac(x-1)*x
|
||||
}
|
||||
fac(x) {
|
||||
if (x == 1) then 1
|
||||
else fac(x-1)*x
|
||||
}
|
||||
fac(x) {
|
||||
if (x == 1) then 1
|
||||
else fac(x-1)*x
|
||||
}
|
||||
fac(x) {
|
||||
if (x == 1) then 1
|
||||
else fac(x-1)*x
|
||||
}
|
||||
fac(x) {
|
||||
if (x == 1) then 1
|
||||
else fac(x-1)*x
|
||||
}
|
||||
fac(x) {
|
||||
if (x == 1) then 1
|
||||
else fac(x-1)*x
|
||||
}
|
||||
in fac(3)
|
||||
@@ -0,0 +1 @@
|
||||
let n(a) {a} in n(5) + m(5) ; let m(a) {a+1} in m(5)
|
||||
1
Project-02-03-04-05/triplaprograms/faulty_if.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/faulty_if.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if (2 && 7 > 2) then 1 else 0
|
||||
7
Project-02-03-04-05/triplaprograms/func.tripla
Normal file
7
Project-02-03-04-05/triplaprograms/func.tripla
Normal file
@@ -0,0 +1,7 @@
|
||||
let func(a,b) {
|
||||
while ( a > 0 && b != a ) do {
|
||||
b = b + 1;
|
||||
a = a - 1
|
||||
}
|
||||
}
|
||||
in func(10, 8)
|
||||
1
Project-02-03-04-05/triplaprograms/geq.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/geq.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if 1 >= 0 then 1 else 0
|
||||
12
Project-02-03-04-05/triplaprograms/ggT_euclid_iter.tripla
Normal file
12
Project-02-03-04-05/triplaprograms/ggT_euclid_iter.tripla
Normal file
@@ -0,0 +1,12 @@
|
||||
let ggT(a, b) {
|
||||
if (a == b) then
|
||||
a
|
||||
else
|
||||
do {
|
||||
if (a > b) then
|
||||
a = a - b
|
||||
else
|
||||
b = b - a
|
||||
} while (a != b);
|
||||
a
|
||||
} in ggT(3528, 3780) // result should be 252
|
||||
8
Project-02-03-04-05/triplaprograms/ggT_euclid_rec.tripla
Normal file
8
Project-02-03-04-05/triplaprograms/ggT_euclid_rec.tripla
Normal file
@@ -0,0 +1,8 @@
|
||||
let ggT(a, b) {
|
||||
if (a == b) then
|
||||
a
|
||||
else if (a > b) then
|
||||
ggT(a-b, b)
|
||||
else
|
||||
ggT(b-a, a)
|
||||
} in ggT(2, 8)
|
||||
16
Project-02-03-04-05/triplaprograms/homework.tripla
Normal file
16
Project-02-03-04-05/triplaprograms/homework.tripla
Normal file
@@ -0,0 +1,16 @@
|
||||
let f(x, y) {
|
||||
if (x == 0) then
|
||||
let g(x, z) {
|
||||
x * y + z
|
||||
} in g(2 * y, x)
|
||||
else
|
||||
x + 1
|
||||
}
|
||||
g (a, i) {
|
||||
while (i > 0) do {
|
||||
a = a * f(a, i);
|
||||
i = i - 1
|
||||
};
|
||||
a + 42
|
||||
}
|
||||
in f (1, 2); g(3, 3)
|
||||
3
Project-02-03-04-05/triplaprograms/invalidProgram.tripla
Normal file
3
Project-02-03-04-05/triplaprograms/invalidProgram.tripla
Normal file
@@ -0,0 +1,3 @@
|
||||
let f1(b) { if (b == 0) then 0 else f1(b-1) }
|
||||
f2(a,b) { if (a > b) then f1(a) else f1(b) }
|
||||
in f1(10); f2(10,-20)
|
||||
@@ -0,0 +1 @@
|
||||
let m(a){a} in m(5);let m(b){b+1} in m(5)
|
||||
1
Project-02-03-04-05/triplaprograms/multiple-let.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/multiple-let.tripla
Normal file
@@ -0,0 +1 @@
|
||||
let n(a) {a} in n(5) ; let m(a) {a+1} in n(5) + m(5)
|
||||
1
Project-02-03-04-05/triplaprograms/or.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/or.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if(true||true==true) then 1 else 0
|
||||
3
Project-02-03-04-05/triplaprograms/p1.tripla
Normal file
3
Project-02-03-04-05/triplaprograms/p1.tripla
Normal file
@@ -0,0 +1,3 @@
|
||||
let g(a) {
|
||||
a*a
|
||||
} in g(5)
|
||||
9
Project-02-03-04-05/triplaprograms/p2.tripla
Normal file
9
Project-02-03-04-05/triplaprograms/p2.tripla
Normal file
@@ -0,0 +1,9 @@
|
||||
let f1(b) {
|
||||
if (b==0) then 0 else f1(b-1)
|
||||
} in f1(10)
|
||||
/*
|
||||
f2(a,b) {
|
||||
if (a>b) then f1(a) else f1(b)
|
||||
}
|
||||
in f1(10); f2(10,20)
|
||||
*/
|
||||
14
Project-02-03-04-05/triplaprograms/p3.tripla
Normal file
14
Project-02-03-04-05/triplaprograms/p3.tripla
Normal file
@@ -0,0 +1,14 @@
|
||||
let f1(b) {
|
||||
if (b==0) then 0 else f1(b-1)
|
||||
}
|
||||
f2(a,b) {
|
||||
if (a>b) then f1(a) else f1(b);
|
||||
let g(c) {
|
||||
a*b*c
|
||||
}
|
||||
in g(a*b)
|
||||
}
|
||||
in f1(10); f2(10, let max(a,b) {
|
||||
if (a>b) then a else b
|
||||
}
|
||||
in max(20,30) )
|
||||
4
Project-02-03-04-05/triplaprograms/p4.tripla
Normal file
4
Project-02-03-04-05/triplaprograms/p4.tripla
Normal file
@@ -0,0 +1,4 @@
|
||||
let func(a,b) {
|
||||
a = b + 1
|
||||
}
|
||||
in func(10, 8)
|
||||
9
Project-02-03-04-05/triplaprograms/p5.tripla
Normal file
9
Project-02-03-04-05/triplaprograms/p5.tripla
Normal file
@@ -0,0 +1,9 @@
|
||||
let func(a, b) {
|
||||
let func(a, b) {
|
||||
a * b
|
||||
} in
|
||||
do {
|
||||
b = b + 1 * func(3, 1);
|
||||
a = a - 1
|
||||
} while ( a > 0 && b != a )
|
||||
} in func(10, 8)
|
||||
13
Project-02-03-04-05/triplaprograms/p6.tripla
Normal file
13
Project-02-03-04-05/triplaprograms/p6.tripla
Normal file
@@ -0,0 +1,13 @@
|
||||
let f(a, b) {
|
||||
if (a == 0) then
|
||||
2 + b
|
||||
else
|
||||
let g(a, c) {
|
||||
a + c + b
|
||||
} in 2 + g(a, b)
|
||||
} g(c, d) {
|
||||
if (c == 0) then
|
||||
1 + d
|
||||
else
|
||||
c * f(c - 1, d)
|
||||
} in f (2, 3); g (3, 2)
|
||||
5
Project-02-03-04-05/triplaprograms/side_effect.tripla
Normal file
5
Project-02-03-04-05/triplaprograms/side_effect.tripla
Normal file
@@ -0,0 +1,5 @@
|
||||
let f(x, y) {
|
||||
let g(x) {
|
||||
y = x + 7
|
||||
} in x = g(5); y
|
||||
} in f(1, 2)
|
||||
5
Project-02-03-04-05/triplaprograms/simpleSequence.tripla
Normal file
5
Project-02-03-04-05/triplaprograms/simpleSequence.tripla
Normal file
@@ -0,0 +1,5 @@
|
||||
let f(x) { x=2*x;
|
||||
if (x>0) then x=x-1 else x;
|
||||
while (x>0) do { x=x-1 }
|
||||
}
|
||||
in f(3)
|
||||
4
Project-02-03-04-05/triplaprograms/simple_dfa.tripla
Normal file
4
Project-02-03-04-05/triplaprograms/simple_dfa.tripla
Normal file
@@ -0,0 +1,4 @@
|
||||
let g(x, y) {
|
||||
y = 3;
|
||||
x
|
||||
} in g(2)
|
||||
1
Project-02-03-04-05/triplaprograms/simple_if.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/simple_if.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if (true) then 1 else 0
|
||||
1
Project-02-03-04-05/triplaprograms/simple_if_2.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/simple_if_2.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if (true && false) then 1 else 0
|
||||
1
Project-02-03-04-05/triplaprograms/simple_if_3.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/simple_if_3.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if (true || false) then 1 else 0
|
||||
1
Project-02-03-04-05/triplaprograms/simple_if_4.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/simple_if_4.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if (1 > 2) then 1 else 0
|
||||
1
Project-02-03-04-05/triplaprograms/simple_if_5.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/simple_if_5.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if (2 > 3 + 5) then 1 else 0
|
||||
1
Project-02-03-04-05/triplaprograms/simple_if_6.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/simple_if_6.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if (1 > 2 || 3 < 5) then 1 else 0
|
||||
1
Project-02-03-04-05/triplaprograms/simple_if_7.tripla
Normal file
1
Project-02-03-04-05/triplaprograms/simple_if_7.tripla
Normal file
@@ -0,0 +1 @@
|
||||
if (2 == 0 == false) then 1 else 0
|
||||
2
Project-02-03-04-05/triplaprograms/square.tripla
Normal file
2
Project-02-03-04-05/triplaprograms/square.tripla
Normal file
@@ -0,0 +1,2 @@
|
||||
let square(x) { x*x }
|
||||
in square(10)
|
||||
4
Project-02-03-04-05/triplaprograms/validProgram.tripla
Normal file
4
Project-02-03-04-05/triplaprograms/validProgram.tripla
Normal file
@@ -0,0 +1,4 @@
|
||||
let mult(a,b) { a*b }
|
||||
add(a,b) { let inc(a) { if (b!=0) then b=b-1;inc(a+1) else mult(a,1) }
|
||||
in inc(a) }
|
||||
in add(mult(2,3),add(4,5))
|
||||
7
Project-02-03-04-05/triplaprograms/while.tripla
Normal file
7
Project-02-03-04-05/triplaprograms/while.tripla
Normal file
@@ -0,0 +1,7 @@
|
||||
let func(a,b) {
|
||||
while ( a > 0 && b != a ) do {
|
||||
b = b + 1;
|
||||
a = a - 1
|
||||
}
|
||||
}
|
||||
in func(10, 8)
|
||||
3
Project-02-03-04-05/triplaprograms/while_2.tripla
Normal file
3
Project-02-03-04-05/triplaprograms/while_2.tripla
Normal file
@@ -0,0 +1,3 @@
|
||||
while (true) do {
|
||||
3
|
||||
}
|
||||
8
Project-02-03-04-05/triplaprograms/wrapped-ggT.tripla
Normal file
8
Project-02-03-04-05/triplaprograms/wrapped-ggT.tripla
Normal file
@@ -0,0 +1,8 @@
|
||||
let wrapper(a, b) {
|
||||
let ggt(noneSense) {
|
||||
if a == b then a
|
||||
else
|
||||
if a > b then wrapper(a-b, b)
|
||||
else wrapper(b-a, a)
|
||||
} in ggt(0)
|
||||
} in wrapper(21, 49)
|
||||
9
Project-02-03-04-05/triplaprograms/wrapper.tripla
Normal file
9
Project-02-03-04-05/triplaprograms/wrapper.tripla
Normal file
@@ -0,0 +1,9 @@
|
||||
let wrapper(number, threshold) {
|
||||
let square(x) {
|
||||
if x*x > threshold
|
||||
then x
|
||||
else x*x
|
||||
}
|
||||
in square(number)
|
||||
}
|
||||
in wrapper(4, 10)
|
||||
148
Project-02-03-04-05/triplayacc.py
Normal file
148
Project-02-03-04-05/triplayacc.py
Normal file
@@ -0,0 +1,148 @@
|
||||
# ------------------------------------------------------------
|
||||
# Grammar of the TRIPLA language
|
||||
# ------------------------------------------------------------
|
||||
|
||||
import ply.yacc as yacc
|
||||
import cfg_build as ast
|
||||
from triplalex import tokens
|
||||
|
||||
precedence = (
|
||||
('left', 'SEMICOLON'),
|
||||
('left', 'IN'),
|
||||
('left', 'ELSE'),
|
||||
('left', 'COMMA'),
|
||||
('right', 'ASSIGN'),
|
||||
('left', 'COMP'),
|
||||
('left', 'EQOP'),
|
||||
('left', 'AOP'),
|
||||
('left', 'COMP'),
|
||||
('left', 'EQOP'),
|
||||
|
||||
)
|
||||
|
||||
start = 'E'
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Rules for E
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def p_E_let(p):
|
||||
'E : LET D IN E'
|
||||
p[0] = ast.LET(p[2], p[4])
|
||||
|
||||
def p_E_id(p):
|
||||
'E : ID'
|
||||
p[0] = ast.ID(p[1])
|
||||
|
||||
def p_E_call(p):
|
||||
'E : ID LPAREN A RPAREN'
|
||||
# E : ID(A)
|
||||
p[0] = ast.CALL(p[1], p[3])
|
||||
|
||||
def p_E_aop(p):
|
||||
'E : E AOP E'
|
||||
p[0] = ast.AOP(p[2], p[1], p[3])
|
||||
|
||||
def p_E_paren(p):
|
||||
'E : LPAREN E RPAREN'
|
||||
# E : (E)
|
||||
p[0] = p[2]
|
||||
|
||||
def p_E_const(p):
|
||||
'E : CONST'
|
||||
p[0] = ast.CONST(p[1])
|
||||
|
||||
def p_E_assign(p):
|
||||
'E : ID ASSIGN E'
|
||||
p[0] = ast.ASSIGN(ast.ID(p[1]), p[3])
|
||||
|
||||
def p_E_seq(p):
|
||||
'E : E SEMICOLON E'
|
||||
p[0] = ast.SEQ(p[1], p[3])
|
||||
|
||||
def p_E_if(p):
|
||||
'E : IF B THEN E ELSE E'
|
||||
p[0] = ast.IF(p[2], p[4], p[6])
|
||||
|
||||
def p_E_while(p):
|
||||
'E : WHILE B DO LBRACE E RBRACE'
|
||||
p[0] = ast.WHILE(p[2], p[5])
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Rules for A
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def p_A_single(p):
|
||||
'A : E'
|
||||
p[0] = [p[1]]
|
||||
|
||||
def p_A_multiple(p):
|
||||
'A : A COMMA E'
|
||||
p[0] = p[1] + [p[3]]
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Rules for D
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def p_D_single(p):
|
||||
'D : ID LPAREN V RPAREN LBRACE E RBRACE'
|
||||
p[0] = [ast.DECL(p[1], p[3], p[6])]
|
||||
|
||||
def p_D_concat(p):
|
||||
'D : D D'
|
||||
p[0] = p[1] + p[2]
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Rules for V
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def p_V_single(p):
|
||||
'V : ID'
|
||||
p[0] = [p[1]]
|
||||
|
||||
def p_V_multiple(p):
|
||||
'V : V COMMA V'
|
||||
p[0] = p[1] + p[3]
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Rules for B
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def p_B_eqop_E(p):
|
||||
'B : E EQOP E'
|
||||
p[0] = ast.EQOP(p[2], p[1], p[3])
|
||||
|
||||
def p_B_comp(p):
|
||||
'B : E COMP E'
|
||||
p[0] = ast.COMP(p[2], p[1], p[3])
|
||||
|
||||
def p_B_eqop_B(p):
|
||||
'B : B EQOP B'
|
||||
p[0] = ast.EQOP(p[2], p[1], p[3])
|
||||
|
||||
def p_B_lop(p):
|
||||
'B : B LOP B'
|
||||
p[0] = ast.LOP(p[2], p[1], p[3])
|
||||
|
||||
def p_B_true(p):
|
||||
'B : TRUE'
|
||||
p[0] = ast.CONST(True)
|
||||
|
||||
def p_B_false(p):
|
||||
'B : FALSE'
|
||||
p[0] = ast.CONST(False)
|
||||
|
||||
def p_B_paren(p):
|
||||
'B : LPAREN B RPAREN'
|
||||
# B : (B)
|
||||
p[0] = p[2]
|
||||
|
||||
# Error handling
|
||||
def p_error(p):
|
||||
if p:
|
||||
print("Syntax error at token:", p.type, "value:", p.value)
|
||||
else:
|
||||
print("Syntax error at EOF")
|
||||
|
||||
parser = yacc.yacc()
|
||||
0
Project-02-03-04-05/vistram/__init__.py
Normal file
0
Project-02-03-04-05/vistram/__init__.py
Normal file
76
Project-02-03-04-05/vistram/assembler.py
Normal file
76
Project-02-03-04-05/vistram/assembler.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# (c) Stephan Diehl, University of Trier, Germany, 2025
|
||||
from . import tram
|
||||
|
||||
class Assembler:
|
||||
@staticmethod
|
||||
def read_tram_code(filename):
|
||||
code = []
|
||||
lines = []
|
||||
labelmap = {}
|
||||
linemap = {}
|
||||
|
||||
try:
|
||||
with open(filename, 'r', encoding='utf-8') as f:
|
||||
line_number = 0
|
||||
for raw_line in f:
|
||||
line = raw_line.strip()
|
||||
if line.startswith("//") or line.startswith("#") or not line:
|
||||
continue
|
||||
if ":" in line:
|
||||
labels_part = line[:line.index(':')]
|
||||
labels = [label.strip() for label in labels_part.split(',')]
|
||||
linemap[line_number] = labels
|
||||
for label in labels:
|
||||
labelmap[label] = tram.Label(line_number,label)
|
||||
line = line[line.index(':') + 1:].strip()
|
||||
lines.append(line)
|
||||
line_number += 1
|
||||
except IOError as e:
|
||||
print(f"Fehler beim Lesen der Datei: {e}")
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
labels = [labelmap.get(label,None) for label in linemap.get(i,[])]
|
||||
instr = Assembler.convert_to_instruction(line, labelmap, labels)
|
||||
code.append(instr)
|
||||
|
||||
return code
|
||||
|
||||
@staticmethod
|
||||
def convert_to_instruction(line, labelmap={}, labels=None):
|
||||
parts = line.split()
|
||||
instr =parts[0].upper()
|
||||
arg1 = Assembler.arg_to_number(parts, 1, labelmap)
|
||||
arg2 = Assembler.arg_to_number(parts, 2, labelmap)
|
||||
arg3 = Assembler.arg_to_number(parts, 3, labelmap)
|
||||
if instr == "CONST": code=tram.const(arg1,assigned_label=labels)
|
||||
elif instr == "LOAD": code=tram.load(arg1, arg2,assigned_label=labels)
|
||||
elif instr == "STORE": code=tram.store(arg1,arg2,assigned_label=labels)
|
||||
elif instr == "ADD": code=tram.add(assigned_label=labels)
|
||||
elif instr == "SUB": code=tram.sub(assigned_label=labels)
|
||||
elif instr == "MUL": code=tram.mul(assigned_label=labels)
|
||||
elif instr == "DIV": code=tram.div(assigned_label=labels)
|
||||
elif instr == "LT": code=tram.lt(assigned_label=labels)
|
||||
elif instr == "GT": code=tram.gt(assigned_label=labels)
|
||||
elif instr == "EQ": code=tram.eq(assigned_label=labels)
|
||||
elif instr == "NEQ": code=tram.neq(assigned_label=labels)
|
||||
elif instr == "IFZERO": code=tram.ifzero(arg1,assigned_label=labels)
|
||||
elif instr == "GOTO": code=tram.goto(arg1,assigned_label=labels)
|
||||
elif instr == "HALT": code=tram.halt(assigned_label=labels)
|
||||
elif instr == "NOP": code=tram.nop(assigned_label=labels)
|
||||
elif instr == "INVOKE": code=tram.invoke(arg1,arg2,arg3,assigned_label=labels)
|
||||
elif instr == "RETURN": code=tram.ireturn(assigned_label=labels)
|
||||
elif instr == "POP": code=tram.pop(assigned_label=labels)
|
||||
else:
|
||||
print(f"Keine gültige Instruktion: {line}")
|
||||
code = None
|
||||
return code
|
||||
|
||||
@staticmethod
|
||||
def arg_to_number(parts, index, labelmap):
|
||||
if index >= len(parts):
|
||||
return 0
|
||||
arg = parts[index]
|
||||
try:
|
||||
return int(arg)
|
||||
except ValueError:
|
||||
return labelmap.get(arg, 0)
|
||||
340
Project-02-03-04-05/vistram/tram.py
Normal file
340
Project-02-03-04-05/vistram/tram.py
Normal file
@@ -0,0 +1,340 @@
|
||||
# (c) Stephan Diehl, University of Trier, Germany, 2025
|
||||
|
||||
class TRAM:
|
||||
def __init__(self, prog):
|
||||
self.set_label_addresses(prog)
|
||||
self.program=prog+[halt()]
|
||||
self.print_prog(self.program)
|
||||
self.pc = 0
|
||||
self.stack = []
|
||||
self.top = -1
|
||||
self.pp = 0 #-1
|
||||
self.fp = 0 #-1
|
||||
|
||||
def start(self):
|
||||
while self.pc>=0:
|
||||
self.print_instruction(self.program[self.pc])
|
||||
self.program[self.pc].execute(self)
|
||||
print(self.stack)
|
||||
|
||||
def set_label_addresses(self,code):
|
||||
pos = 0
|
||||
for instr in code:
|
||||
for label in instr.assigned_labels:
|
||||
label.address = pos
|
||||
pos = pos + 1
|
||||
|
||||
def pop(self):
|
||||
del self.stack[self.top]
|
||||
self.top = self.top - 1
|
||||
|
||||
def push(self,v):
|
||||
self.stack.append(v)
|
||||
self.top = self.top + 1
|
||||
|
||||
def spp(self,d,pp,fp):
|
||||
if (d==0):
|
||||
return pp
|
||||
else:
|
||||
return self.spp(d-1,self.stack[self.fp+3],self.stack[self.fp+4])
|
||||
|
||||
def sfp(self, d, pp, fp):
|
||||
if (d==0):
|
||||
return fp
|
||||
else:
|
||||
return self.sfp(d-1, self.stack[self.fp+3], self.stack[self.fp+4])
|
||||
|
||||
def print_prog(self,prog):
|
||||
pos=0
|
||||
for instr in prog:
|
||||
print(str(pos)+": ",end="")
|
||||
pos=pos+1
|
||||
self.print_instruction(instr)
|
||||
|
||||
def print_instruction(self, instr):
|
||||
print(type(instr).__name__, end = "")
|
||||
for attr in vars(instr).keys():
|
||||
value=getattr(instr,attr)
|
||||
if isinstance(value,list): continue
|
||||
if isinstance(value,Label):
|
||||
value="#"+str(value.address)
|
||||
else:
|
||||
value=str(value)
|
||||
print(" "+value,end="")
|
||||
print()
|
||||
|
||||
#################
|
||||
|
||||
class Label:
|
||||
count=0
|
||||
address=-1
|
||||
|
||||
def __init__(self,address=-1,text=""):
|
||||
Label.count+=1
|
||||
self.id=Label.count
|
||||
self.address=address
|
||||
if text=="":
|
||||
self.text=f"L{Label.count}"
|
||||
else:
|
||||
self.text=text
|
||||
|
||||
def toString(self): return self.text
|
||||
|
||||
|
||||
##################
|
||||
|
||||
class Instruction:
|
||||
|
||||
def __init__(self,assigned_label=None):
|
||||
self.assigned_labels = []
|
||||
if not assigned_label is None:
|
||||
if isinstance(assigned_label,Label):
|
||||
self.assigned_labels+=[assigned_label]
|
||||
else:
|
||||
self.assigned_labels+=assigned_label
|
||||
|
||||
def toString(self):
|
||||
s=self.toStringx()
|
||||
#print(s)
|
||||
return(s)
|
||||
|
||||
def toStringx(self):
|
||||
if (len(self.assigned_labels)==0):
|
||||
return " "
|
||||
else:
|
||||
return ','.join( [ label.toString()
|
||||
for label in self.assigned_labels] )+": "
|
||||
|
||||
class halt(Instruction):
|
||||
def __init__(self,assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
tram.pc=-1
|
||||
|
||||
def toString(self): return super().toString()+"HALT"
|
||||
|
||||
class nop(Instruction):
|
||||
def __init__(self,assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString()+"NOP"
|
||||
|
||||
class pop(Instruction):
|
||||
def __init__(self,assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString()+"POP"
|
||||
|
||||
class const(Instruction):
|
||||
def __init__(self, k, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
self.k=k
|
||||
|
||||
def execute(self,tram):
|
||||
tram.push(self.k)
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString()+"CONST "+str(self.k)
|
||||
|
||||
class store(Instruction):
|
||||
def __init__(self, k, d, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
self.k = k
|
||||
self.d = d
|
||||
|
||||
|
||||
def execute(self,tram):
|
||||
tram.stack[tram.spp(self.d,tram.pp,tram.fp)+self.k]=tram.stack[tram.top]
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self):
|
||||
return super().toString()+"STORE "+str(self.k)+" "+str(self.d)
|
||||
|
||||
class load(Instruction):
|
||||
def __init__(self, k, d, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
self.k=k
|
||||
self.d=d
|
||||
|
||||
def execute(self,tram):
|
||||
tram.push(tram.stack[tram.spp(self.d,tram.pp,tram.fp)+self.k])
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self):
|
||||
return super().toString()+"LOAD "+str(self.k)+" "+str(self.d)
|
||||
|
||||
class add(Instruction):
|
||||
def __init__(self, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
tram.stack[tram.top-1]=tram.stack[tram.top-1]+tram.stack[tram.top]
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString()+"ADD"
|
||||
|
||||
|
||||
|
||||
class sub(Instruction):
|
||||
def __init__(self, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
tram.stack[tram.top-1]=tram.stack[tram.top-1]-tram.stack[tram.top]
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString() + "SUB"
|
||||
|
||||
class mul(Instruction):
|
||||
def __init__(self, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
tram.stack[tram.top-1]=tram.stack[tram.top-1]*tram.stack[tram.top]
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString() + "MUL"
|
||||
|
||||
class div(Instruction):
|
||||
def __init__(self, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
tram.stack[tram.top-1]=tram.stack[tram.top-1]/tram.stack[tram.top]
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString() + "DIV"
|
||||
|
||||
class lt(Instruction):
|
||||
def __init__(self, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
if tram.stack[tram.top-1]<tram.stack[tram.top]:
|
||||
tram.stack[tram.top-1]=1
|
||||
else:
|
||||
tram.stack[tram.top-1]=0
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString() + "LT"
|
||||
|
||||
class gt(Instruction):
|
||||
def __init__(self, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
if tram.stack[tram.top-1]>tram.stack[tram.top]:
|
||||
tram.stack[tram.top-1]=1
|
||||
else:
|
||||
tram.stack[tram.top-1]=0
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString() + "GT"
|
||||
|
||||
class eq(Instruction):
|
||||
def __init__(self, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
if tram.stack[tram.top-1]==tram.stack[tram.top]:
|
||||
tram.stack[tram.top-1]=1
|
||||
else:
|
||||
tram.stack[tram.top-1]=0
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString() + "EQ"
|
||||
|
||||
class neq(Instruction):
|
||||
def __init__(self, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
if tram.stack[tram.top-1]!=tram.stack[tram.top]:
|
||||
tram.stack[tram.top-1]=1
|
||||
else:
|
||||
tram.stack[tram.top-1]=0
|
||||
tram.pop()
|
||||
tram.pc=tram.pc+1
|
||||
|
||||
def toString(self): return super().toString() + "NEQ"
|
||||
|
||||
class goto(Instruction):
|
||||
def __init__(self, label, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
self.label=label
|
||||
|
||||
def execute(self,tram):
|
||||
tram.pc=self.label.address
|
||||
|
||||
def toString(self):
|
||||
return super().toString() + "GOTO "+self.label.toString()
|
||||
|
||||
class ifzero(Instruction):
|
||||
def __init__(self, label, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
self.label=label
|
||||
|
||||
def execute(self,tram):
|
||||
if tram.stack[tram.top]==0:
|
||||
tram.pc=self.label.address
|
||||
else:
|
||||
tram.pc=tram.pc+1
|
||||
tram.pop()
|
||||
|
||||
def toString(self):
|
||||
return super().toString() + "IFZERO "+self.label.toString()
|
||||
|
||||
class invoke(Instruction):
|
||||
def __init__(self,n,label,d, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
self.n=n
|
||||
self.label=label
|
||||
self.d=d
|
||||
|
||||
def execute(self,tram):
|
||||
tmp_top=tram.top
|
||||
tram.push(tram.pc+1)
|
||||
tram.push(tram.pp)
|
||||
tram.push(tram.fp)
|
||||
tram.push(tram.spp(self.d,tram.pp,tram.fp))
|
||||
tram.push(tram.sfp(self.d,tram.pp,tram.fp))
|
||||
tram.pp=tmp_top-self.n+1
|
||||
tram.fp=tmp_top+1
|
||||
tram.pc=self.label.address
|
||||
|
||||
def toString(self):
|
||||
return super().toString() \
|
||||
+ "INVOKE "+str(self.n)+" "+self.label.toString()+" "+str(self.d)
|
||||
|
||||
class ireturn(Instruction):
|
||||
def __init__(self, assigned_label=None):
|
||||
super().__init__(assigned_label=assigned_label)
|
||||
|
||||
def execute(self,tram):
|
||||
res=tram.stack[tram.top]
|
||||
tram.top=tram.pp
|
||||
tram.pc=tram.stack[tram.fp]
|
||||
tram.pp=tram.stack[tram.fp+1]
|
||||
tram.fp=tram.stack[tram.fp+2]
|
||||
del tram.stack[tram.top:]
|
||||
tram.top=tram.top-1
|
||||
tram.push(res)
|
||||
|
||||
def toString(self): return super().toString() + "RETURN"
|
||||
|
||||
220
Project-02-03-04-05/vistram/vistram.py
Normal file
220
Project-02-03-04-05/vistram/vistram.py
Normal file
@@ -0,0 +1,220 @@
|
||||
# (c) Stephan Diehl, University of Trier, Germany, 2025
|
||||
|
||||
import tkinter as tk
|
||||
from copy import deepcopy
|
||||
from tkinter import ttk
|
||||
from tkinter import filedialog
|
||||
import os
|
||||
|
||||
from .assembler import *
|
||||
from .tram import *
|
||||
|
||||
import inspect
|
||||
import re
|
||||
|
||||
"""
|
||||
test_prog1=[const(1), const(2), const(5), store(1, 0), load(1, 0), add(), halt()]
|
||||
|
||||
L4=Label(4)
|
||||
L7=Label(7)
|
||||
L15=Label(15)
|
||||
test_prog2=[const(4),
|
||||
const(10),
|
||||
invoke(2,L4,0),
|
||||
halt(),
|
||||
load(0,0,assigned_label=L4),
|
||||
invoke(1,L7,0),
|
||||
ireturn(),
|
||||
load(0,0,assigned_label=L7),
|
||||
load(0,0),
|
||||
mul(),
|
||||
load(1,1),
|
||||
gt(),
|
||||
ifzero(L15),
|
||||
load(0,0),
|
||||
ireturn(),
|
||||
load(0,0,assigned_label=L15),
|
||||
load(0,0),
|
||||
mul(),
|
||||
ireturn()]
|
||||
"""
|
||||
|
||||
class AbstractMachine(TRAM):
|
||||
def __init__(self):
|
||||
self.initial_program = [] #Assembler.read_tram_code("examples/tramprograms/test.tram")
|
||||
#self.initial_program = test_prog2
|
||||
print(self.initial_program)
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
super().__init__(self.initial_program)
|
||||
self.program_text = [f"{instr.toString()}" for i, instr in enumerate(self.program)]
|
||||
self.running = False
|
||||
|
||||
def step(self):
|
||||
if self.pc >= len(self.program):
|
||||
self.running = False
|
||||
return ("Error: End of program store reached!", None)
|
||||
|
||||
if self.pc == -1:
|
||||
self.running = False
|
||||
return ("The program terminated normally!", None)
|
||||
|
||||
instr=self.program[self.pc]
|
||||
self.print_instruction(instr)
|
||||
instr.execute(self)
|
||||
|
||||
return (f"Ausgeführt: {instr.toString()}", instr)
|
||||
|
||||
class MachineUI:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.machine = AbstractMachine()
|
||||
self.previous_state = None
|
||||
self.minimal_vis = False
|
||||
self.current_instruction = None
|
||||
|
||||
root.title("Visual TRAM")
|
||||
|
||||
# Frames
|
||||
control_frame = ttk.Frame(root)
|
||||
control_frame.pack(pady=10)
|
||||
|
||||
display_frame = ttk.Frame(root)
|
||||
display_frame.pack(padx=10, pady=5, fill="both", expand=True)
|
||||
|
||||
# Buttons
|
||||
ttk.Button(control_frame, text="Start", command=self.start).grid(row=0, column=0, padx=5)
|
||||
ttk.Button(control_frame, text="Stop", command=self.stop).grid(row=0, column=1, padx=5)
|
||||
ttk.Button(control_frame, text="Step", command=self.step).grid(row=0, column=2, padx=5)
|
||||
ttk.Button(control_frame, text="Reset", command=self.reset).grid(row=0, column=3, padx=5)
|
||||
button = ttk.Button(control_frame, text="Open File", command=self.open_file).grid(row=0, column=4, padx=5)
|
||||
|
||||
# Add a label to show the selected file
|
||||
self.label = ttk.Label(root, text="No file selected.", wraplength=800, justify="center")
|
||||
self.label.pack(pady=20)
|
||||
|
||||
# Add a button to open the file browser
|
||||
#button = ttk.Button(root, text="Open File", command=self.open_file)
|
||||
#button.pack(pady=10)
|
||||
|
||||
# Textfelder
|
||||
self.code_text = tk.Text(display_frame, width=35, height=32, wrap="none", bg="#f8f8f8")
|
||||
self.code_text.pack(side="left", padx=10, pady=10, fill="both", expand=True)
|
||||
self.code_text.tag_configure('highlight', background='#AAFFAA')
|
||||
|
||||
self.prev_state_text = tk.Text(display_frame, width=35, height=32, wrap="none", bg="#f0f8ff")
|
||||
self.prev_state_text.pack(side="left", padx=10, pady=10, fill="both", expand=True)
|
||||
|
||||
self.state_text = tk.Text(display_frame, width=35, height=32, wrap="none", bg="#f0f8ff")
|
||||
self.state_text.pack(side="left", padx=10, pady=10, fill="both", expand=True)
|
||||
|
||||
self.instr_text = tk.Text(display_frame, width=70, height=32, wrap="none", bg="#f0f8ff")
|
||||
self.instr_text.pack(side="right", padx=10, pady=10, fill="both", expand=True)
|
||||
|
||||
self.state_text.tag_configure('blue', background='#AAAAFF')
|
||||
self.prev_state_text.tag_configure('blue', background='#AAAAFF')
|
||||
|
||||
self.update_display()
|
||||
|
||||
def update_display(self):
|
||||
# Programmkode anzeigen
|
||||
self.code_text.delete("1.0", tk.END)
|
||||
for i, line in enumerate(self.machine.program_text):
|
||||
if i == self.machine.pc:
|
||||
prefix = "-> "
|
||||
self.code_text.insert(tk.END, f"{prefix}{i:02d}: {line}\n",'highlight')
|
||||
else:
|
||||
self.code_text.insert(tk.END, f" {i:02d}: {line}\n")
|
||||
|
||||
# Maschinenzustand anzeigen
|
||||
self.update_state_display(self.machine, self.state_text)
|
||||
if self.previous_state!=None:
|
||||
self.update_state_display(self.previous_state, self.prev_state_text)
|
||||
else:
|
||||
self.prev_state_text.delete("1.0", tk.END)
|
||||
self.previous_state = deepcopy(self.machine)
|
||||
|
||||
# Aktuell ausgeführte Instruktion anzeigen
|
||||
if self.current_instruction != None:
|
||||
(msg,instr) = self.current_instruction
|
||||
self.instr_text.delete("1.0", tk.END)
|
||||
self.instr_text.insert(tk.END, f"\n{msg}\n\n")
|
||||
if instr!=None:
|
||||
source_text= inspect.getsource(instr.execute)
|
||||
source_text=source_text.replace("tram.","")
|
||||
rest = source_text.split('\n', 1)[1] if '\n' in source_text else source_text
|
||||
source_text = '\n'.join(line.lstrip() for line in rest.splitlines())
|
||||
self.instr_text.insert(tk.END, source_text)
|
||||
else:
|
||||
self.instr_text.delete("1.0", tk.END)
|
||||
|
||||
|
||||
def update_state_display(self, machine, tk_text):
|
||||
tk_text.delete("1.0", tk.END)
|
||||
tk_text.insert(tk.END, f"PC : {machine.pc}\n")
|
||||
tk_text.insert(tk.END, f"FP : {machine.fp}\n")
|
||||
tk_text.insert(tk.END, f"PP : {machine.pp}\n")
|
||||
tk_text.insert(tk.END, f"TOP: {machine.top}\n\n")
|
||||
if (self.minimal_vis == True):
|
||||
tk_text.insert(tk.END, f"Stack: {machine.stack}\n")
|
||||
else:
|
||||
for i, value in enumerate(machine.stack):
|
||||
suffix = " "
|
||||
if i == machine.top: suffix += "<-TOP "
|
||||
if i == machine.pp: suffix += "<-PP "
|
||||
if i == machine.fp: suffix += "<-FP "
|
||||
if i == machine.fp + 4: suffix += "<-end of frame "
|
||||
if i >= machine.pp and i < machine.fp + 5:
|
||||
tk_text.insert(tk.END, f"{i:02d}: {value}{suffix}\n", 'blue')
|
||||
else:
|
||||
tk_text.insert(tk.END, f"{i:02d}: {value}{suffix}\n")
|
||||
def start(self):
|
||||
self.machine.running = True
|
||||
self.run_next()
|
||||
|
||||
def stop(self):
|
||||
self.machine.running = False
|
||||
|
||||
def step(self):
|
||||
self.current_instruction = self.machine.step()
|
||||
self.update_display()
|
||||
|
||||
|
||||
def run_next(self):
|
||||
if self.machine.running:
|
||||
self.step()
|
||||
#msg = self.machine.step()
|
||||
#self.update_display()
|
||||
#if msg:
|
||||
# self.state_text.insert(tk.END, f"\n{msg}\n")
|
||||
if self.machine.running:
|
||||
self.root.after(500, self.run_next) # Automatische Ausführung
|
||||
|
||||
def reset(self):
|
||||
self.machine.reset()
|
||||
self.previous_state=None
|
||||
self.current_instruction=None
|
||||
self.update_display()
|
||||
|
||||
def open_file(self):
|
||||
# Define the starting directory
|
||||
start_dir = os.path.expanduser("examples/tramprograms")
|
||||
|
||||
# Open the file browser starting in start_dir
|
||||
filename = filedialog.askopenfilename(
|
||||
initialdir=start_dir,
|
||||
title="Select a File",
|
||||
filetypes=(("TRAM files", "*.tram"), ("All files", "*.*"))
|
||||
)
|
||||
|
||||
# Display the selected file path in the label
|
||||
if filename:
|
||||
self.label.config(text=f"Selected file:\n{filename}")
|
||||
self.machine.initial_program = Assembler.read_tram_code(filename) #examples/tramprograms/test.tram")
|
||||
self.reset()
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = tk.Tk()
|
||||
app = MachineUI(root)
|
||||
root.mainloop()
|
||||
Reference in New Issue
Block a user