First try
This commit is contained in:
134
Project-02-03-04/cfg_build.py
Normal file
134
Project-02-03-04/cfg_build.py
Normal file
@@ -0,0 +1,134 @@
|
||||
from cfg.CFG_Node import (
|
||||
CFG_Node,
|
||||
CFG_CALL,
|
||||
CFG_RETURN,
|
||||
CFG_DIAMOND,
|
||||
)
|
||||
|
||||
import compiler
|
||||
import syntax
|
||||
|
||||
|
||||
# -------------------------------------------------
|
||||
# Expressions — NO CFG NODES
|
||||
# -------------------------------------------------
|
||||
|
||||
class CONST(compiler.CONST):
|
||||
def cfa(self, pred, end):
|
||||
return pred
|
||||
|
||||
|
||||
class ID(compiler.ID):
|
||||
def cfa(self, pred, end):
|
||||
return pred
|
||||
|
||||
|
||||
class AOP(compiler.AOP):
|
||||
def cfa(self, pred, end):
|
||||
return pred
|
||||
|
||||
|
||||
class COMP(compiler.COMP):
|
||||
def cfa(self, pred, end):
|
||||
return pred
|
||||
|
||||
|
||||
class EQOP(compiler.EQOP):
|
||||
def cfa(self, pred, end):
|
||||
return pred
|
||||
|
||||
|
||||
class LOP(compiler.LOP):
|
||||
def cfa(self, pred, end):
|
||||
return pred
|
||||
|
||||
|
||||
# -------------------------------------------------
|
||||
# Statements
|
||||
# -------------------------------------------------
|
||||
|
||||
class ASSIGN(compiler.ASSIGN):
|
||||
def cfa(self, pred, end):
|
||||
n = CFG_Node(self)
|
||||
pred.add_child(n)
|
||||
return n
|
||||
|
||||
|
||||
class SEQ(compiler.SEQ):
|
||||
def cfa(self, pred, end):
|
||||
mid = self.exp1.cfa(pred, end)
|
||||
if mid is None:
|
||||
return None
|
||||
return self.exp2.cfa(mid, end)
|
||||
|
||||
|
||||
class IF(compiler.IF):
|
||||
def cfa(self, pred, end):
|
||||
cond = CFG_DIAMOND(self)
|
||||
pred.add_child(cond)
|
||||
|
||||
join = CFG_Node()
|
||||
|
||||
then_end = self.exp1.cfa(cond, end)
|
||||
else_end = self.exp2.cfa(cond, end)
|
||||
|
||||
if then_end is not None:
|
||||
then_end.add_child(join)
|
||||
if else_end is not None:
|
||||
else_end.add_child(join)
|
||||
|
||||
return join
|
||||
|
||||
|
||||
class WHILE(compiler.WHILE):
|
||||
def cfa(self, pred, end):
|
||||
cond = CFG_DIAMOND(self)
|
||||
pred.add_child(cond)
|
||||
|
||||
body_end = self.body.cfa(cond, end)
|
||||
if body_end is not None:
|
||||
body_end.add_child(cond)
|
||||
|
||||
after = CFG_Node()
|
||||
cond.add_child(after)
|
||||
|
||||
return after
|
||||
|
||||
|
||||
# -------------------------------------------------
|
||||
# Functions / calls
|
||||
# -------------------------------------------------
|
||||
|
||||
class CALL(compiler.CALL):
|
||||
def cfa(self, pred, end):
|
||||
n = CFG_CALL(self)
|
||||
pred.add_child(n)
|
||||
return n
|
||||
|
||||
|
||||
class DECL(compiler.DECL):
|
||||
def cfa(self, pred, end):
|
||||
entry = CFG_Node(self)
|
||||
pred.add_child(entry)
|
||||
return self.body.cfa(entry, end)
|
||||
|
||||
|
||||
class LET(compiler.LET):
|
||||
def cfa(self, pred, end):
|
||||
current = pred
|
||||
|
||||
decls = self.decl if isinstance(self.decl, list) else [self.decl]
|
||||
for d in decls:
|
||||
current = d.cfa(current, end)
|
||||
if current is None:
|
||||
return None
|
||||
|
||||
return self.body.cfa(current, end)
|
||||
|
||||
|
||||
class RETURN(syntax.EXPRESSION):
|
||||
def cfa(self, pred, end):
|
||||
n = CFG_RETURN(self)
|
||||
pred.add_child(n)
|
||||
n.add_child(end) # direct jump to global END
|
||||
return None # no fallthrough
|
||||
Reference in New Issue
Block a user