{"id":28563722,"url":"https://github.com/googlielmo/subc","last_synced_at":"2025-06-10T13:08:01.501Z","repository":{"id":42065708,"uuid":"336241926","full_name":"googlielmo/subc","owner":"googlielmo","description":"SubC Compiler updated with macOS and Docker support","archived":false,"fork":false,"pushed_at":"2022-04-14T10:52:55.000Z","size":196,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-03T10:38:50.179Z","etag":null,"topics":["c-language","compiler","compiler-construction"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/googlielmo.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-05T10:43:27.000Z","updated_at":"2023-11-15T08:38:18.000Z","dependencies_parsed_at":"2022-08-12T03:50:55.929Z","dependency_job_id":null,"html_url":"https://github.com/googlielmo/subc","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlielmo%2Fsubc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlielmo%2Fsubc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlielmo%2Fsubc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlielmo%2Fsubc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/googlielmo","download_url":"https://codeload.github.com/googlielmo/subc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googlielmo%2Fsubc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259081035,"owners_count":22802404,"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","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":["c-language","compiler","compiler-construction"],"created_at":"2025-06-10T13:07:55.768Z","updated_at":"2025-06-10T13:08:01.493Z","avatar_url":"https://github.com/googlielmo.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nSubC Compiler\n=============\n\n    By Nils M Holm, 2011—2016 \n    Placed in the public domain\n\nThe original\n[SubC compiler](http://www.t3x.org/subc/)\nis described in the excellent book\n[Practical Compiler Construction](http://www.t3x.org/reload/index.html)\nby Nils M Holm.\n\nThe current version starts out from the latest compiler code\navailable from Nils' website:\n[subc-20161212.tgz](http://www.t3x.org/subc/subc-20161212.tgz).\n\n\nWHAT'S NEW\n----------\n\nUpdated by Guglielmo Nigri\n([@googlielmo](https://github.com/googlielmo)), 2021.\n\nSource code available at: https://github.com/googlielmo/subc\n\n- Darwin target now *stable* (tested on macOS 10.15 and 11.1)\n- Ongoing work to update Linux x86-64 target to the latest tool \n  chain\n- Docker support\n\nThe rest of this document is being updated to track the ongoing\ndevelopment.\n\nPlease see [README_ORIG](README_ORIG) for the original README.\n\n\nSUMMARY\n-------\n\nSubC is a compiler for a (mostly) strict and sane subset of\nC as described in \"The C Programming Language\", 2nd Ed (also\nknown informally as \"ANSI C\" or \"C89\").\n\nA previous version of the compiler is described in great detail\nin the book \"Practical Compiler Construction\", which can be\npurchased at Lulu.com. See  http://www.t3x.org/reload/  for\nordering information.\n\nThe SubC compiler can compile itself. Unlike many other small C\ncompilers, it does not bend the rules, though. Its code passes\n`gcc -Wall -pedantic` with little or no warnings (depending on\nthe gcc version used). Of course, you can also bootstrap it with\nother C compilers, such as Clang or PCC.\n\nSubC is fast and simple. Its output is statically linked (where\navailable) and typically small due to a non-bloated library). It\nuses a simple optimizer on per-expression basis.\n\n\nQUICKSTART\n----------\n\nOn supported systems this is the quickest way to compile and\ninstall the `scc` compiler.\n\nMake sure you have the system C compiler on your path.\n\nConfigure the target system:\n\n      make configure\n\nBootstrap the compiler and check everything is in order:\n\n      make tests\n\nInstall the compiler:\n\n      make install\n\nOf course, you can also build and install manually.\nSee below for detailed instructions.\n\n\nSUPPORTED SYSTEMS\n-----------------\n\nSubC generates code for GAS, the GNU assembler (except for the\nDOS version, which emits TASM-style syntax). It targets the\nfollowing processors and operating systems:\n\n    FreeBSD\t\t386\tarmv6\tx86-64\n    Linux\t\t386\t-\tx86-64\n    NetBSD\t\t386\t-\tx86-64\n    OpenBSD\t\t386%\t-\t-\n    Windows/MinGW\t386\t-\t-\n    Darwin\t\t-\t-\tx86-64%\n    DOS\t\t8086!\n\n      %  uses the syscall layer of the host libc\n      *  untested\n      !  experimental\n     (/) broken\n\nPlatforms tagged \"untested\" are not regularly tested by myself\nand are therefore subject to potential bit rot. You can help\nme improve SubC by running `make tests` on an \"untested\"\nplatform and let me know about the results.\n\nPlatforms using the system's libc as a thin system call layer\noften cause build/stability problems due to the omnipresence of\nthe GNU libc, which is not \"thin\" at all. Expect trouble on\nthose systems!\n\nOn Darwin/macOS the system libc is being used (not the GNU libc),\nwhich is linked dynamically and is actually required for\nissuing system calls in a portable way.\n\nPlatforms tagged \"broken\" currently will not compile or run\nproperly for some reason. See the Todo file for details.\n\nThe DOS version brings its own toolchain, which can be found in\nthe s86/ directory, so no pre-existing DOS assembler or linker\nis required to compile SubC programs on DOS.\n\nPorting SubC to other 32-bit or 64-bit platforms should be\nquite straight-forward. See the file \"Porting\" and/or the book\nfor a general road map.\n\n\nCHANGES TO THE BOOK VERSION\n---------------------------\n\nNote: The book version runs on FreeBSD/386 exclusively.\n\nThe current version uses an improved code generator, which\nemits much smaller and faster code than the book compiler.\nThe techniques are described in the book, though.\n\nThe current version of the SubC compiler adds support for\nthe following parts of C language to the version described\nin \"Practical Compiler Construction\":\n\n*  `\u0026array` is now valid syntax (you no longer have to write\n   `\u0026array[0]`).\n\n*  the `auto`, `register`, and `volatile` keywords are recognized\n   (as no-ops). Yes, volatile is safe, because SubC does not\n   have register variables.\n\n*  enums may now be local.\n\n*  extern identifiers may now be declared locally.\n\n*  Prototypes may have the `static` storage class.\n\n*  There is support for `struct` and `union` data types.\n\n*  `jmp_buf` is now a struct; `setjmp()` and `longjmp()` must be\n   called with `\u0026jmp_buf`.\n\n*  FILEs are now structs and can no longer be mistaken for\n   ints by the type checker.\n\n*  The `#error`, `#line`, and `#pragma` commands have been added.\n\n*  There is a (non-standard) `kprintf()` function, which is\n   like `fprintf()`, but uses a file descriptor.\n\n*  There is now a (slightly incompatible) varargs mechanism.\n   Here is how it works:\n\n```c\n   #include \u003cvarargs.h\u003e\n   \n   void p(int a, int b, ...) {\n     int\tfirst;\n     void\t*ap;\n   \n     ap = _va_start(\u0026b);\n     first = (int) _va_arg(\u0026ap);\n     vprintf(\"other args: %d %d %d\\n\", ap);\n     _va_end(\u0026ap);\n   }\n```\n\n*  The `vprintf()`, `vfprintf()`, and `vsprintf()` functions have\n   been added to the runtime library.\n\n*  A broader subset of C expression syntax is accepted\n   in constant expression contexts. For example, pointer\n   variables can be initialized with NULL.\n\n\nDIFFERENCES BETWEEN SUBC (THIS VERSION) AND FULL C89\n----------------------------------------------------\n\n*  The following keywords are not recognized:\n   `const`, `double`, `float`, `goto`, `long`, `short`,\n   `signed`, `typedef`, `unsigned`.\n\n*  There are only two primitive data types: the signed `int` and\n   the unsigned `char`; there are also void pointers, and there\n   is limited support for `int(*)()` (pointers to functions\n   of type int).\n\n*  No more than two levels of indirection are supported, and\n   arrays are limited to one dimension, i.e. valid declarators\n   are limited to `x`, `x[]`, `*x`, `*x[]`, `**x` (and `(*x)()`).\n\n*  K\u0026R-style function declarations (with parameter declarations\n   between the parameter list and function body) are not\n   accepted.\n\n*  There are no `const` variables.\n\n*  There is no `typedef`.\n\n*  There are no unsigned integers, long integers, or signed\n   chars.\n\n*  Struct/union declarations must be separate from the\n   declarations of struct/union objects, i.e.\n   `struct p { int x, y; } q;` will not work.\n\n*  Struct/union declarations must be global (struct and union\n   objects may be declared locally, though).\n\n*  There is no support for bit fields.\n\n*  Only ints, chars, and arrays of int and char can be\n   initialized in their declarations; pointers can be\n   initialized with 0 or NULL.\n\n*  Local arrays cannot have initializers.\n\n*  Local declarations are limited to the beginnings of function\n   bodies (they do not work in other compound statements).\n\n*  Arguments of prototypes must be named.\n\n*  There is no `goto`.\n\n*  There are no parameterized macros.\n\n*  The `#if` and `#elif` preprocessor commands are not recognized.\n\n*  The preprocessor does not accept multi-line commands.\n\n*  The preprocessor does not accept comments in (some) commands.\n\n*  The preprocessor does not recognize the `#` and `##` operators.\n\n*  There may not be any blanks between the `#` that introduces\n   a preprocessor command and the subsequent command (e.g.:\n   `# define` would not be recognized as a valid command).\n\n*  The `sizeof` operator requires parentheses.\n\n*  Subscripting an integer with a pointer (e.g. `1[\"foo\"]`) is\n   not supported.\n\n*  Function pointers are limited to one single type, `int(*)()`,\n   and they have no argument types. Note that this declaration\n   will in fact generate a pointer to `int(*)(void)`.\n\n*  There is no `assert()` due to the lack of parameterized macros.\n\n*  The `atexit()` mechanism is limited to one function (this may\n   even be covered by TCPL2).\n\n*  The `signal()` function returns int due to the lack of a more\n   sophisticated type system; the return value must be casted to\n   `int(*)()` manually.\n\n*  Most of the time-related functions are missing, in particular:\n   `asctime()`, `gmtime()`, `localtime()`, `mktime()`,\n   and `strftime()`.\n\n*  The `clock()` function is missing, because `CLOCKS_PER_SEC`\n   varies among systems.\n\n*  The `ctime()` function ignores the time zone.\n\n*  The varargs mechanism is slightly incompatible.\n\n*  The SubC compiler accepts `//` comments in addition to `/* */`.\n\n\nSELECTING A TARGET PLATFORM\n---------------------------\n\nThe easiest way to prepare a build is to run the `configure`\nscript in this directory (`make configure` also works).\n\nDon't worry, it is just a simple script that will figure out\nthe host platform via uname and link a few machine-dependent \nfiles into place.\n\nIf you want to configure the compiler manually: select one of\nthe target descriptions (cg*.c) files in `src/targets/cg` and\nsymlink it to `src/cg.c`. Also link the corresponding header\nfile into place:\n\n    (cd src \u0026\u0026 ln -fs targets/cg/cg386.c cg.c)\n    (cd src \u0026\u0026 ln -fs targets/cg/cg386.h cg.h)\n\nNext select the C startup (crt0) file for your OS and CPU type\nfrom `src/targets/OS-CPU/` and link it to `src/lib/crt0.s`, e.g.:\n\n    (cd src/lib \u0026\u0026 \\\n     ln -fs ../targets/freebsd-386/crt0-freebsd-386.s \\\n        crt0.s)\n\nIf your OS/CPU combination is not supported, you might try\nto port the compiler. See the file \"Porting\" for details.\n\nYou will also need some operating system-dependent\ndefinitions, which are kept in files named `sys-OS-CPU.h`\nin `src/targets/OS-CPU/`. Just symlink the appropriate file\nto `src/sys.h`:\n\n    (cd src \u0026\u0026 \\\n     ln -fs targets/freebsd-386/sys-freebsd-386.h sys.h)\n\nFinally, select a `limits-*.h` file from `targets/include/` that\nreflects the machine word size of your target and link it to\n`src/include/limits.h`:\n\n    (cd src/include \u0026\u0026 \\\n     ln -fs ../targets/include/limits-32.h limits.h)\n\n\nCOMPILING THE COMPILER\n----------------------\n\nThe compiler sources are contained in the `src` directory,\nso all the subsequent steps assume that this is your current\nworking directory. (I.e. do a `cd src` now.)\n\nOn a supported system, just type `make scc`.\n\nWithout `make` the compiler can be bootstrapped by running:\n\n    cc -o scc0 *.c\n\nTo compile and package the runtime library:\n\n    ./scc0 -c lib/*.c\n    ar -rc lib/libscc.a lib/*.o\n    ranlib lib/libscc.a\n\nTo compile the startup module:\n\n    as -o lib/crt0.o lib/crt0.s\n\nTo test the compiler, either run `make test` or perform the\nfollowing steps:\n\n    ./scc0 -o scc1 *.c\n    ./scc1 -o scc *.c\n    cmp scc1 scc\n\nThere should not be any differences between the `scc1` and `scc`\nexecutables.\n\n\nINSTALLING THE COMPILER\n-----------------------\n\nThe easy way would be to set up the PREFIX (and optionally\nSCCDIR and BINDIR) variables in `src/Makefile` to suit your\ntaste and then run\n\n    make dirs\t# to create the directories\n    make install\n\nIf you want to install the SubC compiler manually, you will\nhave to change the `SCCDIR` variable in the compiler itself.\nIt points to the base directory which will contain the SubC\nheaders and runtime library. `SCCDIR` defaults to \".\", but can\nbe overridden on the command line:\n\n    ./scc1 -o scc -D 'SCCDIR=\"INSTALLDIR\"' *.c\n\n(where `INSTALLDIR` is where the compiler will be installed.)\n\nYou can place the `scc` executable wherever you want, as long\nas its location is covered by the PATH environment variable.\nThe headers (`include/*`) go to `INSTALLDIR/include`, the library\n`lib/libscc.a` and the startup module `lib/crt0.o` go to\n`INSTALLDIR/lib`.\n\nTo test the installation just re-compile the compiler:\n\n    rm scc \u0026\u0026 scc -o scc *.c\n\n\nDOS SUPPORT\n-----------\n\nPlease see the NOTES-DOS file!\n\n\nWINDOWS SUPPORT\n---------------\n\nPlease see the NOTES-WINDOWS file!\n\n\nTHANKS\n------\n\nTo the Super Dimension Fortress (SDF.ORG) for providing\nfree shell accounts on 64-bit NetBSD machines.\n\nTo Bakul Shah for granting me remote access to a 64-bit\nFreeBSD system and a Linux VM.\n\nTo \"minux\" for porting the runtime module to Linux/x86-64.\n\nTo Jean-Marc Lienher (cod5.org) for porting the runtime module\nto MinGW Windows/386.\n\nTo Romain LWPB for porting the runtime module to OpenBSD/386\nand Darwin/x86-64 as well as for modifying the x86-64 code\ngenerator to emit proper code for Darwin.\n\nTo everybody who test-drove SubC and submitted bug reports.\n\nTo the Unknown Hacker for various minor and not so minor\ncontributions.\n\n\nCONTACT\n-------\n\nSend feedback, suggestions, etc to:\n\nn m h @ t 3 x . o r g\n\nSee http://t3x.org/contact.html for current ways through my\nspam filter.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglielmo%2Fsubc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgooglielmo%2Fsubc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglielmo%2Fsubc/lists"}