def tac_ForStmt( ic: IntermediateCode, node: syntree.ForStmt, new_children: List[List[Any]], return_val: List[Any], ): symtab.leave_scope()
def p_IfStmt(p): """IfStmt : KW_IF new_scope Expression Block | KW_IF new_scope SimpleStmt ';' Expression Block | KW_IF new_scope Expression Block leave_scope KW_ELSE IfStmt | KW_IF new_scope Expression Block leave_scope KW_ELSE Block | KW_IF new_scope SimpleStmt ';' Expression Block leave_scope KW_ELSE IfStmt | KW_IF new_scope SimpleStmt ';' Expression Block leave_scope KW_ELSE Block """ if len(p) == 5: p[0] = syntree.IfStmt(body=p[4], expr=p[3], lineno=p.lineno(1)) symtab.leave_scope() elif len(p) == 7: p[0] = syntree.IfStmt(body=p[6], expr=p[5], statement=p[3], lineno=p.lineno(1)) symtab.leave_scope() elif len(p) == 8: p[0] = syntree.IfStmt(body=p[4], expr=p[3], next_=p[7], lineno=p.lineno(1)) elif len(p) == 10: p[0] = syntree.IfStmt(body=p[6], statement=p[3], expr=p[5], next_=p[9], lineno=p.lineno(1))
def p_FunctionDecl(p): """FunctionDecl : KW_FUNC FunctionName Signature | KW_FUNC FunctionName Signature FunctionBody """ if len(p) == 4: p[0] = syntree.Function(p[2], p[3], lineno=p.lineno(2)) elif len(p) == 5: p[0] = syntree.Function(p[2], p[3], body=p[4], lineno=p.lineno(2)) symtab.leave_scope()
def tac_Function( ic: IntermediateCode, node: syntree.Function, new_children: List[List[Any]], return_val: List[Any], ): fn_name = syntree.FunctionCall.get_fn_name(node.fn_name) fn_label = ic.get_fn_end_label(fn_name) ic.add_label(fn_label) symtab.leave_scope() symtab.leave_scope()
def tac_pre_IfStmt( ic: IntermediateCode, node: syntree.IfStmt, ): symtab.enter_scope() # there can be a statement to be executed just before # the condition. specified as "if a := 10; a > 5 {...}" # we process the statement before anything else and remove # it from the children before_statement = node.statement if before_statement is not None: _recur_codegen(before_statement, ic) node.children.remove(before_statement) # we'll process the condition here # so we are removing it from the children condition = node.expr node.children.remove(condition) condition_res = _recur_codegen(condition, ic)[0] symtab.enter_scope() # now add the actual if statement true_label = ic.get_new_increment_label("if_true") false_label = ic.get_new_increment_label("if_false") g1 = ConditionalGoTo(true_label, condition_res, false_label) ic.add_to_list(g1) ic.add_label(true_label) # now the body (after true label) body = node.body node.children.remove(body) _recur_codegen(body, ic) # false label after body ic.add_label(false_label) symtab.leave_scope() # else part next_ = node.next_ if next_ is not None: symtab.enter_scope() node.children.remove(next_) _recur_codegen(next_, ic) symtab.leave_scope() symtab.leave_scope()
def tac_pre_ForStmt(ic: IntermediateCode, node: syntree.ForStmt): symtab.enter_scope() if hasattr(node.clause, "type_") and getattr(node.clause, "type_") == "bool": # start of loop start_label = ic.get_new_increment_label("for_simple_start") ic.add_label(start_label) # the condition condition = node.clause node.children.remove(condition) condition_res = _recur_codegen(condition, ic)[0] true_label = ic.get_new_increment_label("for_simple_true") end_label = ic.get_new_increment_label("for_simple_end") symtab.enter_scope() # actual if else g1 = ConditionalGoTo(true_label, condition_res, end_label) ic.add_to_list(g1) ic.add_label(true_label) ic.enter_new_loop(start_label, end_label) # now the body (after true label) body = node.body if body is not None: node.children.remove(body) _recur_codegen(body, ic) # loop back to start label ic.add_goto(start_label) # end label after body ic.add_label(end_label) ic.exit_loop() elif isinstance(node.clause, syntree.ForClause): clause = node.clause # init statement (first part of for) if clause.init is not None: _recur_codegen(clause.init, ic) clause.children.remove(clause.init) # start of loop (just before condition) start_label = ic.get_new_increment_label("for_cmpd_start") ic.add_label(start_label) # the condition condition = clause.cond clause.children.remove(condition) condition_res = _recur_codegen(condition, ic)[0] true_label = ic.get_new_increment_label("for_cmpd_true") end_label = ic.get_new_increment_label("for_cmpd_end") symtab.enter_scope() # actual if else g1 = ConditionalGoTo(true_label, condition_res, end_label) ic.add_to_list(g1) ic.add_label(true_label) ic.enter_new_loop(start_label, end_label) # now the body (after true label) body = node.body if body is not None: node.children.remove(body) _recur_codegen(body, ic) # the post statement (increment/decrement) if clause.post is not None: _recur_codegen(clause.post, ic) clause.children.remove(clause.post) # loop back to start label ic.add_goto(start_label) # end label after body ic.add_label(end_label) ic.exit_loop() else: print("Could not determine clause type") symtab.leave_scope()
def p_leave_scope(p): """leave_scope :""" symtab.leave_scope()
def p_Block(p): """Block : '{' new_scope StatementList '}' """ p[0] = p[3] symtab.leave_scope()