Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
UchihaIthachi committed Apr 29, 2024
1 parent 433f513 commit 5c88f4a
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 49 deletions.
Binary file added .coverage
Binary file not shown.
28 changes: 28 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# - `make test_st F=...`: Executes a specific test case related to ST. (in rpal_tests/rpal_sources)
# - `make clean`: Cleans up generated files.
# - `make all`: Installs dependencies, runs the RPAL interpreter, runs tests, and cleans up.
# - `make converge`: run all pytest, runs the RPAL interpreter
# - `make converg_report`: get converg report in html format

############################################################################################################
# define variables for the RPAL interpreter
Expand Down Expand Up @@ -203,7 +205,33 @@ requirements.txt:
# end of makefile for the RPAL interpreter
############################################################################################################

############################################################################################################
# coverage check for the RPAL interpreter
############################################################################################################

coverage:
@echo "Running tests..."
$(PYTHON) -m coverage run -m pytest
@echo "Generating HTML coverage report..."
$(PYTHON) -m coverage html

coverage_report:
@echo "Generating HTML coverage report..."
$(PYTHON) -m coverage html
@echo "Opening HTML coverage report..."
@if [ "$(OS)" = "Windows_NT" ] ; then \
cmd /c start htmlcov/index.html ; \
@echo "Generating coverage report...";\
$(PYTHON) -m coverage html;\
else \
xdg-open htmlcov/index.html; \
fi

############################################################################################################

############################################################################################################

############################################################################################################



Expand Down
Binary file added docs/cse_machine_rules.pdf
Binary file not shown.
2 changes: 1 addition & 1 deletion myrpal.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def main():
# Check if there are enough command-line arguments
if len(sys.argv) < 2:
print("[Version 1.0 by Malindu & Harshana 4/12/2024]")
print("\nUsage: python main.py [-ast] [-t] [-ft] [-st] [-r] [-rast] [-ct] [-l] [-noout] file_name ")
print("Usage: python main.py [-ast] [-t] [-ft] [-st] [-r] [-rast] [-ct] [-l] [-noout] file_name ")
return

# Get the filename from the command-line arguments
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pytest==8.1.1
pytest-timeout
coverage

Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def apply_binary(cse_machine, rator, rand, binop):
ValueError
If the binary operator is not recognized.
"""

# Dictionary mapping binary operators to their corresponding functions
binary_operators = {
"aug" : lambda cse_machine, rator, rand : apply_aug(cse_machine, rator, rand),
Expand Down Expand Up @@ -86,6 +87,7 @@ def apply_aug(cse_machine, rator, rand):
ValueError
If the binary operator is not recognized.
"""

if rator.type == "nil" :
return ControlStructureElement("tuple", [rand])
elif rand.type == "nil":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
# This module can be imported and used to apply uninary operations to operands in the CSE machine.

from src.utils.control_structure_element import ControlStructureElement
def apply_unary(cse_machine, rator_e, unop):

def apply_unary(cse_machine, rator, unop):
"""
Apply a unary operation to an operand.
Expand All @@ -22,7 +23,10 @@ def apply_unary(cse_machine, rator_e, unop):
Raises:
ValueError: If the unary operation is not recognized.
"""
rator = rator_e.value

# Extract the operator from the RatorExpr
rator_value = rator.value

# Dictionary mapping binary operators to their corresponding functions
unary_operators = {
"Print" : lambda cse_machine, operand: apply_print(cse_machine, operand),
Expand All @@ -39,11 +43,13 @@ def apply_unary(cse_machine, rator_e, unop):
"neg" : lambda cse_machine, operand: -operand.value if isinstance(operand.value, int) else cse_machine._error_handler.handle_error("CSE : Invalid unary operation"),
"not" : lambda cse_machine, operand: not operand.value if isinstance(operand.value, bool) else cse_machine._error_handler.handle_error("CSE : Invalid unary operation"),
}

# Get the operation function corresponding to the binary operator
operation_function = unary_operators.get(unop)

if operation_function:
# Apply the operation function with the provided operands
return operation_function(cse_machine, rator_e)
return operation_function(cse_machine, rator)
else:
# If the binary operator is not recognized, raise an error
raise ValueError("Invalid binary operation: " + unop)
Expand All @@ -61,7 +67,9 @@ def apply_print(cse_machine, operand):
Expr: A dummy value.
"""

element = operand.value

# Define the covertToString function
def covert_to_string(element):
if isinstance(element, list):
Expand Down Expand Up @@ -97,8 +105,9 @@ def convert_list(element,out):
else:
out += covert_to_string(element.value) + ", "
return out

# convert the element to a string
cse_machine._outputs.append(covert_to_string(element).replace("\\n", "\n").replace("\\t", "\t"))
cse_machine._print_queue.append(covert_to_string(element).replace("\\n", "\n").replace("\\t", "\t"))

# Return a dummy value
return "dummy"
Expand All @@ -119,6 +128,7 @@ def apply_order(cse_machine, operand):
Raises:
ValueError: If the operand is not a string.
"""

if isinstance(operand.value, list):
return len(operand.value)
elif operand.type == "nil":
Expand All @@ -141,11 +151,13 @@ def apply_stern(cse_machine, operand):
Raises:
ValueError: If the operand is not a string or is empty.
"""

if isinstance(operand, str) and len(operand) >= 1:
return operand[1:]
else:
cse_machine._error_handler.handle_error("CSE : Invalid unary operation")

# Function to apply the Stem unary operator
def apply_stem(cse_machine, operand):
"""
Apply the Stem unary operation to an operand.
Expand All @@ -160,7 +172,9 @@ def apply_stem(cse_machine, operand):
Raises:
ValueError: If the operand is not a string or is empty.
"""

if isinstance(operand, str) and len(operand) >= 1:
return operand[0]
else:
cse_machine._error_handler.handle_error("CSE : Invalid unary operation")
cse_machine._error_handler.handle_error("CSE : Invalid unary operation")

2 changes: 1 addition & 1 deletion src/cse_machine/data_structures/enviroment.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def _initialize_initial_vars(self):
"""
Initialize initial variables.
"""
initial_vars = {var: None for var in self.INITIAL_VARIABLES}
initial_vars = {var: ["inbuilt-functions",None] for var in self.INITIAL_VARIABLES}
self._environment.update(initial_vars)

def add_var(self, name, type, value):
Expand Down
85 changes: 51 additions & 34 deletions src/cse_machine/machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
from src.cse_machine.data_structures.stack import Stack
from src.cse_machine.utils.STlinearizer import Linearizer
from src.cse_machine.utils.util import add_table_data, print_cse_table , var_lookup , raw , add_table_data_decorator
from src.cse_machine.apply_operations.apply_bin import apply_binary
from src.cse_machine.apply_operations.apply_un import apply_unary
from src.cse_machine.apply_operations.apply_binary_operations import apply_binary
from src.cse_machine.apply_operations.apply_unary_operations import apply_unary
from src.utils.control_structure_element import ControlStructureElement

class CSEMachine:
Expand All @@ -43,13 +43,13 @@ class CSEMachine:
_error_handler (CseErrorHandler): Error handler instance for managing errors during execution.
control_structures (list): List of control structures extracted from the Standardized Tree (ST).
environment_tree (Environment): Environment tree representing the current execution environment.
current_env (Environment): Reference to the current environment in the environment tree.
current_enviroment (Environment): Reference to the current environment in the environment tree.
stack (Stack): Stack for managing the execution stack.
control (Stack): Stack for managing the control structures during execution.
_linearizer (Linearizer): Linearizer instance for converting the ST to linear form.
binary_operator (set): Set of binary operators supported by the RPAL language.
unary_operators (set): Set of unary operators supported by the RPAL language.
_outputs (list): List to store the output generated during execution.
_print_queue (list): List to store the print data as queue generated during execution.
table_data (list): List to store data for generating the execution table.
"""

Expand All @@ -68,12 +68,12 @@ def __init__(self):

# Initialize the control structures, environment, and stacks
self.control_structures = None
self.current_env = self.primitive_environment
self.current_enviroment = self.primitive_environment
self.stack = Stack()
self.control = Stack()

# Initialize the output and table data
self._outputs = list()
# Initialize print queue and table data
self._print_queue = list()
self.table_data = list()

# binary operators supported by RPAL and inbuilt functions(Conc)
Expand Down Expand Up @@ -103,17 +103,30 @@ def __init__(self):
# String manipulation inbuilt functions
"Order", "Stern", "Stem", "ItoS", "$ConcPartial"
}

# inbuilt functions support by RPAL

self.inbuilt_functions = {
# print inbuilt functions
"Print",
# type checking inbuilt functions
"Isstring", "Isinteger", "Istruthvalue", "Isfunction", "Null","Istuple",
# String manipulation inbuilt functions
"Order", "Stern", "Stem", "ItoS", "$ConcPartial"
}
def initialize(self):
"""
Initialize the CSEMachine with necessary components.
:return: None
"""
# Push an environment marker onto the stack and control structures
env_marker = ControlStructureElement("env_marker", "env_marker", None, None, self.current_env)
self.stack.push(env_marker)
self.control.push(env_marker)

# Create the primitive environment as element
primitive_enviroment = ControlStructureElement("env_marker", "env_marker", None, None, self.current_enviroment)

# Push the primitive environment onto both the stack and control stack
self.stack.push(primitive_enviroment)
self.control.push(primitive_enviroment)

# Push elements from the first control structure onto the control stack
if self.control_structures:
Expand Down Expand Up @@ -206,7 +219,7 @@ def CSErule2(self):
push it onto the stack. Set the environment of the lambda expression to the current environment.
"""
lambda_ = self.control.pop()
lambda_.env = self.current_env
lambda_.env = self.current_enviroment
self.stack.push(lambda_)

@add_table_data_decorator("3")
Expand All @@ -219,30 +232,34 @@ def CSErule4(self):
CSE rule 4: If the top of the control stack is a lambda expression,
push it onto the stack. Set the environment of the lambda expression to the current environment.
"""
if self.current_env.index >= 2000:

# for avoiding infinite loop
if self.current_enviroment.index >= 2000:
self._error_handler.handle_error("CSE : Environment limit exceeded")
return

self.control.pop()
lambda_ = self.stack.pop()
rand = self.stack.pop()
new_env = Environment()
new_enviroment = Environment()
if rand.type == "eta" or rand.type == "lambda":
new_env.add_var(lambda_.bounded_variable[0],rand.type,rand)
new_enviroment.add_var(lambda_.bounded_variable[0],rand.type,rand)
elif rand.type in ["tuple","INT","bool","STR","nil"]:
new_env.add_var(lambda_.bounded_variable[0],rand.type,rand.value)
new_enviroment.add_var(lambda_.bounded_variable[0],rand.type,rand.value)
else:
self._error_handler.handle_error("CSE : Invalid type")
new_env.parent = lambda_.env
new_enviroment.parent = lambda_.env

self.current_env = new_env
self.current_enviroment = new_enviroment

env_marker = ControlStructureElement("env_marker","env_marker",None,None,new_env)
new_enviroment_element = ControlStructureElement("env_marker","env_marker",None,None,new_enviroment)

self.control.push(env_marker)
self.control.push(new_enviroment_element)

for element in self.control_structures[lambda_.control_structure].elements:
self.control.push(element)

self.stack.push(env_marker)
self.stack.push(new_enviroment_element)

@add_table_data_decorator("5")
def CSErule5(self):
Expand Down Expand Up @@ -270,7 +287,7 @@ def CSErule5(self):
self.stack.push(value)
for element in reversed(self.stack.whole_stack()):
if element.type == "env_marker":
self.current_env = element.env
self.current_enviroment = element.env
break
else:
self._error_handler.handle_error("CSE : Invalid environment")
Expand All @@ -297,14 +314,13 @@ def CSErule6(self):
if rator.type == "STR" and rand.type == "STR":
result =self._apply_binary(rator.value,rand.value,binop)
self.stack.push(ControlStructureElement("STR",result))
while self.control.peek().type == "gamma":
self.control.pop()
self.remove_gamma()
self.remove_gamma()
elif rator.type == "STR":
rator.type = "ConcPartial"
self.stack.push(rand)
self.stack.push(rator)
while self.control.peek().type == "gamma":
self.control.pop()
self.remove_gamma()
else:
self._error_handler.handle_error("CSE : Invalid type for concatenation")
else:
Expand Down Expand Up @@ -338,8 +354,8 @@ def CSErule7(self):
res_type = "STR"
else :
res_type = "INT"
while self.control.peek().type == "gamma":
self.control.pop()
if unop in self.inbuilt_functions:
self.remove_gamma()
self.stack.push(ControlStructureElement(res_type,result))

@add_table_data_decorator("8")
Expand Down Expand Up @@ -432,7 +448,7 @@ def CSErule11(self):
new_env.add_var(var_list[i],rand.value[i].type,rand.value[i].value)

new_env.parent = c
self.current_env = new_env
self.current_enviroment = new_env
env_marker = ControlStructureElement("env_marker","env_marker",None,None,new_env)
self.stack.push(env_marker)
self.control.push(env_marker)
Expand Down Expand Up @@ -472,8 +488,7 @@ def Concpartial(self):
if rand.type == "STR":
result = self._apply_binary(rator.value,rand.value,"Conc")
self.stack.push(ControlStructureElement("STR",result))
while self.control.peek().type == "gamma":
self.control.pop()
self.remove_gamma()
else:
self._error_handler.handle_error("CSE : Invalid type for concatenation")

Expand All @@ -482,8 +497,6 @@ def Concpartial(self):
# helper functions
##############################################################################################################

def _var_lookup(self , var_name):
return var_lookup(self, var_name)
def _var_lookup(self , var_name):
return var_lookup(self, var_name)

Expand All @@ -501,10 +514,14 @@ def _print_cse_table(self):
print_cse_table(self)

def _generate_output(self):
return "".join(self._outputs)+"\n"
return "".join(self._print_queue)+"\n"

def _generate_raw_output(self):
return raw(self._generate_output())

def remove_gamma(self):
if self.control.peek().type == "gamma":
self.control.pop()



Loading

0 comments on commit 5c88f4a

Please sign in to comment.