Skip to content

Instantly share code, notes, and snippets.

@Abdisalan
Created January 14, 2023 01:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Abdisalan/55a1c8ce11a70c43d1e12bf0a57f9383 to your computer and use it in GitHub Desktop.
Save Abdisalan/55a1c8ce11a70c43d1e12bf0a57f9383 to your computer and use it in GitHub Desktop.
Primitive language that works as a calculator
"""
input: a variable name and a list of expressions
output: the value of the variable
eg:
T1
T3 = 5
T1 = T2 + T4
T2 = 9
T4 = T2 - T3
expected output of T1 is 13
considerations
var assignment
number assignment
addition
subtraction
variables can be hoisted (used before their values are known)
"""
class Token:
def __init__(self, type_, value):
self.type = type_
self.value = value
class Operation:
def __init__(self, operator, l_token, r_token):
self.operator = operator
self.l_token = l_token
self.r_token = r_token
class Lexer:
def tokenizeOperation(self, operation, operator):
l_value, r_value = operation.split(operator)
l_token = self.tokenizeValue(l_value)
r_token = self.tokenizeValue(r_value)
return Token('operation', Operation(operator, l_token, r_token))
def tokenizeValue(self, value):
value = value.strip()
if value.isnumeric():
return Token('number', int(value.strip()))
else:
return Token('var', value)
def tokenizeExpression(self, expression):
destination, source = expression.split("=")
destination = destination.strip()
if '-' in source:
tokenized_source = self.tokenizeOperation(source, '-')
elif '+' in source:
tokenized_source = self.tokenizeOperation(source, '+')
else:
tokenized_source = self.tokenizeValue(source)
return destination, tokenized_source
class Calculator:
def __init__(self):
self.registry = {}
self.lexer = Lexer()
def applyExpression(self, expression):
dest, src = self.lexer.tokenizeExpression(expression)
self.registry[dest] = src
def getValue(self, var):
return self.__resolveToken(Token('var', var))
def __resolveOperation(self, operation):
l_value = self.__resolveToken(operation.l_token)
r_value = self.__resolveToken(operation.r_token)
if operation.operator == '-':
return l_value - r_value
elif operation.operator == '+':
return l_value + r_value
def __resolveToken(self, token):
while not isinstance(token, int):
if token.type == 'number':
token = token.value
elif token.type == 'var':
token = self.registry[token.value]
elif token.type == 'operation':
token = self.__resolveOperation(token.value)
return token
"""
Tests
"""
c = Calculator()
for exp in ["T3 = T2", "T2 = T1", "T1 = 2"]:
c.applyExpression(exp)
assert(2 == c.getValue("T3"))
c = Calculator()
for exp in ["T4 = T2", "T2 = T1", "T1 = T3", "T1 = 2", "T3 = 5"]:
c.applyExpression(exp)
assert(2 == c.getValue("T4"))
c = Calculator()
for exp in ["T4 = T2", "T2 = T1 + T3", "T1 = 2 + 2", "T3 = 5"]:
c.applyExpression(exp)
assert(9 == c.getValue("T4"))
c = Calculator()
for exp in ["T3 = 5", "T1 = T2 + T4", "T2 = 9", "T4 = T2 - T3"]:
c.applyExpression(exp)
assert(13 == c.getValue("T1"))
c = Calculator()
for exp in ["T9 = T7 - T1", "T2 = 1 - 1", "T1 = T3 + 9", "T3 = 5", "T4 = T3 + T3", "T5 = 2 - T4", "T7 = 10 + T5"]:
c.applyExpression(exp)
assert(-12 == c.getValue("T9"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment