Known Problems
- (inlinearrayproblem.kc) Arrays / strings allocated inline destroy functions (because they are allocated where the call enters.
- (forincrementassign.kc) Classic for() does not allow assignment as increment, eg. for(byte i=0;i<25;i=i+2) {}
- (forrangesymbolic.kc) Range-based for does not recognize symbolic constants. The following gives a ParseTreeConstantEvaluator$NotConstantException - const byte* BITMAP = $2000; for(byte* b : BITMAP..BITMAP+$2000) { *b = 0; }
- (wordexpr.kc) Expressions based on bytes but resulting in words are erronously infered as bytes - eg. yoffs = yoffs + 40*8;
- (useuninitialized.kc) Using an uninitialized variable fails in the optimizer phase. It should fail much earlier.
- (inline-asm-param.kc) Inline ASM does not attempt to handle parameters (variables).

Features
- Improve locality of block sequence for if(cond) { stmt1; } else { stmt2; } to if(!cond) goto @else stmt1; jmp @end; @else: stmt2; @end:
- Optimize if/else by swapping if & else if cond is easier to evaluate than !cond.
- Let { stmt } and for() {} introduce a new anonymous scope. (But not when optimizing)
- Implement inline compilation of functions (and a mechanism for choosing which methods / calls to inline)
- Handle long branches
- Optimize loops by unrolling them somewhat
- Optimize loops with Strength reduction (https://en.wikipedia.org/wiki/Strength_reduction)
- Add syntax for encoded chars (eg. PETSCII instead of SCREEN)

Syntax Checking
- Disallow code outside functions.
- Check that declared constants are never assigned.
- Graceful error when using undeclared variable.
- Graceful error when using uninitialized variable.

New language Features
- Add signed bytes / words
- Add Fixed Point number types fixed[8.8], fixed[16.8] - maybe even fixed[24.4]
- Add structs

Pointers
- Support calculated pointers eg. *(ptr+i)
- Use a rule-based approach to de-inline most pointer derefs again just before register allocation. ( *a = *b + *c => $1=*b (reg a), $2=*c (alu), $3=$1+$2 (reg a), *a = $3  - but *a=*a+const should stay inlined as it has efficient ASM)
- VariableReplacer, GraphReplacer, Pass1GenerateSSA#versionAllUses() has a pretty ugly handling of pointers. Abstract prettier code.
- AsmFragmentManager only handles _neq_ pointer comparison. Abstract a better replacer and handle the rest.
- Consider if array-indexing should be handled in the same way as unary * when generating statements (put into inline Pointers instead of temporary variables.) This will fix a[2]++, which probably does not work atm.

Compiletime (Preprocessing)
- Add preprocessing / find a way to allow some functions to run at compile time. This will always be to initialize memory to a certain state.
  - Syntax: A compiletime keyword usable before initializers or global statements blocks? (compiletime is a better word as it is not a preprocessor in the C-sense of the word)
  - byte[$100] sins = compiletime { [x] = sin(2.0*PI*x/$100) };
  - byte[$100] sins; compiletime { for(byte x : 0 $ff) { sins[x] = sin(2.0*PI*x/$100)}};

Imports
- Remove unused functions & symbols.
- Add imports
- Add an export keyword ensuring that a function is generated even if it is never called. Maybe export can be handled by generating a call that can be used as stub.

Constants
- Do not create multiple versions & phi-statements for declared constants.
- Perform static constant analysis determining if a var is ever assigned. Mark as constant before creating SSA/versions.
- Limit number of versions & phi-blocks by create a generative algorithm for creating initial phi-blocks & variable versions.
  - When an assignment is encountered create a new version.
  - Backtrack the necessary new phi-blocks and changes into the code?

Word Operations / Math
- Syntax for composing a word from two bytes. word w = { lo, hi } --> ICL: w = lo _word_ hi;
- Support Word table lookup (through 2 byte-tables)
- Support word math operations (addition, subtraction)
- Implement a word-ALU
  - Usage: word[] plotter_x; word[] plotter_y; byte* plotter = plotter_x[x] + plotter_y[y]; ->     lda plotter_x_lo,x; clc; adc plotter_y_lo,y; sta plotter; lda plotter_x_hi,x; adc plotter_y_hi,y; sta plotter+1
- Add support for casting. Specifically casting a byte* to a word and the other way (eg. to enable calculating D018-value from pointer to bitmap & screen.) -  *D018 = (byte*)((word)SCREEN/$40)|((word)BITMAP/$400);
  - Consider whether autocasting word & byte* is possible ?

Arrays / Strings / Inline data
- New semantic: Arrays are always allocated inline (and must therefore have a size). Pointers are never.
- Allow complex array expressions in lValues eg. (SCREEN+$100)[idx]
- Add string / static array length operation.
- Add array initializer filling with a specific value / (pattern?).
- Add support for empty / filled byte data arrays.
- Add support for expressions in data initializers.
- Create a fill-like array initialization - byte[$100] plot_xlo = { [x] = x&$f8 };
- Support word-arrays as two underlying byte-arrays in memory: word[$100] plot_x; -> ASM { plot_x_lo .fill $100,0 plot_x_hi .fill $100,0; }
  - Support syntax for initializing the address of the two byte-arrays underlying a word array. word[] plot_x = { lo=$1000, hi=$1000 };
  - Support syntax for initializing the address of a byte-array. byte[] plot_x = { addr=$1000 }; -- current syntax as a short hand byte[] plot_x = $1000;
  - Syntax for accessing the low/high byte-array that underlies the word-array. word[$100] plot_x; byte* plot_x_lo = plot_x.lo; plot_x_lo[0] = 0;

ASM Integration / Inline ASM
- Allow inline ASM parameter expansion - eg lda line (where line is a variable)
- Allow lda <var> or sta <var> to just perform a register copy if possible.
- Add syntax for ensuring specific values are in A/X/Y when entering ASM - eg. asm( A: i, X: bits+1 ) { sta {SCREEN},x };
- Add syntax for specifying that ASM does not clobber specific registers (if the values are used but preserved through pha/pla) - eg. asm( A: noclob, X: i ) { pha lda #0 sta {SCREEN},x pla};
- Add ability to call external ASM code from KC.
- Add ability to call KC code from ASM. (Maybe declare some functions external to ensure their interface is well defined. Maybe generate ASM call stubs.)
- A syntax for supporting custom ASM fragments? Allowing the adding of a new operator / function call that is compiled into custom written ASM-fragments. Currently there seems to be a quite short way when adding a new expression operator - maybe give the programmer the same freedom.

Assembler Improvements
- Relabel blocks eliminating long labels such as b3_from_b11
- Eliminate chained JMP's (replace by direct JMP) - example: loopsplit.asm
- Better ASM static value analysis
  - Not just constants - but also other values (value of var, value of var1[var2], value of var+4 etc.)
  - Also analyze back/forward through block entry/exit
  - Also analyze value of flags (eg. N=N(var1))
- Eliminate CPX from DEX, CPX #0, BNE la1 (using ASM static value analysis for N flag - it might be worth annotating CPX with the fact that only the N-flag is relevant - or creating a special instruction for setting the N-flag)
- Eliminate LDA from DEC $2, LDA $2, BNE la1 (using ASM static value analysis for N flag - it might be worth annotating LDA $2 with the fact that only the N-flag is relevant - or creating a special instruction for setting the N-flag)
- Eliminate LDA from STA $11, LDA $11 (using ASM static value analysis of A-register)
- Optimize by allowing resequencing of ASM (statements and phi assignments) in a final phase.
- ASM loop analysis: If all usages of a register has the same value move the assignment out of the loop (if the assignment is simple enough).

Register Allocation
- Allow user to limit number of combinations tested
- Safe-Copy based SSA deconstruction
  - Optimize by finding optimal sequence for multiple phi assignments in entry-segments.
  - Avoid clobbering alive vars
- Maybe support several fragments for the same operation with different cost and clobbering profiles.
- Add memory registers (if we need to free some ZP).
- Improve combination testing by finding live range overlaps and not creating combinations that would create an overlap conflict.
  - Combinations should be created in a tree-structure instead of just doing all combinations
  - Example: For equivalence classes a, b, c if a&c have overlapping live ranges they can never have the same register. Therefore the combination iterator should not create combinations where C has the same register as a.
- Optimize registers in local windows - creating smaller sets of combinations. Currently some programs easily has millions of possible combinations.
- Optimize registers in a tree search.
  - Initially allocate all variables to ZP registers
  - Handle each scope prioritized
  - Handle each variable prioritized
  - For each variable try each potential register.
    - Examine if current variables overlap with other variable assigned to the same register. If an overlap is found - the branch is dead
    - Generate ASM & examine clobber. If the potential register allocation results in clobber - the branch is dead.
    - Handle each remaining allocation possibility in order of their score - highest score first.
    - Assign the variable to the selected register & Recurse down to the next variable.
- Add UpliftRemains support for attempting to uplift potentials to ALU (requires modifying two registers: 1. the ALU potential to ALU - the one added to the ALU potential to A.)
- Add ability to store/restore registers to free up registers for allocation in outer scopes. Requires marking registers as non-clobbered in certain cases.

Process/Code Structure Improvement
- Eliminate copy visitor (using ListIterator option for adding elements)
- Refactor Expression Operator Implementation & Evaluation into one class per operator
- Improve error messages to give better context
- Offer to compile resulting ASM with KickAssembler

Testing
- Test single passes by configuring compiler to only log ICL before & after the tested step!
- Implement ICL syntax (printer & parser). Drop the JSON.
- Test that the parse tree for specific KC syntax is as expected. Use a print function for the parse tree to generate output for comparison.
- Test that the parse tree for specific KC syntax is as expected. Use a print function for the parse tree to generate output for comparison.
- Emulate/Run the ASM for a specific KC program compiled. Compare the emulated ASM output to output calculated by executing directly on the KC tree.
- Add assert statements to the language. Create KC programs that test the compiler by compiling, running and testing assertions.

Usages
- Implement library for memory allocation in main memory
- Implement library for output on the screen (using basic functions)

Real Usage
- Implement library for fast multiply (mul.asm)
- Implement spline library (spline.asm)
- Implement polygon filler for complex polygons.
- Implement a true type font renderer.

Done
+ Test the ASM program output resulting from compiling specific KC program input.
+ Create a proper main function for the compiler
+ Add ++/-- incrementing/decrementing operators.
+ Optimize if's without else if(expr) { stmt; } -> $1=!expr; if($1) goto @1; stmt; @1:
+ Add a for loop for(init;condition;increment) {stmt} -> { init; do { stmt; increment } while (condition) }
+ Add for loop for(byte i: 1..100) { } and for(byte i : 100..0) {}  (plus maybe .+. and .-. to make the inc/dec unambiguous)
+ Eliminate unnecessary labels in ASM
+ Make generated ASM human readable.
  + Use hex-numbers
  + add labels for constants and zp-variables.
+ Procedures that modify variables outside their scope does not work. Outer vars must be transfered in/out like parameters/return values to get it working.
+ Alive vars are propagated backward through procedures (correctly). However they are then propagated back through ALL calls to the procedure incorrectly. They should only be alive at calls where they are alive after the call. In summin.kc s1#0 is incirrectly backpropagated through the first call, where it is not alive.
+ Reuse phi-transitions that are identical
+ Optimize phi transitions by ensuring that identical phi-transitions with regards to register allocation are collected into a single transition.
+ Limit number of combinations tested
+ Equivalences not tested through combinaitons should be tested individually afterwards.
+ Matrix Phi operation (instead of separate statements)
+ Phi Lifting
+ PhiLifting & PhiMemCoalesce (http://compilers.cs.ucla.edu/fernando/projects/soc/reports/short_tech.pdf)
+ Interval Analysis (variable liveness intervals)
+ ComputeLoopNestDepth(b) - Assign loop nesting levels to blocks.
+ ComputeRegisterPreference(v), ComputeWeight(v)
+ CalculateClobbering(i)
+ Register types: A, X, Y, ZP, (memory).
+ Implement a register allocation (coloring) algorithm using by liveness intervals, preferences, weights & clobbering information.
  + Optimize register allocation by combining with knowledge of ASM program cost (bytes/cycles) and different ASM fragments with different clobbering.
+ Live range overlap analysis of register combinations inside methods must also look at registers alive at all calls.
+ Examine why temp-vars are used in flipper.
+ Examine why flipper is plotted in a wrong position on the screen.
+ Implement constants into the symbol table and support them in code.
+ Implement new constant consolidation steps.
+ Reintroduce constant addition optimization
+ Add asmName for ConstantVar to remove subscripts
+ Inline constants for "single" versions of vars - such as .const i#0 = 0
+ Look at optimizing liverange.kc's ASM further - atm. there are to many copy-operations into unnecesary registers.
+ In summin.asm the result of the 2nd sum() is clobbered twice during call to sum(). jsr sum, txa, lda #$d, ldx #$9, jsr sum
  + Fix by introducing "effective alive vars" which includes alive vars at all calls to containing methods and using that during clobber check.
+ In loopnest.asm x&y are used in both loops - the outer x&y are clobbered by the inner loop.
+ In voronoi.asm in render() x is clobbered during call to findcol().
+ Optimize getAliveEffective() to improve speed
+ Add possibility of declaring in-program data - just like .byte/.fill in KickAss.
+ In immemarray.kc the if(++j==8) is broken because the optimizer culls the empty block main::@3 (because the value is constant). In the end the phi()-function in main::@2 has two handlers for min::@1 phi( main::@1/(byte) main::j#1 main::@1/(const byte) main::j#2 )
+ Add literal char syntax ( 'c' == (byte) 3 )
+ Add string constants
+ Clobber can occur in PHI-statements. Example: scroll-clobber.kc. c#1/c#2 (A-register) is clobbered by //SEG18 [6] phi (byte*) main::nxt#4 = (const byte[]) TEXT#0 -- zpptrby1=cowo1
+ Implement fast combination elimination based on live ranges (skipping the ASM-code.)
+ Implemenent Assertions for the output of different phases (ensuring that the result of the phase is consistent)
+ Make each phase return a separate object graph (allowing for keeeping the history in memory & performing rollbacks)
+ Remove "string" keyword (if it exists).
+ Support hi/lo-byte lvalues - <plotter = plot_xlo[x]+plot_ylo[y]; >plotter = plot_xhi[x]+plot_yhi[y];
+ Add ALU support for lo/hi operators on pointers - to avoid unnecessary zp-variable holding for cases like byte v = y&$7 | <yoffs;
+ (callconstparam.kc) Constant parameters to multiple calls are mixed together because their versioned names (x0#0, X0#1) are shortened to not include the version and only one version is output in the ASM.
+ (callconstparam.kc) Constant call parameters are stored as values in the called function - not at the call. The reference from the call to the constant does not include the function name, so the result is an unknown symbol error when compiling the ASM.
+ Inline constants that are only call parameters used once (eg. x0#0 and x0#1 in callconstparam.kc)
+ Ensured that assignment to variables with ALU potential does not affect potential registers through clobbering.
+ (const-identification.kc) Constants are not identified correctly. Some times constant pointers are treated as variables Eg. byte* SCREEN = $0400 is adressed through zero-page even though it can be adressed directly.
+ Add support for inline asm
  + Syntax: asm { asm... } - using real ASM syntax inline!
+ Support ASM syntax check etc.
+ Also perform ASM clobber analysis when assigning registers.
+ Move the main code into a main() function. The main function per default has no parameters and exits with RTS.
+ (incd020.kc) Increment/decrement of value pointed to by pointer does not work. eg. byte* BGCOL = $d020; (*BGCOL)++;
+ All pointer derefs *ptr should per default be inlined as rValues/lValues in early passes (PointerDereference).
+ Alternatively: Selectively inline some pointer derefs that can be optimized in ASM
+ Change pointer derefs ASM signature to _deref_xxx (from _star_xxx)
