/// ///
/// ______ ________________________ ///
/// / ____ \/ / /_ _/ __/ / / ///
/// / /\ \/ / / / / __/_ _/ ///
/// \___\_\/ \___//___/_____/___/__/ ///
/// ///
/// ///

QForj is an experimental stack-based array programming language with the goal of giving the programmer the granular control over hardware that comes with assembly, while being just extensible enough for comfortable operating system programming.
It's intended to be compiled to a custom RISC architecture (see the 16 instructions in qforj.c), which has vector and tensor operations as well as built-in stack operations that all synergize with this language.
The processor is being designed for the ecp5 lattice fpga using the SpinalHDL scala library.
It will be uploaded when the pipelining behavior is complete.

Intended Features:
complete:
Stack-based ops and post-fix notation

Namespaces and scoping and local overrides/redefinitions

ALL statements merely push their value to the stack, for any effect to be taken, the special '!' char must be invoked

Maintain "Homoiconicity" https://en.wikipedia.org/wiki/Homoiconicity
- The language can be manipulated as data.

building:
x-time execution and n-order functions
- Allow code execution at any time
- Funcs can return funcs that return funcs etc

designed:
Synthesis-driven design
- Compiler merely assists your source code in controlling its own compilation through the builtin library

Element-wise array operations
- Hopefully without separate combinators

planning:
Functions are "first-class citizens" (behave like data)
Types and OOP behavior entirely functionally programmed
- Type check using a 'covariant' or 'contravariant' function that compares inputted types on the type tree.
- Use synthesis-driven design with namespaces and scoping to type-check and create objects at compiletime.
- Since functions are "first-class", and types are functions, types are also "first-class" (we can manipulate types at any time and return them from functions)