frontend/frontend.cpp
// type check a block. If `retty` exists, check that all returns return a
// thing of type retty.
type check a block. If `retty` exists, check that all returns return a
thing of type retty.
type check a block . If ` retty ` exists check that all returns return a thing of type retty .
void typeCheckBlock(TypeContext tc, Block *b) {
  for (Stmt *s : b->stmts) {
    if (auto let = mlir::dyn_cast<StmtLet>(s)) {
      typeCheckExpr(tc, let->rhs);
      if (let->type.strict) {
        tc.assertStrict(let->rhs->type, let->rhs->span);
      } else {
        tc.assertNonStrict(let->rhs);
      }
      IRType *declaredty = tc.lookupSurfaceType(let->type);
      tc.assertTypeEquality(declaredty, let->rhs->type, let->span);
      tc.insertValue(let->name, let->rhs->type);
      continue;
    }
    if (auto ret = mlir::dyn_cast<StmtReturn>(s)) {
      typeCheckExpr(tc, ret->e);
      assert(ret->e->type);
      if (b->type) {
        tc.assertTypeEquality(b->type, ret->e->type, ret->e->span);
      } else {
        b->type = ret->e->type;
        assert(b->type);
      }
      continue;
    }
    assert(false && "unknown type of statment");
  }
  if (!b->type) {
    tc.assertVoidBlock(b->span);
  }
}
void typeCheckBlock ( TypeContext tc , Block * b ) { for ( Stmt * s : b -> stmts ) { if ( auto let = mlir :: dyn_cast < StmtLet > ( s ) ) { typeCheckExpr ( tc , let -> rhs ) ; if ( let -> type . strict ) { tc . assertStrict ( let -> rhs -> type , let -> rhs -> span ) ; } else { tc . assertNonStrict ( let -> rhs ) ; } IRType * declaredty = tc . lookupSurfaceType ( let -> type ) ; tc . assertTypeEquality ( declaredty , let -> rhs -> type , let -> span ) ; tc . insertValue ( let -> name , let -> rhs -> type ) ; continue ; } if ( auto ret = mlir :: dyn_cast < StmtReturn > ( s ) ) { typeCheckExpr ( tc , ret -> e ) ; assert ( ret -> e -> type ) ; if ( b -> type ) { tc . assertTypeEquality ( b -> type , ret -> e -> type , ret -> e -> span ) ; } else { b -> type = ret -> e -> type ; assert ( b -> type ) ; } continue ; } assert ( false && " " ) ; } if ( ! b -> type ) { tc . assertVoidBlock ( b -> span ) ; } }
type check a block.
type check a block .