def p_if_end(p): ''' if_end : ''' label_index = codegen.pop_label_stack() l1 = Factor(Scope.LOCAL, val=f"if.end.{label_index}") codegen.push_code(llvmcodes.LLVMCodeBrUncond(l1)) codegen.push_code(llvmcodes.LLVMCodeRegisterLabel(f"if.end.{label_index}"))
def p_while_init(p): ''' while_init : ''' label_index = codegen.label_index() l_init = Factor(Scope.LOCAL, val=f"while.init.{label_index}") codegen.push_code(llvmcodes.LLVMCodeBrUncond(l_init)) codegen.push_code(llvmcodes.LLVMCodeRegisterLabel(f"while.init.{label_index}"))
def p_for_end(p): ''' for_end : ''' # statement 終了後は強制的に for.condition に戻して n < range_to を評価する label_index = codegen.pop_label_stack() l_cond = Factor(Scope.LOCAL, val=f"for.condition.{label_index}") codegen.push_code(llvmcodes.LLVMCodeBrUncond(l_cond)) codegen.push_code(llvmcodes.LLVMCodeRegisterLabel(f"for.end.{label_index}"))
def p_for_init(p): ''' for_init : ''' # for n:= 2 to 100 # ↓ # for ident := range_from to range_to ident = latest_id_name(p) range_to = codegen.pop_factor() range_from = codegen.pop_factor() var = parse_variable(ident) label_index = codegen.label_index() # n := 2 codegen.push_code(llvmcodes.LLVMCodeStore(range_from, var)) # 初期化時は無条件で statement に移動 l_body = Factor(Scope.LOCAL, val=f"for.body.{label_index}") codegen.push_code(llvmcodes.LLVMCodeBrUncond(l_body)) # statement が終わったあとに戻ってくる for.condition のポイントを作成 codegen.push_code(llvmcodes.LLVMCodeRegisterLabel(f"for.condition.{label_index}")) # n++ ## n をレジスタに読み込み reg_ident = Factor(Scope.LOCAL, val=codegen.register()) codegen.push_code(llvmcodes.LLVMCodeLoad(reg_ident, var)) ## n + 1 one = Factor(Scope.CONSTANT, val=1) reg_ident_increased = Factor(Scope.LOCAL, val=codegen.register()) codegen.push_code(llvmcodes.LLVMCodeAdd(reg_ident, one, reg_ident_increased)) ## レジスタの内容を n に戻す codegen.push_code(llvmcodes.LLVMCodeStore(reg_ident_increased, var)) # n が range_from に到達したかのチェック ## n <= range_to cond = Factor(Scope.LOCAL, val=codegen.register()) codegen.push_code(llvmcodes.LLVMCodeIcmp(llvmcodes.CmpType.SLE, reg_ident_increased, range_to, cond)) l_end = Factor(Scope.LOCAL, val=f"for.end.{label_index}") codegen.push_code(llvmcodes.LLVMCodeBrCond(cond, l_body, l_end)) codegen.push_code(llvmcodes.LLVMCodeRegisterLabel(f"for.body.{label_index}"))
def p_if_condition(p): ''' if_condition : ''' label_index = codegen.label_index() cond = codegen.pop_factor() l1 = Factor(Scope.LOCAL, val=f"if.true.{label_index}") l2 = Factor(Scope.LOCAL, val=f"if.else.{label_index}") codegen.push_code(llvmcodes.LLVMCodeBrCond(cond, l1, l2)) codegen.push_code(llvmcodes.LLVMCodeRegisterLabel(f"if.true.{label_index}"))
def p_while_condition(p): ''' while_condition : ''' label_index = codegen.pop_label_stack(keep=True) cond = codegen.pop_factor() l1 = Factor(Scope.LOCAL, val=f"while.body.{label_index}") l2 = Factor(Scope.LOCAL, val=f"while.end.{label_index}") codegen.push_code(llvmcodes.LLVMCodeBrCond(cond, l1, l2)) codegen.push_code(llvmcodes.LLVMCodeRegisterLabel(f"while.body.{label_index}"))