Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
LeviPesin authored Oct 15, 2020
1 parent 84281bd commit 6805bb2
Show file tree
Hide file tree
Showing 3 changed files with 267 additions and 121 deletions.
152 changes: 152 additions & 0 deletions s1_compiler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
class Function:
def __init__(self, name):
self.name = name
self.uncompiledPars = [];
self.uncompiledCode = []
self.code = dict()
self.variables = dict()

class Variable:
def __init__(self, name, func, reg):
self.name = name
self.function = func
self.register = reg

class Compiler:
'''Operations of Madhine:
1) MovOp - copy value from source to target.
2) ClearOp - assign empty set to target.
3) AddOp - add element to target set.
4) BinOp - make operation (+, *, - or ~) with arg1 and arg2 and assign result to res.
5) JumpOp - if test is empty, jump to one state, else to another.
6) DeconstructOp - if test is empty, jump to one state. Else select one element, assign it to element,
assign rest of test to rest, jump to another state.
7) AssertOp - raise error if test is empty.
8) CallOp - call function.
9) ReturnOp - return to return_state, specified by CallOp.'''
def __init__(self, parser):
self.tree = parser.parse()
self.code = dict()
main = Function("main")
self.functions = {"main": main}
self.next_var_register = 0
self.next_code_register = 0
self.next_id = 0

def findFunctions(self):
main_tree = []
for block in self.tree.blocks:
if type(block).__name__ == "Func":
func = Function(block.name)
self.functions[block.name] = func
func.uncompiledPars = block.pars
func.uncompiledCode = block.code
else:
main_tree = main_tree + block
self.functions["main"].uncompiledCode = main_tree

def compile(self):
self.findFunctions()
for name in self.functions:
func = self.functions[name]
self.parseFunction(func)
for name in self.functions:
func = self.functions[name]
self.parseCallsInFunction(func)
self.code = self.code.update(func.code)
return self.code

def parseFunction(self, func):
func.code.update(self.parseStatList(func.uncompiledCode, func))

def parseCallsInFunction(self, func):
#???????!!!!????!!!!?????!!!!?????!???!?!?!?!?!?

def parseStatList(self, list, func):
code = dict()
for stat in list.stats:
if type(stat).__name__ in ['IfE', 'IfNe', 'WhileE', 'WhileNe']:
var = Variable("temp_" + str(self.next_id), func, self.next_var_register)
func.variables["temp_" + str(self.next_id)] = var
self.next_id += 1
self.next_var_register += 1
code.update(parseExpr(stat.cond, var))
register = self.next_code_register
self.next_code_register += 1
code.update(parseStatList(stat.stat, func))
if type(stat).__name__ == 'IfE':
code[register] = JumpOp(register + 1, self.next_code_register, var.register)
elif type(stat).__name__ == 'IfNe':
code[register] = JumpOp(self.next_code_register, register + 1, var.register)
elif type(stat).__name__ == 'WhileE':
code[register] = code[self.next_code_register] = JumpOp(register + 1, self.next_code_register + 1, \
var.register)
self.next_code_register += 1
else:
code[register] = code[self.next_code_register] = JumpOp(self.next_code_register + 1, register + 1, \
var.register)
self.next_code_register += 1
elif type(stat).__name__ == 'Return':
var = Variable("temp_" + str(self.next_id), func, self.next_var_register)
func.variables["temp_" + str(self.next_id)] = var
self.next_id += 1
self.next_var_register += 1
code.update(parseExpr(stat.cond, var))
code[self.next_register] = ReturnOp(var.register) #???????!!!!????!!!!?????!!!!?????!???!?!?!?!?!?
self.next_code_register += 1
elif type(stat).__name__ == 'Assign':
var_name = stat.var
try:
var = func.variables[var_name]
except:
var = Variable(var_name, func, self.next_var_register)
func.variables[var_name] = var
self.next_var_register += 1
code.update(parseExpr(stat.value, var))
else:
assert type(stat).__name__ == 'FuncCall'
#???????!!!!????!!!!?????!!!!?????!???!?!?!?!?!?
return code

def parseExpr(expr, var):
code = dict()
func = var.function
if type(expr).__name__ == 'Var':
try:
var2 = func.variables[expr.name]
except:
var2 = self.functions["main"].variables[expr.name]
code[self.next_code_register] = MovOp(self.next_code_register + 1, var2.register, var.register)
self.next_code_register += 1
return code
elif type(expr).__name__ == 'BinOp':
var2 = Variable("temp_" + str(self.next_id), func, self.next_var_register)
func.variables["temp_" + str(self.next_id)] = var2
self.next_id += 1
self.next_var_register += 1
var3 = Variable("temp_" + str(self.next_id), func, self.next_var_register)
func.variables["temp_" + str(self.next_id)] = var3
self.next_id += 1
self.next_var_register += 1
code.update(parseExpr(left, var2))
code.update(parseExpr(right, var3))
op = {"+": BinOpType.UNION, "*": BinOpType.INTERSECTION,
"-": BinOpType.DIFFERENCE, "~": BinOpType.SYM_DIFFERENCE}[expr.op.value]
code[self.next_code_register] = BinOp(self.next_code_register + 1, op, var2, var3, var)
self.next_code_register += 1
return code
elif type(expr).__name__ == 'Set':
code[self.next_code_register] = ClearOp(self.next_code_register + 1, var)
self.next_code_register += 1
var2 = Variable("temp_" + str(self.next_id), func, self.next_var_register)
func.variables["temp_" + str(self.next_id)] = var2
self.next_id += 1
self.next_var_register += 1
for par in expr.pars:
code.update(parseExpr(par, var2))
code[self.next_code_register] = AddOp(self.next_code_register + 1, var2, var)
self.next_code_register += 1
return code
else:
assert type(expr).__name__ == 'FuncCall'
#???????!!!!????!!!!?????!!!!?????!???!?!?!?!?!?
145 changes: 51 additions & 94 deletions s1_parser.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,59 @@
class AST:
pass
repr_start_start = "\n========== START OF "
repr_end_start = "\n========== END OF "
repr_end = " =========="
def parser_format(self, first, second):
return f"{AST.repr_start_start}{first}{AST.repr_end}\n{str(second)}{AST.repr_end_start}{first}{AST.repr_end}"

class IfE(AST):
class Conditional(AST):
def __init__(self, left, right):
self.cond = left
self.stat = right

def __repr__(self):
return f"Condition of this {self.__class__.name}:\n" + self.parser_format("CONDITION", self.cond) + \
f"\nStatements of this {self.__class__.name}:\n" + self.parser_format("LIST OF STATEMENTS", self.stat)

class IfNe(AST):
def __init__(self, left, right):
self.cond = left
self.stat = right
class IfE(Conditional):
name = "IfE"

class WhileE(AST):
def __init__(self, left, right):
self.cond = left
self.stat = right
class IfNe(Conditional):
name = "IfNe"

class WhileNe(AST):
def __init__(self, left, right):
self.cond = left
self.stat = right
class WhileE(Conditional):
name = "WhileE"

class WhileNe(Conditional):
name = "WhileNe"

class Return(AST):
def __init__(self, expr):
self.expr = expr

def __repr__(self):
return "Expression of this return:\n" + self.parser_format("EXPRESSION", self.expr)

class Func(AST):
def __init__(self, left, right):
def __init__(self, left, middle, right):
self.name = left
self.pars = []
self.pars = middle
self.code = right

class StatsList(AST):
def __init__(self):
self.stats = []

def __repr__(self):
repr = "Name of this function:\n" + self.name + "\nFormal parameters of this function:\n"
for parameter in self.pars:
repr += str(parameter) + "\n"
return repr + "Code of this function:\n" + self.parser_format("LIST OF STATEMENTS", self.code)

class Program(AST):
def __init__(self):
self.blocks = []

def __repr__(self):
repr = "Blocks of this program:"
for block in self.blocks:
repr += "\n" + self.parser_format("BLOCK", block)
return repr

class Assign(AST):
def __init__(self, left, right):
Expand All @@ -62,6 +78,9 @@ def __init__(self):
class Var(AST):
def __init__(self, token):
self.name = token.value

def __repr__(self):
return "Variable " + self.name

class Set(AST):
def __init__(self):
Expand All @@ -70,7 +89,7 @@ def __init__(self):
class Parser:
def __init__(self, lexer):
self.lexer = lexer
self.current_token = self.lexer.get_next_token()
self.next()

def next(self):
self.current_token = self.lexer.get_next_token()
Expand All @@ -87,14 +106,9 @@ def program(self):
return node

def block(self):
if self.current_token.type == 'IFE':
return self.ife()
elif self.current_token.type == 'IFNE':
return self.ifne()
elif self.current_token.type == 'WHIE':
return self.whilee()
elif self.current_token.type == 'WHINE':
return self.whilene()
if self.current_token.type in ['IFE', 'IFNE', 'WHIE', 'WHINE']:
token = self.current_token.type
return self.conditional(token, {"IFE": IfE, "IFNE": IfNe, "WHIE": WhileE, "WHINE": WhileNe}[token])
else:
assert self.current_token.type == 'ID'
pos = self.lexer.pos
Expand All @@ -106,8 +120,8 @@ def block(self):
self.current_token = token
return self.statement_list()

def ife(self):
assert self.current_token.type == 'IFE'
def conditional(self, token, class_name):
assert self.current_token.type == token
self.next()
assert self.current_token.type == 'LBR'
self.next()
Expand All @@ -119,52 +133,7 @@ def ife(self):
stats_list = self.statement_list()
assert self.current_token.type == 'RCBR'
self.next()
return IfE(expr, stats_list)

def ifne(self):
assert self.current_token.type == 'IFNE'
self.next()
assert self.current_token.type == 'LBR'
self.next()
expr = self.expr()
assert self.current_token.type == 'RBR'
self.next()
assert self.current_token.type == 'LCBR'
self.next()
stats_list = self.statement_list()
assert self.current_token.type == 'RCBR'
self.next()
return IfNe(expr, stats_list)

def whilee(self):
assert self.current_token.type == 'WHIE'
self.next()
assert self.current_token.type == 'LBR'
self.next()
expr = self.expr()
assert self.current_token.type == 'RBR'
self.next()
assert self.current_token.type == 'LCBR'
self.next()
stats_list = self.statement_list()
assert self.current_token.type == 'RCBR'
self.next()
return WhileE(expr, stats_list)

def whilene(self):
assert self.current_token.type == 'WHINE'
self.next()
assert self.current_token.type == 'LBR'
self.next()
expr = self.expr()
assert self.current_token.type == 'RBR'
self.next()
assert self.current_token.type == 'LCBR'
self.next()
stats_list = self.statement_list()
assert self.current_token.type == 'RCBR'
self.next()
return WhileNe(expr, stats_list)
return class_name(expr, stats_list)

def func(self):
name = self.func_name()
Expand All @@ -175,12 +144,10 @@ def func(self):
self.next()
assert self.current_token.type == 'LCBR'
self.next()
stats_list = self.func_statement_list()
stats_list = self.statement_list(True)
assert self.current_token.type == 'RCBR'
self.next()
node = Func(name, stats_list)
node.pars = pars
return node
return Func(name, pars, stats_list)

def formparams(self):
node = []
Expand Down Expand Up @@ -209,27 +176,17 @@ def func_name(self):
self.next()
return token.value

def statement_list(self):
def statement_list(self, is_func = False):
stats_list = []
while True:
if self.current_token.type in ['ID', 'LCOMM', 'IFE', 'IFNE', 'WHIE', 'WHINE']:
stats_list.append(self.statement())
elif is_func and (self.current_token.type == 'RET'):
stats_list.append(self.func_statement())
else:
break
return stats_list

def func_statement_list(self):
stats_list = []
while True:
if self.current_token.type in ['ID', 'LCOMM', 'IFE', 'IFNE', 'WHIE', 'WHINE']:
stats_list.append(self.statement())
else:
if self.current_token.type == 'RET':
stats_list.append(self.func_statement())
else:
break
return stats_list

def func_statement(self):
assert self.current_token.type == 'RET'
self.next()
Expand Down
Loading

0 comments on commit 6805bb2

Please sign in to comment.