Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 21 additions & 21 deletions basicparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ def __factor(self):
else:
#default int
self.__operand_stack.append(0)

self.__advance()

elif self.__token.category == Token.LEFTPAREN:
Expand Down Expand Up @@ -1106,33 +1106,33 @@ def __get_array_val(self, BASICarray, indexvars):

def __validate_array_indices(self, BASICarray, indexvars):
"""Validates array indices and raises SUBSCRIPT ERROR if invalid

:param BASICarray: The BASICArray to validate against
:param indexvars: List of index values to validate
:raises RuntimeError: If indices are out of bounds
"""
if BASICarray.dims != len(indexvars):
raise RuntimeError('SUBSCRIPT ERROR in line ' + str(self.__line_number))

for i, index in enumerate(indexvars):
# Convert float to int (truncate toward zero)
if isinstance(index, float):
index = int(index)
indexvars[i] = index

# Check bounds - negative or greater than declared dimension
if index < 0 or index > BASICarray.original_dims[i]:
raise RuntimeError('SUBSCRIPT ERROR in line ' + str(self.__line_number))

def __assign_array_val(self, BASICarray, indexvars, value):
"""Assigns a value to an array element after validating indices

:param BASICarray: The BASICArray
:param indexvars: List of indices
:param value: Value to assign
"""
self.__validate_array_indices(BASICarray, indexvars)

try:
if len(indexvars) == 1:
BASICarray.data[indexvars[0]] = value
Expand All @@ -1145,40 +1145,40 @@ def __assign_array_val(self, BASICarray, indexvars, value):

def __parse_variable_target(self):
"""Parses a variable target which can be a simple variable or array element

:return: Dictionary with 'type' ('simple' or 'array'), 'name' (variable name),
'indices' (list of index values for arrays), 'is_string' (boolean)
"""
if self.__token.category != Token.NAME:
raise SyntaxError('Expecting variable name in line ' + str(self.__line_number))

var_name = self.__token.lexeme
is_string = var_name.endswith('$')
self.__advance()

# Check if this is an array element
if self.__token.category == Token.LEFTPAREN:
# Array element target
array_name = var_name + '_array'

# Check if array exists
if array_name not in self.__symbol_table:
raise RuntimeError('Array not dimensioned in line ' + str(self.__line_number))

self.__advance() # Past LEFTPAREN

# Parse index expressions
indexvars = []
self.__expr()
indexvars.append(self.__operand_stack.pop())

while self.__token.category == Token.COMMA:
self.__advance() # Past comma
self.__expr()
indexvars.append(self.__operand_stack.pop())

self.__consume(Token.RIGHTPAREN)

return {
'type': 'array',
'name': var_name,
Expand All @@ -1193,21 +1193,21 @@ def __parse_variable_target(self):
'name': var_name,
'is_string': is_string
}

def __assign_to_target(self, target, value):
"""Assigns a value to a target (simple variable or array element)

:param target: Target dictionary from __parse_variable_target
:param value: Value to assign
"""
# Type checking
if target['is_string'] and not isinstance(value, str):
raise ValueError('Non-string input provided to a string variable in line ' +
raise ValueError('Non-string input provided to a string variable in line ' +
str(self.__line_number))
elif not target['is_string'] and isinstance(value, str):
raise ValueError('Non-numeric input provided to a numeric variable in line ' +
raise ValueError('Non-numeric input provided to a numeric variable in line ' +
str(self.__line_number))

if target['type'] == 'simple':
self.__symbol_table[target['name']] = value
else: # array
Expand Down
12 changes: 6 additions & 6 deletions interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
def main():

banner = (r"""
._____________ ___________. ___ ___________ ______
._____________ ___________. ___ ___________ ______
| _ .__ \ / ___ _ \ / \ / | / |
| |_) | \ \/ / | |_) | / ^ \ | (----`| | | ,----'
| ___/ \_ _/ | _ < / /_\ \ \ \ | | | |
| ___/ \_ _/ | _ < / /_\ \ \ \ | | | |
| | | | | |_) \/ _____ \----) | | | | `----.
| _| |__| |___________/ \_________/ |____________|
""")
Expand Down Expand Up @@ -127,7 +127,7 @@ def main():
# Parse comma-separated arguments, handling blank parameters
args = []
current_arg = ""

for i in range(1, len(tokenlist)):
if tokenlist[i].category == Token.COMMA:
# Process the accumulated argument
Expand All @@ -138,20 +138,20 @@ def main():
current_arg = ""
elif tokenlist[i].category == Token.UNSIGNEDINT:
current_arg += tokenlist[i].lexeme

# Process the final argument if any
if current_arg.strip():
args.append(int(current_arg.strip()))
elif len(tokenlist) > 1 and tokenlist[-1].category == Token.COMMA:
args.append(None) # Trailing comma means blank parameter

# Convert args list to proper parameters for renumber()
# RENUMBER [newStart][,increment][,oldStart][,oldEnd]
new_start = args[0] if len(args) > 0 and args[0] is not None else 10
increment = args[1] if len(args) > 1 and args[1] is not None else 10
old_start = args[2] if len(args) > 2 and args[2] is not None else None
old_end = args[3] if len(args) > 3 and args[3] is not None else None

program.renumber(new_start, increment, old_start, old_end)
print("Program renumbered")
except Exception as e:
Expand Down
2 changes: 1 addition & 1 deletion lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,4 @@ def __get_next_char(self):

if __name__ == "__main__":
import doctest
doctest.testmod()
doctest.testmod()
Loading