Skip to content
Snippets Groups Projects
Commit 66a1234d authored by pycsham's avatar pycsham
Browse files

Completed adding of line nodes. Not tested yet

parent 1a33cf1a
No related branches found
No related tags found
No related merge requests found
from AST import ASTNode, getParseTreeNodes, getTypeName
from AST import ASTNode, getParseTreeNodes
from Environment import Env
from WordNodes import makeNodeFromExpr
from ExprPrimaryNodes import makeNodeFromExpr, makeNodeFromAllPrimary, MethodInvNode
from UnitNodes import TypeNode
# Contains:
# block
# for/while/if
# declaration
# return statement
###########################################################
# factory methods
###########################################################
# Creates AST node from statement and statementNoShortIf
def makeNodeFromAllStatement(parseTree):
parent = parseTree
child = parent.children[0]
if child.name == 'noTailStatement':
return makeNodeFromNoTailStatement(child)
elif child.name == 'ifStatement' or child.name == 'ifElseStatement' or child.name == 'ifElseStatementNoShortIf':
return IfNode(child)
elif child.name == 'forStatement' or child.name == 'forStatementNoShortIf':
return ForNode(child)
elif child.name == 'whileStatement' or child.name == 'whileStatementNoShortIf':
return WhileNode(child)
elif child.name == 'variableDcl':
return VarDclNode(child)
# Creates AST node from statementExpr
def makeNodeFromStatementExpr(parseTree):
parent = parseTree
child = parent.children[0]
if child.name == 'assignment':
return(makeNodeFromExpr(child))
elif child.name == 'methodInvoc':
return(MethodInvNode(child))
# Creates AST node from noTailStatement
def makeNodeFromNoTailStatement(parseTree):
parent = parseTree
child = parent.children[0]
if child.name == 'SEMICO':
return None
elif child.name == 'block':
return BlockNode(child)
elif child.name == 'exprStatement':
child = child.children[0]
return makeNodeFromStatementExpr(child)
elif child.name == 'returnStatement':
return ReturnNode(child)
# containing line level nodes: block, for/while/if, declaration
# block
# Rules:
# block LBRACK statements RBRACK
class BlockNode(ASTNode):
# always list all fields in the init method to show the class structure
def __init__(self, parseTree):
self.parseTree = parseTree
self.statements = StatementsNode(parseTree.children[1]) # block LBRACK statements RBRACK
self.statements = []
self.env = None
self.children = self.statements
# a wrapper around statementsNode use to check double declaration within a block
allStatements = getParseTreeNodes(['statement'], parseTree.children[1])
for node in allStatements:
self.statements.append(makeNodeFromAllStatement(node))
self.children = self.statements
# variableDcl
# Rules:
# 1. variableDcl type ID
# 2. variableDcl type ID ASSIGN variableInit
class VarDclNode(ASTNode):
# always list all fields in the init method to show the class structure
def __init__(self, parseTree):
self.parseTree = parseTree
self.dclType = ''
self.name = ''
self.assign = None # AssignNode, can be None
self.statements = [] # list of nodes representing statements in a block
self.dclType = None
self.varName = None
self.variableInit = None # could be none if not intialized
self.env = None
self.children = []
# input is : statement type variableDcl SEMICO
self.dclType = TypeNode(parseTree.children[0])
self.varName = parseTree.children[1].lex
if len(parseTree.children) > 2:
# Handling rule: variableInit expr
self.variableInit = makeNodeFromExpr(parseTree.children[3].children[0])
self.children.append(self.dclType)
self.children.append(self.varName)
self.children.append(self.variableInit)
# ifStatement, ifElseStatement, ifElseStatementNoShortIf
# Rules:
# 1. ifStatement IF LPAREN expr RPAREN statement
# 2. ifElseStatement IF LPAREN expr RPAREN statementNoShortIf ELSE statement
# 3. ifElseStatementNoShortIf IF LPAREN expr RPAREN statementNoShortIf ELSE statementNoShortIf
class IfNode(ASTNode):
def __init__(self, parseTree):
self.parseTree = parseTree
self.env = None
self.children = []
self.ifConditional = None # the check for the if statement
self.ifBody = None # the body of the if statement
self.elseBody = None # there are if statements without the else statement
self.ifConditional = makeNodeFromExpr(parseTree.children[2])
self.ifBody = makeNodeFromAllStatement(parseTree.children[4])
if parseTree.name == 'ifElseStatement':
self.elseBody = makeNodeFromAllStatement(parseTree.children[6])
self.children.append(self.ifConditional)
self.children.append(self.ifBody)
self.children.append(self.elseBody)
# whileStatement, whileStatementNoShortIf
# Rules:
# 1. whileStatement WHILE LPAREN expr RPAREN statement
# 2. whileStatementNoShortIf WHILE LPAREN expr RPAREN statementNoShortIf
class WhileNode(ASTNode):
def __init__(self, parseTree):
self.parseTree = parseTree
self.env = None
self.children = []
self.whileBound = None
self.whileBody = None
self.whileBound = makeNodeFromExpr(parseTree.children[2])
self.whileBody = makeNodeFromAllStatement(parseTree.children[4])
self.children.append(self.whileBound)
self.children.append(self.whileBody)
# returnStatement
# Rules:
# 1. returnStatement RETURN expr SEMICO
# 2. returnStatement RETURN SEMICO
class ReturnNode(ASTNode):
def __init__(self, parseTree):
self.parseTree = parseTree
self.env = None
self.children = []
self.expr = None # could be None
if len(parseTree.children) == 3:
self.expr = makeNodeFromExpr(parseTree.children[1])
self.children.append(self.expr)
# forStatement and forStatementNoShortIf
# Rules:
# 1. forStatement FOR LPAREN forInit SEMICO forExpr SEMICO forInit RPAREN statement
# 2. forStatementNoShortIf FOR LPAREN forInit SEMICO forExpr SEMICO forInit RPAREN statementNoShortIf
class ForNode(ASTNode):
# always list all fields in the init method to show the class structure
def __init__(self, parseTree):
self.parseTree = parseTree
self.statements = [] # list of nodes representing statements in a block
self.forInit = None # could be None
self.forBound = None # could be None
self.forUpdate = None # could be None
self.bodyStatement = None
self.env = None
self.children = []
InitFlag = False # flag for forInit vs forUpdate
for node in parseTree.children:
if node.name == 'forInit':
# Handling case where forInit could derive empty
if not node.children:
InitFlag = True
continue
statementNode = node.children[0]
exprAstNode = None
if statementNode.name == 'statementExpr':
exprAstNode = makeNodeFromStatementExpr(statementNode)
elif statementNode.name == 'variableDcl':
exprAstNode = VarDclNode(statementNode)
if not InitFlag:
self.forInit = exprAstNode
InitFlag = True
else:
self.forUpdate = exprAstNode
elif node.name == 'forExpr':
# Handling case where forExpr could derive empty
if not node.children:
continue
self.forBound = makeNodeFromExpr(node.children[0])
elif node.name == 'statement' ofr node.name == 'statementNoShortIf':
self.bodyStatement = makeNodeFromAllStatement(node)
self.children.append(self.forInit)
self.children.append(self.forBound)
self.children.append(self.forUpdate)
self.children.append(self.bodyStatement)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment