pslang/plans.txt

46 lines
3 KiB
Text

Future plans:
* Split compiler into IR generation, IR optimization, and target-specific bytecode emitter
* Globals (requires a separate mmaped segment in JIT compiler)
* Pointers: pointer types, address-of operator (&), dereferencing, scope-based lifetime tracking in interpreter
* Function overloading: separate functions from values (again) in interpreter, allow casting to specific function type to take function value
* Const propagation: annotate expression AST nodes that are computable in compile-time
* Generic parameters: can be either values or `t : type`, but always compile-time
* Generic structs: `struct <t : type, n : u64> array:`, require explicitly specifying parameters when instantiated (used as a type or creating a value)
* Generic functions: `func <t : type, n : u64> max(a : t[n]):`, require explicitly specifying parameters when called or converted to function pointer
* Generic parameter inference for functions & structs
* Extension functions: operator overloading, destructors, iterators & for loop, move assignment (replaces built-in copy)
* Metaprogramming: assigning types to variables (of type `type`), functions can take `type` as regular arguments and return `type`, all type computations are compile-time only
Interpreter backlog:
* Fix identifier resolution for functions & variables
* C FFI (foreign functions)
Aarch64 compiler backlog:
* Struct fields in structs (initialization & field access)
* Struct function arguments & return values
* Arrays
IR outline:
* Doubly-linked list (std::list will do) of instruction nodes
* Nodes reference other nodes for input data or branching target
* No temporary variables, nodes themselves represent data flow
* Assignment expressions turn into nodes that assign to previously-defined nodes
* Jump targets (first `while` node, node after an `if`, etc) are generated as nop nodes, to prevent them from being removed by the optimizer
* Structs & arrays can be split into several independent nodes per-field (before pointers are introduced)
IR optimizations:
* Inlining: track function IR size (number of nodes will do), substitute its code instead of calling if it is small enough (pay attention to recursion)
* Constant folding & propagation: if all node arguments are `const` nodes, replace the current node with the computed value
* Arithmetic simplification: replace a+0 with a, etc
* Branch removal: `if` nodes with condition nodes being `const` are replaced with unconditional jumps
* Jump removal: `jump` that jumps to the immediate successor node is removed
* Dead code elimination: DFS from function `return` nodes & impure function calls, remove all nodes not visited (make sure to not remove function arguments)
General backlog:
* Mutually recursive structs (relevant only with pointers)
* Empty array expression
* Calling functions as methods
* Replace std::runtime_error with appropriate custom exception types
* Replace std::ostringstream with std::format (need support for std::format in type/ast printing)
* TEST COVERAGE!!!
* Separate actual AST from pre-AST (the one before indentation & scoping is resolved)