{"id":31765106,"url":"https://github.com/rachitdhar/em","last_synced_at":"2026-05-14T23:07:18.749Z","repository":{"id":317984363,"uuid":"1050937994","full_name":"rachitdhar/em","owner":"rachitdhar","description":"Compiler for the Em programming language","archived":false,"fork":false,"pushed_at":"2025-10-07T20:58:46.000Z","size":107,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-07T22:34:49.845Z","etag":null,"topics":["compilers","languages","llvm","parsing","syntax-analysis"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rachitdhar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-05T07:20:40.000Z","updated_at":"2025-10-07T20:58:49.000Z","dependencies_parsed_at":"2025-10-04T10:36:49.223Z","dependency_job_id":"46f45057-9bf6-48cc-b94b-9ddd5b6cd6bb","html_url":"https://github.com/rachitdhar/em","commit_stats":null,"previous_names":["rachitdhar/vanta","rachitdhar/em"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/rachitdhar/em","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rachitdhar%2Fem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rachitdhar%2Fem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rachitdhar%2Fem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rachitdhar%2Fem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rachitdhar","download_url":"https://codeload.github.com/rachitdhar/em/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rachitdhar%2Fem/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002382,"owners_count":26083356,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compilers","languages","llvm","parsing","syntax-analysis"],"created_at":"2025-10-10T00:13:14.008Z","updated_at":"2026-05-09T16:41:06.278Z","avatar_url":"https://github.com/rachitdhar.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Em (Programming Language)\nCompiler for the Em programming language, a systems programming language with a C-style syntax that emphasizes clean, simple and minimal features with high performance.\n\nThis project was largely undertaken by me for fun and educational purposes, but it is semi-serious in the sense that it is a full-fledged compiler that can be used for real purposes.\n\n\u003e **Note:** This project is still in early development.\n\n## Installation\n\nBefore using this compiler, you would need to have Visual Studio Build Tools\ninstalled on your system (I know, this is a stupid pain, but unfortunately,\nat least on Windows, certain C Runtime libs are present only via Build Tools).\n\nYou can download the Build Tools installer yourself, or you may use a script to\ndo so, called `build_tools_installation.bat`, located in the bin folder. This\nwill automatically download the installer, and then run it (it will open the GUI\ninterface for you to then work with).\n\nThe only thing needed is really the C++ Developer Tools, which will bring in the\nlibs like vcruntime.lib, msvcrt.lib, and libcmt.lib, required at link time (Technically,\nthese are not _really_ required if you write your own runtime. I did provide a\nminimal runtime to link with, called win_runtime.bc, which is a bitcode file that\nprovides the startup glue code needed for an executable. But this is devoid of any\nC runtime library features, which usually are useful, and otherwise you would have to\nimplement on your own (which is an option if desired)).\n\nThe first time the compiler is run and it reaches the linking stage, it will search for\nthe paths to the Windows SDK and VS Build Tools. If it does not find them, it will\nprint an error on the console. If found, these are going to be cached in a txt file\ncalled `cached_paths.txt`, for future use.\n\n## Usage\n\nCompile a file at a given path using emc (the \"Em compiler\"):\n\n```\nemc \u003cFILE_PATH\u003e\n```\n\nThe file must have a .em extension.\nTo compile multiple files at once:\n\n```\nemc \u003cFILE_1\u003e \u003cFILE_2\u003e ... \u003cFILE_n\u003e\n```\n\n## Flags\n\nWe can add some compilation flags when compiling, as:\n\n```\nemc \u003cFILE_1\u003e \u003cFILE_2\u003e ... \u003cFILE_n\u003e ...\n                                    ^ flags (optional)\n```\n\nA flag is identified as something that starts with a hyphen (-).\nEverything before the first flag will be treated as a file to be compiled.\n\nHere are the flags that can be added, along with their purposes:\n\n- **-pout** : Prints the Parser Output (structure of the AST)\n- **-llout** : Prints the LLVM IR generated\n- **-ll** : Generates a .ll file (LLVM IR) instead of an executable\n- **-asm** : Generates a .s file (Assembly) instead of an executable\n- **-cpu** : To specify the target CPU type. This flag must be followed by the CPU name\n- **-o** : To name the output file (for any type). This flag must be followed by the file name\n- **-benchmark** : Prints the performance metrics for the compilation process\n- **-O1 / -O2 / -O3** : To specify the optimization level (1, 2 or 3). If not given, default is 0.\n\nThe list of CPU types that can be set as targets using \"-cpu\", are:\n\n```\nx86-64\ncortex-m3\ncortex-m4\ncortex-m7\ncortex-a7\ncortex-a53\ncortex-a72\ncortex-a76\ncortex-a78\ncortex-x1\napple-m1\napple-m2\nneoverse-n1\nneoverse-v1\nneoverse-n2\n```\n\nIf the \"-cpu\" flag is not specified, the cpu type of the host machine is determined by the compiler automatically at compile time.\n\nFor example, in order to compile a program called \"prog.em\" and get the assembly for the x86-64 target, we will compile using the command:\n\n```\nemc prog.em -asm -cpu x86-64\n```\n\n\u003e **Note:**\n\u003e When benchmarking, ensure that any Real-Time Anti-Virus Scanning is turned off, since that would significantly slow down\n\u003e the entire linking stage (where CreateProcessA is called to create the executable). I personally figured this out when\n\u003e I implemented this, and was trying to determine why CreateProcessA was taking 900 ms alone, for the same linking task\n\u003e that was being performed in just 100 ms through a system() call!\n\n## Compiling the Compiler + LLVM Linking\n\nIt turns out that one of the most difficult and irritating parts of developing this compiler was to figure out how LLVM libraries can actually be included and compiled. After doing almost every possible thing - from installing the LLVM binaries and manually linking; using Visual Studio configurations; using CMAKE to handle builds; to building LLVM myself from the llvm-project source and trying to fix the compatibility issues between it and my own mingw compiler - I finally found that MSYS2 comes with the ability to install everything I need: C/C++ compilers, GDB, LLC,... and most importantly all the LLVM headers and libraries. From within the MSYS MINGW64 shell, all the compilation problems get handled very smoothly.\n\nAt the location msys64/mingw64/bin, running the command:\n\n```\nllvm-config --cxxflags --ldflags --libs all --system-libs\n```\n\ngives me the output:\n\n```\n-ID:/softwares/msys64/mingw64/include -std=c++17 -fno-exceptions -funwind-tables -DEXPERIMENTAL_KEY_INSTRUCTIONS -D_FILE_OFFSET_BITS=64 -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -LD:/softwares/msys64/mingw64/lib -lLLVM-21\n```\n\nwhich contains the information needed regarding the include paths, compiler flags and library paths that are needed for linking LLVM during the compilation of my compiler.\n\nI have a build script to compile the compiler:\n\n```\n./build.bat\n```\n\nTo compile with debugging symbols, use the -debug flag:\n\n```\n./build.bat -debug\n```\n\n## Compiling the Compiler (Visual Studio / MSVC cl.exe compiler + LLVM for Windows)\n\nSo here's the thing. Visual Studio uses the MSVC cl.exe compiler, which CAN actually be used to build this project.\nThe thing where I was going wrong was, I was trying to use the LLVM version for GNU based C++ compilers. What I did not\nrealise at the time was that this is a problem because the GNU based LLVM libraries and MSVC cl.exe compiler are not ABI\ncompatible, since of course, GNU compilers (used to build the GNU based LLVM) are just different from MSVC ones. So I had to use\nthe correct build of LLVM. I DID in fact try to do this earlier, and HAD even installed the one from the LLVM releases page. The\nproblem there was that it did not have all the libraries and libs I needed to be able to use it.\n\nTurns out, that on their releases page itself, they have mentioned clearly that for Windows, the clang+llvm artifact is the one\nthat contains all the libraries and libs, which for some reason is this way only for Windows (otherwise for other cases, as I previously\nassumed, it shouldn't matter which one you installed, as they are all the same LLVM version and under the same release).\n\nAnyways, long story short, now I can actually build using the Visual Studio default compiler. Of course, I wrote a separate build script\nfor this purpose, in build-msvc.bat, which I configured Visual Studio to use as part of its Makefile project configuration. It took a\nfew hours figuring out how I am supposed to add the flags for linking and stuff, but now it seems to be working fine.\n\n## Profiling using Tracy\n\nIn order to check for performance bottlenecks, I am using the Tracy profiler. For this I have basically just added the necessary flags in the build script for Debug builds, and added a ZoneScopedS function call in certain key places in the frontend (which is the place I can control the most at the moment).\n\nDue to this, you would need to have the Tracy repo downloaded, and set the path for it in the script, in case you want to build the compiler yourself. Alternatively, you could just remove the flag for tracy and remove the cpp file path for the TracyClient.cpp from the list of files being compiled. This is the simplest way if you just want to build the project without any plan for running a profiler on it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frachitdhar%2Fem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frachitdhar%2Fem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frachitdhar%2Fem/lists"}