private static TypeDesc ResolveType(IfInstr ifinstr, Environment env, CodePosition position) { TypeDesc conditionType = ResolveType(ifinstr.Condition, env, ifinstr.Condition.Position); ExprNode mainBranchLast; ExprNode elseBranchLast; TypeDesc mainBranchType; TypeDesc elseBranchType; if (!(conditionType is BoolType)) { throw new TypecheckerError( new MismatchedTypes(new BoolType(), conditionType), ifinstr.Condition.Position ); } RegularChecker mainChecker = new RegularChecker(ifinstr.MainBranch, env); RegularChecker elseChecker = new RegularChecker(ifinstr.ElseBranch, env); mainChecker.Typecheck(); elseChecker.Typecheck(); try { mainBranchLast = Utils.GetBlockLast(ifinstr.MainBranch); } catch (ArgumentException) { mainBranchLast = new ExprNode(new NullExpr(), ifinstr.Condition.Position); } try { elseBranchLast = Utils.GetBlockLast(ifinstr.ElseBranch); } catch (ArgumentException) { elseBranchLast = new ExprNode(new NullExpr(), ifinstr.Condition.Position); } mainBranchType = ResolveType(mainBranchLast, env, position); elseBranchType = ResolveType(elseBranchLast, env, position); if (mainBranchType.GetType() != elseBranchType.GetType()) { throw new TypecheckerError( new MismatchedTypes(mainBranchType, elseBranchType), position ); } return(mainBranchType); }
public void Typecheck() { foreach (InstrNode node in block.Instructions) { Instr instruction = node.Value; if (instruction is VarDecl) { RegularChecker.CheckVarDecl(node, ref env); } if (instruction is ClassDecl) { ClassDecl decl = (ClassDecl)instruction; env.AddEntry(decl.Name, new Class(decl.Typevars.Sequence), node.Position); } } }