2023-02-05 18:21:26 +00:00
module tlang.compiler.codegen.emit.dgen ;
2021-11-02 08:41:03 +00:00
2023-02-05 18:21:26 +00:00
import tlang.compiler.codegen.emit.core : CodeEmitter ;
import tlang.compiler.typecheck.core ;
2021-11-02 13:13:44 +00:00
import std.container.slist : SList ;
2023-02-05 18:21:26 +00:00
import tlang.compiler.codegen.instruction ;
2021-11-02 13:13:44 +00:00
import std.stdio ;
import std.file ;
2021-11-02 15:03:38 +00:00
import std.conv : to ;
import std.string : cmp ;
2021-11-02 15:24:08 +00:00
import gogga ;
2022-12-11 15:52:36 +00:00
import std.range : walkLength ;
2022-12-11 19:00:48 +00:00
import std.string : wrap ;
2022-12-11 19:41:15 +00:00
import std.process : spawnProcess , Pid , ProcessException , wait ;
2023-02-05 18:21:26 +00:00
import tlang.compiler.typecheck.dependency.core : Context , FunctionData , DNode ;
import tlang.compiler.codegen.mapper.core : SymbolMapper ;
import tlang.compiler.symbols.data : SymbolType , Variable , Function , VariableParameter ;
import tlang.compiler.symbols.check : getCharacter ;
2022-12-12 14:40:45 +00:00
import misc.utils : Stack ;
Array support (#1)
* Parser
- Added ability for `parseName()` to recognize array types
- Added array type handling to `parseTypedDeclaration()`
- Removed unneeded `derefCount` and comment in `parseTypedDeclaration()`
Check
- Added new symbol types `OBRACKET` and `CBRACKET`
* Tets cases
- We will now be using `simple_arrays2.t` as our testing bench for array support
* Dependency
- When a variable declaration has a kind-of type we are unaware of then print out an error message before asserting `false`
* Builtins
- `getBuiltInType(TypeChecker, string)` will now return a `Pointer` object for arrays of which the type was `<componentType>[]` (non-stack bound) as effectively they are pointers with a different syntax -doing it here means that it is transparent and typechecking, code gen and emit will just see a pointer type which makes life a lot easier
* Builtins
- Added information about the current bug faced in issue #81 (third sub-issue)
* Test cases
- Updated test case `simple_arrays2.t` to show case bug sub-issue 3 in issue #81
* Builtins
- Removed seperate handling of `<componentType>[]` and incorporated it into the pointer check, now we have fixed sub-issue 3 of issue #81
Test cases
- Updated test case `simple_arrays2.t` to showcase the aforementioned fix
* Builtins
- Updated TODO
* Builtins
- Removed comment as now fixed
* Array
- Added `getComponentType()` method which will return the array's element type
* Dependency
- When processing the `Array` type which is now to be seen as a stack-based array (fixed size), error out in processing it during variable declarations
* Builtins
- Added `bool isStackArray(string)` in order to check if a given type string is designated as a stack-array type or not
- `Type getBuiltInType(TypeChecker, string)` now can generate the `StackArray` type including the component type and the size of the stack allocation
Parser
- Added support to`parseTypedDeclaration` to be able to parse stack-based array types
- Added terminator `]` to `parseExpression()`
DGen
- Added stack-based array type transformation support to `string typeTransform(Type)`
- Added transformation support for stack-based arrays for the `VariableDeclaration` instruction
StackArray
- Renamed `Array` type to `StackArray`
` The `StackArray` type now has an `arraySize` field and is included in the constructor's paremeters
- Added a `getAllocatedSize()` method to retrieve the `arraySize` field
Dependency
- Temporarily enabled the `StackArray` type in dependency processing for `VariableDeclarations` such that we can continue through the pipeline
Test cases
- Updated `simple_arrays.t` to test stack-based array types
* Tets cases
- Added new test case for testing (later) multi-dimensional stack-arrays
* Parser
- Working on adding array index assignment support
Test cases
- Added test case to test array assignments with
* Parser
- We can now detect when infact we are doing an array-indexed assignment and when not, we then flip` arrayIndexing` to `true` if that is the case and ensure that `=` SymbolType.ASSIGN is not triggering the varaible-declaration-with-assignment but rather eters a different branch based on this boolean
- Set the identifier being assigned to (in the array indexing case) to the `type` with the `[]...` stripped
Notes
- Added a TODO file `wip.txt` with notes about what is to be done for adding full array support
* Parser
- Handle the case whereby `SymbolType.ASSIGN` or `SymbolType.IDENT_TYPE` is not found by throwing an error
* Parser
- Moved logic for array assignments into the branch for it (deferred it)
* Data
- Added new work-in-progress parser node type `ArrayAssignment`
Parser
- Added TODO about the type of returned parse node needing to be updated down the line
Notes
- Updated `wip.txt` with more thoughts
* Expressions
- Added new parse node (a sub-type of `Expression`) for representing array indexing; `ArrayIndex`
Data
- Fixed compilation error caused by missing semi-colon
* Parser
- Added support for array accesses/indexing in `parseExpression()`
- Added a token-rerun mechanism that lets us replay the needed tokens which needed to be looked ahead in order to determine an array access was about to occur
* Parser
- Removed now-completed TODO relating to array accesses in `parseExpression()`
* Parser
- Added right-hand side expression parsing for array assignments
Test cases
- Updated test case to test both array expressions on the left-hand side of an assignment and as a free-standing expression on the right hand side
Data
- Implemeneted `ArrayAssignment` which is to be used for assigning into arrays
* Instruction
- Added new instruction for indexing into arrays, a new `Value`-type instruction called `ArrayIndexInstruction`
* DGen
- Handle `ArrayIndexInstruction` which is for whenever you index into a point-based array (an expression like `myArray[i]` is now being supported in emit (first steps))
* Instructions
- Added a new instruction type, `StackArrayINdexInstruction`, which is used to know when we are indexing into a stack-based array rather than a pointer-based array (just to be able to disambiguate between the two)
- Added a work-in-progress type `StackArrayIndexAssignmentInstruction` which will be used for assigning to stack arrays at a given index
* Instructions
- Added implementation for `StackArrayIndexAssignmentInstruction` which represents the assignment of some `Value` instruction to a stack-based array (indicated by the `arrayName` string field) at the index indicated by the provided `Value` instruction
* DGen
- Added a stub emitter for `ArrayIndexInstruction` (pointer-based array indexing)
- Added a stub emitter for `StackArrayINdexInstruction` (stack-array based array indexing)
* INstructions
- Added `getArrayName()`, `getIndexInstr()` and `getAssignedValue()` to `StackArrayIndexAssignmentInstruction`
* Instructions
- Added `ArrayIndexAssignmentInstruction` which is intended to be used for when one wants to assign into a pointer-based array
- It embeds a `Value` instruction which is what is to be assigned and then an `ArrayIndexInstruction` representing the base of the poiinter-based array (base address) coupled with an "index" (offset)
- Added a `toString()` override for `StackArrayIndexAssignmentInstruction`
* Test cases
- Added `complex_stack_arrays1.t`
- This tests a stack array of a fixed size of `int[]` (basically `int*`) and assigneing into it
* Test cases
- Added `simple_arrays4.t` which makes an `int[]` (which is an `int*`) and then assignes into it at `i` whilst referring to itself at `i` and doing a binary operation
* Test cases
- Added `simple_stack_arrays2.t` which tests a stack array of a fixed size and then assigns into it a value
* Test cases
- Added `simple_stack_arrays4.t` which just tests assigning to a stack array of a fixed size BUT referring to said stack array itself as part of the assignment expression
* DGen
- Removed TODO comment for `ArrayIndexInstruction` transformation branch
- Added a description for when the `ArrayIndexInstruction` branch is activated for a transformation
- Implemented transformation for `ArrayIndexInstruction`
- Added comment on when `ArrayIndexAssignmentInstruction` activates
- Implemented transformation for `ArrayIndexAssignmentInstruction`
- Added comment for when the `StackArrayIndexInstruction` branch activates
- Implemented transformation for `StackArrayIndexInstruction`
- Added comment for when `StackArrayIndexAssignmentInstruction` branch activates
- Implemented transformation for `StackArrayIndexAssignmentInstruction`
* Dependency
- Added dependency node generation for the `ArrayIndex`
- This will pool the `ArrayIndex` parser-node
- This will then set the context of the parser-node to the current context
- The index expression will be depended upon
- The indexed expression (the entity being indexed) will be depended upon
---
- Added dependency generation for `ArrayAssignment`
- The `ArrayAssignment` parser node will be pooled
- The `ArrayAssignment` will have its context set to the current context
- The assigned expression will be depended upon
- The entity being indexed will be depended upon
- The index expression will be depended upon
* Parser
- Added a branch to `parseName()` which handles array assignments's semicolon consumption and token cursor movement to the next token
- Updated `parseTypedDeclaration()` to return an object of type `Statement` rather than `TypedEntity`
- Disabled the intentional `assert(false)` when handling array assignments
- Assign the generated `ArrayAssignment` to the `generated` variable
- Updated `parseExtern()` to cast to `TypedEntity` to ensure that the `Statement` returned is of that sub-type (added an assertion to then check this fact)
* Typechecker/Codegen
- Implemented `isStackArray(Value)` which checks if the given `Value` instruction is a `FetchValueVar`, then extracts the `Variable` being referred to in said instruction and checks if its declared type is that of `StackArray`
- Implemented code generation for `ArrayAssignment`
- Implemented code generation for `ArrayIndex`
* Test cases
- WIP: Added `simple_stack_array_coerce.t` as we want to add coercion for this now
* Typecheck
- Added rudimentary check for checking if an argument is a stack array, and if the parameter (to a function call) is a pointer and if so then returns whether they have matching component types in a new function named `canCoerceStackArray(Type, Type)`
* Typecheck
- Fixed `canCoerceStackArray(Type, Type)` to actually coerce the first type first into a pointer type (coercing the stack array's component type to `<compType>*`) and THEN apply the `isSameType(Type, Type)` check
* Typecheck
- Hoisted up `canCoerceStackArray(Type, Type)` to the class-level of `TypeChecker`
- Removed debug prints from `canCoerceStackArray(Type, Type)`
- Added a TODO where the check should be done in the `FunctionCall` branch of the `DNode` processor
* TypeChecker
- Added a seperate check for function call `DNode` processing which now checks if we can coerce the stack-array-based argument to the pointer-based type parameter
Notes
- Emit now fails as we haven't implement an emit for this case, so we need to do that.
- Also, should we change the type of what is being passed in - perhaps that actually makes sense here - we haven't fully coerced it actually
* TypeChecker
- Updated `canCoerceStackArray(Type, Type)` to now take in `canCoerceStackArray(Type, Type, ref Type)` to set the newly created coerced type
- Fixed bug whereby if the coercion succeeded we didn't actually add to the list of evaluation-instructions in the `FuncCallInstr` object, hence there would be a `null` Instruction object appearing in the code emit phase.
- Added some NOTEs which we can clean up this code using
* TypeChecker
- Cleaned up commented-out code
* Added CI/CD test for 'simple_stack_array_coerce.t'
* Added CI/CD test for 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_stack_array_coerce.t' and 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Fixed filepath for test 'simple_arrays.t'
* Fixed typechecking tests for arrays
* DGen
- Added instrumentation for `simple_stack_array_coerce.t`
Test cases
- Updated `simple_stack_array_coerce.t` to update the array passed in a manner such that we can sum the two elements later, return it and assert to ensure it is set correctly
* Parser
- Had to ensure the old identifier code was removed too, was too early; therefore this now-dead code was removed
* Test cases
- Added this test (even though it is a bad test, the syntax ie wrong)
* Test cases
- Update `simple_stack_arrsys4.t` to return an `int` such that we can verify it works.
- Also added more tests to it.
DGen
- Added semantic test code generation for `simple_stack_arrays4.t`
CI
- Re-organised tests for semantics in emit for arrays into those "Which have semantic tests" and "those which don't (yet)"
- Added semantic/emit test for `simple_stack_arrays4.t`
* Test cases
- Updated `simple_arrays2.t` to test casting of complex array types
* Test cases
- Updated `complex_stack_arrays1.t`
* Test cases
- Added new test for testing pointer syntax; `simple_stack_array_coerce_ptr_syntax.t`
- FIXME: It is broken as we don't have the latest pointer code - that must still be finished
* Test cases
- Added test case `simple_stack_array_ceorce_wrong.t` where coercion must fail
* Test cases
- Added `simple_pointer_array_syntax.t` which should test the `int[] == int*` stuff
* DGen
- Made semantic test for `simple_pointer_array_syntax.t`
Test cases
- Added a test for `simple_pointer_array_syntax.t.t`
* Branding
- Added logo here
* Test cases
- Addes semantic code emit instrucmentation for `simple_stack_array_coerce_ptr_syntax.t`
* Pipelines
- Added test case for `source/tlang/testing/simple_stack_array_coerce_wrong.t` for typechecking phase
* Test cases
- Added test case `complex_stack_array_coerce.t`
* Test cases
- Added extensive positive test case `complex_stack_array_coerce_permutation_good.t` which has a lot of different ways to write `int**` (think `int*[]` etc)
- Added negative test cases `complex_stack_array_coerce_bad1.t`, `complex_stack_array_coerce_bad2.t` and `complex_stack_array_coerce_bad3.t`
2023-04-20 10:21:50 +01:00
import tlang.compiler.symbols.typing.core ;
2023-02-05 18:21:26 +00:00
import tlang.compiler.configuration : CompilerConfiguration ;
2021-11-02 13:27:17 +00:00
2021-11-02 08:41:03 +00:00
public final class DCodeEmitter : CodeEmitter
2023-02-04 10:41:30 +00:00
{
2023-07-22 17:12:16 +01:00
/ * *
* Whether or not symbol mappi g should
* apply to identifiers
* /
private bool symbolMapping ;
2023-01-23 18:44:35 +00:00
// NOTE: In future store the mapper in the config please
this ( TypeChecker typeChecker , File file , CompilerConfiguration config , SymbolMapper mapper )
2021-11-02 13:13:44 +00:00
{
2023-01-23 18:44:35 +00:00
super ( typeChecker , file , config , mapper ) ;
2023-07-22 17:12:16 +01:00
// By default symbols will be mapped
enableSymbolMapping ( ) ;
}
/ * *
* Enables symbol mapping
* /
private void enableSymbolMapping ( )
{
this . symbolMapping = true ;
}
/ * *
* Disables symbol mapping
* /
private void disableSymbolMapping ( )
{
this . symbolMapping = false ;
2021-11-09 13:30:37 +00:00
}
2022-12-19 13:37:55 +00:00
private ulong transformDepth = 0 ;
private string genTabs ( ulong count )
{
string tabStr ;
2023-01-19 19:06:20 +00:00
/* Only generate tabs if enabled in compiler config */
2023-01-28 16:12:49 +00:00
if ( config . getConfig ( "dgen:pretty_code" ) . getBoolean ( ) )
2022-12-19 13:37:55 +00:00
{
2023-01-19 19:06:20 +00:00
for ( ulong i = 0 ; i < count ; i + + )
{
tabStr ~ = "\t" ;
}
2022-12-19 13:37:55 +00:00
}
2023-01-19 19:06:20 +00:00
2022-12-19 13:37:55 +00:00
return tabStr ;
}
2023-01-15 10:36:54 +00:00
/ * *
* Given an instance of a Type this will transform it to a string
*
* Params :
* typeIn = The Type to transform
*
* Returns : The string representation of the transformed type
* /
public string typeTransform ( Type typeIn )
{
string stringRepr ;
// TODO: Some types will ident transform
2023-01-15 10:49:28 +00:00
/* Pointer types */
if ( cast ( Pointer ) typeIn )
{
/* Extract type being pointed to */
Pointer pointerType = cast ( Pointer ) typeIn ;
2023-01-15 10:59:41 +00:00
Type referType = pointerType . getReferredType ( ) ;
2023-01-15 10:49:28 +00:00
/* The type is then `transform(<refertype>)*` */
return typeTransform ( referType ) ~ "*" ;
}
2023-01-15 10:36:54 +00:00
/* Integral types transformation */
2023-01-15 10:49:28 +00:00
else if ( cast ( Integer ) typeIn )
2023-01-15 10:36:54 +00:00
{
Integer integralType = cast ( Integer ) typeIn ;
/* u<>_t or <>_t (Determine signedness) */
string typeString = integralType . isSigned ( ) ? "int" : "uint" ;
/* Width of integer */
typeString ~ = to ! ( string ) ( integralType . getSize ( ) * 8 ) ;
/* Trailing `_t` */
typeString ~ = "_t" ;
return typeString ;
}
/* Void type */
else if ( cast ( Void ) typeIn )
{
return "void" ;
}
Array support (#1)
* Parser
- Added ability for `parseName()` to recognize array types
- Added array type handling to `parseTypedDeclaration()`
- Removed unneeded `derefCount` and comment in `parseTypedDeclaration()`
Check
- Added new symbol types `OBRACKET` and `CBRACKET`
* Tets cases
- We will now be using `simple_arrays2.t` as our testing bench for array support
* Dependency
- When a variable declaration has a kind-of type we are unaware of then print out an error message before asserting `false`
* Builtins
- `getBuiltInType(TypeChecker, string)` will now return a `Pointer` object for arrays of which the type was `<componentType>[]` (non-stack bound) as effectively they are pointers with a different syntax -doing it here means that it is transparent and typechecking, code gen and emit will just see a pointer type which makes life a lot easier
* Builtins
- Added information about the current bug faced in issue #81 (third sub-issue)
* Test cases
- Updated test case `simple_arrays2.t` to show case bug sub-issue 3 in issue #81
* Builtins
- Removed seperate handling of `<componentType>[]` and incorporated it into the pointer check, now we have fixed sub-issue 3 of issue #81
Test cases
- Updated test case `simple_arrays2.t` to showcase the aforementioned fix
* Builtins
- Updated TODO
* Builtins
- Removed comment as now fixed
* Array
- Added `getComponentType()` method which will return the array's element type
* Dependency
- When processing the `Array` type which is now to be seen as a stack-based array (fixed size), error out in processing it during variable declarations
* Builtins
- Added `bool isStackArray(string)` in order to check if a given type string is designated as a stack-array type or not
- `Type getBuiltInType(TypeChecker, string)` now can generate the `StackArray` type including the component type and the size of the stack allocation
Parser
- Added support to`parseTypedDeclaration` to be able to parse stack-based array types
- Added terminator `]` to `parseExpression()`
DGen
- Added stack-based array type transformation support to `string typeTransform(Type)`
- Added transformation support for stack-based arrays for the `VariableDeclaration` instruction
StackArray
- Renamed `Array` type to `StackArray`
` The `StackArray` type now has an `arraySize` field and is included in the constructor's paremeters
- Added a `getAllocatedSize()` method to retrieve the `arraySize` field
Dependency
- Temporarily enabled the `StackArray` type in dependency processing for `VariableDeclarations` such that we can continue through the pipeline
Test cases
- Updated `simple_arrays.t` to test stack-based array types
* Tets cases
- Added new test case for testing (later) multi-dimensional stack-arrays
* Parser
- Working on adding array index assignment support
Test cases
- Added test case to test array assignments with
* Parser
- We can now detect when infact we are doing an array-indexed assignment and when not, we then flip` arrayIndexing` to `true` if that is the case and ensure that `=` SymbolType.ASSIGN is not triggering the varaible-declaration-with-assignment but rather eters a different branch based on this boolean
- Set the identifier being assigned to (in the array indexing case) to the `type` with the `[]...` stripped
Notes
- Added a TODO file `wip.txt` with notes about what is to be done for adding full array support
* Parser
- Handle the case whereby `SymbolType.ASSIGN` or `SymbolType.IDENT_TYPE` is not found by throwing an error
* Parser
- Moved logic for array assignments into the branch for it (deferred it)
* Data
- Added new work-in-progress parser node type `ArrayAssignment`
Parser
- Added TODO about the type of returned parse node needing to be updated down the line
Notes
- Updated `wip.txt` with more thoughts
* Expressions
- Added new parse node (a sub-type of `Expression`) for representing array indexing; `ArrayIndex`
Data
- Fixed compilation error caused by missing semi-colon
* Parser
- Added support for array accesses/indexing in `parseExpression()`
- Added a token-rerun mechanism that lets us replay the needed tokens which needed to be looked ahead in order to determine an array access was about to occur
* Parser
- Removed now-completed TODO relating to array accesses in `parseExpression()`
* Parser
- Added right-hand side expression parsing for array assignments
Test cases
- Updated test case to test both array expressions on the left-hand side of an assignment and as a free-standing expression on the right hand side
Data
- Implemeneted `ArrayAssignment` which is to be used for assigning into arrays
* Instruction
- Added new instruction for indexing into arrays, a new `Value`-type instruction called `ArrayIndexInstruction`
* DGen
- Handle `ArrayIndexInstruction` which is for whenever you index into a point-based array (an expression like `myArray[i]` is now being supported in emit (first steps))
* Instructions
- Added a new instruction type, `StackArrayINdexInstruction`, which is used to know when we are indexing into a stack-based array rather than a pointer-based array (just to be able to disambiguate between the two)
- Added a work-in-progress type `StackArrayIndexAssignmentInstruction` which will be used for assigning to stack arrays at a given index
* Instructions
- Added implementation for `StackArrayIndexAssignmentInstruction` which represents the assignment of some `Value` instruction to a stack-based array (indicated by the `arrayName` string field) at the index indicated by the provided `Value` instruction
* DGen
- Added a stub emitter for `ArrayIndexInstruction` (pointer-based array indexing)
- Added a stub emitter for `StackArrayINdexInstruction` (stack-array based array indexing)
* INstructions
- Added `getArrayName()`, `getIndexInstr()` and `getAssignedValue()` to `StackArrayIndexAssignmentInstruction`
* Instructions
- Added `ArrayIndexAssignmentInstruction` which is intended to be used for when one wants to assign into a pointer-based array
- It embeds a `Value` instruction which is what is to be assigned and then an `ArrayIndexInstruction` representing the base of the poiinter-based array (base address) coupled with an "index" (offset)
- Added a `toString()` override for `StackArrayIndexAssignmentInstruction`
* Test cases
- Added `complex_stack_arrays1.t`
- This tests a stack array of a fixed size of `int[]` (basically `int*`) and assigneing into it
* Test cases
- Added `simple_arrays4.t` which makes an `int[]` (which is an `int*`) and then assignes into it at `i` whilst referring to itself at `i` and doing a binary operation
* Test cases
- Added `simple_stack_arrays2.t` which tests a stack array of a fixed size and then assigns into it a value
* Test cases
- Added `simple_stack_arrays4.t` which just tests assigning to a stack array of a fixed size BUT referring to said stack array itself as part of the assignment expression
* DGen
- Removed TODO comment for `ArrayIndexInstruction` transformation branch
- Added a description for when the `ArrayIndexInstruction` branch is activated for a transformation
- Implemented transformation for `ArrayIndexInstruction`
- Added comment on when `ArrayIndexAssignmentInstruction` activates
- Implemented transformation for `ArrayIndexAssignmentInstruction`
- Added comment for when the `StackArrayIndexInstruction` branch activates
- Implemented transformation for `StackArrayIndexInstruction`
- Added comment for when `StackArrayIndexAssignmentInstruction` branch activates
- Implemented transformation for `StackArrayIndexAssignmentInstruction`
* Dependency
- Added dependency node generation for the `ArrayIndex`
- This will pool the `ArrayIndex` parser-node
- This will then set the context of the parser-node to the current context
- The index expression will be depended upon
- The indexed expression (the entity being indexed) will be depended upon
---
- Added dependency generation for `ArrayAssignment`
- The `ArrayAssignment` parser node will be pooled
- The `ArrayAssignment` will have its context set to the current context
- The assigned expression will be depended upon
- The entity being indexed will be depended upon
- The index expression will be depended upon
* Parser
- Added a branch to `parseName()` which handles array assignments's semicolon consumption and token cursor movement to the next token
- Updated `parseTypedDeclaration()` to return an object of type `Statement` rather than `TypedEntity`
- Disabled the intentional `assert(false)` when handling array assignments
- Assign the generated `ArrayAssignment` to the `generated` variable
- Updated `parseExtern()` to cast to `TypedEntity` to ensure that the `Statement` returned is of that sub-type (added an assertion to then check this fact)
* Typechecker/Codegen
- Implemented `isStackArray(Value)` which checks if the given `Value` instruction is a `FetchValueVar`, then extracts the `Variable` being referred to in said instruction and checks if its declared type is that of `StackArray`
- Implemented code generation for `ArrayAssignment`
- Implemented code generation for `ArrayIndex`
* Test cases
- WIP: Added `simple_stack_array_coerce.t` as we want to add coercion for this now
* Typecheck
- Added rudimentary check for checking if an argument is a stack array, and if the parameter (to a function call) is a pointer and if so then returns whether they have matching component types in a new function named `canCoerceStackArray(Type, Type)`
* Typecheck
- Fixed `canCoerceStackArray(Type, Type)` to actually coerce the first type first into a pointer type (coercing the stack array's component type to `<compType>*`) and THEN apply the `isSameType(Type, Type)` check
* Typecheck
- Hoisted up `canCoerceStackArray(Type, Type)` to the class-level of `TypeChecker`
- Removed debug prints from `canCoerceStackArray(Type, Type)`
- Added a TODO where the check should be done in the `FunctionCall` branch of the `DNode` processor
* TypeChecker
- Added a seperate check for function call `DNode` processing which now checks if we can coerce the stack-array-based argument to the pointer-based type parameter
Notes
- Emit now fails as we haven't implement an emit for this case, so we need to do that.
- Also, should we change the type of what is being passed in - perhaps that actually makes sense here - we haven't fully coerced it actually
* TypeChecker
- Updated `canCoerceStackArray(Type, Type)` to now take in `canCoerceStackArray(Type, Type, ref Type)` to set the newly created coerced type
- Fixed bug whereby if the coercion succeeded we didn't actually add to the list of evaluation-instructions in the `FuncCallInstr` object, hence there would be a `null` Instruction object appearing in the code emit phase.
- Added some NOTEs which we can clean up this code using
* TypeChecker
- Cleaned up commented-out code
* Added CI/CD test for 'simple_stack_array_coerce.t'
* Added CI/CD test for 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_stack_array_coerce.t' and 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Fixed filepath for test 'simple_arrays.t'
* Fixed typechecking tests for arrays
* DGen
- Added instrumentation for `simple_stack_array_coerce.t`
Test cases
- Updated `simple_stack_array_coerce.t` to update the array passed in a manner such that we can sum the two elements later, return it and assert to ensure it is set correctly
* Parser
- Had to ensure the old identifier code was removed too, was too early; therefore this now-dead code was removed
* Test cases
- Added this test (even though it is a bad test, the syntax ie wrong)
* Test cases
- Update `simple_stack_arrsys4.t` to return an `int` such that we can verify it works.
- Also added more tests to it.
DGen
- Added semantic test code generation for `simple_stack_arrays4.t`
CI
- Re-organised tests for semantics in emit for arrays into those "Which have semantic tests" and "those which don't (yet)"
- Added semantic/emit test for `simple_stack_arrays4.t`
* Test cases
- Updated `simple_arrays2.t` to test casting of complex array types
* Test cases
- Updated `complex_stack_arrays1.t`
* Test cases
- Added new test for testing pointer syntax; `simple_stack_array_coerce_ptr_syntax.t`
- FIXME: It is broken as we don't have the latest pointer code - that must still be finished
* Test cases
- Added test case `simple_stack_array_ceorce_wrong.t` where coercion must fail
* Test cases
- Added `simple_pointer_array_syntax.t` which should test the `int[] == int*` stuff
* DGen
- Made semantic test for `simple_pointer_array_syntax.t`
Test cases
- Added a test for `simple_pointer_array_syntax.t.t`
* Branding
- Added logo here
* Test cases
- Addes semantic code emit instrucmentation for `simple_stack_array_coerce_ptr_syntax.t`
* Pipelines
- Added test case for `source/tlang/testing/simple_stack_array_coerce_wrong.t` for typechecking phase
* Test cases
- Added test case `complex_stack_array_coerce.t`
* Test cases
- Added extensive positive test case `complex_stack_array_coerce_permutation_good.t` which has a lot of different ways to write `int**` (think `int*[]` etc)
- Added negative test cases `complex_stack_array_coerce_bad1.t`, `complex_stack_array_coerce_bad2.t` and `complex_stack_array_coerce_bad3.t`
2023-04-20 10:21:50 +01:00
/* Stack-based array type */
else if ( cast ( StackArray ) typeIn )
{
// TODO: Still implement stakc-based arrays
// we won't be able to tyoe transform just here
// ... as we need <componentType> <varName>[<arraySize>]
// ... hence this must be performed in avriable declaration
StackArray stackArray = cast ( StackArray ) typeIn ;
return typeTransform ( stackArray . getComponentType ( ) ) ;
// return "KAK TODO";
}
2023-01-15 10:36:54 +00:00
2023-07-17 15:35:32 +01:00
gprintln ( "Type transform unimplemented for type '" ~ to ! ( string ) ( typeIn ) ~ "'" , DebugType . ERROR ) ;
2023-01-15 10:36:54 +00:00
assert ( false ) ;
// return stringRepr;
}
2023-07-22 11:55:26 +01:00
public override string transform ( const Instruction instruction )
2022-12-11 19:41:15 +00:00
{
2022-12-16 12:53:33 +00:00
writeln ( "\n" ) ;
2022-12-14 17:49:08 +00:00
gprintln ( "transform(): " ~ to ! ( string ) ( instruction ) ) ;
2022-12-19 13:37:55 +00:00
transformDepth + + ;
2023-08-17 07:46:59 +01:00
// The data to emit
string emmmmit ;
2022-12-19 13:37:55 +00:00
// At any return decrement the depth
scope ( exit )
{
transformDepth - - ;
}
2022-12-14 17:49:08 +00:00
2022-12-12 13:36:07 +00:00
/* VariableAssignmentInstr */
if ( cast ( VariableAssignmentInstr ) instruction )
2022-12-11 19:41:15 +00:00
{
2022-12-16 12:53:33 +00:00
gprintln ( "type: VariableAssignmentInstr" ) ;
2022-12-12 13:36:07 +00:00
VariableAssignmentInstr varAs = cast ( VariableAssignmentInstr ) instruction ;
Context context = varAs . getContext ( ) ;
2022-12-11 19:41:15 +00:00
2022-12-12 13:36:07 +00:00
gprintln ( "Is ContextNull?: " ~ to ! ( string ) ( context is null ) ) ;
2022-12-16 12:53:33 +00:00
gprintln ( "Wazza contect: " ~ to ! ( string ) ( context . container ) ) ;
2023-01-23 18:44:35 +00:00
auto typedEntityVariable = typeChecker . getResolver ( ) . resolveBest ( context . getContainer ( ) , varAs . varName ) ; //TODO: Remove `auto`
2023-01-30 17:08:48 +00:00
gprintln ( "Hi" ~ to ! ( string ) ( varAs ) ) ;
gprintln ( "Hi" ~ to ! ( string ) ( varAs . data ) ) ;
2023-02-01 12:55:23 +00:00
gprintln ( "Hi" ~ to ! ( string ) ( varAs . data . getInstrType ( ) ) ) ;
2023-01-30 17:08:48 +00:00
// NOTE: For tetsing issue #94 coercion (remove when done)
2023-02-01 12:55:23 +00:00
string typeName = ( cast ( Type ) varAs . data . getInstrType ( ) ) . getName ( ) ;
2023-01-30 17:08:48 +00:00
gprintln ( "VariableAssignmentInstr: The data to assign's type is: " ~ typeName ) ;
2022-12-11 19:41:15 +00:00
2022-12-12 13:36:07 +00:00
2023-01-19 07:03:19 +00:00
/* If it is not external */
if ( ! typedEntityVariable . isExternal ( ) )
2022-12-12 14:56:54 +00:00
{
2023-01-23 18:44:35 +00:00
string renamedSymbol = mapper . symbolLookup ( typedEntityVariable ) ;
2022-12-12 17:12:39 +00:00
2023-08-17 07:46:59 +01:00
emmmmit = renamedSymbol ~ " = " ~ transform ( varAs . data ) ~ ";" ;
2023-01-19 07:03:19 +00:00
}
/* If it is external */
else
{
2023-08-17 07:46:59 +01:00
emmmmit = typedEntityVariable . getName ( ) ~ " = " ~ transform ( varAs . data ) ~ ";" ;
2023-01-19 07:03:19 +00:00
}
2022-12-11 19:41:15 +00:00
}
2022-12-12 13:36:07 +00:00
/* VariableDeclaration */
else if ( cast ( VariableDeclaration ) instruction )
2022-12-11 19:41:15 +00:00
{
2022-12-16 12:53:33 +00:00
gprintln ( "type: VariableDeclaration" ) ;
2022-12-12 13:36:07 +00:00
VariableDeclaration varDecInstr = cast ( VariableDeclaration ) instruction ;
Context context = varDecInstr . getContext ( ) ;
2023-01-23 18:44:35 +00:00
Variable typedEntityVariable = cast ( Variable ) typeChecker . getResolver ( ) . resolveBest ( context . getContainer ( ) , varDecInstr . varName ) ; //TODO: Remove `auto`
2022-12-12 13:36:07 +00:00
2023-01-19 07:03:19 +00:00
/* If the variable is not external */
if ( ! typedEntityVariable . isExternal ( ) )
2022-12-12 17:12:39 +00:00
{
2023-01-19 07:03:19 +00:00
//NOTE: We should remove all dots from generated symbol names as it won't be valid C (I don't want to say C because
// a custom CodeEmitter should be allowed, so let's call it a general rule)
//
//simple_variables.x -> simple_variables_x
//NOTE: We may need to create a symbol table actually and add to that and use that as these names
//could get out of hand (too long)
// NOTE: Best would be identity-mapping Entity's to a name
2023-01-23 18:44:35 +00:00
string renamedSymbol = mapper . symbolLookup ( typedEntityVariable ) ;
2022-12-19 13:37:55 +00:00
2022-12-12 17:12:39 +00:00
Array support (#1)
* Parser
- Added ability for `parseName()` to recognize array types
- Added array type handling to `parseTypedDeclaration()`
- Removed unneeded `derefCount` and comment in `parseTypedDeclaration()`
Check
- Added new symbol types `OBRACKET` and `CBRACKET`
* Tets cases
- We will now be using `simple_arrays2.t` as our testing bench for array support
* Dependency
- When a variable declaration has a kind-of type we are unaware of then print out an error message before asserting `false`
* Builtins
- `getBuiltInType(TypeChecker, string)` will now return a `Pointer` object for arrays of which the type was `<componentType>[]` (non-stack bound) as effectively they are pointers with a different syntax -doing it here means that it is transparent and typechecking, code gen and emit will just see a pointer type which makes life a lot easier
* Builtins
- Added information about the current bug faced in issue #81 (third sub-issue)
* Test cases
- Updated test case `simple_arrays2.t` to show case bug sub-issue 3 in issue #81
* Builtins
- Removed seperate handling of `<componentType>[]` and incorporated it into the pointer check, now we have fixed sub-issue 3 of issue #81
Test cases
- Updated test case `simple_arrays2.t` to showcase the aforementioned fix
* Builtins
- Updated TODO
* Builtins
- Removed comment as now fixed
* Array
- Added `getComponentType()` method which will return the array's element type
* Dependency
- When processing the `Array` type which is now to be seen as a stack-based array (fixed size), error out in processing it during variable declarations
* Builtins
- Added `bool isStackArray(string)` in order to check if a given type string is designated as a stack-array type or not
- `Type getBuiltInType(TypeChecker, string)` now can generate the `StackArray` type including the component type and the size of the stack allocation
Parser
- Added support to`parseTypedDeclaration` to be able to parse stack-based array types
- Added terminator `]` to `parseExpression()`
DGen
- Added stack-based array type transformation support to `string typeTransform(Type)`
- Added transformation support for stack-based arrays for the `VariableDeclaration` instruction
StackArray
- Renamed `Array` type to `StackArray`
` The `StackArray` type now has an `arraySize` field and is included in the constructor's paremeters
- Added a `getAllocatedSize()` method to retrieve the `arraySize` field
Dependency
- Temporarily enabled the `StackArray` type in dependency processing for `VariableDeclarations` such that we can continue through the pipeline
Test cases
- Updated `simple_arrays.t` to test stack-based array types
* Tets cases
- Added new test case for testing (later) multi-dimensional stack-arrays
* Parser
- Working on adding array index assignment support
Test cases
- Added test case to test array assignments with
* Parser
- We can now detect when infact we are doing an array-indexed assignment and when not, we then flip` arrayIndexing` to `true` if that is the case and ensure that `=` SymbolType.ASSIGN is not triggering the varaible-declaration-with-assignment but rather eters a different branch based on this boolean
- Set the identifier being assigned to (in the array indexing case) to the `type` with the `[]...` stripped
Notes
- Added a TODO file `wip.txt` with notes about what is to be done for adding full array support
* Parser
- Handle the case whereby `SymbolType.ASSIGN` or `SymbolType.IDENT_TYPE` is not found by throwing an error
* Parser
- Moved logic for array assignments into the branch for it (deferred it)
* Data
- Added new work-in-progress parser node type `ArrayAssignment`
Parser
- Added TODO about the type of returned parse node needing to be updated down the line
Notes
- Updated `wip.txt` with more thoughts
* Expressions
- Added new parse node (a sub-type of `Expression`) for representing array indexing; `ArrayIndex`
Data
- Fixed compilation error caused by missing semi-colon
* Parser
- Added support for array accesses/indexing in `parseExpression()`
- Added a token-rerun mechanism that lets us replay the needed tokens which needed to be looked ahead in order to determine an array access was about to occur
* Parser
- Removed now-completed TODO relating to array accesses in `parseExpression()`
* Parser
- Added right-hand side expression parsing for array assignments
Test cases
- Updated test case to test both array expressions on the left-hand side of an assignment and as a free-standing expression on the right hand side
Data
- Implemeneted `ArrayAssignment` which is to be used for assigning into arrays
* Instruction
- Added new instruction for indexing into arrays, a new `Value`-type instruction called `ArrayIndexInstruction`
* DGen
- Handle `ArrayIndexInstruction` which is for whenever you index into a point-based array (an expression like `myArray[i]` is now being supported in emit (first steps))
* Instructions
- Added a new instruction type, `StackArrayINdexInstruction`, which is used to know when we are indexing into a stack-based array rather than a pointer-based array (just to be able to disambiguate between the two)
- Added a work-in-progress type `StackArrayIndexAssignmentInstruction` which will be used for assigning to stack arrays at a given index
* Instructions
- Added implementation for `StackArrayIndexAssignmentInstruction` which represents the assignment of some `Value` instruction to a stack-based array (indicated by the `arrayName` string field) at the index indicated by the provided `Value` instruction
* DGen
- Added a stub emitter for `ArrayIndexInstruction` (pointer-based array indexing)
- Added a stub emitter for `StackArrayINdexInstruction` (stack-array based array indexing)
* INstructions
- Added `getArrayName()`, `getIndexInstr()` and `getAssignedValue()` to `StackArrayIndexAssignmentInstruction`
* Instructions
- Added `ArrayIndexAssignmentInstruction` which is intended to be used for when one wants to assign into a pointer-based array
- It embeds a `Value` instruction which is what is to be assigned and then an `ArrayIndexInstruction` representing the base of the poiinter-based array (base address) coupled with an "index" (offset)
- Added a `toString()` override for `StackArrayIndexAssignmentInstruction`
* Test cases
- Added `complex_stack_arrays1.t`
- This tests a stack array of a fixed size of `int[]` (basically `int*`) and assigneing into it
* Test cases
- Added `simple_arrays4.t` which makes an `int[]` (which is an `int*`) and then assignes into it at `i` whilst referring to itself at `i` and doing a binary operation
* Test cases
- Added `simple_stack_arrays2.t` which tests a stack array of a fixed size and then assigns into it a value
* Test cases
- Added `simple_stack_arrays4.t` which just tests assigning to a stack array of a fixed size BUT referring to said stack array itself as part of the assignment expression
* DGen
- Removed TODO comment for `ArrayIndexInstruction` transformation branch
- Added a description for when the `ArrayIndexInstruction` branch is activated for a transformation
- Implemented transformation for `ArrayIndexInstruction`
- Added comment on when `ArrayIndexAssignmentInstruction` activates
- Implemented transformation for `ArrayIndexAssignmentInstruction`
- Added comment for when the `StackArrayIndexInstruction` branch activates
- Implemented transformation for `StackArrayIndexInstruction`
- Added comment for when `StackArrayIndexAssignmentInstruction` branch activates
- Implemented transformation for `StackArrayIndexAssignmentInstruction`
* Dependency
- Added dependency node generation for the `ArrayIndex`
- This will pool the `ArrayIndex` parser-node
- This will then set the context of the parser-node to the current context
- The index expression will be depended upon
- The indexed expression (the entity being indexed) will be depended upon
---
- Added dependency generation for `ArrayAssignment`
- The `ArrayAssignment` parser node will be pooled
- The `ArrayAssignment` will have its context set to the current context
- The assigned expression will be depended upon
- The entity being indexed will be depended upon
- The index expression will be depended upon
* Parser
- Added a branch to `parseName()` which handles array assignments's semicolon consumption and token cursor movement to the next token
- Updated `parseTypedDeclaration()` to return an object of type `Statement` rather than `TypedEntity`
- Disabled the intentional `assert(false)` when handling array assignments
- Assign the generated `ArrayAssignment` to the `generated` variable
- Updated `parseExtern()` to cast to `TypedEntity` to ensure that the `Statement` returned is of that sub-type (added an assertion to then check this fact)
* Typechecker/Codegen
- Implemented `isStackArray(Value)` which checks if the given `Value` instruction is a `FetchValueVar`, then extracts the `Variable` being referred to in said instruction and checks if its declared type is that of `StackArray`
- Implemented code generation for `ArrayAssignment`
- Implemented code generation for `ArrayIndex`
* Test cases
- WIP: Added `simple_stack_array_coerce.t` as we want to add coercion for this now
* Typecheck
- Added rudimentary check for checking if an argument is a stack array, and if the parameter (to a function call) is a pointer and if so then returns whether they have matching component types in a new function named `canCoerceStackArray(Type, Type)`
* Typecheck
- Fixed `canCoerceStackArray(Type, Type)` to actually coerce the first type first into a pointer type (coercing the stack array's component type to `<compType>*`) and THEN apply the `isSameType(Type, Type)` check
* Typecheck
- Hoisted up `canCoerceStackArray(Type, Type)` to the class-level of `TypeChecker`
- Removed debug prints from `canCoerceStackArray(Type, Type)`
- Added a TODO where the check should be done in the `FunctionCall` branch of the `DNode` processor
* TypeChecker
- Added a seperate check for function call `DNode` processing which now checks if we can coerce the stack-array-based argument to the pointer-based type parameter
Notes
- Emit now fails as we haven't implement an emit for this case, so we need to do that.
- Also, should we change the type of what is being passed in - perhaps that actually makes sense here - we haven't fully coerced it actually
* TypeChecker
- Updated `canCoerceStackArray(Type, Type)` to now take in `canCoerceStackArray(Type, Type, ref Type)` to set the newly created coerced type
- Fixed bug whereby if the coercion succeeded we didn't actually add to the list of evaluation-instructions in the `FuncCallInstr` object, hence there would be a `null` Instruction object appearing in the code emit phase.
- Added some NOTEs which we can clean up this code using
* TypeChecker
- Cleaned up commented-out code
* Added CI/CD test for 'simple_stack_array_coerce.t'
* Added CI/CD test for 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_stack_array_coerce.t' and 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Fixed filepath for test 'simple_arrays.t'
* Fixed typechecking tests for arrays
* DGen
- Added instrumentation for `simple_stack_array_coerce.t`
Test cases
- Updated `simple_stack_array_coerce.t` to update the array passed in a manner such that we can sum the two elements later, return it and assert to ensure it is set correctly
* Parser
- Had to ensure the old identifier code was removed too, was too early; therefore this now-dead code was removed
* Test cases
- Added this test (even though it is a bad test, the syntax ie wrong)
* Test cases
- Update `simple_stack_arrsys4.t` to return an `int` such that we can verify it works.
- Also added more tests to it.
DGen
- Added semantic test code generation for `simple_stack_arrays4.t`
CI
- Re-organised tests for semantics in emit for arrays into those "Which have semantic tests" and "those which don't (yet)"
- Added semantic/emit test for `simple_stack_arrays4.t`
* Test cases
- Updated `simple_arrays2.t` to test casting of complex array types
* Test cases
- Updated `complex_stack_arrays1.t`
* Test cases
- Added new test for testing pointer syntax; `simple_stack_array_coerce_ptr_syntax.t`
- FIXME: It is broken as we don't have the latest pointer code - that must still be finished
* Test cases
- Added test case `simple_stack_array_ceorce_wrong.t` where coercion must fail
* Test cases
- Added `simple_pointer_array_syntax.t` which should test the `int[] == int*` stuff
* DGen
- Made semantic test for `simple_pointer_array_syntax.t`
Test cases
- Added a test for `simple_pointer_array_syntax.t.t`
* Branding
- Added logo here
* Test cases
- Addes semantic code emit instrucmentation for `simple_stack_array_coerce_ptr_syntax.t`
* Pipelines
- Added test case for `source/tlang/testing/simple_stack_array_coerce_wrong.t` for typechecking phase
* Test cases
- Added test case `complex_stack_array_coerce.t`
* Test cases
- Added extensive positive test case `complex_stack_array_coerce_permutation_good.t` which has a lot of different ways to write `int**` (think `int*[]` etc)
- Added negative test cases `complex_stack_array_coerce_bad1.t`, `complex_stack_array_coerce_bad2.t` and `complex_stack_array_coerce_bad3.t`
2023-04-20 10:21:50 +01:00
// Check if the type is a stack-based array
// ... if so then take make symbolName := `<symbolName>[<stackArraySize>]`
if ( cast ( StackArray ) varDecInstr . varType )
{
StackArray stackArray = cast ( StackArray ) varDecInstr . varType ;
renamedSymbol ~ = "[" ~ to ! ( string ) ( stackArray . getAllocatedSize ( ) ) ~ "]" ;
}
2023-01-19 07:03:19 +00:00
// Check to see if this declaration has an assignment attached
if ( typedEntityVariable . getAssignment ( ) )
{
2023-02-04 10:41:30 +00:00
Value varAssInstr = varDecInstr . getAssignmentInstr ( ) ;
2023-02-04 12:25:39 +00:00
gprintln ( "VarDec(with assignment): My assignment type is: " ~ varAssInstr . getInstrType ( ) . getName ( ) ) ;
2023-01-19 07:03:19 +00:00
// Generate the code to emit
2023-08-17 07:46:59 +01:00
emmmmit = typeTransform ( cast ( Type ) varDecInstr . varType ) ~ " " ~ renamedSymbol ~ " = " ~ transform ( varAssInstr ) ~ ";" ;
}
else
{
emmmmit = typeTransform ( cast ( Type ) varDecInstr . varType ) ~ " " ~ renamedSymbol ~ ";" ;
2023-01-19 07:03:19 +00:00
}
}
/* If the variable is external */
else
{
2023-08-17 07:46:59 +01:00
emmmmit = "extern " ~ typeTransform ( cast ( Type ) varDecInstr . varType ) ~ " " ~ typedEntityVariable . getName ( ) ~ ";" ;
2022-12-12 17:12:39 +00:00
}
2022-12-12 13:36:07 +00:00
}
/* LiteralValue */
else if ( cast ( LiteralValue ) instruction )
{
2022-12-16 12:53:33 +00:00
gprintln ( "type: LiteralValue" ) ;
2022-12-12 13:36:07 +00:00
LiteralValue literalValueInstr = cast ( LiteralValue ) instruction ;
2023-08-17 07:46:59 +01:00
emmmmit = to ! ( string ) ( literalValueInstr . getLiteralValue ( ) ) ;
2022-12-13 09:46:40 +00:00
}
/* FetchValueVar */
else if ( cast ( FetchValueVar ) instruction )
{
2022-12-16 12:53:33 +00:00
gprintln ( "type: FetchValueVar" ) ;
2022-12-13 09:51:44 +00:00
FetchValueVar fetchValueVarInstr = cast ( FetchValueVar ) instruction ;
Context context = fetchValueVarInstr . getContext ( ) ;
2022-12-13 09:46:40 +00:00
2023-01-23 18:44:35 +00:00
Variable typedEntityVariable = cast ( Variable ) typeChecker . getResolver ( ) . resolveBest ( context . getContainer ( ) , fetchValueVarInstr . varName ) ; //TODO: Remove `auto`
2022-12-13 09:51:44 +00:00
2023-01-19 07:03:19 +00:00
/* If it is not external */
if ( ! typedEntityVariable . isExternal ( ) )
{
//TODO: THis is giving me kak (see issue #54), it's generating name but trying to do it for the given container, relative to it
//TODO: We might need a version of generateName that is like generatenamebest (currently it acts like generatename, within)
2022-12-17 11:41:00 +00:00
2023-01-23 18:44:35 +00:00
string renamedSymbol = mapper . symbolLookup ( typedEntityVariable ) ;
2022-12-13 09:51:44 +00:00
2023-08-17 07:46:59 +01:00
emmmmit = renamedSymbol ;
2023-01-19 07:03:19 +00:00
}
/* If it is external */
else
{
2023-08-17 07:46:59 +01:00
emmmmit = typedEntityVariable . getName ( ) ;
2023-01-19 07:03:19 +00:00
}
2022-12-12 13:36:07 +00:00
}
/* BinOpInstr */
else if ( cast ( BinOpInstr ) instruction )
{
2022-12-16 12:53:33 +00:00
gprintln ( "type: BinOpInstr" ) ;
2022-12-12 13:36:07 +00:00
BinOpInstr binOpInstr = cast ( BinOpInstr ) instruction ;
2022-12-11 19:41:15 +00:00
2022-12-19 13:37:55 +00:00
// TODO: I like having `lhs == rhs` for `==` or comparators but not spaces for `lhs+rhs`
🧠️ 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
2023-08-10 18:42:11 +01:00
/ * *
* C compiler ' s do this thing where :
*
* If `<a>` is a pointer and `<b>` is an integer then the
* following pointer arithmetic is allowed :
*
* int * a = ( int * ) 2 ;
* a = a + b ;
*
* But it ' s WRONG if you do
*
* a = a + ( int * ) b ;
*
* Even though it makes logical sense coercion wise .
*
* Therefore we need to check such a case and yank
* the cast out me thinks .
*
* See issue # 140 ( https : //deavmi.assigned.network/git/tlang/tlang/issues/140#issuecomment-1892)
* /
Type leftHandOpType = ( cast ( Value ) binOpInstr . lhs ) . getInstrType ( ) ;
Type rightHandOpType = ( cast ( Value ) binOpInstr . rhs ) . getInstrType ( ) ;
if ( typeChecker . isPointerType ( leftHandOpType ) )
{
// Sanity check the other side should have been coerced to CastedValueInstruction
CastedValueInstruction cvInstr = cast ( CastedValueInstruction ) binOpInstr . rhs ;
assert ( cvInstr ) ;
gprintln ( "CastedValueInstruction relax setting: Da funk RIGHT " ) ;
// Relax the CV-instr to prevent it from emitting explicit cast code
cvInstr . setRelax ( true ) ;
}
else if ( typeChecker . isPointerType ( rightHandOpType ) )
{
// Sanity check the other side should have been coerced to CastedValueInstruction
CastedValueInstruction cvInstr = cast ( CastedValueInstruction ) binOpInstr . lhs ;
assert ( cvInstr ) ;
gprintln ( "CastedValueInstruction relax setting: Da funk LEFT " ) ;
// Relax the CV-instr to prevent it from emitting explicit cast code
cvInstr . setRelax ( true ) ;
}
2023-08-17 07:46:59 +01:00
emmmmit = transform ( binOpInstr . lhs ) ~ to ! ( string ) ( getCharacter ( binOpInstr . operator ) ) ~ transform ( binOpInstr . rhs ) ;
2022-12-11 19:41:15 +00:00
}
2022-12-16 12:53:33 +00:00
/* FuncCallInstr */
else if ( cast ( FuncCallInstr ) instruction )
{
gprintln ( "type: FuncCallInstr" ) ;
FuncCallInstr funcCallInstr = cast ( FuncCallInstr ) instruction ;
Context context = funcCallInstr . getContext ( ) ;
assert ( context ) ;
2023-01-23 18:44:35 +00:00
Function functionToCall = cast ( Function ) typeChecker . getResolver ( ) . resolveBest ( context . getContainer ( ) , funcCallInstr . functionName ) ; //TODO: Remove `auto`
2022-12-16 12:53:33 +00:00
// TODO: SymbolLookup?
string emit = functionToCall . getName ( ) ~ "(" ;
//TODO: Insert argument passimng code here
//NOTE: Typechecker must have checked for passing arguments to a function that doesn't take any, for example
//NOTE (Behaviour): We may want to actually have an preinliner for these arguments
//such to enforce a certain ordering. I believe this should be done in the emitter stage,
//so it is best placed here
if ( functionToCall . hasParams ( ) )
{
Value [ ] argumentInstructions = funcCallInstr . getEvaluationInstructions ( ) ;
string argumentString ;
for ( ulong argIdx = 0 ; argIdx < argumentInstructions . length ; argIdx + + )
{
Value currentArgumentInstr = argumentInstructions [ argIdx ] ;
argumentString ~ = transform ( currentArgumentInstr ) ;
if ( argIdx ! = ( argumentInstructions . length - 1 ) )
{
argumentString ~ = ", " ;
}
}
emit ~ = argumentString ;
}
emit ~ = ")" ;
2023-04-28 10:03:46 +01:00
// If this is a statement-level function call then tack on a `;`
if ( funcCallInstr . isStatementLevel ( ) )
{
emit ~ = ";" ;
}
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
2022-12-16 12:53:33 +00:00
}
2022-12-17 17:02:14 +00:00
/* ReturnInstruction */
else if ( cast ( ReturnInstruction ) instruction )
{
gprintln ( "type: ReturnInstruction" ) ;
ReturnInstruction returnInstruction = cast ( ReturnInstruction ) instruction ;
Context context = returnInstruction . getContext ( ) ;
assert ( context ) ;
/* Get the return expression instruction */
Value returnExpressionInstr = returnInstruction . getReturnExpInstr ( ) ;
2023-08-17 07:46:59 +01:00
emmmmit = "return " ~ transform ( returnExpressionInstr ) ~ ";" ;
2022-12-17 17:02:14 +00:00
}
2022-12-19 13:37:55 +00:00
/ * *
* If statements ( IfStatementInstruction )
* /
else if ( cast ( IfStatementInstruction ) instruction )
{
IfStatementInstruction ifStatementInstruction = cast ( IfStatementInstruction ) instruction ;
BranchInstruction [ ] branchInstructions = ifStatementInstruction . getBranchInstructions ( ) ;
gprintln ( "Holla" ~ to ! ( string ) ( branchInstructions ) ) ;
string emit ;
for ( ulong i = 0 ; i < branchInstructions . length ; i + + )
{
BranchInstruction curBranchInstr = branchInstructions [ i ] ;
if ( curBranchInstr . hasConditionInstr ( ) )
{
Value conditionInstr = cast ( Value ) curBranchInstr . getConditionInstr ( ) ;
string hStr = ( i = = 0 ) ? "if" : genTabs ( transformDepth ) ~ "else if" ;
emit ~ = hStr ~ "(" ~ transform ( conditionInstr ) ~ ")\n" ;
emit ~ = genTabs ( transformDepth ) ~ "{\n" ;
foreach ( Instruction branchBodyInstr ; curBranchInstr . getBodyInstructions ( ) )
{
emit ~ = genTabs ( transformDepth ) ~ "\t" ~ transform ( branchBodyInstr ) ~ "\n" ;
}
emit ~ = genTabs ( transformDepth ) ~ "}\n" ;
}
else
{
emit ~ = genTabs ( transformDepth ) ~ "else\n" ;
emit ~ = genTabs ( transformDepth ) ~ "{\n" ;
foreach ( Instruction branchBodyInstr ; curBranchInstr . getBodyInstructions ( ) )
{
emit ~ = genTabs ( transformDepth ) ~ "\t" ~ transform ( branchBodyInstr ) ~ "\n" ;
}
emit ~ = genTabs ( transformDepth ) ~ "}\n" ;
}
}
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
2022-12-19 13:37:55 +00:00
}
2023-01-04 10:03:50 +00:00
/ * *
* While loops ( WhileLoopInstruction )
2023-01-11 08:43:29 +00:00
*
* TODO : Add do - while check
2023-01-04 10:03:50 +00:00
* /
else if ( cast ( WhileLoopInstruction ) instruction )
{
WhileLoopInstruction whileLoopInstr = cast ( WhileLoopInstruction ) instruction ;
BranchInstruction branchInstr = whileLoopInstr . getBranchInstruction ( ) ;
Value conditionInstr = branchInstr . getConditionInstr ( ) ;
Instruction [ ] bodyInstructions = branchInstr . getBodyInstructions ( ) ;
string emit ;
/* Generate the `while(<expr>)` and opening curly brace */
emit = "while(" ~ transform ( conditionInstr ) ~ ")\n" ;
emit ~ = genTabs ( transformDepth ) ~ "{\n" ;
/* Transform each body statement */
foreach ( Instruction curBodyInstr ; bodyInstructions )
{
emit ~ = genTabs ( transformDepth ) ~ "\t" ~ transform ( curBodyInstr ) ~ "\n" ;
}
/* Closing curly brace */
emit ~ = genTabs ( transformDepth ) ~ "}" ;
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
2023-01-04 10:03:50 +00:00
}
2023-01-11 08:43:29 +00:00
/ * *
* For loops ( ForLoopInstruction )
* /
else if ( cast ( ForLoopInstruction ) instruction )
{
ForLoopInstruction forLoopInstr = cast ( ForLoopInstruction ) instruction ;
BranchInstruction branchInstruction = forLoopInstr . getBranchInstruction ( ) ;
Value conditionInstr = branchInstruction . getConditionInstr ( ) ;
Instruction [ ] bodyInstructions = branchInstruction . getBodyInstructions ( ) ;
string emit = "for(" ;
// Emit potential pre-run instruction
emit ~ = forLoopInstr . hasPreRunInstruction ( ) ? transform ( forLoopInstr . getPreRunInstruction ( ) ) : ";" ;
// Condition
emit ~ = transform ( conditionInstr ) ~ ";" ;
// NOTE: We are leaving the post-iteration blank due to us including it in the body
// TODO: We can hoist bodyInstructions[$] maybe if we want to generate it as C-for-loops
// if(forLoopInstr.hasPostIterationInstruction())
emit ~ = ")\n" ;
// Open curly (begin body)
emit ~ = genTabs ( transformDepth ) ~ "{\n" ;
/* Transform each body statement */
foreach ( Instruction curBodyInstr ; bodyInstructions )
{
emit ~ = genTabs ( transformDepth ) ~ "\t" ~ transform ( curBodyInstr ) ~ "\n" ;
}
// Close curly (body end)
emit ~ = genTabs ( transformDepth ) ~ "}" ;
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
2023-01-12 08:53:48 +00:00
}
/ * *
* Unary operators ( UnaryOpInstr )
* /
else if ( cast ( UnaryOpInstr ) instruction )
{
UnaryOpInstr unaryOpInstr = cast ( UnaryOpInstr ) instruction ;
Value operandInstruction = cast ( Value ) unaryOpInstr . getOperand ( ) ;
assert ( operandInstruction ) ;
string emit ;
/* The operator's symbol */
emit ~ = getCharacter ( unaryOpInstr . getOperator ( ) ) ;
/* Transform the operand */
emit ~ = transform ( operandInstruction ) ;
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
2023-01-12 08:53:48 +00:00
}
/ * *
* Pointer dereference assignment ( PointerDereferenceAssignmentInstruction )
* /
else if ( cast ( PointerDereferenceAssignmentInstruction ) instruction )
{
PointerDereferenceAssignmentInstruction pointerDereferenceAssignmentInstruction = cast ( PointerDereferenceAssignmentInstruction ) instruction ;
Value lhsPtrAddrExprInstr = pointerDereferenceAssignmentInstruction . getPointerEvalInstr ( ) ;
assert ( lhsPtrAddrExprInstr ) ;
Value rhsAssExprInstr = pointerDereferenceAssignmentInstruction . getAssExprInstr ( ) ;
assert ( rhsAssExprInstr ) ;
string emit ;
/* Star followed by transformation of the pointer address expression */
string starsOfLiberty ;
for ( ulong i = 0 ; i < pointerDereferenceAssignmentInstruction . getDerefCount ( ) ; i + + )
{
starsOfLiberty ~ = "*" ;
}
2023-04-17 15:50:11 +01:00
emit ~ = starsOfLiberty ~ "(" ~ transform ( lhsPtrAddrExprInstr ) ~ ")" ;
2023-01-12 08:53:48 +00:00
/* Assignment operator follows */
emit ~ = " = " ;
/* Expression to be assigned on the right hand side */
emit ~ = transform ( rhsAssExprInstr ) ~ ";" ;
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
2023-01-13 08:49:47 +00:00
}
/ * *
* Discard instruction ( DiscardInstruction )
* /
else if ( cast ( DiscardInstruction ) instruction )
{
DiscardInstruction discardInstruction = cast ( DiscardInstruction ) instruction ;
Value valueInstruction = discardInstruction . getExpressionInstruction ( ) ;
string emit ;
/* Transform the expression */
emit ~ = transform ( valueInstruction ) ~ ";" ;
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
2023-01-14 16:40:08 +00:00
}
/ * *
* Type casting instruction ( CastedValueInstruction )
* /
else if ( cast ( CastedValueInstruction ) instruction )
{
CastedValueInstruction castedValueInstruction = cast ( CastedValueInstruction ) instruction ;
Type castingTo = castedValueInstruction . getCastToType ( ) ;
// TODO: Dependent on type being casted one must handle different types, well differently (as is case for atleast OOP)
Value uncastedInstruction = castedValueInstruction . getEmbeddedInstruction ( ) ;
string emit ;
🧠️ 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
2023-08-10 18:42:11 +01:00
/ * *
* Issue # 140
*
* If relaxed then just emit the uncasted instruction
* /
if ( castedValueInstruction . isRelaxed ( ) )
{
/* The original expression */
emit ~ = transform ( uncastedInstruction ) ;
2023-01-14 16:40:08 +00:00
}
else
{
2023-08-17 07:46:59 +01:00
/* Handling of primitive types */
if ( cast ( Primitive ) castingTo )
{
/* Add the actual cast */
emit ~ = "(" ~ typeTransform ( castingTo ) ~ ")" ;
2023-01-14 16:40:08 +00:00
2023-08-17 07:46:59 +01:00
/* The expression being casted */
emit ~ = transform ( uncastedInstruction ) ;
}
else
{
// TODO: Implement this
gprintln ( "Non-primitive type casting not yet implemented" , DebugType . ERROR ) ;
assert ( false ) ;
}
}
2023-01-14 16:40:08 +00:00
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
Array support (#1)
* Parser
- Added ability for `parseName()` to recognize array types
- Added array type handling to `parseTypedDeclaration()`
- Removed unneeded `derefCount` and comment in `parseTypedDeclaration()`
Check
- Added new symbol types `OBRACKET` and `CBRACKET`
* Tets cases
- We will now be using `simple_arrays2.t` as our testing bench for array support
* Dependency
- When a variable declaration has a kind-of type we are unaware of then print out an error message before asserting `false`
* Builtins
- `getBuiltInType(TypeChecker, string)` will now return a `Pointer` object for arrays of which the type was `<componentType>[]` (non-stack bound) as effectively they are pointers with a different syntax -doing it here means that it is transparent and typechecking, code gen and emit will just see a pointer type which makes life a lot easier
* Builtins
- Added information about the current bug faced in issue #81 (third sub-issue)
* Test cases
- Updated test case `simple_arrays2.t` to show case bug sub-issue 3 in issue #81
* Builtins
- Removed seperate handling of `<componentType>[]` and incorporated it into the pointer check, now we have fixed sub-issue 3 of issue #81
Test cases
- Updated test case `simple_arrays2.t` to showcase the aforementioned fix
* Builtins
- Updated TODO
* Builtins
- Removed comment as now fixed
* Array
- Added `getComponentType()` method which will return the array's element type
* Dependency
- When processing the `Array` type which is now to be seen as a stack-based array (fixed size), error out in processing it during variable declarations
* Builtins
- Added `bool isStackArray(string)` in order to check if a given type string is designated as a stack-array type or not
- `Type getBuiltInType(TypeChecker, string)` now can generate the `StackArray` type including the component type and the size of the stack allocation
Parser
- Added support to`parseTypedDeclaration` to be able to parse stack-based array types
- Added terminator `]` to `parseExpression()`
DGen
- Added stack-based array type transformation support to `string typeTransform(Type)`
- Added transformation support for stack-based arrays for the `VariableDeclaration` instruction
StackArray
- Renamed `Array` type to `StackArray`
` The `StackArray` type now has an `arraySize` field and is included in the constructor's paremeters
- Added a `getAllocatedSize()` method to retrieve the `arraySize` field
Dependency
- Temporarily enabled the `StackArray` type in dependency processing for `VariableDeclarations` such that we can continue through the pipeline
Test cases
- Updated `simple_arrays.t` to test stack-based array types
* Tets cases
- Added new test case for testing (later) multi-dimensional stack-arrays
* Parser
- Working on adding array index assignment support
Test cases
- Added test case to test array assignments with
* Parser
- We can now detect when infact we are doing an array-indexed assignment and when not, we then flip` arrayIndexing` to `true` if that is the case and ensure that `=` SymbolType.ASSIGN is not triggering the varaible-declaration-with-assignment but rather eters a different branch based on this boolean
- Set the identifier being assigned to (in the array indexing case) to the `type` with the `[]...` stripped
Notes
- Added a TODO file `wip.txt` with notes about what is to be done for adding full array support
* Parser
- Handle the case whereby `SymbolType.ASSIGN` or `SymbolType.IDENT_TYPE` is not found by throwing an error
* Parser
- Moved logic for array assignments into the branch for it (deferred it)
* Data
- Added new work-in-progress parser node type `ArrayAssignment`
Parser
- Added TODO about the type of returned parse node needing to be updated down the line
Notes
- Updated `wip.txt` with more thoughts
* Expressions
- Added new parse node (a sub-type of `Expression`) for representing array indexing; `ArrayIndex`
Data
- Fixed compilation error caused by missing semi-colon
* Parser
- Added support for array accesses/indexing in `parseExpression()`
- Added a token-rerun mechanism that lets us replay the needed tokens which needed to be looked ahead in order to determine an array access was about to occur
* Parser
- Removed now-completed TODO relating to array accesses in `parseExpression()`
* Parser
- Added right-hand side expression parsing for array assignments
Test cases
- Updated test case to test both array expressions on the left-hand side of an assignment and as a free-standing expression on the right hand side
Data
- Implemeneted `ArrayAssignment` which is to be used for assigning into arrays
* Instruction
- Added new instruction for indexing into arrays, a new `Value`-type instruction called `ArrayIndexInstruction`
* DGen
- Handle `ArrayIndexInstruction` which is for whenever you index into a point-based array (an expression like `myArray[i]` is now being supported in emit (first steps))
* Instructions
- Added a new instruction type, `StackArrayINdexInstruction`, which is used to know when we are indexing into a stack-based array rather than a pointer-based array (just to be able to disambiguate between the two)
- Added a work-in-progress type `StackArrayIndexAssignmentInstruction` which will be used for assigning to stack arrays at a given index
* Instructions
- Added implementation for `StackArrayIndexAssignmentInstruction` which represents the assignment of some `Value` instruction to a stack-based array (indicated by the `arrayName` string field) at the index indicated by the provided `Value` instruction
* DGen
- Added a stub emitter for `ArrayIndexInstruction` (pointer-based array indexing)
- Added a stub emitter for `StackArrayINdexInstruction` (stack-array based array indexing)
* INstructions
- Added `getArrayName()`, `getIndexInstr()` and `getAssignedValue()` to `StackArrayIndexAssignmentInstruction`
* Instructions
- Added `ArrayIndexAssignmentInstruction` which is intended to be used for when one wants to assign into a pointer-based array
- It embeds a `Value` instruction which is what is to be assigned and then an `ArrayIndexInstruction` representing the base of the poiinter-based array (base address) coupled with an "index" (offset)
- Added a `toString()` override for `StackArrayIndexAssignmentInstruction`
* Test cases
- Added `complex_stack_arrays1.t`
- This tests a stack array of a fixed size of `int[]` (basically `int*`) and assigneing into it
* Test cases
- Added `simple_arrays4.t` which makes an `int[]` (which is an `int*`) and then assignes into it at `i` whilst referring to itself at `i` and doing a binary operation
* Test cases
- Added `simple_stack_arrays2.t` which tests a stack array of a fixed size and then assigns into it a value
* Test cases
- Added `simple_stack_arrays4.t` which just tests assigning to a stack array of a fixed size BUT referring to said stack array itself as part of the assignment expression
* DGen
- Removed TODO comment for `ArrayIndexInstruction` transformation branch
- Added a description for when the `ArrayIndexInstruction` branch is activated for a transformation
- Implemented transformation for `ArrayIndexInstruction`
- Added comment on when `ArrayIndexAssignmentInstruction` activates
- Implemented transformation for `ArrayIndexAssignmentInstruction`
- Added comment for when the `StackArrayIndexInstruction` branch activates
- Implemented transformation for `StackArrayIndexInstruction`
- Added comment for when `StackArrayIndexAssignmentInstruction` branch activates
- Implemented transformation for `StackArrayIndexAssignmentInstruction`
* Dependency
- Added dependency node generation for the `ArrayIndex`
- This will pool the `ArrayIndex` parser-node
- This will then set the context of the parser-node to the current context
- The index expression will be depended upon
- The indexed expression (the entity being indexed) will be depended upon
---
- Added dependency generation for `ArrayAssignment`
- The `ArrayAssignment` parser node will be pooled
- The `ArrayAssignment` will have its context set to the current context
- The assigned expression will be depended upon
- The entity being indexed will be depended upon
- The index expression will be depended upon
* Parser
- Added a branch to `parseName()` which handles array assignments's semicolon consumption and token cursor movement to the next token
- Updated `parseTypedDeclaration()` to return an object of type `Statement` rather than `TypedEntity`
- Disabled the intentional `assert(false)` when handling array assignments
- Assign the generated `ArrayAssignment` to the `generated` variable
- Updated `parseExtern()` to cast to `TypedEntity` to ensure that the `Statement` returned is of that sub-type (added an assertion to then check this fact)
* Typechecker/Codegen
- Implemented `isStackArray(Value)` which checks if the given `Value` instruction is a `FetchValueVar`, then extracts the `Variable` being referred to in said instruction and checks if its declared type is that of `StackArray`
- Implemented code generation for `ArrayAssignment`
- Implemented code generation for `ArrayIndex`
* Test cases
- WIP: Added `simple_stack_array_coerce.t` as we want to add coercion for this now
* Typecheck
- Added rudimentary check for checking if an argument is a stack array, and if the parameter (to a function call) is a pointer and if so then returns whether they have matching component types in a new function named `canCoerceStackArray(Type, Type)`
* Typecheck
- Fixed `canCoerceStackArray(Type, Type)` to actually coerce the first type first into a pointer type (coercing the stack array's component type to `<compType>*`) and THEN apply the `isSameType(Type, Type)` check
* Typecheck
- Hoisted up `canCoerceStackArray(Type, Type)` to the class-level of `TypeChecker`
- Removed debug prints from `canCoerceStackArray(Type, Type)`
- Added a TODO where the check should be done in the `FunctionCall` branch of the `DNode` processor
* TypeChecker
- Added a seperate check for function call `DNode` processing which now checks if we can coerce the stack-array-based argument to the pointer-based type parameter
Notes
- Emit now fails as we haven't implement an emit for this case, so we need to do that.
- Also, should we change the type of what is being passed in - perhaps that actually makes sense here - we haven't fully coerced it actually
* TypeChecker
- Updated `canCoerceStackArray(Type, Type)` to now take in `canCoerceStackArray(Type, Type, ref Type)` to set the newly created coerced type
- Fixed bug whereby if the coercion succeeded we didn't actually add to the list of evaluation-instructions in the `FuncCallInstr` object, hence there would be a `null` Instruction object appearing in the code emit phase.
- Added some NOTEs which we can clean up this code using
* TypeChecker
- Cleaned up commented-out code
* Added CI/CD test for 'simple_stack_array_coerce.t'
* Added CI/CD test for 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_stack_array_coerce.t' and 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Fixed filepath for test 'simple_arrays.t'
* Fixed typechecking tests for arrays
* DGen
- Added instrumentation for `simple_stack_array_coerce.t`
Test cases
- Updated `simple_stack_array_coerce.t` to update the array passed in a manner such that we can sum the two elements later, return it and assert to ensure it is set correctly
* Parser
- Had to ensure the old identifier code was removed too, was too early; therefore this now-dead code was removed
* Test cases
- Added this test (even though it is a bad test, the syntax ie wrong)
* Test cases
- Update `simple_stack_arrsys4.t` to return an `int` such that we can verify it works.
- Also added more tests to it.
DGen
- Added semantic test code generation for `simple_stack_arrays4.t`
CI
- Re-organised tests for semantics in emit for arrays into those "Which have semantic tests" and "those which don't (yet)"
- Added semantic/emit test for `simple_stack_arrays4.t`
* Test cases
- Updated `simple_arrays2.t` to test casting of complex array types
* Test cases
- Updated `complex_stack_arrays1.t`
* Test cases
- Added new test for testing pointer syntax; `simple_stack_array_coerce_ptr_syntax.t`
- FIXME: It is broken as we don't have the latest pointer code - that must still be finished
* Test cases
- Added test case `simple_stack_array_ceorce_wrong.t` where coercion must fail
* Test cases
- Added `simple_pointer_array_syntax.t` which should test the `int[] == int*` stuff
* DGen
- Made semantic test for `simple_pointer_array_syntax.t`
Test cases
- Added a test for `simple_pointer_array_syntax.t.t`
* Branding
- Added logo here
* Test cases
- Addes semantic code emit instrucmentation for `simple_stack_array_coerce_ptr_syntax.t`
* Pipelines
- Added test case for `source/tlang/testing/simple_stack_array_coerce_wrong.t` for typechecking phase
* Test cases
- Added test case `complex_stack_array_coerce.t`
* Test cases
- Added extensive positive test case `complex_stack_array_coerce_permutation_good.t` which has a lot of different ways to write `int**` (think `int*[]` etc)
- Added negative test cases `complex_stack_array_coerce_bad1.t`, `complex_stack_array_coerce_bad2.t` and `complex_stack_array_coerce_bad3.t`
2023-04-20 10:21:50 +01:00
}
/ * *
* Array indexing ( pointer - based arrays )
*
* Handles `myArray[<index>]` where `myArray` is
* of type `int[]` ( i . e . `int*` )
* /
else if ( cast ( ArrayIndexInstruction ) instruction )
{
ArrayIndexInstruction arrAssInstr = cast ( ArrayIndexInstruction ) instruction ;
gprintln ( "TODO: Implement Pointer-array index emit" , DebugType . ERROR ) ;
gprintln ( "ArrayInstr: " ~ arrAssInstr . getIndexedToInstr ( ) . toString ( ) ) ;
gprintln ( "ArrayIndexInstr: " ~ to ! ( string ) ( arrAssInstr . getIndexInstr ( ) ) ) ;
/* Obtain the entity being indexed */
Value indexed = arrAssInstr . getIndexedToInstr ( ) ;
/* Obtain the index */
Value index = arrAssInstr . getIndexInstr ( ) ;
/ * *
* Emit * ( < indexedEval > + < index > )
* /
string emit ;
emit ~ = "*(" ;
emit ~ = transform ( indexed ) ;
emit ~ = "+" ;
emit ~ = transform ( index ) ;
emit ~ = ")" ;
// return "*("~transform(indexed)~"+"~transform(index)~")";
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
Array support (#1)
* Parser
- Added ability for `parseName()` to recognize array types
- Added array type handling to `parseTypedDeclaration()`
- Removed unneeded `derefCount` and comment in `parseTypedDeclaration()`
Check
- Added new symbol types `OBRACKET` and `CBRACKET`
* Tets cases
- We will now be using `simple_arrays2.t` as our testing bench for array support
* Dependency
- When a variable declaration has a kind-of type we are unaware of then print out an error message before asserting `false`
* Builtins
- `getBuiltInType(TypeChecker, string)` will now return a `Pointer` object for arrays of which the type was `<componentType>[]` (non-stack bound) as effectively they are pointers with a different syntax -doing it here means that it is transparent and typechecking, code gen and emit will just see a pointer type which makes life a lot easier
* Builtins
- Added information about the current bug faced in issue #81 (third sub-issue)
* Test cases
- Updated test case `simple_arrays2.t` to show case bug sub-issue 3 in issue #81
* Builtins
- Removed seperate handling of `<componentType>[]` and incorporated it into the pointer check, now we have fixed sub-issue 3 of issue #81
Test cases
- Updated test case `simple_arrays2.t` to showcase the aforementioned fix
* Builtins
- Updated TODO
* Builtins
- Removed comment as now fixed
* Array
- Added `getComponentType()` method which will return the array's element type
* Dependency
- When processing the `Array` type which is now to be seen as a stack-based array (fixed size), error out in processing it during variable declarations
* Builtins
- Added `bool isStackArray(string)` in order to check if a given type string is designated as a stack-array type or not
- `Type getBuiltInType(TypeChecker, string)` now can generate the `StackArray` type including the component type and the size of the stack allocation
Parser
- Added support to`parseTypedDeclaration` to be able to parse stack-based array types
- Added terminator `]` to `parseExpression()`
DGen
- Added stack-based array type transformation support to `string typeTransform(Type)`
- Added transformation support for stack-based arrays for the `VariableDeclaration` instruction
StackArray
- Renamed `Array` type to `StackArray`
` The `StackArray` type now has an `arraySize` field and is included in the constructor's paremeters
- Added a `getAllocatedSize()` method to retrieve the `arraySize` field
Dependency
- Temporarily enabled the `StackArray` type in dependency processing for `VariableDeclarations` such that we can continue through the pipeline
Test cases
- Updated `simple_arrays.t` to test stack-based array types
* Tets cases
- Added new test case for testing (later) multi-dimensional stack-arrays
* Parser
- Working on adding array index assignment support
Test cases
- Added test case to test array assignments with
* Parser
- We can now detect when infact we are doing an array-indexed assignment and when not, we then flip` arrayIndexing` to `true` if that is the case and ensure that `=` SymbolType.ASSIGN is not triggering the varaible-declaration-with-assignment but rather eters a different branch based on this boolean
- Set the identifier being assigned to (in the array indexing case) to the `type` with the `[]...` stripped
Notes
- Added a TODO file `wip.txt` with notes about what is to be done for adding full array support
* Parser
- Handle the case whereby `SymbolType.ASSIGN` or `SymbolType.IDENT_TYPE` is not found by throwing an error
* Parser
- Moved logic for array assignments into the branch for it (deferred it)
* Data
- Added new work-in-progress parser node type `ArrayAssignment`
Parser
- Added TODO about the type of returned parse node needing to be updated down the line
Notes
- Updated `wip.txt` with more thoughts
* Expressions
- Added new parse node (a sub-type of `Expression`) for representing array indexing; `ArrayIndex`
Data
- Fixed compilation error caused by missing semi-colon
* Parser
- Added support for array accesses/indexing in `parseExpression()`
- Added a token-rerun mechanism that lets us replay the needed tokens which needed to be looked ahead in order to determine an array access was about to occur
* Parser
- Removed now-completed TODO relating to array accesses in `parseExpression()`
* Parser
- Added right-hand side expression parsing for array assignments
Test cases
- Updated test case to test both array expressions on the left-hand side of an assignment and as a free-standing expression on the right hand side
Data
- Implemeneted `ArrayAssignment` which is to be used for assigning into arrays
* Instruction
- Added new instruction for indexing into arrays, a new `Value`-type instruction called `ArrayIndexInstruction`
* DGen
- Handle `ArrayIndexInstruction` which is for whenever you index into a point-based array (an expression like `myArray[i]` is now being supported in emit (first steps))
* Instructions
- Added a new instruction type, `StackArrayINdexInstruction`, which is used to know when we are indexing into a stack-based array rather than a pointer-based array (just to be able to disambiguate between the two)
- Added a work-in-progress type `StackArrayIndexAssignmentInstruction` which will be used for assigning to stack arrays at a given index
* Instructions
- Added implementation for `StackArrayIndexAssignmentInstruction` which represents the assignment of some `Value` instruction to a stack-based array (indicated by the `arrayName` string field) at the index indicated by the provided `Value` instruction
* DGen
- Added a stub emitter for `ArrayIndexInstruction` (pointer-based array indexing)
- Added a stub emitter for `StackArrayINdexInstruction` (stack-array based array indexing)
* INstructions
- Added `getArrayName()`, `getIndexInstr()` and `getAssignedValue()` to `StackArrayIndexAssignmentInstruction`
* Instructions
- Added `ArrayIndexAssignmentInstruction` which is intended to be used for when one wants to assign into a pointer-based array
- It embeds a `Value` instruction which is what is to be assigned and then an `ArrayIndexInstruction` representing the base of the poiinter-based array (base address) coupled with an "index" (offset)
- Added a `toString()` override for `StackArrayIndexAssignmentInstruction`
* Test cases
- Added `complex_stack_arrays1.t`
- This tests a stack array of a fixed size of `int[]` (basically `int*`) and assigneing into it
* Test cases
- Added `simple_arrays4.t` which makes an `int[]` (which is an `int*`) and then assignes into it at `i` whilst referring to itself at `i` and doing a binary operation
* Test cases
- Added `simple_stack_arrays2.t` which tests a stack array of a fixed size and then assigns into it a value
* Test cases
- Added `simple_stack_arrays4.t` which just tests assigning to a stack array of a fixed size BUT referring to said stack array itself as part of the assignment expression
* DGen
- Removed TODO comment for `ArrayIndexInstruction` transformation branch
- Added a description for when the `ArrayIndexInstruction` branch is activated for a transformation
- Implemented transformation for `ArrayIndexInstruction`
- Added comment on when `ArrayIndexAssignmentInstruction` activates
- Implemented transformation for `ArrayIndexAssignmentInstruction`
- Added comment for when the `StackArrayIndexInstruction` branch activates
- Implemented transformation for `StackArrayIndexInstruction`
- Added comment for when `StackArrayIndexAssignmentInstruction` branch activates
- Implemented transformation for `StackArrayIndexAssignmentInstruction`
* Dependency
- Added dependency node generation for the `ArrayIndex`
- This will pool the `ArrayIndex` parser-node
- This will then set the context of the parser-node to the current context
- The index expression will be depended upon
- The indexed expression (the entity being indexed) will be depended upon
---
- Added dependency generation for `ArrayAssignment`
- The `ArrayAssignment` parser node will be pooled
- The `ArrayAssignment` will have its context set to the current context
- The assigned expression will be depended upon
- The entity being indexed will be depended upon
- The index expression will be depended upon
* Parser
- Added a branch to `parseName()` which handles array assignments's semicolon consumption and token cursor movement to the next token
- Updated `parseTypedDeclaration()` to return an object of type `Statement` rather than `TypedEntity`
- Disabled the intentional `assert(false)` when handling array assignments
- Assign the generated `ArrayAssignment` to the `generated` variable
- Updated `parseExtern()` to cast to `TypedEntity` to ensure that the `Statement` returned is of that sub-type (added an assertion to then check this fact)
* Typechecker/Codegen
- Implemented `isStackArray(Value)` which checks if the given `Value` instruction is a `FetchValueVar`, then extracts the `Variable` being referred to in said instruction and checks if its declared type is that of `StackArray`
- Implemented code generation for `ArrayAssignment`
- Implemented code generation for `ArrayIndex`
* Test cases
- WIP: Added `simple_stack_array_coerce.t` as we want to add coercion for this now
* Typecheck
- Added rudimentary check for checking if an argument is a stack array, and if the parameter (to a function call) is a pointer and if so then returns whether they have matching component types in a new function named `canCoerceStackArray(Type, Type)`
* Typecheck
- Fixed `canCoerceStackArray(Type, Type)` to actually coerce the first type first into a pointer type (coercing the stack array's component type to `<compType>*`) and THEN apply the `isSameType(Type, Type)` check
* Typecheck
- Hoisted up `canCoerceStackArray(Type, Type)` to the class-level of `TypeChecker`
- Removed debug prints from `canCoerceStackArray(Type, Type)`
- Added a TODO where the check should be done in the `FunctionCall` branch of the `DNode` processor
* TypeChecker
- Added a seperate check for function call `DNode` processing which now checks if we can coerce the stack-array-based argument to the pointer-based type parameter
Notes
- Emit now fails as we haven't implement an emit for this case, so we need to do that.
- Also, should we change the type of what is being passed in - perhaps that actually makes sense here - we haven't fully coerced it actually
* TypeChecker
- Updated `canCoerceStackArray(Type, Type)` to now take in `canCoerceStackArray(Type, Type, ref Type)` to set the newly created coerced type
- Fixed bug whereby if the coercion succeeded we didn't actually add to the list of evaluation-instructions in the `FuncCallInstr` object, hence there would be a `null` Instruction object appearing in the code emit phase.
- Added some NOTEs which we can clean up this code using
* TypeChecker
- Cleaned up commented-out code
* Added CI/CD test for 'simple_stack_array_coerce.t'
* Added CI/CD test for 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_stack_array_coerce.t' and 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Fixed filepath for test 'simple_arrays.t'
* Fixed typechecking tests for arrays
* DGen
- Added instrumentation for `simple_stack_array_coerce.t`
Test cases
- Updated `simple_stack_array_coerce.t` to update the array passed in a manner such that we can sum the two elements later, return it and assert to ensure it is set correctly
* Parser
- Had to ensure the old identifier code was removed too, was too early; therefore this now-dead code was removed
* Test cases
- Added this test (even though it is a bad test, the syntax ie wrong)
* Test cases
- Update `simple_stack_arrsys4.t` to return an `int` such that we can verify it works.
- Also added more tests to it.
DGen
- Added semantic test code generation for `simple_stack_arrays4.t`
CI
- Re-organised tests for semantics in emit for arrays into those "Which have semantic tests" and "those which don't (yet)"
- Added semantic/emit test for `simple_stack_arrays4.t`
* Test cases
- Updated `simple_arrays2.t` to test casting of complex array types
* Test cases
- Updated `complex_stack_arrays1.t`
* Test cases
- Added new test for testing pointer syntax; `simple_stack_array_coerce_ptr_syntax.t`
- FIXME: It is broken as we don't have the latest pointer code - that must still be finished
* Test cases
- Added test case `simple_stack_array_ceorce_wrong.t` where coercion must fail
* Test cases
- Added `simple_pointer_array_syntax.t` which should test the `int[] == int*` stuff
* DGen
- Made semantic test for `simple_pointer_array_syntax.t`
Test cases
- Added a test for `simple_pointer_array_syntax.t.t`
* Branding
- Added logo here
* Test cases
- Addes semantic code emit instrucmentation for `simple_stack_array_coerce_ptr_syntax.t`
* Pipelines
- Added test case for `source/tlang/testing/simple_stack_array_coerce_wrong.t` for typechecking phase
* Test cases
- Added test case `complex_stack_array_coerce.t`
* Test cases
- Added extensive positive test case `complex_stack_array_coerce_permutation_good.t` which has a lot of different ways to write `int**` (think `int*[]` etc)
- Added negative test cases `complex_stack_array_coerce_bad1.t`, `complex_stack_array_coerce_bad2.t` and `complex_stack_array_coerce_bad3.t`
2023-04-20 10:21:50 +01:00
}
/ * *
* Array assignments ( pointer - based arrays )
*
* Handles `myArray[<index>] = <expression>` where `myArray`
* is of type `int[]` ( i . e . `int*` )
* /
else if ( cast ( ArrayIndexAssignmentInstruction ) instruction )
{
ArrayIndexAssignmentInstruction arrayAssignmentInstr = cast ( ArrayIndexAssignmentInstruction ) instruction ;
/ * *
* Obtain the array pointer evaluation
* /
ArrayIndexInstruction arrayPtrEval = arrayAssignmentInstr . getArrayPtrEval ( ) ;
// NOTE: See above
// /**
// * Obtain the index being assigned at
// */
// Value index = arrayAssignmentInstr.getIndexInstr();
/ * *
* Obtain the expression being assigned
* /
Value assignmentInstr = arrayAssignmentInstr . getAssignmentInstr ( ) ;
/ * *
* Emit * ( < arrayPtrVal > + < indexInstr > ) = < assignmentInstr > ;
* /
string emit ;
// NOTE: Below is done by ArrayIndexInstruction
// emit ~= "*(";
// emit ~= transform(arrayPtrEval);
// emit ~= "+";
// emit ~= transform(index);
// emit ~= ")";
emit ~ = transform ( arrayPtrEval ) ;
emit ~ = " = " ;
emit ~ = transform ( assignmentInstr ) ;
emit ~ = ";" ;
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
Array support (#1)
* Parser
- Added ability for `parseName()` to recognize array types
- Added array type handling to `parseTypedDeclaration()`
- Removed unneeded `derefCount` and comment in `parseTypedDeclaration()`
Check
- Added new symbol types `OBRACKET` and `CBRACKET`
* Tets cases
- We will now be using `simple_arrays2.t` as our testing bench for array support
* Dependency
- When a variable declaration has a kind-of type we are unaware of then print out an error message before asserting `false`
* Builtins
- `getBuiltInType(TypeChecker, string)` will now return a `Pointer` object for arrays of which the type was `<componentType>[]` (non-stack bound) as effectively they are pointers with a different syntax -doing it here means that it is transparent and typechecking, code gen and emit will just see a pointer type which makes life a lot easier
* Builtins
- Added information about the current bug faced in issue #81 (third sub-issue)
* Test cases
- Updated test case `simple_arrays2.t` to show case bug sub-issue 3 in issue #81
* Builtins
- Removed seperate handling of `<componentType>[]` and incorporated it into the pointer check, now we have fixed sub-issue 3 of issue #81
Test cases
- Updated test case `simple_arrays2.t` to showcase the aforementioned fix
* Builtins
- Updated TODO
* Builtins
- Removed comment as now fixed
* Array
- Added `getComponentType()` method which will return the array's element type
* Dependency
- When processing the `Array` type which is now to be seen as a stack-based array (fixed size), error out in processing it during variable declarations
* Builtins
- Added `bool isStackArray(string)` in order to check if a given type string is designated as a stack-array type or not
- `Type getBuiltInType(TypeChecker, string)` now can generate the `StackArray` type including the component type and the size of the stack allocation
Parser
- Added support to`parseTypedDeclaration` to be able to parse stack-based array types
- Added terminator `]` to `parseExpression()`
DGen
- Added stack-based array type transformation support to `string typeTransform(Type)`
- Added transformation support for stack-based arrays for the `VariableDeclaration` instruction
StackArray
- Renamed `Array` type to `StackArray`
` The `StackArray` type now has an `arraySize` field and is included in the constructor's paremeters
- Added a `getAllocatedSize()` method to retrieve the `arraySize` field
Dependency
- Temporarily enabled the `StackArray` type in dependency processing for `VariableDeclarations` such that we can continue through the pipeline
Test cases
- Updated `simple_arrays.t` to test stack-based array types
* Tets cases
- Added new test case for testing (later) multi-dimensional stack-arrays
* Parser
- Working on adding array index assignment support
Test cases
- Added test case to test array assignments with
* Parser
- We can now detect when infact we are doing an array-indexed assignment and when not, we then flip` arrayIndexing` to `true` if that is the case and ensure that `=` SymbolType.ASSIGN is not triggering the varaible-declaration-with-assignment but rather eters a different branch based on this boolean
- Set the identifier being assigned to (in the array indexing case) to the `type` with the `[]...` stripped
Notes
- Added a TODO file `wip.txt` with notes about what is to be done for adding full array support
* Parser
- Handle the case whereby `SymbolType.ASSIGN` or `SymbolType.IDENT_TYPE` is not found by throwing an error
* Parser
- Moved logic for array assignments into the branch for it (deferred it)
* Data
- Added new work-in-progress parser node type `ArrayAssignment`
Parser
- Added TODO about the type of returned parse node needing to be updated down the line
Notes
- Updated `wip.txt` with more thoughts
* Expressions
- Added new parse node (a sub-type of `Expression`) for representing array indexing; `ArrayIndex`
Data
- Fixed compilation error caused by missing semi-colon
* Parser
- Added support for array accesses/indexing in `parseExpression()`
- Added a token-rerun mechanism that lets us replay the needed tokens which needed to be looked ahead in order to determine an array access was about to occur
* Parser
- Removed now-completed TODO relating to array accesses in `parseExpression()`
* Parser
- Added right-hand side expression parsing for array assignments
Test cases
- Updated test case to test both array expressions on the left-hand side of an assignment and as a free-standing expression on the right hand side
Data
- Implemeneted `ArrayAssignment` which is to be used for assigning into arrays
* Instruction
- Added new instruction for indexing into arrays, a new `Value`-type instruction called `ArrayIndexInstruction`
* DGen
- Handle `ArrayIndexInstruction` which is for whenever you index into a point-based array (an expression like `myArray[i]` is now being supported in emit (first steps))
* Instructions
- Added a new instruction type, `StackArrayINdexInstruction`, which is used to know when we are indexing into a stack-based array rather than a pointer-based array (just to be able to disambiguate between the two)
- Added a work-in-progress type `StackArrayIndexAssignmentInstruction` which will be used for assigning to stack arrays at a given index
* Instructions
- Added implementation for `StackArrayIndexAssignmentInstruction` which represents the assignment of some `Value` instruction to a stack-based array (indicated by the `arrayName` string field) at the index indicated by the provided `Value` instruction
* DGen
- Added a stub emitter for `ArrayIndexInstruction` (pointer-based array indexing)
- Added a stub emitter for `StackArrayINdexInstruction` (stack-array based array indexing)
* INstructions
- Added `getArrayName()`, `getIndexInstr()` and `getAssignedValue()` to `StackArrayIndexAssignmentInstruction`
* Instructions
- Added `ArrayIndexAssignmentInstruction` which is intended to be used for when one wants to assign into a pointer-based array
- It embeds a `Value` instruction which is what is to be assigned and then an `ArrayIndexInstruction` representing the base of the poiinter-based array (base address) coupled with an "index" (offset)
- Added a `toString()` override for `StackArrayIndexAssignmentInstruction`
* Test cases
- Added `complex_stack_arrays1.t`
- This tests a stack array of a fixed size of `int[]` (basically `int*`) and assigneing into it
* Test cases
- Added `simple_arrays4.t` which makes an `int[]` (which is an `int*`) and then assignes into it at `i` whilst referring to itself at `i` and doing a binary operation
* Test cases
- Added `simple_stack_arrays2.t` which tests a stack array of a fixed size and then assigns into it a value
* Test cases
- Added `simple_stack_arrays4.t` which just tests assigning to a stack array of a fixed size BUT referring to said stack array itself as part of the assignment expression
* DGen
- Removed TODO comment for `ArrayIndexInstruction` transformation branch
- Added a description for when the `ArrayIndexInstruction` branch is activated for a transformation
- Implemented transformation for `ArrayIndexInstruction`
- Added comment on when `ArrayIndexAssignmentInstruction` activates
- Implemented transformation for `ArrayIndexAssignmentInstruction`
- Added comment for when the `StackArrayIndexInstruction` branch activates
- Implemented transformation for `StackArrayIndexInstruction`
- Added comment for when `StackArrayIndexAssignmentInstruction` branch activates
- Implemented transformation for `StackArrayIndexAssignmentInstruction`
* Dependency
- Added dependency node generation for the `ArrayIndex`
- This will pool the `ArrayIndex` parser-node
- This will then set the context of the parser-node to the current context
- The index expression will be depended upon
- The indexed expression (the entity being indexed) will be depended upon
---
- Added dependency generation for `ArrayAssignment`
- The `ArrayAssignment` parser node will be pooled
- The `ArrayAssignment` will have its context set to the current context
- The assigned expression will be depended upon
- The entity being indexed will be depended upon
- The index expression will be depended upon
* Parser
- Added a branch to `parseName()` which handles array assignments's semicolon consumption and token cursor movement to the next token
- Updated `parseTypedDeclaration()` to return an object of type `Statement` rather than `TypedEntity`
- Disabled the intentional `assert(false)` when handling array assignments
- Assign the generated `ArrayAssignment` to the `generated` variable
- Updated `parseExtern()` to cast to `TypedEntity` to ensure that the `Statement` returned is of that sub-type (added an assertion to then check this fact)
* Typechecker/Codegen
- Implemented `isStackArray(Value)` which checks if the given `Value` instruction is a `FetchValueVar`, then extracts the `Variable` being referred to in said instruction and checks if its declared type is that of `StackArray`
- Implemented code generation for `ArrayAssignment`
- Implemented code generation for `ArrayIndex`
* Test cases
- WIP: Added `simple_stack_array_coerce.t` as we want to add coercion for this now
* Typecheck
- Added rudimentary check for checking if an argument is a stack array, and if the parameter (to a function call) is a pointer and if so then returns whether they have matching component types in a new function named `canCoerceStackArray(Type, Type)`
* Typecheck
- Fixed `canCoerceStackArray(Type, Type)` to actually coerce the first type first into a pointer type (coercing the stack array's component type to `<compType>*`) and THEN apply the `isSameType(Type, Type)` check
* Typecheck
- Hoisted up `canCoerceStackArray(Type, Type)` to the class-level of `TypeChecker`
- Removed debug prints from `canCoerceStackArray(Type, Type)`
- Added a TODO where the check should be done in the `FunctionCall` branch of the `DNode` processor
* TypeChecker
- Added a seperate check for function call `DNode` processing which now checks if we can coerce the stack-array-based argument to the pointer-based type parameter
Notes
- Emit now fails as we haven't implement an emit for this case, so we need to do that.
- Also, should we change the type of what is being passed in - perhaps that actually makes sense here - we haven't fully coerced it actually
* TypeChecker
- Updated `canCoerceStackArray(Type, Type)` to now take in `canCoerceStackArray(Type, Type, ref Type)` to set the newly created coerced type
- Fixed bug whereby if the coercion succeeded we didn't actually add to the list of evaluation-instructions in the `FuncCallInstr` object, hence there would be a `null` Instruction object appearing in the code emit phase.
- Added some NOTEs which we can clean up this code using
* TypeChecker
- Cleaned up commented-out code
* Added CI/CD test for 'simple_stack_array_coerce.t'
* Added CI/CD test for 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_stack_array_coerce.t' and 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Fixed filepath for test 'simple_arrays.t'
* Fixed typechecking tests for arrays
* DGen
- Added instrumentation for `simple_stack_array_coerce.t`
Test cases
- Updated `simple_stack_array_coerce.t` to update the array passed in a manner such that we can sum the two elements later, return it and assert to ensure it is set correctly
* Parser
- Had to ensure the old identifier code was removed too, was too early; therefore this now-dead code was removed
* Test cases
- Added this test (even though it is a bad test, the syntax ie wrong)
* Test cases
- Update `simple_stack_arrsys4.t` to return an `int` such that we can verify it works.
- Also added more tests to it.
DGen
- Added semantic test code generation for `simple_stack_arrays4.t`
CI
- Re-organised tests for semantics in emit for arrays into those "Which have semantic tests" and "those which don't (yet)"
- Added semantic/emit test for `simple_stack_arrays4.t`
* Test cases
- Updated `simple_arrays2.t` to test casting of complex array types
* Test cases
- Updated `complex_stack_arrays1.t`
* Test cases
- Added new test for testing pointer syntax; `simple_stack_array_coerce_ptr_syntax.t`
- FIXME: It is broken as we don't have the latest pointer code - that must still be finished
* Test cases
- Added test case `simple_stack_array_ceorce_wrong.t` where coercion must fail
* Test cases
- Added `simple_pointer_array_syntax.t` which should test the `int[] == int*` stuff
* DGen
- Made semantic test for `simple_pointer_array_syntax.t`
Test cases
- Added a test for `simple_pointer_array_syntax.t.t`
* Branding
- Added logo here
* Test cases
- Addes semantic code emit instrucmentation for `simple_stack_array_coerce_ptr_syntax.t`
* Pipelines
- Added test case for `source/tlang/testing/simple_stack_array_coerce_wrong.t` for typechecking phase
* Test cases
- Added test case `complex_stack_array_coerce.t`
* Test cases
- Added extensive positive test case `complex_stack_array_coerce_permutation_good.t` which has a lot of different ways to write `int**` (think `int*[]` etc)
- Added negative test cases `complex_stack_array_coerce_bad1.t`, `complex_stack_array_coerce_bad2.t` and `complex_stack_array_coerce_bad3.t`
2023-04-20 10:21:50 +01:00
}
/ * *
* Array indexing ( stack - based arrays )
*
* Handles `myArray[<index>]` where `myArray` is
* of type `int[<size>]` ( i . e . a stack - array )
* /
else if ( cast ( StackArrayIndexInstruction ) instruction )
{
StackArrayIndexInstruction stackArrInstr = cast ( StackArrayIndexInstruction ) instruction ;
Context context = stackArrInstr . getContext ( ) ;
/* Obtain the stack array variable being indexed */
// TODO: Investigate, nroamlly we do a `FetchValueVar` as like the instr which is fine actually
FetchValueVar array = cast ( FetchValueVar ) stackArrInstr . getIndexedToInstr ( ) ;
assert ( array ) ;
Variable arrayVariable = cast ( Variable ) typeChecker . getResolver ( ) . resolveBest ( context . getContainer ( ) , array . varName ) ;
/* Perform symbol mapping */
string arrayName = mapper . symbolLookup ( arrayVariable ) ;
/* Obtain the index expression */
Value indexInstr = stackArrInstr . getIndexInstr ( ) ;
/ * *
* Emit < arrayName > [ < index > ]
* /
string emit = arrayName ;
emit ~ = "[" ;
emit ~ = transform ( indexInstr ) ;
emit ~ = "]" ;
gprintln ( "TODO: Implement Stack-array index emit" , DebugType . ERROR ) ;
// return "(TODO: Stack-array index emit)";
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
Array support (#1)
* Parser
- Added ability for `parseName()` to recognize array types
- Added array type handling to `parseTypedDeclaration()`
- Removed unneeded `derefCount` and comment in `parseTypedDeclaration()`
Check
- Added new symbol types `OBRACKET` and `CBRACKET`
* Tets cases
- We will now be using `simple_arrays2.t` as our testing bench for array support
* Dependency
- When a variable declaration has a kind-of type we are unaware of then print out an error message before asserting `false`
* Builtins
- `getBuiltInType(TypeChecker, string)` will now return a `Pointer` object for arrays of which the type was `<componentType>[]` (non-stack bound) as effectively they are pointers with a different syntax -doing it here means that it is transparent and typechecking, code gen and emit will just see a pointer type which makes life a lot easier
* Builtins
- Added information about the current bug faced in issue #81 (third sub-issue)
* Test cases
- Updated test case `simple_arrays2.t` to show case bug sub-issue 3 in issue #81
* Builtins
- Removed seperate handling of `<componentType>[]` and incorporated it into the pointer check, now we have fixed sub-issue 3 of issue #81
Test cases
- Updated test case `simple_arrays2.t` to showcase the aforementioned fix
* Builtins
- Updated TODO
* Builtins
- Removed comment as now fixed
* Array
- Added `getComponentType()` method which will return the array's element type
* Dependency
- When processing the `Array` type which is now to be seen as a stack-based array (fixed size), error out in processing it during variable declarations
* Builtins
- Added `bool isStackArray(string)` in order to check if a given type string is designated as a stack-array type or not
- `Type getBuiltInType(TypeChecker, string)` now can generate the `StackArray` type including the component type and the size of the stack allocation
Parser
- Added support to`parseTypedDeclaration` to be able to parse stack-based array types
- Added terminator `]` to `parseExpression()`
DGen
- Added stack-based array type transformation support to `string typeTransform(Type)`
- Added transformation support for stack-based arrays for the `VariableDeclaration` instruction
StackArray
- Renamed `Array` type to `StackArray`
` The `StackArray` type now has an `arraySize` field and is included in the constructor's paremeters
- Added a `getAllocatedSize()` method to retrieve the `arraySize` field
Dependency
- Temporarily enabled the `StackArray` type in dependency processing for `VariableDeclarations` such that we can continue through the pipeline
Test cases
- Updated `simple_arrays.t` to test stack-based array types
* Tets cases
- Added new test case for testing (later) multi-dimensional stack-arrays
* Parser
- Working on adding array index assignment support
Test cases
- Added test case to test array assignments with
* Parser
- We can now detect when infact we are doing an array-indexed assignment and when not, we then flip` arrayIndexing` to `true` if that is the case and ensure that `=` SymbolType.ASSIGN is not triggering the varaible-declaration-with-assignment but rather eters a different branch based on this boolean
- Set the identifier being assigned to (in the array indexing case) to the `type` with the `[]...` stripped
Notes
- Added a TODO file `wip.txt` with notes about what is to be done for adding full array support
* Parser
- Handle the case whereby `SymbolType.ASSIGN` or `SymbolType.IDENT_TYPE` is not found by throwing an error
* Parser
- Moved logic for array assignments into the branch for it (deferred it)
* Data
- Added new work-in-progress parser node type `ArrayAssignment`
Parser
- Added TODO about the type of returned parse node needing to be updated down the line
Notes
- Updated `wip.txt` with more thoughts
* Expressions
- Added new parse node (a sub-type of `Expression`) for representing array indexing; `ArrayIndex`
Data
- Fixed compilation error caused by missing semi-colon
* Parser
- Added support for array accesses/indexing in `parseExpression()`
- Added a token-rerun mechanism that lets us replay the needed tokens which needed to be looked ahead in order to determine an array access was about to occur
* Parser
- Removed now-completed TODO relating to array accesses in `parseExpression()`
* Parser
- Added right-hand side expression parsing for array assignments
Test cases
- Updated test case to test both array expressions on the left-hand side of an assignment and as a free-standing expression on the right hand side
Data
- Implemeneted `ArrayAssignment` which is to be used for assigning into arrays
* Instruction
- Added new instruction for indexing into arrays, a new `Value`-type instruction called `ArrayIndexInstruction`
* DGen
- Handle `ArrayIndexInstruction` which is for whenever you index into a point-based array (an expression like `myArray[i]` is now being supported in emit (first steps))
* Instructions
- Added a new instruction type, `StackArrayINdexInstruction`, which is used to know when we are indexing into a stack-based array rather than a pointer-based array (just to be able to disambiguate between the two)
- Added a work-in-progress type `StackArrayIndexAssignmentInstruction` which will be used for assigning to stack arrays at a given index
* Instructions
- Added implementation for `StackArrayIndexAssignmentInstruction` which represents the assignment of some `Value` instruction to a stack-based array (indicated by the `arrayName` string field) at the index indicated by the provided `Value` instruction
* DGen
- Added a stub emitter for `ArrayIndexInstruction` (pointer-based array indexing)
- Added a stub emitter for `StackArrayINdexInstruction` (stack-array based array indexing)
* INstructions
- Added `getArrayName()`, `getIndexInstr()` and `getAssignedValue()` to `StackArrayIndexAssignmentInstruction`
* Instructions
- Added `ArrayIndexAssignmentInstruction` which is intended to be used for when one wants to assign into a pointer-based array
- It embeds a `Value` instruction which is what is to be assigned and then an `ArrayIndexInstruction` representing the base of the poiinter-based array (base address) coupled with an "index" (offset)
- Added a `toString()` override for `StackArrayIndexAssignmentInstruction`
* Test cases
- Added `complex_stack_arrays1.t`
- This tests a stack array of a fixed size of `int[]` (basically `int*`) and assigneing into it
* Test cases
- Added `simple_arrays4.t` which makes an `int[]` (which is an `int*`) and then assignes into it at `i` whilst referring to itself at `i` and doing a binary operation
* Test cases
- Added `simple_stack_arrays2.t` which tests a stack array of a fixed size and then assigns into it a value
* Test cases
- Added `simple_stack_arrays4.t` which just tests assigning to a stack array of a fixed size BUT referring to said stack array itself as part of the assignment expression
* DGen
- Removed TODO comment for `ArrayIndexInstruction` transformation branch
- Added a description for when the `ArrayIndexInstruction` branch is activated for a transformation
- Implemented transformation for `ArrayIndexInstruction`
- Added comment on when `ArrayIndexAssignmentInstruction` activates
- Implemented transformation for `ArrayIndexAssignmentInstruction`
- Added comment for when the `StackArrayIndexInstruction` branch activates
- Implemented transformation for `StackArrayIndexInstruction`
- Added comment for when `StackArrayIndexAssignmentInstruction` branch activates
- Implemented transformation for `StackArrayIndexAssignmentInstruction`
* Dependency
- Added dependency node generation for the `ArrayIndex`
- This will pool the `ArrayIndex` parser-node
- This will then set the context of the parser-node to the current context
- The index expression will be depended upon
- The indexed expression (the entity being indexed) will be depended upon
---
- Added dependency generation for `ArrayAssignment`
- The `ArrayAssignment` parser node will be pooled
- The `ArrayAssignment` will have its context set to the current context
- The assigned expression will be depended upon
- The entity being indexed will be depended upon
- The index expression will be depended upon
* Parser
- Added a branch to `parseName()` which handles array assignments's semicolon consumption and token cursor movement to the next token
- Updated `parseTypedDeclaration()` to return an object of type `Statement` rather than `TypedEntity`
- Disabled the intentional `assert(false)` when handling array assignments
- Assign the generated `ArrayAssignment` to the `generated` variable
- Updated `parseExtern()` to cast to `TypedEntity` to ensure that the `Statement` returned is of that sub-type (added an assertion to then check this fact)
* Typechecker/Codegen
- Implemented `isStackArray(Value)` which checks if the given `Value` instruction is a `FetchValueVar`, then extracts the `Variable` being referred to in said instruction and checks if its declared type is that of `StackArray`
- Implemented code generation for `ArrayAssignment`
- Implemented code generation for `ArrayIndex`
* Test cases
- WIP: Added `simple_stack_array_coerce.t` as we want to add coercion for this now
* Typecheck
- Added rudimentary check for checking if an argument is a stack array, and if the parameter (to a function call) is a pointer and if so then returns whether they have matching component types in a new function named `canCoerceStackArray(Type, Type)`
* Typecheck
- Fixed `canCoerceStackArray(Type, Type)` to actually coerce the first type first into a pointer type (coercing the stack array's component type to `<compType>*`) and THEN apply the `isSameType(Type, Type)` check
* Typecheck
- Hoisted up `canCoerceStackArray(Type, Type)` to the class-level of `TypeChecker`
- Removed debug prints from `canCoerceStackArray(Type, Type)`
- Added a TODO where the check should be done in the `FunctionCall` branch of the `DNode` processor
* TypeChecker
- Added a seperate check for function call `DNode` processing which now checks if we can coerce the stack-array-based argument to the pointer-based type parameter
Notes
- Emit now fails as we haven't implement an emit for this case, so we need to do that.
- Also, should we change the type of what is being passed in - perhaps that actually makes sense here - we haven't fully coerced it actually
* TypeChecker
- Updated `canCoerceStackArray(Type, Type)` to now take in `canCoerceStackArray(Type, Type, ref Type)` to set the newly created coerced type
- Fixed bug whereby if the coercion succeeded we didn't actually add to the list of evaluation-instructions in the `FuncCallInstr` object, hence there would be a `null` Instruction object appearing in the code emit phase.
- Added some NOTEs which we can clean up this code using
* TypeChecker
- Cleaned up commented-out code
* Added CI/CD test for 'simple_stack_array_coerce.t'
* Added CI/CD test for 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_stack_array_coerce.t' and 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Fixed filepath for test 'simple_arrays.t'
* Fixed typechecking tests for arrays
* DGen
- Added instrumentation for `simple_stack_array_coerce.t`
Test cases
- Updated `simple_stack_array_coerce.t` to update the array passed in a manner such that we can sum the two elements later, return it and assert to ensure it is set correctly
* Parser
- Had to ensure the old identifier code was removed too, was too early; therefore this now-dead code was removed
* Test cases
- Added this test (even though it is a bad test, the syntax ie wrong)
* Test cases
- Update `simple_stack_arrsys4.t` to return an `int` such that we can verify it works.
- Also added more tests to it.
DGen
- Added semantic test code generation for `simple_stack_arrays4.t`
CI
- Re-organised tests for semantics in emit for arrays into those "Which have semantic tests" and "those which don't (yet)"
- Added semantic/emit test for `simple_stack_arrays4.t`
* Test cases
- Updated `simple_arrays2.t` to test casting of complex array types
* Test cases
- Updated `complex_stack_arrays1.t`
* Test cases
- Added new test for testing pointer syntax; `simple_stack_array_coerce_ptr_syntax.t`
- FIXME: It is broken as we don't have the latest pointer code - that must still be finished
* Test cases
- Added test case `simple_stack_array_ceorce_wrong.t` where coercion must fail
* Test cases
- Added `simple_pointer_array_syntax.t` which should test the `int[] == int*` stuff
* DGen
- Made semantic test for `simple_pointer_array_syntax.t`
Test cases
- Added a test for `simple_pointer_array_syntax.t.t`
* Branding
- Added logo here
* Test cases
- Addes semantic code emit instrucmentation for `simple_stack_array_coerce_ptr_syntax.t`
* Pipelines
- Added test case for `source/tlang/testing/simple_stack_array_coerce_wrong.t` for typechecking phase
* Test cases
- Added test case `complex_stack_array_coerce.t`
* Test cases
- Added extensive positive test case `complex_stack_array_coerce_permutation_good.t` which has a lot of different ways to write `int**` (think `int*[]` etc)
- Added negative test cases `complex_stack_array_coerce_bad1.t`, `complex_stack_array_coerce_bad2.t` and `complex_stack_array_coerce_bad3.t`
2023-04-20 10:21:50 +01:00
}
/ * *
* Array assignments ( stack - based arrays )
*
* Handles `myArray[<index>] = <expression>` where `myArray`
* is of type `int[<size>]` ( i . e . a stack - array )
* /
else if ( cast ( StackArrayIndexAssignmentInstruction ) instruction )
{
StackArrayIndexAssignmentInstruction stackArrAssInstr = cast ( StackArrayIndexAssignmentInstruction ) instruction ;
Context context = stackArrAssInstr . getContext ( ) ;
assert ( context ) ;
/ * *
* Obtain the stack array being assigned to
* /
string arrayName = stackArrAssInstr . getArrayName ( ) ;
Variable arrayVariable = cast ( Variable ) typeChecker . getResolver ( ) . resolveBest ( context . getContainer ( ) , arrayName ) ;
/* Perform symbol mapping */
string arrayNameMapped = mapper . symbolLookup ( arrayVariable ) ;
/* Obtain the index expression */
Value indexInstr = stackArrAssInstr . getIndexInstr ( ) ;
/* Obtain the expresison being assigned */
Value assignmentInstr = stackArrAssInstr . getAssignedValue ( ) ;
/ * *
* Emit < arrayName > [ < index > ] = < expression > ;
* /
string emit = arrayNameMapped ;
emit ~ = "[" ;
emit ~ = transform ( indexInstr ) ;
emit ~ = "]" ;
emit ~ = " = " ;
emit ~ = transform ( assignmentInstr ) ;
emit ~ = ";" ;
// return "(StackArrAssignmentInstr: TODO)";
2023-08-17 07:46:59 +01:00
emmmmit = emit ;
2023-01-11 08:43:29 +00:00
}
2023-01-15 18:48:40 +00:00
// TODO: MAAAAN we don't even have this yet
// else if(cast(StringExpression))
2023-08-17 07:46:59 +01:00
/ * *
* Unsupported instruction
*
* If you get here then normally it ' s because
* you didn ' t implement a transformation for
* an instruction yet .
* /
else
{
emmmmit = "<TODO: Base emit: " ~ to ! ( string ) ( instruction ) ~ ">" ;
}
2022-12-13 09:45:45 +00:00
2023-08-17 07:46:59 +01:00
return emmmmit ;
2022-12-11 19:41:15 +00:00
}
2022-12-12 13:36:07 +00:00
2021-11-02 08:41:03 +00:00
public override void emit ( )
{
2022-12-11 19:00:48 +00:00
// Emit header comment (NOTE: Change this to a useful piece of text)
emitHeaderComment ( "Place any extra information by code generator here" ) ; // NOTE: We can pass a string with extra information to it if we want to
2022-12-11 15:52:36 +00:00
2023-01-15 10:36:54 +00:00
// Emit standard integer header import
emitStdint ( ) ;
2022-12-17 12:31:03 +00:00
// Emit static allocation code
2022-12-12 17:12:39 +00:00
emitStaticAllocations ( ) ;
2022-12-11 15:52:36 +00:00
2022-12-17 12:31:03 +00:00
// Emit globals
2022-12-16 12:53:33 +00:00
emitCodeQueue ( ) ;
2022-12-17 12:31:03 +00:00
// Emit function definitions
2023-01-13 09:22:47 +00:00
emitFunctionPrototypes ( ) ;
2022-12-14 17:49:08 +00:00
emitFunctionDefinitions ( ) ;
2023-01-19 19:06:20 +00:00
// If enabled (default: yes) then emit entry point (TODO: change later)
2023-01-28 16:12:49 +00:00
if ( config . getConfig ( "dgen:emit_entrypoint_test" ) . getBoolean ( ) )
2023-01-19 19:06:20 +00:00
{
//TODO: Emit main (entry point)
emitEntryPoint ( ) ;
}
2022-12-11 15:52:36 +00:00
}
2022-12-11 15:58:33 +00:00
/ * *
* Emits the header comment which contains information about the source
* file and the generated code file
*
* Params :
* headerPhrase = Optional additional string information to add to the header comment
* /
2022-12-11 15:52:36 +00:00
private void emitHeaderComment ( string headerPhrase = "" )
{
2022-12-11 16:01:54 +00:00
// NOTE: We could maybe fetch input fiel info too? Although it would have to be named similiarly in any case
// so perhaps just appending a `.t` to the module name below would be fine
2022-12-11 15:57:16 +00:00
string moduleName = typeChecker . getResolver ( ) . generateName ( typeChecker . getModule ( ) , typeChecker . getModule ( ) ) ; //TODO: Lookup actual module name (I was lazy)
2022-12-11 15:52:36 +00:00
string outputCFilename = file . name ( ) ;
2022-12-11 16:09:56 +00:00
file . write ( ` / * *
2022-12-11 15:52:36 +00:00
* TLP compiler generated code
*
* Module name : ` ) ;
file . writeln ( moduleName ) ;
file . write ( " * Output C file: " ) ;
file . writeln ( outputCFilename ) ;
2022-12-11 15:55:18 +00:00
if ( headerPhrase . length )
{
2022-12-11 19:00:48 +00:00
file . write ( wrap ( headerPhrase , 40 , " *\n * " , " * " ) ) ;
2022-12-11 15:55:18 +00:00
}
2022-12-11 15:52:36 +00:00
2022-12-11 19:00:48 +00:00
file . write ( " */\n" ) ;
2022-12-11 15:52:36 +00:00
}
/ * *
* Emits the static allocations provided
*
* Params :
* initQueue = The allocation queue to emit static allocations from
* /
2022-12-12 17:12:39 +00:00
private void emitStaticAllocations ( )
2022-12-11 15:52:36 +00:00
{
2022-12-14 17:49:08 +00:00
selectQueue ( QueueType . ALLOC_QUEUE ) ;
gprintln ( "Static allocations needed: " ~ to ! ( string ) ( getQueueLength ( ) ) ) ;
2022-12-16 12:53:33 +00:00
file . writeln ( ) ;
2022-12-14 17:49:08 +00:00
}
/ * *
2023-01-13 09:22:47 +00:00
* Emits the function prototypes
* /
private void emitFunctionPrototypes ( )
{
gprintln ( "Function definitions needed: " ~ to ! ( string ) ( getFunctionDefinitionsCount ( ) ) ) ;
Instruction [ ] [ string ] functionBodyInstrs = typeChecker . getFunctionBodyCodeQueues ( ) ;
string [ ] functionNames = getFunctionDefinitionNames ( ) ;
gprintln ( "WOAH: " ~ to ! ( string ) ( functionNames ) ) ;
foreach ( string currentFunctioName ; functionNames )
{
emitFunctionPrototype ( currentFunctioName ) ;
file . writeln ( ) ;
}
}
/ * *
* Emits the function definitions
2022-12-14 17:49:08 +00:00
* /
private void emitFunctionDefinitions ( )
{
2022-12-16 12:53:33 +00:00
gprintln ( "Function definitions needed: " ~ to ! ( string ) ( getFunctionDefinitionsCount ( ) ) ) ;
2022-12-14 17:49:08 +00:00
Instruction [ ] [ string ] functionBodyInstrs = typeChecker . getFunctionBodyCodeQueues ( ) ;
string [ ] functionNames = getFunctionDefinitionNames ( ) ;
gprintln ( "WOAH: " ~ to ! ( string ) ( functionNames ) ) ;
foreach ( string currentFunctioName ; functionNames )
{
emitFunctionDefinition ( currentFunctioName ) ;
2022-12-16 12:53:33 +00:00
file . writeln ( ) ;
2023-01-13 09:22:47 +00:00
}
2022-12-14 17:49:08 +00:00
}
private string generateSignature ( Function func )
{
string signature ;
2023-01-15 10:40:42 +00:00
// Extract the Function's return Type
2023-01-15 10:36:54 +00:00
Type returnType = typeChecker . getType ( func . context . container , func . getType ( ) ) ;
2022-12-14 17:49:08 +00:00
// <type> <functionName> (
2023-01-15 10:36:54 +00:00
signature = typeTransform ( returnType ) ~ " " ~ func . getName ( ) ~ "(" ;
2022-12-14 17:49:08 +00:00
// Generate parameter list
if ( func . hasParams ( ) )
{
2022-12-17 12:00:16 +00:00
VariableParameter [ ] parameters = func . getParams ( ) ;
2022-12-14 17:49:08 +00:00
string parameterString ;
for ( ulong parIdx = 0 ; parIdx < parameters . length ; parIdx + + )
{
Variable currentParameter = parameters [ parIdx ] ;
2022-12-17 12:00:16 +00:00
2023-01-15 10:40:42 +00:00
// Extract the variable's type
Type parameterType = typeChecker . getType ( currentParameter . context . container , currentParameter . getType ( ) ) ;
2022-12-17 12:00:16 +00:00
// Generate the symbol-mapped names for the parameters
Variable typedEntityVariable = cast ( Variable ) typeChecker . getResolver ( ) . resolveBest ( func , currentParameter . getName ( ) ) ; //TODO: Remove `auto`
2023-01-23 18:44:35 +00:00
string renamedSymbol = mapper . symbolLookup ( typedEntityVariable ) ;
2022-12-17 12:00:16 +00:00
// Generate <type> <parameter-name (symbol mapped)>
2023-01-15 10:40:42 +00:00
parameterString ~ = typeTransform ( parameterType ) ~ " " ~ renamedSymbol ;
2022-12-14 17:49:08 +00:00
if ( parIdx ! = ( parameters . length - 1 ) )
{
parameterString ~ = ", " ;
}
}
signature ~ = parameterString ;
}
// )
signature ~ = ")" ;
2023-01-15 18:48:40 +00:00
// If the function is marked as external then place `extern` infront
if ( func . isExternal ( ) )
{
signature = "extern " ~ signature ;
}
2022-12-14 17:49:08 +00:00
return signature ;
}
2023-01-13 09:22:47 +00:00
private void emitFunctionPrototype ( string functionName )
{
selectQueue ( QueueType . FUNCTION_DEF_QUEUE , functionName ) ;
gprintln ( "emotFunctionDefinition(): Function: " ~ functionName ~ ", with " ~ to ! ( string ) ( getSelectedQueueLength ( ) ) ~ " many instructions" ) ;
//TODO: Look at nested definitions or nah? (Context!!)
//TODO: And what about methods defined in classes? Those should technically be here too
Function functionEntity = cast ( Function ) typeChecker . getResolver ( ) . resolveBest ( typeChecker . getModule ( ) , functionName ) ; //TODO: Remove `auto`
// Emit the function signature
file . writeln ( generateSignature ( functionEntity ) ~ ";" ) ;
}
2022-12-14 17:49:08 +00:00
private void emitFunctionDefinition ( string functionName )
{
selectQueue ( QueueType . FUNCTION_DEF_QUEUE , functionName ) ;
2022-12-16 12:53:33 +00:00
gprintln ( "emotFunctionDefinition(): Function: " ~ functionName ~ ", with " ~ to ! ( string ) ( getSelectedQueueLength ( ) ) ~ " many instructions" ) ;
2022-12-14 17:49:08 +00:00
//TODO: Look at nested definitions or nah? (Context!!)
//TODO: And what about methods defined in classes? Those should technically be here too
Function functionEntity = cast ( Function ) typeChecker . getResolver ( ) . resolveBest ( typeChecker . getModule ( ) , functionName ) ; //TODO: Remove `auto`
2023-01-15 18:48:40 +00:00
// If the Entity is NOT external then emit the signature+body
if ( ! functionEntity . isExternal ( ) )
{
// Emit the function signature
file . writeln ( generateSignature ( functionEntity ) ) ;
2022-12-14 17:49:08 +00:00
2023-01-15 18:48:40 +00:00
// Emit opening curly brace
file . writeln ( getCharacter ( SymbolType . OCURLY ) ) ;
2022-12-11 15:52:36 +00:00
2023-01-15 18:48:40 +00:00
// Emit body
while ( hasInstructions ( ) )
{
Instruction curFuncBodyInstr = getCurrentInstruction ( ) ;
2022-12-14 17:49:08 +00:00
2023-01-15 18:48:40 +00:00
string emit = transform ( curFuncBodyInstr ) ;
gprintln ( "emitFunctionDefinition(" ~ functionName ~ "): Emit: " ~ emit ) ;
file . writeln ( "\t" ~ emit ) ;
nextInstruction ( ) ;
}
2022-12-14 17:49:08 +00:00
2023-01-15 18:48:40 +00:00
// Emit closing curly brace
file . writeln ( getCharacter ( SymbolType . CCURLY ) ) ;
}
// If the Entity IS external then don't emit anything as the signature would have been emitted via a prorotype earlier with `emitPrototypes()`
else
{
// Do nothing
}
2021-11-02 08:41:03 +00:00
}
2022-12-11 16:04:53 +00:00
2022-12-12 17:12:39 +00:00
private void emitCodeQueue ( )
2022-12-11 16:04:53 +00:00
{
2022-12-14 17:49:08 +00:00
selectQueue ( QueueType . GLOBALS_QUEUE ) ;
gprintln ( "Code emittings needed: " ~ to ! ( string ) ( getQueueLength ( ) ) ) ;
while ( hasInstructions ( ) )
2022-12-11 16:06:10 +00:00
{
2022-12-14 17:49:08 +00:00
Instruction currentInstruction = getCurrentInstruction ( ) ;
2022-12-12 13:36:07 +00:00
file . writeln ( transform ( currentInstruction ) ) ;
2022-12-12 17:12:39 +00:00
2022-12-14 17:49:08 +00:00
nextInstruction ( ) ;
2022-12-11 16:06:10 +00:00
}
2022-12-16 12:53:33 +00:00
file . writeln ( ) ;
2022-12-11 16:04:53 +00:00
}
2022-12-11 19:41:15 +00:00
2023-01-15 10:36:54 +00:00
private void emitStdint ( )
{
file . writeln ( "#include<stdint.h>" ) ;
}
2022-12-11 19:41:15 +00:00
private void emitEntryPoint ( )
{
2023-01-24 17:57:27 +00:00
// TODO: Implement me
2022-12-11 19:41:15 +00:00
2023-01-04 10:03:50 +00:00
// Test for `simple_functions.t` (function call testing)
2022-12-19 13:37:55 +00:00
if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_functions" ) = = 0 )
{
2023-01-04 10:03:50 +00:00
file . writeln ( `
2022-12-16 12:53:33 +00:00
# include < stdio . h >
2023-01-04 10:03:50 +00:00
# include < assert . h >
2022-12-11 19:41:15 +00:00
int main ( )
{
2023-01-04 10:03:50 +00:00
assert ( t_7b6d477c5859059f16bc9da72fc8cc3b = = 22 ) ;
2022-12-17 12:31:03 +00:00
printf ( "k: %u\n" , t_7b6d477c5859059f16bc9da72fc8cc3b ) ;
2023-01-04 10:03:50 +00:00
2022-12-16 12:53:33 +00:00
banana ( 1 ) ;
2023-01-04 10:03:50 +00:00
assert ( t_7b6d477c5859059f16bc9da72fc8cc3b = = 72 ) ;
2022-12-17 12:31:03 +00:00
printf ( "k: %u\n" , t_7b6d477c5859059f16bc9da72fc8cc3b ) ;
2023-01-04 10:03:50 +00:00
2023-04-28 10:03:46 +01:00
return 0 ;
} ` ) ;
}
// Test for `simple_function_recursion_factorial.t` (recursive function call testing)
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_function_recursion_factorial" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
int result = factorial ( 3 ) ;
assert ( result = = 6 ) ;
printf ( "factorial: %u\n" , result ) ;
return 0 ;
} ` ) ;
}
// Test for `simple_direct_func_call.t` (statement-level function call)
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_direct_func_call" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
// Before it should be 0
assert ( t_de44aff5a74865c97c4f8701d329f28d = = 0 ) ;
// Call the function
function ( ) ;
// After it it should be 69
assert ( t_de44aff5a74865c97c4f8701d329f28d = = 69 ) ;
2023-01-04 10:03:50 +00:00
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_while" ) = = 0 )
{
file . writeln ( `
2023-01-11 08:43:29 +00:00
# include < stdio . h >
# include < assert . h >
int main ( )
{
int result = function ( 3 ) ;
printf ( "result: %d\n" , result ) ;
assert ( result = = 3 ) ;
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_for_loops" ) = = 0 )
{
file . writeln ( `
2023-01-04 10:03:50 +00:00
# include < stdio . h >
# include < assert . h >
int main ( )
{
int result = function ( 3 ) ;
printf ( "result: %d\n" , result ) ;
assert ( result = = 3 ) ;
2023-01-12 08:53:48 +00:00
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_pointer" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
2023-01-14 10:39:37 +00:00
int retValue = thing ( ) ;
2023-01-12 08:53:48 +00:00
assert ( t_87bc875d0b65f741b69fb100a0edebc7 = = 4 ) ;
2023-01-14 10:39:37 +00:00
assert ( retValue = = 6 ) ;
2023-01-12 08:53:48 +00:00
Array support (#1)
* Parser
- Added ability for `parseName()` to recognize array types
- Added array type handling to `parseTypedDeclaration()`
- Removed unneeded `derefCount` and comment in `parseTypedDeclaration()`
Check
- Added new symbol types `OBRACKET` and `CBRACKET`
* Tets cases
- We will now be using `simple_arrays2.t` as our testing bench for array support
* Dependency
- When a variable declaration has a kind-of type we are unaware of then print out an error message before asserting `false`
* Builtins
- `getBuiltInType(TypeChecker, string)` will now return a `Pointer` object for arrays of which the type was `<componentType>[]` (non-stack bound) as effectively they are pointers with a different syntax -doing it here means that it is transparent and typechecking, code gen and emit will just see a pointer type which makes life a lot easier
* Builtins
- Added information about the current bug faced in issue #81 (third sub-issue)
* Test cases
- Updated test case `simple_arrays2.t` to show case bug sub-issue 3 in issue #81
* Builtins
- Removed seperate handling of `<componentType>[]` and incorporated it into the pointer check, now we have fixed sub-issue 3 of issue #81
Test cases
- Updated test case `simple_arrays2.t` to showcase the aforementioned fix
* Builtins
- Updated TODO
* Builtins
- Removed comment as now fixed
* Array
- Added `getComponentType()` method which will return the array's element type
* Dependency
- When processing the `Array` type which is now to be seen as a stack-based array (fixed size), error out in processing it during variable declarations
* Builtins
- Added `bool isStackArray(string)` in order to check if a given type string is designated as a stack-array type or not
- `Type getBuiltInType(TypeChecker, string)` now can generate the `StackArray` type including the component type and the size of the stack allocation
Parser
- Added support to`parseTypedDeclaration` to be able to parse stack-based array types
- Added terminator `]` to `parseExpression()`
DGen
- Added stack-based array type transformation support to `string typeTransform(Type)`
- Added transformation support for stack-based arrays for the `VariableDeclaration` instruction
StackArray
- Renamed `Array` type to `StackArray`
` The `StackArray` type now has an `arraySize` field and is included in the constructor's paremeters
- Added a `getAllocatedSize()` method to retrieve the `arraySize` field
Dependency
- Temporarily enabled the `StackArray` type in dependency processing for `VariableDeclarations` such that we can continue through the pipeline
Test cases
- Updated `simple_arrays.t` to test stack-based array types
* Tets cases
- Added new test case for testing (later) multi-dimensional stack-arrays
* Parser
- Working on adding array index assignment support
Test cases
- Added test case to test array assignments with
* Parser
- We can now detect when infact we are doing an array-indexed assignment and when not, we then flip` arrayIndexing` to `true` if that is the case and ensure that `=` SymbolType.ASSIGN is not triggering the varaible-declaration-with-assignment but rather eters a different branch based on this boolean
- Set the identifier being assigned to (in the array indexing case) to the `type` with the `[]...` stripped
Notes
- Added a TODO file `wip.txt` with notes about what is to be done for adding full array support
* Parser
- Handle the case whereby `SymbolType.ASSIGN` or `SymbolType.IDENT_TYPE` is not found by throwing an error
* Parser
- Moved logic for array assignments into the branch for it (deferred it)
* Data
- Added new work-in-progress parser node type `ArrayAssignment`
Parser
- Added TODO about the type of returned parse node needing to be updated down the line
Notes
- Updated `wip.txt` with more thoughts
* Expressions
- Added new parse node (a sub-type of `Expression`) for representing array indexing; `ArrayIndex`
Data
- Fixed compilation error caused by missing semi-colon
* Parser
- Added support for array accesses/indexing in `parseExpression()`
- Added a token-rerun mechanism that lets us replay the needed tokens which needed to be looked ahead in order to determine an array access was about to occur
* Parser
- Removed now-completed TODO relating to array accesses in `parseExpression()`
* Parser
- Added right-hand side expression parsing for array assignments
Test cases
- Updated test case to test both array expressions on the left-hand side of an assignment and as a free-standing expression on the right hand side
Data
- Implemeneted `ArrayAssignment` which is to be used for assigning into arrays
* Instruction
- Added new instruction for indexing into arrays, a new `Value`-type instruction called `ArrayIndexInstruction`
* DGen
- Handle `ArrayIndexInstruction` which is for whenever you index into a point-based array (an expression like `myArray[i]` is now being supported in emit (first steps))
* Instructions
- Added a new instruction type, `StackArrayINdexInstruction`, which is used to know when we are indexing into a stack-based array rather than a pointer-based array (just to be able to disambiguate between the two)
- Added a work-in-progress type `StackArrayIndexAssignmentInstruction` which will be used for assigning to stack arrays at a given index
* Instructions
- Added implementation for `StackArrayIndexAssignmentInstruction` which represents the assignment of some `Value` instruction to a stack-based array (indicated by the `arrayName` string field) at the index indicated by the provided `Value` instruction
* DGen
- Added a stub emitter for `ArrayIndexInstruction` (pointer-based array indexing)
- Added a stub emitter for `StackArrayINdexInstruction` (stack-array based array indexing)
* INstructions
- Added `getArrayName()`, `getIndexInstr()` and `getAssignedValue()` to `StackArrayIndexAssignmentInstruction`
* Instructions
- Added `ArrayIndexAssignmentInstruction` which is intended to be used for when one wants to assign into a pointer-based array
- It embeds a `Value` instruction which is what is to be assigned and then an `ArrayIndexInstruction` representing the base of the poiinter-based array (base address) coupled with an "index" (offset)
- Added a `toString()` override for `StackArrayIndexAssignmentInstruction`
* Test cases
- Added `complex_stack_arrays1.t`
- This tests a stack array of a fixed size of `int[]` (basically `int*`) and assigneing into it
* Test cases
- Added `simple_arrays4.t` which makes an `int[]` (which is an `int*`) and then assignes into it at `i` whilst referring to itself at `i` and doing a binary operation
* Test cases
- Added `simple_stack_arrays2.t` which tests a stack array of a fixed size and then assigns into it a value
* Test cases
- Added `simple_stack_arrays4.t` which just tests assigning to a stack array of a fixed size BUT referring to said stack array itself as part of the assignment expression
* DGen
- Removed TODO comment for `ArrayIndexInstruction` transformation branch
- Added a description for when the `ArrayIndexInstruction` branch is activated for a transformation
- Implemented transformation for `ArrayIndexInstruction`
- Added comment on when `ArrayIndexAssignmentInstruction` activates
- Implemented transformation for `ArrayIndexAssignmentInstruction`
- Added comment for when the `StackArrayIndexInstruction` branch activates
- Implemented transformation for `StackArrayIndexInstruction`
- Added comment for when `StackArrayIndexAssignmentInstruction` branch activates
- Implemented transformation for `StackArrayIndexAssignmentInstruction`
* Dependency
- Added dependency node generation for the `ArrayIndex`
- This will pool the `ArrayIndex` parser-node
- This will then set the context of the parser-node to the current context
- The index expression will be depended upon
- The indexed expression (the entity being indexed) will be depended upon
---
- Added dependency generation for `ArrayAssignment`
- The `ArrayAssignment` parser node will be pooled
- The `ArrayAssignment` will have its context set to the current context
- The assigned expression will be depended upon
- The entity being indexed will be depended upon
- The index expression will be depended upon
* Parser
- Added a branch to `parseName()` which handles array assignments's semicolon consumption and token cursor movement to the next token
- Updated `parseTypedDeclaration()` to return an object of type `Statement` rather than `TypedEntity`
- Disabled the intentional `assert(false)` when handling array assignments
- Assign the generated `ArrayAssignment` to the `generated` variable
- Updated `parseExtern()` to cast to `TypedEntity` to ensure that the `Statement` returned is of that sub-type (added an assertion to then check this fact)
* Typechecker/Codegen
- Implemented `isStackArray(Value)` which checks if the given `Value` instruction is a `FetchValueVar`, then extracts the `Variable` being referred to in said instruction and checks if its declared type is that of `StackArray`
- Implemented code generation for `ArrayAssignment`
- Implemented code generation for `ArrayIndex`
* Test cases
- WIP: Added `simple_stack_array_coerce.t` as we want to add coercion for this now
* Typecheck
- Added rudimentary check for checking if an argument is a stack array, and if the parameter (to a function call) is a pointer and if so then returns whether they have matching component types in a new function named `canCoerceStackArray(Type, Type)`
* Typecheck
- Fixed `canCoerceStackArray(Type, Type)` to actually coerce the first type first into a pointer type (coercing the stack array's component type to `<compType>*`) and THEN apply the `isSameType(Type, Type)` check
* Typecheck
- Hoisted up `canCoerceStackArray(Type, Type)` to the class-level of `TypeChecker`
- Removed debug prints from `canCoerceStackArray(Type, Type)`
- Added a TODO where the check should be done in the `FunctionCall` branch of the `DNode` processor
* TypeChecker
- Added a seperate check for function call `DNode` processing which now checks if we can coerce the stack-array-based argument to the pointer-based type parameter
Notes
- Emit now fails as we haven't implement an emit for this case, so we need to do that.
- Also, should we change the type of what is being passed in - perhaps that actually makes sense here - we haven't fully coerced it actually
* TypeChecker
- Updated `canCoerceStackArray(Type, Type)` to now take in `canCoerceStackArray(Type, Type, ref Type)` to set the newly created coerced type
- Fixed bug whereby if the coercion succeeded we didn't actually add to the list of evaluation-instructions in the `FuncCallInstr` object, hence there would be a `null` Instruction object appearing in the code emit phase.
- Added some NOTEs which we can clean up this code using
* TypeChecker
- Cleaned up commented-out code
* Added CI/CD test for 'simple_stack_array_coerce.t'
* Added CI/CD test for 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_stack_array_coerce.t' and 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Fixed filepath for test 'simple_arrays.t'
* Fixed typechecking tests for arrays
* DGen
- Added instrumentation for `simple_stack_array_coerce.t`
Test cases
- Updated `simple_stack_array_coerce.t` to update the array passed in a manner such that we can sum the two elements later, return it and assert to ensure it is set correctly
* Parser
- Had to ensure the old identifier code was removed too, was too early; therefore this now-dead code was removed
* Test cases
- Added this test (even though it is a bad test, the syntax ie wrong)
* Test cases
- Update `simple_stack_arrsys4.t` to return an `int` such that we can verify it works.
- Also added more tests to it.
DGen
- Added semantic test code generation for `simple_stack_arrays4.t`
CI
- Re-organised tests for semantics in emit for arrays into those "Which have semantic tests" and "those which don't (yet)"
- Added semantic/emit test for `simple_stack_arrays4.t`
* Test cases
- Updated `simple_arrays2.t` to test casting of complex array types
* Test cases
- Updated `complex_stack_arrays1.t`
* Test cases
- Added new test for testing pointer syntax; `simple_stack_array_coerce_ptr_syntax.t`
- FIXME: It is broken as we don't have the latest pointer code - that must still be finished
* Test cases
- Added test case `simple_stack_array_ceorce_wrong.t` where coercion must fail
* Test cases
- Added `simple_pointer_array_syntax.t` which should test the `int[] == int*` stuff
* DGen
- Made semantic test for `simple_pointer_array_syntax.t`
Test cases
- Added a test for `simple_pointer_array_syntax.t.t`
* Branding
- Added logo here
* Test cases
- Addes semantic code emit instrucmentation for `simple_stack_array_coerce_ptr_syntax.t`
* Pipelines
- Added test case for `source/tlang/testing/simple_stack_array_coerce_wrong.t` for typechecking phase
* Test cases
- Added test case `complex_stack_array_coerce.t`
* Test cases
- Added extensive positive test case `complex_stack_array_coerce_permutation_good.t` which has a lot of different ways to write `int**` (think `int*[]` etc)
- Added negative test cases `complex_stack_array_coerce_bad1.t`, `complex_stack_array_coerce_bad2.t` and `complex_stack_array_coerce_bad3.t`
2023-04-20 10:21:50 +01:00
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_pointer_array_syntax" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
int retValue = thing ( ) ;
assert ( t_9d01d71b858651e520c9b503122a1b7a = = 4 ) ;
assert ( retValue = = 6 ) ;
2023-04-17 15:50:11 +01:00
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_pointer_cast_le" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
int retValue = thing ( ) ;
assert ( t_e159019f766be1a175186a13f16bcfb7 = = 256 + 4 ) ;
assert ( retValue = = 256 + 4 + 2 ) ;
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_pointer_malloc" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
test ( ) ;
// TODO: Test the value
2023-01-15 18:48:40 +00:00
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_extern" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
test ( ) ;
Array support (#1)
* Parser
- Added ability for `parseName()` to recognize array types
- Added array type handling to `parseTypedDeclaration()`
- Removed unneeded `derefCount` and comment in `parseTypedDeclaration()`
Check
- Added new symbol types `OBRACKET` and `CBRACKET`
* Tets cases
- We will now be using `simple_arrays2.t` as our testing bench for array support
* Dependency
- When a variable declaration has a kind-of type we are unaware of then print out an error message before asserting `false`
* Builtins
- `getBuiltInType(TypeChecker, string)` will now return a `Pointer` object for arrays of which the type was `<componentType>[]` (non-stack bound) as effectively they are pointers with a different syntax -doing it here means that it is transparent and typechecking, code gen and emit will just see a pointer type which makes life a lot easier
* Builtins
- Added information about the current bug faced in issue #81 (third sub-issue)
* Test cases
- Updated test case `simple_arrays2.t` to show case bug sub-issue 3 in issue #81
* Builtins
- Removed seperate handling of `<componentType>[]` and incorporated it into the pointer check, now we have fixed sub-issue 3 of issue #81
Test cases
- Updated test case `simple_arrays2.t` to showcase the aforementioned fix
* Builtins
- Updated TODO
* Builtins
- Removed comment as now fixed
* Array
- Added `getComponentType()` method which will return the array's element type
* Dependency
- When processing the `Array` type which is now to be seen as a stack-based array (fixed size), error out in processing it during variable declarations
* Builtins
- Added `bool isStackArray(string)` in order to check if a given type string is designated as a stack-array type or not
- `Type getBuiltInType(TypeChecker, string)` now can generate the `StackArray` type including the component type and the size of the stack allocation
Parser
- Added support to`parseTypedDeclaration` to be able to parse stack-based array types
- Added terminator `]` to `parseExpression()`
DGen
- Added stack-based array type transformation support to `string typeTransform(Type)`
- Added transformation support for stack-based arrays for the `VariableDeclaration` instruction
StackArray
- Renamed `Array` type to `StackArray`
` The `StackArray` type now has an `arraySize` field and is included in the constructor's paremeters
- Added a `getAllocatedSize()` method to retrieve the `arraySize` field
Dependency
- Temporarily enabled the `StackArray` type in dependency processing for `VariableDeclarations` such that we can continue through the pipeline
Test cases
- Updated `simple_arrays.t` to test stack-based array types
* Tets cases
- Added new test case for testing (later) multi-dimensional stack-arrays
* Parser
- Working on adding array index assignment support
Test cases
- Added test case to test array assignments with
* Parser
- We can now detect when infact we are doing an array-indexed assignment and when not, we then flip` arrayIndexing` to `true` if that is the case and ensure that `=` SymbolType.ASSIGN is not triggering the varaible-declaration-with-assignment but rather eters a different branch based on this boolean
- Set the identifier being assigned to (in the array indexing case) to the `type` with the `[]...` stripped
Notes
- Added a TODO file `wip.txt` with notes about what is to be done for adding full array support
* Parser
- Handle the case whereby `SymbolType.ASSIGN` or `SymbolType.IDENT_TYPE` is not found by throwing an error
* Parser
- Moved logic for array assignments into the branch for it (deferred it)
* Data
- Added new work-in-progress parser node type `ArrayAssignment`
Parser
- Added TODO about the type of returned parse node needing to be updated down the line
Notes
- Updated `wip.txt` with more thoughts
* Expressions
- Added new parse node (a sub-type of `Expression`) for representing array indexing; `ArrayIndex`
Data
- Fixed compilation error caused by missing semi-colon
* Parser
- Added support for array accesses/indexing in `parseExpression()`
- Added a token-rerun mechanism that lets us replay the needed tokens which needed to be looked ahead in order to determine an array access was about to occur
* Parser
- Removed now-completed TODO relating to array accesses in `parseExpression()`
* Parser
- Added right-hand side expression parsing for array assignments
Test cases
- Updated test case to test both array expressions on the left-hand side of an assignment and as a free-standing expression on the right hand side
Data
- Implemeneted `ArrayAssignment` which is to be used for assigning into arrays
* Instruction
- Added new instruction for indexing into arrays, a new `Value`-type instruction called `ArrayIndexInstruction`
* DGen
- Handle `ArrayIndexInstruction` which is for whenever you index into a point-based array (an expression like `myArray[i]` is now being supported in emit (first steps))
* Instructions
- Added a new instruction type, `StackArrayINdexInstruction`, which is used to know when we are indexing into a stack-based array rather than a pointer-based array (just to be able to disambiguate between the two)
- Added a work-in-progress type `StackArrayIndexAssignmentInstruction` which will be used for assigning to stack arrays at a given index
* Instructions
- Added implementation for `StackArrayIndexAssignmentInstruction` which represents the assignment of some `Value` instruction to a stack-based array (indicated by the `arrayName` string field) at the index indicated by the provided `Value` instruction
* DGen
- Added a stub emitter for `ArrayIndexInstruction` (pointer-based array indexing)
- Added a stub emitter for `StackArrayINdexInstruction` (stack-array based array indexing)
* INstructions
- Added `getArrayName()`, `getIndexInstr()` and `getAssignedValue()` to `StackArrayIndexAssignmentInstruction`
* Instructions
- Added `ArrayIndexAssignmentInstruction` which is intended to be used for when one wants to assign into a pointer-based array
- It embeds a `Value` instruction which is what is to be assigned and then an `ArrayIndexInstruction` representing the base of the poiinter-based array (base address) coupled with an "index" (offset)
- Added a `toString()` override for `StackArrayIndexAssignmentInstruction`
* Test cases
- Added `complex_stack_arrays1.t`
- This tests a stack array of a fixed size of `int[]` (basically `int*`) and assigneing into it
* Test cases
- Added `simple_arrays4.t` which makes an `int[]` (which is an `int*`) and then assignes into it at `i` whilst referring to itself at `i` and doing a binary operation
* Test cases
- Added `simple_stack_arrays2.t` which tests a stack array of a fixed size and then assigns into it a value
* Test cases
- Added `simple_stack_arrays4.t` which just tests assigning to a stack array of a fixed size BUT referring to said stack array itself as part of the assignment expression
* DGen
- Removed TODO comment for `ArrayIndexInstruction` transformation branch
- Added a description for when the `ArrayIndexInstruction` branch is activated for a transformation
- Implemented transformation for `ArrayIndexInstruction`
- Added comment on when `ArrayIndexAssignmentInstruction` activates
- Implemented transformation for `ArrayIndexAssignmentInstruction`
- Added comment for when the `StackArrayIndexInstruction` branch activates
- Implemented transformation for `StackArrayIndexInstruction`
- Added comment for when `StackArrayIndexAssignmentInstruction` branch activates
- Implemented transformation for `StackArrayIndexAssignmentInstruction`
* Dependency
- Added dependency node generation for the `ArrayIndex`
- This will pool the `ArrayIndex` parser-node
- This will then set the context of the parser-node to the current context
- The index expression will be depended upon
- The indexed expression (the entity being indexed) will be depended upon
---
- Added dependency generation for `ArrayAssignment`
- The `ArrayAssignment` parser node will be pooled
- The `ArrayAssignment` will have its context set to the current context
- The assigned expression will be depended upon
- The entity being indexed will be depended upon
- The index expression will be depended upon
* Parser
- Added a branch to `parseName()` which handles array assignments's semicolon consumption and token cursor movement to the next token
- Updated `parseTypedDeclaration()` to return an object of type `Statement` rather than `TypedEntity`
- Disabled the intentional `assert(false)` when handling array assignments
- Assign the generated `ArrayAssignment` to the `generated` variable
- Updated `parseExtern()` to cast to `TypedEntity` to ensure that the `Statement` returned is of that sub-type (added an assertion to then check this fact)
* Typechecker/Codegen
- Implemented `isStackArray(Value)` which checks if the given `Value` instruction is a `FetchValueVar`, then extracts the `Variable` being referred to in said instruction and checks if its declared type is that of `StackArray`
- Implemented code generation for `ArrayAssignment`
- Implemented code generation for `ArrayIndex`
* Test cases
- WIP: Added `simple_stack_array_coerce.t` as we want to add coercion for this now
* Typecheck
- Added rudimentary check for checking if an argument is a stack array, and if the parameter (to a function call) is a pointer and if so then returns whether they have matching component types in a new function named `canCoerceStackArray(Type, Type)`
* Typecheck
- Fixed `canCoerceStackArray(Type, Type)` to actually coerce the first type first into a pointer type (coercing the stack array's component type to `<compType>*`) and THEN apply the `isSameType(Type, Type)` check
* Typecheck
- Hoisted up `canCoerceStackArray(Type, Type)` to the class-level of `TypeChecker`
- Removed debug prints from `canCoerceStackArray(Type, Type)`
- Added a TODO where the check should be done in the `FunctionCall` branch of the `DNode` processor
* TypeChecker
- Added a seperate check for function call `DNode` processing which now checks if we can coerce the stack-array-based argument to the pointer-based type parameter
Notes
- Emit now fails as we haven't implement an emit for this case, so we need to do that.
- Also, should we change the type of what is being passed in - perhaps that actually makes sense here - we haven't fully coerced it actually
* TypeChecker
- Updated `canCoerceStackArray(Type, Type)` to now take in `canCoerceStackArray(Type, Type, ref Type)` to set the newly created coerced type
- Fixed bug whereby if the coercion succeeded we didn't actually add to the list of evaluation-instructions in the `FuncCallInstr` object, hence there would be a `null` Instruction object appearing in the code emit phase.
- Added some NOTEs which we can clean up this code using
* TypeChecker
- Cleaned up commented-out code
* Added CI/CD test for 'simple_stack_array_coerce.t'
* Added CI/CD test for 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_stack_array_coerce.t' and 'complex_stack_arrays1.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Added CI/CD semantic tests (WIP) for 'simple_arrays2.t' and 'simple_arrays4.t'
* Fixed filepath for test 'simple_arrays.t'
* Fixed typechecking tests for arrays
* DGen
- Added instrumentation for `simple_stack_array_coerce.t`
Test cases
- Updated `simple_stack_array_coerce.t` to update the array passed in a manner such that we can sum the two elements later, return it and assert to ensure it is set correctly
* Parser
- Had to ensure the old identifier code was removed too, was too early; therefore this now-dead code was removed
* Test cases
- Added this test (even though it is a bad test, the syntax ie wrong)
* Test cases
- Update `simple_stack_arrsys4.t` to return an `int` such that we can verify it works.
- Also added more tests to it.
DGen
- Added semantic test code generation for `simple_stack_arrays4.t`
CI
- Re-organised tests for semantics in emit for arrays into those "Which have semantic tests" and "those which don't (yet)"
- Added semantic/emit test for `simple_stack_arrays4.t`
* Test cases
- Updated `simple_arrays2.t` to test casting of complex array types
* Test cases
- Updated `complex_stack_arrays1.t`
* Test cases
- Added new test for testing pointer syntax; `simple_stack_array_coerce_ptr_syntax.t`
- FIXME: It is broken as we don't have the latest pointer code - that must still be finished
* Test cases
- Added test case `simple_stack_array_ceorce_wrong.t` where coercion must fail
* Test cases
- Added `simple_pointer_array_syntax.t` which should test the `int[] == int*` stuff
* DGen
- Made semantic test for `simple_pointer_array_syntax.t`
Test cases
- Added a test for `simple_pointer_array_syntax.t.t`
* Branding
- Added logo here
* Test cases
- Addes semantic code emit instrucmentation for `simple_stack_array_coerce_ptr_syntax.t`
* Pipelines
- Added test case for `source/tlang/testing/simple_stack_array_coerce_wrong.t` for typechecking phase
* Test cases
- Added test case `complex_stack_array_coerce.t`
* Test cases
- Added extensive positive test case `complex_stack_array_coerce_permutation_good.t` which has a lot of different ways to write `int**` (think `int*[]` etc)
- Added negative test cases `complex_stack_array_coerce_bad1.t`, `complex_stack_array_coerce_bad2.t` and `complex_stack_array_coerce_bad3.t`
2023-04-20 10:21:50 +01:00
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_stack_array_coerce" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
int result = function ( ) ;
assert ( result = = 420 + 69 ) ;
printf ( "stackArr sum: %d\n" , result ) ;
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "complex_stack_array_coerce" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
int result = function ( ) ;
assert ( result = = 69 + 420 ) ;
printf ( "val1: %d\n" , t_596f49b2a2784a3c1b073ccfe174caa0 ) ;
printf ( "val2: %d\n" , t_4233b83329676d70ab4afaa00b504564 ) ;
printf ( "stackArr sum: %d\n" , result ) ;
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_stack_array_coerce_ptr_syntax" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
int result = function ( ) ;
assert ( result = = 420 + 69 ) ;
printf ( "stackArr sum: %d\n" , result ) ;
return 0 ;
} ` ) ;
}
else if ( cmp ( typeChecker . getModule ( ) . getName ( ) , "simple_stack_arrays4" ) = = 0 )
{
file . writeln ( `
# include < stdio . h >
# include < assert . h >
int main ( )
{
int result = function ( ) ;
assert ( result = = 61 ) ;
2022-12-11 19:41:15 +00:00
return 0 ;
} ` ) ;
2022-12-19 13:37:55 +00:00
}
else
{
file . writeln ( `
int main ( )
{
return 0 ;
}
` ) ;
}
2022-12-11 19:41:15 +00:00
}
2022-12-12 13:36:07 +00:00
public override void finalize ( )
{
try
{
2023-08-20 14:26:54 +01:00
string systemCompiler = config . getConfig ( "dgen:compiler" ) . getText ( ) ;
2023-08-20 14:28:05 +01:00
gprintln ( "Using system C compiler '" ~ systemCompiler ~ "' for compilation" ) ;
2023-08-20 14:26:54 +01:00
string [ ] compileArgs = [ systemCompiler , "-o" , "tlang.out" , file . name ( ) ] ;
2023-01-28 16:12:49 +00:00
// Check for object files to be linked in
string [ ] objectFilesLink ;
if ( config . hasConfig ( "linker:link_files" ) )
{
objectFilesLink = config . getConfig ( "linker:link_files" ) . getArray ( ) ;
gprintln ( "Object files to be linked in: " ~ to ! ( string ) ( objectFilesLink ) ) ;
}
else
{
gprintln ( "No files to link in" ) ;
}
Pid ccPID = spawnProcess ( compileArgs ~ objectFilesLink ) ;
2022-12-12 13:36:07 +00:00
int code = wait ( ccPID ) ;
if ( code )
{
//NOTE: Make this a TLang exception
2022-12-16 12:53:33 +00:00
throw new Exception ( "The CC exited with a non-zero exit code (" ~ to ! ( string ) ( code ) ~ ")" ) ;
2022-12-12 13:36:07 +00:00
}
}
catch ( ProcessException e )
{
gprintln ( "NOTE: Case where it exited and Pid now inavlid (if it happens it would throw processexception surely)?" , DebugType . ERROR ) ;
assert ( false ) ;
}
}
2021-11-02 08:41:03 +00:00
}