secd/doc/ideas.md

3.9 KiB
Raw Blame History

Goals

  • Be an efficent compilation target for typed lambda calculi

  • Be substantially easier to translate to than machine code.

  • Run cross-platform on as many operating systems and architectures as possible. (bare minimum 32-bit).

  • Allow for code completely independent of the host machine.

  • Leave memory managment out of the question for the compiler writer.

  • Provide significant IO functionality.

  • Provide efficient native methods for manipulating commonly used types

    • Strings (dont represent as a list of characters, god)
    • Characters
    • Integers
    • Floating point numbers
    • Raw bytes
    • Lists (cons linked list), efficient map, foldr, and filter instructions would be nice
    • Arrays (constant lookup continous memory)
  • Have methods for representing algebraic data types built into the machine.

    • Sums and products of arbitrary size, and methods for (de)constructing them.
    • Sums as tagged pairs since the machine is untyped
  • Instruction for tail recursion which takes the new parameters of the stack and resets the C pointer to where it last entered a closure.

  • Recursion instruction which functions as dup : app

  • GMP arithmetic

  • Some sort of pattern matching facility for matching on the first element of a pair, (the constructor).

Non-Goals

  • Safely error out or leave catchable exceptions when instruction is called with wrongful operands.

  • Dynamic linking, creating object files with polymorphic types.

  • Lazy evaluation.

Nicities (plausible)

  • Provide a compiler from a simply typed lambda calculus, coupled with a small standard library which would confirm type safety of all used instructions. Maybe go even further? System F?

  • Maybe some vector operations? You could reasonably operate on chunks of the stack.

Nicities (dreaming)

  • Provide more complete IO functionality, such as networking, etc. (this is not likely to happen)

  • Provide some sort of FFI (this is not likely to happen)

  • Its possible one might be able to JIT compile some stuff?

Encoding stuff

  • Common instructions are 1 byte and a lookup table is used to run a function executing said instruction. Less common instructions will have the first byte take them to a function which reads the next byte, allowing for a tree of instructions.

  • All words realistically have to be the same size for the stack to make sense. Which size should be used? This feels like it could easily become machine dependant.

    • Possibly go for the highest you have, 8 bytes? Would mean that performance would be god awful on 32 bit machines. I might be ok with that? Am I?
    • What about byte types, etc? Should we really allow that? It becomes a pain. Perhaps it is easiest to pretend computers do not exist and only deal with numbers? Only use GMP arithmetic then?
      • Possible set of builtin types:
        • Int64 - 64-bit signed integer
        • Word64 - 64-bit unsigned integer
        • Float - 64-bit double precision floating point number
        • Integer - GMP
        • Natural - GMP
        • Float - GMP
        • Rational - GMP
        • String - Like Data.Text
        • Char - 64-bit unicode codepoint.
        • List - Pointer to linked list
        • Array - Pointer to length tagged constant memory
        • Pair - Pointer to constant memory of length 2

File Format stuff

  • Much like ELF, start of with header containing basic info, reserve some bytes for future additions, have field specifing version. Then have sections.

  • Code section, the initial C stack.

  • Global section, the initial G env.

  • Linkable and Executable. Linkables have some sort of symbol table for wanted symbols, as well as a list of files it wishes to link with. The linker, or perhaps the VM, when loading, will then lookup these files in a global search path, perform substitution with the symbols to create an Executable file with a complete global table.

  • Must realise an encoding for closures, products and GMP numbers to be used in globals.