If: Improve expansion to match when other directives do it. It used to register and expand later than usual in resolve / getBytes, because we don’t want to evaluate the condition sooner in case $ is used in it. However we now give the then and else sources their own scope, and register symbols in the containing scope with the condition embedded in them. This makes ifs work better inside macros.
ErrorLiteral: Introduce an error type. This represents bottom from lambda calculus, a computation which never completes successfully. It is a member of any type, and throws an exception on evaluation. This allows some expressions to evaluate without throwing errors unnecessarily. For example, scope lookups in a ternary which never evaluates to take the path which causes the error.
Line: Also copy directives with sources inside. It would cause symbol / address redefinition and not found errors when used in repeat blocks (which copy). Note there is some duplication of logic in SourceBuilder and the copy method with regards to which scope is used.
test: Improve exception assertions to include context checks etc. Adds helper methods to Parser, SourceFileSpan and SymbolNotFoundException. In the process we also improve a couple of InstructionTests by splitting the two throwing parses into two assertions, and the ParserTests for character literals which were syntax erroring on the wrong thing.