INTRO Pec is a strict, impure, procedural language. It is intended to have the look and feel of Haskell and compile to LLVM and C. It is strongly influenced by all three languages: Haskell - Strong typing with Hindley-Milner type inference - Variants, tuples, records - case expressions, pattern matching - User defined, polymorphic data structures - Parametric polymorphism, limited ad-hoc polymorphism - Modules - Syntax/Layout - productive LLVM & C - compiles to C & LLVM - easy integration - efficient - simple run-time system - arbitrary sized integers (LLVM) - single static assignment (SSA) names - no garbage collection - no closures - no objects Pec - small syntax - safe pointers - type system prevents out of bounds array indexing - no recursion - no operator precedence COMPILER ARCHITECTURE The pec compiler leverages several tools in its compilation pipeline. This allows the compiler to be small and nimble (but can also have drawbacks, e.g. error messages). src/Pec.hs implements the compiler pipeline. Pec/Base.hs is the code generation library used by the generated Haskell modules. Pec compilation begins by specifying the "main" pec module on the command line. e.g. pec Foo.pec The main module is parsed and its import dependencies are noted. This is then repeated recursively for each dependency. e.g. Foo.pec, Bar.pec, Baz.pec These pec modules are all transformed to corresponding Haskell modules and a "main" Haskell module. These Haskell modules contain the code needed to generate the goal LLVM/C code. They also contain enough type information for the ghc type inference/checking to be leveraged. e.g. Foo_.hs, Bar_.hs, Baz_.hs, Foo_main.hs ghc is then used to infer/check types and build the code generation executable. e.g. ghc --make Foo_main.hs When run, the resulting executable will create corresponding LLVM IR modules or C modules. e.g. Foo.ll, Bar.ll, Baz.ll LLVM/gcc are then used to transform the code into the desired executable.