Check performs a semantic check of the astNode, and returns a potentially
modified astNode and either a list of errors found, or nil if the program is
semantically valid. At the completion of Check, the symbol table and type
annotation are also complete.