Tipc
A compiler from TIP to llvm bitcode
Install / Use
/learn @matthewbdwyer/TipcREADME
tipc
A compiler from TIP to llvm bitcode
TIP Language, Interpreter, and Analyzers
TIP is a "Tiny Imperative Programming" language developed by Anders Møller and Michael I. Schwartzbach for the Static Program Analysis lecture notes that they developed for graduate instruction at Aarhus University.
Accompanying those notes is a Scala implementation that provides a number of static analysis implementations and interpreter-based evaluators.
This project implements tipc which compiles TIP programs into LLVM bitcode. Linking that bitcode with the runtime library routines and standard libraries will produce an executable.
Dependencies
tipc is implemented in C++17 and depends on a number of tools and packages, e.g., ANTLR4, Catch2, CMake, Doxygen, loguru, Java, LLVM. To simplify dependency management the project provides a bootstrap script to install all of the required dependencies on linux ubuntu and mac platforms; if you are using portal.cs.virginia.edu to build then you can replace this script with running module load <pathto>/tipc/conf/modulefiles/tipc/F24, where <pathto> is the path to where you have installed tipc.
Building tipc
The project uses GitHub Actions for building and testing and CodeCov for reporting code and documentation coverage. The build-and-test.yml file provides details of this process. If you would prefer to build and test manually then read on.
After cloning this repository you can build the compiler by moving to into the top-level directory and issuing these commands:
./bin/bootstrap.sh. ~/.bashrcmkdir buildcd buildcmake ..make
The build process will download an up to date version of ANTLR4 if needed, build the C++ target for ANTLR4, and then build all of tipc including its substantial body of unit tests. This may take some time - to speed it up use multiple threads in the make command, e.g., make -j6.
You may see some warnings, e.g., CMake policy warnings, due to some of the packages we use in the project. As those projects are updated, to avoid CMake feature deprecation, these will go away.
When finished the tipc executable will be located in build/src/. You can copy it to a more convenient location if you like, but a number of scripts in the project expect it to be in this location so don't move it.
The project includes more than 300 unit tests grouped into several executables. The project also includes more than 90 system tests. These are TIP programs that have built in test oracles that check for the expected results. For convenience, there is a runtests.sh script provided in the bin directory. You can run this script to invoke the entire collection of tests. See the README in the bin directory for more information.
All of the tests should pass.
Ubuntu Linux
Our continuous integration process builds on both Ubuntu 22.04 and 20.04, so these are well-supported. We do not support other linux distributions, but we know that people in the past have ported tipc to different distributions.
Mac OS
Our continuous integration process builds on macOS 12 and macOS 13 so modern versions of macOS are well-supported. tipc builds on both Intel and Apple Silicon, i.e., Apple's M1 ARM processor.
Windows Subsystem for Linux
If you are using a Windows machine, tipc can be built in the Windows Subsystem for Linux (WSL). Here are instructions to install WSL and upgrade to WSL2. It is highly recommended to upgrade to WSL2. Once installed, you should install Ubuntu 20.04. Once finished, you can open a virtual instance of Ubuntu and follow the instructions above to build tipc.
You may recieve an error saying "No CMAKE_CXX_COMPILER could be found" when running cmake ... If this is the case, you should install g++ with the command: sudo apt-get install g++.
Using tipc
The tipc compiler has a limited set of options available through the --help flag.
OVERVIEW: tipc - a TIP to llvm compiler
USAGE: tipc [options] <tip source file>
OPTIONS:
Generic Options:
--help - Display available options (--help-hidden for more)
--help-list - Display list of available options (--help-list-hidden for more)
--version - Display the version of this program
tipc Options:
Options for controlling the TIP compilation process.
--asm - emit human-readable LLVM assembly language
--do - disable bitcode optimization
--log=<logfile> - log all messages to logfile (enables --verbose 3)
-o=<outputfile> - write output to <outputfile>
--pa=<AST output file> - print AST to a file in dot syntax
--pcg=<call graph output file> - print call graph to a file in dot syntax
--pi - perform polymorphic type inference
--pp - pretty print
--ps - print symbols
--pt - print symbols with types (supercedes --ps)
--verbose=<int> - enable log messages (Levels 1-3)
Level 1 - Basic logging for every phase.
Level 2 - Level 1 and type constraints being unified.
Level 3 - Level 2 and union-find solving steps.
By default it will accept a .tip file, parse it, perform a series of semantic analyses to determine if it is a legal TIP program, generate LLVM bitcode, and emit a .bc file which is a binary encoding of the bitcodes. You can see a human readable version of the bitcodes by running llvm-dis on the .bc file.
To produce an executable version of a TIP program, the .bc file must be linked with the bitcode for tip_rtlib.c. Running the build.sh script in the rtlib directory once will create that library bitcode file.
The link step is performed using clang which will include additional libraries needed by tip_rtlib.c.
For convenience, we provide a script build.sh that will compile the tip program and perform the link step. The script can be used within this git repository, or if you define the shell variable TIPDIR to the path to the root of the repository you can run it from any location as follows:
$ cd
$ more hello.tip
main() { return 42; }
$ $HOME/tipc/bin/build.sh hello.tip
$ ./hello
Program output: 42
$ $HOME/tipc/bin/build.sh -pp -pt hello.tip
main()
{
return 42;
}
Functions : {
main : () -> int
}
Locals for function main : {
}
Working with tipc
The instructions above, and the scripts described below, make it possible to develop from the command line. This gives you lots of control, but it means you will miss the benefit of modern IDEs. Below we describe how to set up the CLion IDE for use with the project.
Command line
During development you need only run build steps 1 through 5 a single time, unless you modify some CMakeLists.txt file. Just run make in the build directory to rebuild after making changes to the source.
If you do need to add a source file then you will have to edit the appropriate CMakeLists.txt file to add it. In this case, you should:
cd buildrm CMakeCache.txtcmake ..
which will regenerate the makefiles that you can then run, by typing make, to build.
Note that the tipg4 directory has a standalone ANTLR4 grammar. It's README describes how to build it in isolation and run it using the ANTLR4 jar file.
The bin directory
To facilitate development of tipc we have collected a number of helper scripts into the bin directory of the project. Among them are scripts to run the entire test bed (runtests.sh), to run a code coverage analysis (gencov.sh), and to generate the project documentation (gendocs.sh). Please see the README in the bin directory for example usages.
When rebuilding and rerunning tests you may get errors about
failing to merge gcov files. This happens when gcov files linger from previous
runs. To cleanup these messages, simply run the cleancov.sh script.
CLion
CLion is C++ IDE that can be used to develop and build tipc. CLion can be installed with the JetBrains suite of tools, or as a standalone tool here. Once installed, you can start a 30 day trial license or, as a student, you can get a free educational license here.
These instructions are with respect to CLion 2023.1.3, but older or new versions work similarly - though the UI may be a bit different.
If you are building for the first time with CLion, follow the first two ste
