public IType Visit(CASE_OF node) { IType type_exp = Visit(node.exp); List <IType> types_branches = new List <IType>(); foreach (var br in node.branches.list_Node) { types_branches.Add(Visit(br)); } IType type = types_branches[0]; for (int i = 1; i < types_branches.Count; i++) { if (type == null || types_branches[i] == null) { return(null); } type = type.LCA(types_branches[i]); } return(type); }
public string Visit(CASE_OF node) { var exp = node.exp.Visit(this); var solution = method.Add_local("expr", true); var exp_type = method.Add_local("exp_type", true); var match_type = method.Add_local("match", true); var cmp = method.Add_local("cmp", true); method.Add_Instruction(new CIL_Typeof(exp_type, exp)); var finish = method.current_scope.Var("finish"); method.Add_Instruction(new CIL_Assig(match_type, "9999")); List <string> distances = new List <string>(); List <string> labels = new List <string>(); foreach (var item in node.branches.list_Node) { labels.Add(method.current_scope.Var("label")); string branch_type = method.Add_local("branch_type", true); string branch_inst = method.Add_local("branch_inst", true); method.Add_Instruction(new CIL_Allocate(branch_inst, item.formal.type.s)); method.Add_Instruction(new CIL_Typeof(branch_type, branch_inst)); string distans = method.Add_local("distans", true); distances.Add(distans); method.Add_Instruction(new CIL_Call(distans, "__distans", "this", new List <string>() { branch_type, exp_type })); method.Add_Instruction(new CIL_ArithExpr(cmp, match_type, distans, "<")); var _if = method.current_scope.Var("if"); method.Add_Instruction(new CIL_ConditionalJump(cmp, _if)); method.Add_Instruction(new CIL_Assig(match_type, distans)); method.Add_Instruction(new CIL_Label(_if)); } for (int i = 0; i < distances.Count; i++) { method.Add_Instruction(new CIL_ArithExpr(cmp, match_type, distances[i], "=")); method.Add_Instruction(new CIL_ConditionalJump(cmp, labels[i])); } for (int i = 0; i < distances.Count; i++) { method.Add_Instruction(new CIL_Label(labels[i])); method.Add_scope("branch"); var dest = method.Add_local(node.branches.list_Node[i].formal.name.name); var exp_branch = node.branches.list_Node[i].exp.Visit(this); method.Add_Instruction(new CIL_Assig(solution, exp_branch)); method.End_scope(); method.Add_Instruction(new CIL_Goto(finish)); } method.Add_Instruction(new CIL_Label(finish)); return(solution); }
public bool Visit(CASE_OF node) { bool solve = Visit(node.exp); foreach (var br in node.branches.list_Node) { solve &= Visit(br); } return(solve); }