mirror of https://github.com/tbklang/tlang.git
1 Commits
Author | SHA1 | Message | Date |
---|---|---|---|
Tristan B. Velloza Kildaire |
b47a651caf
|
🧠️ Feature: Universal coercion and type enforcer (#9)
* TypeChecker - Added `bool isSameType2(Value v1, Value v2, bool attemptCoercion = false)` for future implementation of universal coercion as per #115 * TypeChecker - Renamed `isSameType2` to `typeEnforce` - Updated `typeEnforce`'s default parameter documentation from `false` to `attemptCoercion` (as it should have been in the beginning) * TypeCheckerException - Save the `TypecheckError` coming in as `errType` and make it available via `getError()` TypemMismatchException - Save the original (expected) and attempted types and make them available via `getExpectedType()` and `getATtemptedType()` respectively * TypeChecker - Updated `typeEnforce` from taking in `Value v1, Value v2, bool` to `Type t1, Value v2, bool`. - `typeEnforce()` will now extract the `Type` of `Value v2` and call `isSameType(t1, t2)`, if that fails and coercion is allowed then it is attempted, however if that fails then it causes an exception to be thrown. In the case coercion is not allowed, then a `TypeMismatchException` is thrown Unit tests - Tested the new `typeEnforce(Type t1, Value v2, bool)` and it seems to work, both a case of failing matching (coercion disallowed) and working coercion (coercion allowed) * TypeChecker - Documented existing unittest for `typeEnforce(Type, Value, bool)` - Added new unit test for `typeEnforce(Type, Value, bool)` which tests when the types ARE the same * TypeChecker - Cleaned up `typeEnforce(Type, Value, bool)` * TypeChecker - Added a work-in-progress unit test to test how I would use `typeEnforce(Type t1, Value v2, bool coercion = false)` in practice - Added TODOs in `attemptCoercion(Type, Type)` where I must add support * TypeChecker - Finished the unit test testing out the usage for `typeEnforce(Type, Value, bool coerce = false)` - Added TODOs to `attemptCoercion(Type, Value)` for the changes required to it * TypeChecker - Removed incorrect TODOs from `attemptCoerce(Type, Value)` and updated the message when the coercion fails Unit tests - Updated first unit test for `typeEnforce()` to test failing coercion on a non-`LiteralValue` instruction - Added a unit test where `typeEnforce()` WILL pass as it coerces a `LiteralValue` instruction * Exceptions (`typechecker`) - Added new exception type `CoercionException` to be thrown whenever a coercion cannot take place. * TypeChecker - Ensure that `attemptCoercion(Type, Value)` only throws instances of `CoercionException` * Unit tests - Fixed failing-coercion check by catching the correct exception when it fails `CoercionException` instead of `TypeMismatchException`) * TypeChecker - Added documentation for `isSameType(Type t1, Type t2)` * TypeChecker - Updated documentation for `isCoercibleRange(Type, Value)` - Updated `attemptCoercion(Type, Value)` with new documentation and renamed parameters * Unit tests (typechecker) - Added comments * TypeChecker - Removed now-completed TODO in `typeEnforce(Type t1, Value v2, bool allowCoercion = false)` * TypeChecker - Removed unused `typeStatus` variable in `typeEnforce(Type, Value, bool)` * TypeChecker - Variable declarations (with assignments) now use the `typeEnforce()` method with coercion allowed in order to do the type checking and coercion changes - Added a comment explaining a certain branch of `attemptCoercion(Type, Value)` * TypeChecker - If the to-type and provided-type are both numerical then use a size-based test Test cases - Added two test cases which test `typeEnforce()` on incoming `Value`-based instructions as part of variable declarations * Test cases - Fixed negative test case - it MUST have an error and that should be seen as a pass * TypeChecker (unit tests) - Disabled invalid unit test (marked for re-writing) - I should re-write the below. It is now incorrect as I DO ALLOW coercion of non literal-based instructions now - so it fails because it is using an older specification of TLang * TypeChecker - Migrated the type checking of standalone variable assignments to using `typeEnforce()` Test cases - Added positive and negative test cases * - Updated `.gitignore` * Feature/type enforcer cast instr emit (#13) * TypeChecker - `typeEnforce()` now will not change the type of `Value`-based instruction `v2` but rather return, on successful coercion set a `ref`-based argument to a new instance of a `CastedValueInstruction`, if coercion fails or was disabled and types mismatched then an exeption is thrown as normal. - If the types are an exact same match, a-la `isSameType(Type, Type)`, then this `ref` value is set to `v2` (makes programming easy) else we would have no way to know - `attemptCoerce()` now, to go with the above changes to `typeEnforce()`, returns a `CatsedValueInstruction` to the to-type on successful coercion, else an exception is thrown as usual - Updated two cases of `typeEnforce()` usage to the new method signature, also now add a sanity check assertion that the types now DO match as they should * TypeChecker - We need not set it again, look the value we use when we CALL `typeEnforce()` is that of the `fromInstruction` and if no changes occur we still have it, it is fine - if it changes via the call to `typeEnforce()` via the `ref` based argument thne same old - No need for us to set it here in the event of no changes, we are writing back the exact same Instruction/object-reference * TypeChecker (unit tests) - Upgraded to the new `typeEnforcer()` method signature * TypeChecker - Improved documentation for `typeEnforce()` * TypeChecker - Added TODO regarding pointer coercion with integers in `Pointer + Integer` case (for pointer airthmetic) * TypeChecker - Added a new branch which currently throws an exception as it is unimplememted - This branch (above) is in `attemptCoercion()` and is to handle the coercion of `Integer` to `Pointer` for pointer arithmetic - When doing the typechecking/codegen for `BinaryOp`, disable the pointer coercion call to `attemptPointerAriehmeticCoercion()`, instead now make calls in those cases they apply, to `typeEnforce()` - The above stuff is still broken, not yet implemented. * TypeChecker - Cannot use cast as that can return false positives for an all pointer case as all `Pointer`s are `Integer`s - Added `isPointerType(Type)` to check the above - Added then also `isIntegralTypeButNotPointer(Type)` which checks for an `Integer` type but excluding if it is a `Pointer` - Updated the checks in the `BinaryOperator` branch of `typeCheckThing(DNode)` to do this * TypeChecker - Need to do the `Pointer` checks first in `attemptCoercion(Type, Value)` * TypeChecker - `attemptCoercion(Type, Value)` now returns a `CastedValueInstruction` to cast the `Integer` type to the `Pointer` type * TypeCHecker - Catch mis use of type enforcement by using `isIntegralTypeButNotPointer(Type)` and isPointerType`(Type)` for the previous commit * TypeChecker - Refresh the types after the potential calls to `typeEnforce(..., ..., ..., ...)` * Pipeline - Use `set -e` for `simple_pointer.t` test in emit stage * Pipelines (emit stage) - Previous compilation may have succeeded, meaning ./tlang.out never gets updated and exits fine with 0, but we only use the last commands exit status to check for a pass for a test. - By setting this if COMPILATION fails then we exit with its code and the test status is set via that * Pipelines - Removed the `set -e` code as the correct `Exception` now causes a non-zero exit code from the changes made in `varass_vardec_dependency` * DGen - Added notice for issue #140 * TypeChecker - Made `isIntegralTypeButNotPointer(Type)` public - Made `isPointerType(Type)` public * Instructions - `CastedValueInstruction` now is unrelaxed by default but can be set (tis aids in how it can be emitted later for issue #140) * DGen - Added some checks for certain conditions whereby pointer coercion requires relaxing the casted operands (coerced operands) * DGen - Relax `CastedValueInstruction`(s) when appropriate in `BinaryOpInstr` handling code - Removed panics * DGen - Added relaxation support to the code emitting code for `CastedValueInstruction` * DGen - make debug messages for when relaxation occurs for `CastedValueInstruction` emitting more clear * TypeChecker - Implemented `biggerOfTheTwo(Integer, Integer)` which determines the biggest of the two `Integer`-based types and returns that one. * TypeChecker - Fixed incorrect variable name in `biggerOfTheTwo(Integer, Integer)` * TypeChecker - Throw an error in the case where a `BinaryOperatorExpression` occurs with non-`Integer`-based instructions (at least for now) * TypeChecker - If both types are `Integral` (but not `Pointer`) then smaller coerces to bigger, if they however are equal then signed coerces to unsigned * TypeChecker - Removed now irrelevant comment * TypeChecker - Don't throw exception here, rather let the `isSameType(Type, Type)` check handle that - We still keep the warning we print about missing cases implementation-wise * TypeChecker - Fixed explanation * TypeChecker - Marked related issue * TypeChecker - Implemented ` isStackArrayType(Type typeIn)` - WIP: Added a check for handling `StackArray -> Pointer` coercion to `attemptCoercion(Type, Value)` * TypeChecker - `attemptCoercion(Type, Value)` will now ensure firstly that the `StackArray`'s component type matches that of the `Pointer`'s referred type, if not throw an exception, if so, then return a `CastedValueInstruction` * TypeChecker - Print out a debug message when attempting to coerce a `StackArray` to a `Pointer` - Fixed the error message thrown when a `StackArray` could not be coerced to a `Pointer` due to the component type != ptr's referred type - `FunctionCall` handling now has the `canCoerceStackArray()` code disabled and uses the `typeEnforce()` method * TypeChecker - Type checking code for `FunctionCall` * TypeCheck - Completed TODO comment * TypeChecker - Added a TODO * TypeChecker - Added FIXME where the `typeEnforce()` call need to be made for the `ReturnStmt`'s return expression's type to match or be checked-against the containing `Function`'s * TypeChecker - `ReturnStmt` now uses `typeEnforce()` * Test cases - Added two new checks for checking the return type of a function and matching a `ReturnStmt`'s expression's type to it * TypeChecker - Removed assertion check, rather let the exception thrown handle the error - Only after we know the finally-parenting `Container` is a `Function` (should we reference `funcContainer` * Test cases - Removed explicit cast from `simple_function_recursion_factorial.t` * TypeChecker - If we have a `LiteralValue` and a non-`LiteralValue` then coerce the `LiteralValue` towards the non`-LiteralValue` via `typeEnforce()` - This should allow the correct range checking of literal values within the range of the to-type and not require annoying explicit casts * Test cases - Removed now-unneeded explicit casts on literal values in `simple_function_recursion_factorial.t` * TypeChecker - Added comment describing the process used - Removed now-completed TODO * TypeChecker - Removed some dead code - Removed now-completed FIXME/TODO * TypeChecker - Removed old type checking code for variable declarations with assignments - Removed old type checking code for standalone variable assignments |