{"id":13687393,"url":"https://github.com/saman-pasha/lcc","last_synced_at":"2025-05-16T10:12:13.054Z","repository":{"id":197645775,"uuid":"293309385","full_name":"saman-pasha/lcc","owner":"saman-pasha","description":"Lisp C Compiler aka. 'El-Cici' programming language, which compiles Lisp-like syntax to C code and more extra features like method, lambda, defer.","archived":false,"fork":false,"pushed_at":"2025-04-24T05:36:17.000Z","size":663,"stargazers_count":29,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-01T12:41:09.499Z","etag":null,"topics":["c","compiler","lisp","programming-language"],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saman-pasha.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}},"created_at":"2020-09-06T15:48:53.000Z","updated_at":"2025-04-24T05:36:21.000Z","dependencies_parsed_at":"2025-04-16T22:33:57.162Z","dependency_job_id":"248ee50d-fceb-4575-bbd1-f28e850ce2ac","html_url":"https://github.com/saman-pasha/lcc","commit_stats":null,"previous_names":["saman-pasha/lcc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saman-pasha%2Flcc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saman-pasha%2Flcc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saman-pasha%2Flcc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saman-pasha%2Flcc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saman-pasha","download_url":"https://codeload.github.com/saman-pasha/lcc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254509449,"owners_count":22082896,"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","compiler","lisp","programming-language"],"created_at":"2024-08-02T15:00:54.049Z","updated_at":"2025-05-16T10:12:13.040Z","avatar_url":"https://github.com/saman-pasha.png","language":"Common Lisp","funding_links":[],"categories":["Languages"],"sub_categories":["C/C++"],"readme":"# Notic\nThis reposirory will be known by a different brand `Cicili` and archived. lcc moves to [github.com/saman-pasha/cicili](https://github.com/saman-pasha/cicili).\n# lcc\nLisp C Compiler aka. 'Cicili' programming language, which compiles Lisp-like syntax to C code and more extra features like method, lambda, defer.\n## Instruction\n* Install [SBCL](www.sbcl.org).\n* `clang` required for compiling and linking. `apt` or `brew` can be used to install [Clang](https://clang.llvm.org). Current used version: `(clang-1700.0.13.3)`\n* lcc uses [Libtool](https://www.gnu.org/software/libtool) as default for perfoming better compiling and linking `C` code. Install it for your platform and put it in the `PATH` environment variable. Compiler and linker could be set in `config.lisp` file. Current used version: `(GNU libtool) 2.5.4`\n* Download and copy lcc folder to `~/common-lisp` for enabling [ASDF](https://common-lisp.net/project/asdf) access to lcc package.\n* Write your own lcc code and save it in `.lcc` or `.lisp` extension.\n* Copy `lcc.lisp` file from source folder into your project path.\n* Send your file as an argument to lcc.lisp. `sbcl --script lcc.lisp test.lisp`\n* If you are using EMACS editor, copy `mode.lisp` file content into `.emacs` or `.emacs.d/init.el` file for syntax highlighting.\n## * New Features\n* lcc now uses `IR` (Intermediate Representation) to handle more clauses and features.\n* modularizing lcc code makes clarity and easy to follow C code but makes debugging harder. refer to [module](test/module) test folder `module.lisp` sample.\n* `lambda` clause allows developer to write in-place function for sending as other function argument or `defer` destructure. refer to [lambda](test/lambda) test folder `lambda.lisp` sample.\n* `defer` attribute. only available for variables defined by `let` expression. Allows developers to set a function how to destruct a variable or a pointer. refer to [defer](test/lambda) test folder `defer.lisp` sample.\n* auto deferral is a way let expressions will defined to automatically release dynamic memory allocated by `alloc` clause. refer to [alloc](test/lambda) test folder `defer.lisp` sample.\n* `method` clause will receive current instance or pointer as `this` parameter. Methods are defined outside a structure by access method operator `-\u003e` placed between struct name and method name like `Employee-\u003eSign`.  refer to [method](test/method) test folder `method.lisp` sample.\n* `auto` variable type simplifies lambda and function pointer variables. also `typeof` clause is added to use other variables type for define another variable.\n* `inline struct` can be defined in variable declaration, function parameters or outputs which permits to return multiple values from a function. refer to [multi](test) `multi.lisp` file for complex samples.\n* `func` type allows developer to define a function pointer which wasn't available before.\n* refer to [basic](test) `basic.lisp` file for some struct definition samples.\n* refer to [control](test) `control.lisp` file for some control structures samples.\n## Identifiers\nFor basic variable definition refer to [var](test) `var.lisp` file.\n```lisp\n(var int amount)\n(var double total)\n(var double * total2)\n```\n```c\nint amount;\ndouble total;\ndouble * total2;\n```\n## Constants\n```lisp\n(var const int SIDE . 10)\n(var const int * SIDE1 . #'(aof SIDE))\n(var const int * const SIDE2 . #'(aof SIDE1))\n```\n```c\nconst int SIDE = 10;\nconst int * SIDE1 = \u0026SIDE;\nconst int * const SIDE2 = \u0026SIDE1;\n```\n## Operators\n### Arithmetic\nlcc Operator | C Operator\n------------ | ----------\n`+`|`+`\n`-`|`-`\n`*`|`*`\n`/`|`/`\n`%`|`%`\n```lisp\n(set total (+ total amount))\n\n(let ((int i . 3)\n      (int j . 7)\n      (int k))\n  (set k (+ i j)))\n```\n```c\ntotal = total + amount;\n\n{\n  int i = 3, j = 7, k;\n  k = i + j;\n}\n```\n### Increment and Decrement\nlcc Operator | C Operator\n------------ | ----------\n`++`|prefix `++`\n`--`|prefix `--`\n`1+`|postfix `++`\n`1-`|postfix `--`\n```lisp\n(source \"main.c\" ()\n  (include \u003cstdio.h\u003e)\n\n  (func main ()\n    (let ((int a . 5)\n          (int b . 5))\n          \n      ;; Print them and decrementing each time.\n      ;; Use postfix mode for a and prefix mode for b.\n      \n      (printf \"\\n%d %d\" (1- a) (-- b))\n      (printf \"\\n%d %d\" (1- a) (-- b))\n      (printf \"\\n%d %d\" (1- a) (-- b))\n      (printf \"\\n%d %d\" (1- a) (-- b))\n      (printf \"\\n%d %d\" (1- a) (-- b)))))\n```\n```c\n#include \u003cstdio.h\u003e\n\nint main()\n{\n  {\n    int a = 5, b = 5;\n    \n    //Print them and decrementing each time.\n    //Use postfix mode for a and prefix mode for b.\n    \n    printf(\"\\n%d %d\", a--, --b);\n    printf(\"\\n%d %d\", a--, --b);\n    printf(\"\\n%d %d\", a--, --b);\n    printf(\"\\n%d %d\", a--, --b);\n    printf(\"\\n%d %d\", a--, --b);\n  }\n}\n```\n### Relational\nlcc Operator | C Operator\n------------ | ----------\n`==`|`==`\n`!=`|`!=`\n`\u003e`|`\u003e`\n`\u003c`|`\u003c`\n`\u003e=`|`\u003e=`\n`\u003c=`|`\u003c=`\n### Logical\nlcc Operator | C Operator\n------------ | ----------\n`and`|`\u0026\u0026`\n`or`|`\\|\\|`\n`not`|`!`\n### Bitwise\nlcc Operator | C Operator\n------------ | ----------\n`\u003c\u003c`|`\u003c\u003c`\n`\u003e\u003e`|`\u003e\u003e`\n`~`|`~`\n`bitand`|`\u0026`\n`bitor`|`\\|`\n`xor`|`^`\n`^`|`^`\n### Assignment\nlcc Operator | C Operator\n------------ | ----------\n`set`|`=`\n`+=`|`+=`\n`-=`|`-=`\n`*=`|`*=`\n`/=`|`/=`\n`%=`|`%=`\n`\u003c\u003c=`|`\u003c\u003c=`\n`\u003e\u003e=`|`\u003e\u003e=`\n### Conditional\nlcc Operator | C Operator\n------------ | ----------\n`?`|`?:`\n```lisp\n(set a (? (== b 2) 20 30))\n```\n```c\na = (b == 2) ? 20 : 30;\n```\n### Special\nlcc Operator | C Operator\n------------ | ----------\n`sizeof`|`sizeof()`\n`typeof`|`typeof()`\n`aof`|`\u0026`\n`cof`|`*`\n## Data Types\nANSI C provides three types of data types:\n\n* Primary(Built-in) Data Types: void, int, char, double and float.\n* Derived Data Types: Array, References, and Pointers.\n* User Defined Data Types: Structure, Union, and Enumeration.\n\nlcc supports declaration and definition of all ANCI C data types.\nlcc Data Type | C Data Type\n------------- | -----------\n`nil`|`NULL`\n`void`|`void`\n`bool`|`bool`\n`char`|`char`\n`uchar`|`unsigned char`\n`short`|`short`\n`ushort`|`unsigned short`\n`int`|`int`\n`uint`|`unsigned int`\n`long`|`long`\n`ulong`|`unsigned long`\n`llong`|`long long`\n`ullong`|`unsigned long long`\n`i8`|`int8_t`\n`u8`|`uint8_t`\n`i16`|`int16_t`\n`u16`|`uint16_t`\n`i32`|`int32_t`\n`u32`|`uint32_t`\n`i64`|`int64_t`\n`u64`|`uint64_t`\n`i128`|`__int128`\n`u128`|`unsigned __int128`\n`float`|`float`\n`double`|`double`\n`real`|`long double`\n`auto`|`__auto_type`\n## Variable\n```lisp\n(source \"main.c\" ()\n        (func main ()\n              (let ((double price . 500.4)                         ; atom initialization\n                    (double price_array [] . '{100.2 230.7 924.8}) ; list initialization\n                    (double price_calc . #'(calculate_price))      ; initialization by output of a function\n                    (auto identity . '(lambda ((int x)) (out int) (return x))))))) ; lambda initialization\n```\n```c\nint __lccLambda_main_178 (int x) {\n  return x ;\n}\nint main () {\n  { \n    double price = 500.4;\n    double price_array[] = {100.2, 230.7, 924.8};\n    double price_calc = calculate_price ();\n    __auto_type identity = __lccLambda_main_178 ;\n  } \n}\n```\n### Free Variable Declaration and Initialization\nA free variable can has some attributes or storage class. each attribute enclosed in braces or parentheses. free variables can only be defined as global variable for inside function variable declaration `let` clause should be used.\n* {auto}\n* {register}\n* {static}\n* {extern}\n```lisp\n{auto} (var int width)\n{register} (var int height . 5)\n(var char letter . #\\A)\n(var float age)\n{extern} (var float area)\n{static} (var double d)\n\n;; actual initialization\n(set width 10)\n(set age 26.5)\n```\n```c\nauto int width; \nregister height = 5;\nchar   letter = 'A';\nfloat  age;\nextern float area;\nstatic double d;\n\n/* actual initialization */\nwidth = 10;\nage = 26.5;\n```\n### Scoped Variable Declaration and Initialization\nA scoped variable can has some attributes or storage class. each attribute enclosed in braces or parentheses. `let` clause allows to declare a `defer` destructure for every variable as a lambda or a function which receives a pointer of variable type. useful for free struct pointers or any resource which stored inside a struct.\n* {auto}\n* {register}\n* {static}\n* {defer `'(lambda ((int * intPtr)) (printf \"int gone out of scope\\n\"))`} variable destructor\n```lisp\n(source \"main.c\" ()\n        (func main ()\n              (let ({static} (int width . 3)\n                    {register} (int height . 4)\n                    {defer '(lambda ((Employee ** empPtr))\n                              (free (cof empPtr))\n                              (printf \"from defer, emp is freed\\n\"))}\n                    (Employee * emp . #'(alloc (sizeof Employee))))\n                (printf \"area: %d\" (* width height)))))\n```\n```c\nvoid __lccLambda_main_178 (Employee ** empPtr) {\n  free ((*empPtr));\n  printf (\"from defer, emp is freed\\n\");\n}\nint main () {\n  { \n    static int width = 3;\n    register int height = 4;\n    Employee * emp __attribute__((__cleanup__(__lccLambda_main_178))) = ((Employee *)malloc(sizeof(Employee)));\n    printf (\"area: %d\", (width * height));\n  } \n}\n```\n### Assignment\n```lisp\n(set width 60)\n(set age 35)\n(set width 65 age 40) ; multi assignment\n```\n```c\nwidth = 60;\nage = 31;\nwidth = 65;\nage = 40;\n```\n```lisp\n(source \"main.c\" ()\n  (include \u003cstdio.h\u003e)\n  \n  (func main ()\n    (let ((int age . 33))\n      (printf \"I am %d years old.\\n\" age))))\n```\n```c\n#include \u003cstdio.h\u003e\n\nint main()\n{\n  {\n    int age = 33;\n    printf(\"I am %d years old.\\n\", age);\n  }\n}\n```\n## Type Casting\n```lisp\n(source \"main.c\" ()\n  (include \u003cstdio.h\u003e)\n  (func main ()\n    (let ((float a))\n      (set a (cast float (/ 15 6)))\n      (printf \"%f\" a))))\n```\n```c\n#include \u003cstdio.h\u003e\nmain ()\n{\n  {\n    float a;\n    a = (float) 15 / 6;\n    printf(\"%f\", a);\n  }\n}\n```\n## Program Structure\nlcc program involves one or many header or source forms calling targets.\ntargets are translating its content forms to C code. header targets only compile its content without resolving, but source targets resolves attribue and method access of any struct variable. for example \n```lisp\n(let ((Employee emp)\n      (Employee * empPtr))\n  ($ emp id)     ; do not needd resolve\n  ($ empPtr id)) ; resolves pointer access\n```\n```c\n{\n  Employee emp;\n  Employee * empPtr;\n  emp.id;\n  empPtr-\u003eid;\n}\n```\neach target must has a target c file, and a list of feature arguments.\n### Features\nAll features could be omitted or if available accept `#t` for default behaviour or `#f` for do nothing.\n* \u003cb\u003e:std\u003c/b\u003e: writes standard libraries inclusion at top of target file.\n```lisp\n(source \"main.c\"\n  (:std #t)\n  ;; some forms\n  )\n```\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstddef.h\u003e\n#include \u003cstdint.h\u003e\n#include \u003cstdlib.h\u003e\n#include \u003cstdbool.h\u003e\n```\n* \u003cb\u003e:compile\u003c/b\u003e: used for compiling target file. Dafault behaviour is `-c target.c`. Could be a list of arguments that will send to compiler which has been set in `config.lisp`.\n* \u003cb\u003e:link\u003c/b\u003e: used for linking and builing target file as library or executable. It has not default behaviour. Could be a list of arguments that will send to linker which has been set in `config.lisp`.\n```lisp\n;; MyMath library declaration\n(header \"mymath.h\"\n  (:compile #f)\n\n  (guard __MYMATH_H__\n    {decl} (func obj1_does ((int) (int)) (out int))\n    {decl} (func obj2_does ((int) (int)) (out int))\n    {decl} (func obj3_does ((int) (int)) (out int))))\n\n;; Default compilation\n(source \"obj1.c\"\n  (:compile #t)\n  (include \"mymath.h\")\n  (func obj1_does ((int x) (int y)) (out int)\n\t    (return (+ x y))))\n\n;; Custom compilation\n(source \"obj2.c\"\n  (:compile \"-c obj2.c -o objmul.lo\")\n  (include \"mymath.h\")\n  (func obj2_does ((int x) (int y)) (out int)\n\t    (return (* x y))))\n\n;; Library creation and linking\n(source \"obj3.c\"\n  (:compile #t :link \"-o libMyMath.la -L{$CWD} obj1.lo objmul.lo obj3.lo\")\n  (include \"mymath.h\")\n  (func obj3_does ((int x) (int y)) (out int)\n\t    (return (obj1_does (obj2_does x y) (obj2_does x y)))))\n\n;; Executable creation and linking\n(source \"main.c\"\n  (:std #t :compile #t :link \"-o CompileTest -L{$CWD} main.lo -lMyMath\")\n  (include \"mymath.h\")\n  (func main ((int argc) (char * argv []))\n\t    (if (!= argc 3)\n\t\t    (block\n\t\t        (printf \"two digits needed!\")\n\t\t      (return EXIT_FAILURE)))\n\t    (let ((int x . #'(atoi (nth 1 argv)))\n\t\t      (int y . #'(atoi (nth 2 argv))))\n\t      (printf \"MyMath lib outputs: %d\\n\" (obj3_does x y)))\n\t    (return EXIT_SUCCESS)))\n```\n```\nlcc % sbcl --script lcc.lisp test/test.lisp\nsoftware type: \"Darwin\"\narg specified: test/mylib.lisp\nlcc: specifying target mymath.h\nlcc: resolving target mymath.h\nlcc: specifying target obj1.c\nlcc: resolving target obj1.c.run1.c\nrun out 1 \u003e glibtool: compile:  clang -g -O \"\" -c obj1.c.run1.c  -fno-common -DPIC -o .libs/obj1.c.run1.o \nrun out 1 \u003e glibtool: compile:  clang -g -O \"\" -c obj1.c.run1.c -o obj1.c.run1.o \u003e/dev/null 2\u003e\u00261 \nlcc: resolving target obj1.c.run2.c\nrun out 2 \u003e glibtool: compile:  clang -g -O \"\" -c obj1.c.run2.c  -fno-common -DPIC -o .libs/obj1.c.run2.o \nrun out 2 \u003e glibtool: compile:  clang -g -O \"\" -c obj1.c.run2.c -o obj1.c.run2.o \u003e/dev/null 2\u003e\u00261 \nlcc: resolving target obj1.c.run3.c\nrun out 3 \u003e glibtool: compile:  clang -g -O \"\" -c obj1.c.run3.c  -fno-common -DPIC -o .libs/obj1.c.run3.o \nrun out 3 \u003e glibtool: compile:  clang -g -O \"\" -c obj1.c.run3.c -o obj1.c.run3.o \u003e/dev/null 2\u003e\u00261 \nlcc: compiling target obj1.c\nglibtool: compile:  clang -g -O \"\" -c obj1.c  -fno-common -DPIC -o .libs/obj1.o\nglibtool: compile:  clang -g -O \"\" -c obj1.c -o obj1.o \u003e/dev/null 2\u003e\u00261\nlcc: specifying target obj2.c\nlcc: resolving target obj2.c.run1.c\nrun out 1 \u003e glibtool: compile:  clang -g -O \"\" -c obj2.c  -fno-common -DPIC -o .libs/objmul.o \nrun out 1 \u003e glibtool: compile:  clang -g -O \"\" -c obj2.c -o objmul.o \u003e/dev/null 2\u003e\u00261 \nlcc: resolving target obj2.c.run2.c\nrun out 2 \u003e glibtool: compile:  clang -g -O \"\" -c obj2.c  -fno-common -DPIC -o .libs/objmul.o \nrun out 2 \u003e glibtool: compile:  clang -g -O \"\" -c obj2.c -o objmul.o \u003e/dev/null 2\u003e\u00261 \nlcc: resolving target obj2.c.run3.c\nrun out 3 \u003e glibtool: compile:  clang -g -O \"\" -c obj2.c  -fno-common -DPIC -o .libs/objmul.o \nrun out 3 \u003e glibtool: compile:  clang -g -O \"\" -c obj2.c -o objmul.o \u003e/dev/null 2\u003e\u00261 \nlcc: compiling target obj2.c\nglibtool: compile:  clang -g -O \"\" -c obj2.c  -fno-common -DPIC -o .libs/objmul.o\nglibtool: compile:  clang -g -O \"\" -c obj2.c -o objmul.o \u003e/dev/null 2\u003e\u00261\nlcc: specifying target obj3.c\nlcc: resolving target obj3.c.run1.c\nrun out 1 \u003e glibtool: compile:  clang -g -O \"\" -c obj3.c.run1.c  -fno-common -DPIC -o .libs/obj3.c.run1.o \nrun out 1 \u003e glibtool: compile:  clang -g -O \"\" -c obj3.c.run1.c -o obj3.c.run1.o \u003e/dev/null 2\u003e\u00261 \nrun out 1 \u003e glibtool: link: rm -fr  .libs/libMyMath.a .libs/libMyMath.la \nrun out 1 \u003e glibtool: link: ar cr .libs/libMyMath.a .libs/obj1.o .libs/objmul.o .libs/obj3.o  \nrun out 1 \u003e glibtool: link: ranlib .libs/libMyMath.a \nrun out 1 \u003e glibtool: link: ( cd \".libs\" \u0026\u0026 rm -f \"libMyMath.la\" \u0026\u0026 ln -s \"../libMyMath.la\" \"libMyMath.la\" ) \nlcc: resolving target obj3.c.run2.c\nrun out 2 \u003e glibtool: compile:  clang -g -O \"\" -c obj3.c.run2.c  -fno-common -DPIC -o .libs/obj3.c.run2.o \nrun out 2 \u003e glibtool: compile:  clang -g -O \"\" -c obj3.c.run2.c -o obj3.c.run2.o \u003e/dev/null 2\u003e\u00261 \nrun out 2 \u003e glibtool: link: rm -fr  .libs/libMyMath.a .libs/libMyMath.la \nrun out 2 \u003e glibtool: link: ar cr .libs/libMyMath.a .libs/obj1.o .libs/objmul.o .libs/obj3.o  \nrun out 2 \u003e glibtool: link: ranlib .libs/libMyMath.a \nrun out 2 \u003e glibtool: link: ( cd \".libs\" \u0026\u0026 rm -f \"libMyMath.la\" \u0026\u0026 ln -s \"../libMyMath.la\" \"libMyMath.la\" ) \nlcc: resolving target obj3.c.run3.c\nrun out 3 \u003e glibtool: compile:  clang -g -O \"\" -c obj3.c.run3.c  -fno-common -DPIC -o .libs/obj3.c.run3.o \nrun out 3 \u003e glibtool: compile:  clang -g -O \"\" -c obj3.c.run3.c -o obj3.c.run3.o \u003e/dev/null 2\u003e\u00261 \nrun out 3 \u003e glibtool: link: rm -fr  .libs/libMyMath.a .libs/libMyMath.la \nrun out 3 \u003e glibtool: link: ar cr .libs/libMyMath.a .libs/obj1.o .libs/objmul.o .libs/obj3.o  \nrun out 3 \u003e glibtool: link: ranlib .libs/libMyMath.a \nrun out 3 \u003e glibtool: link: ( cd \".libs\" \u0026\u0026 rm -f \"libMyMath.la\" \u0026\u0026 ln -s \"../libMyMath.la\" \"libMyMath.la\" ) \nlcc: compiling target obj3.c\nglibtool: compile:  clang -g -O \"\" -c obj3.c  -fno-common -DPIC -o .libs/obj3.o\nglibtool: compile:  clang -g -O \"\" -c obj3.c -o obj3.o \u003e/dev/null 2\u003e\u00261\nglibtool: link: rm -fr  .libs/libMyMath.a .libs/libMyMath.la\nglibtool: link: ar cr .libs/libMyMath.a .libs/obj1.o .libs/objmul.o .libs/obj3.o \nglibtool: link: ranlib .libs/libMyMath.a\nglibtool: link: ( cd \".libs\" \u0026\u0026 rm -f \"libMyMath.la\" \u0026\u0026 ln -s \"../libMyMath.la\" \"libMyMath.la\" )\nlcc: specifying target main.c\nlcc: resolving target main.c.run1.c\nrun out 1 \u003e glibtool: compile:  clang -g -O \"\" -c main.c.run1.c  -fno-common -DPIC -o .libs/main.c.run1.o \nrun out 1 \u003e glibtool: compile:  clang -g -O \"\" -c main.c.run1.c -o main.c.run1.o \u003e/dev/null 2\u003e\u00261 \nrun out 1 \u003e glibtool: link: clang -g -O \"\" -o CompileTest .libs/main.o  -L/Users/a1/Projects/GitHub/lcc/test/ /Users/a1/Projects/GitHub/lcc/test/.libs/libMyMath.a  \nlcc: resolving target main.c.run2.c\nrun out 2 \u003e glibtool: compile:  clang -g -O \"\" -c main.c.run2.c  -fno-common -DPIC -o .libs/main.c.run2.o \nrun out 2 \u003e glibtool: compile:  clang -g -O \"\" -c main.c.run2.c -o main.c.run2.o \u003e/dev/null 2\u003e\u00261 \nrun out 2 \u003e glibtool: link: clang -g -O \"\" -o CompileTest .libs/main.o  -L/Users/a1/Projects/GitHub/lcc/test/ /Users/a1/Projects/GitHub/lcc/test/.libs/libMyMath.a  \nlcc: resolving target main.c.run3.c\nrun out 3 \u003e glibtool: compile:  clang -g -O \"\" -c main.c.run3.c  -fno-common -DPIC -o .libs/main.c.run3.o \nrun out 3 \u003e glibtool: compile:  clang -g -O \"\" -c main.c.run3.c -o main.c.run3.o \u003e/dev/null 2\u003e\u00261 \nrun out 3 \u003e glibtool: link: clang -g -O \"\" -o CompileTest .libs/main.o  -L/Users/a1/Projects/GitHub/lcc/test/ /Users/a1/Projects/GitHub/lcc/test/.libs/libMyMath.a  \nlcc: compiling target main.c\nglibtool: compile:  clang -g -O \"\" -c main.c  -fno-common -DPIC -o .libs/main.o\nglibtool: compile:  clang -g -O \"\" -c main.c -o main.o \u003e/dev/null 2\u003e\u00261\nglibtool: link: clang -g -O \"\" -o CompileTest .libs/main.o  -L/Users/a1/Projects/GitHub/lcc/test/ /Users/a1/Projects/GitHub/lcc/test/.libs/libMyMath.a\n```\n### Sections\n* Documentations: starts with semi-colon(s) \";\"\n```lisp\n;;; about a lisp file\n;;;; author, licence and/or documentation about each target\n(var long height) ; description of a form\n(func sqr ((double a)) \n  (out double)\n  ;; some commented code or documentation inside code\n  (return (* a a)))\n```\n* Preprocessor Forms: a form which starts with at-sign \"@\" and accepts one argument. code form is used for writing C code inside lcc.\n```lisp\n(@define (code \"SHA1_ROTL(bits, word) (((word) \u003c\u003c (bits)) | ((word) \u003e\u003e (32-(bits)))\"))\n\n(struct SHA512Context\n  (@ifdef USE_32BIT_ONLY)\n  (member uint32_t Intermediate_Hash[(/ SHA512HashSize 4)]) ; Message Digest\n  (member uint32_t Length[4])                               ; Message length in bits\n  (@else)                                                   ; !USE_32BIT_ONLY\n  (member uint64_t Intermediate_Hash[(/ SHA512HashSize 8)]) ; Message Digest\n  (member uint64_t Length_High)\n  (member uint64_t Length_Low)                              ; Message length in bits\n  (@endif)                                                  ; USE_32BIT_ONLY\n  (member int_least16_t Message_Block_Index)                ; Message_Block array index\n  (member uint8_t Message_Block[SHA512_Message_Block_Size]) ; 1024-bit message blocks\n  (member int Computed)                                     ; Is the hash computed?\n  (member int Corrupted))                                   ; Cumulative corruption code\n```\n```c\n#define SHA1_ROTL(bits, word) (((word) \u003c\u003c (bits)) | ((word) \u003e\u003e (32-(bits)))\n\ntypedef struct SHA512Context {\n#ifdef USE_32BIT_ONLY\n  uint32_t Intermediate_Hash [SHA512HashSize / 4];\n  uint32_t Length [4];\n#else\n  uint64_t Intermediate_Hash [SHA512HashSize / 8];\n  uint64_t Length_High;\n  uint64_t Length_Low;\n#endif\n  int_least16_t Message_Block_Index;\n  uint8_t Message_Block [SHA512_Message_Block_Size];\n  int Computed;\n  int Corrupted;\n} SHA512Context;\n```\n* Main Function: The main function is where program execution begins. Every lcc program must contain only one main function.\n## Decision Making\n### if\nIf form accepts 2 or 3 argument. condition, form for true evaluation of condition and form for false evaluation. third part(else) could be omitted. use ```block``` form if you need more forms in each part.\n```lisp\n(let ((int a . 5)\n      (int b . 6))\n  (if (\u003e a b)\n     (printf \"a is greater\")\n    (printf \"maybe b is greater\")))\n```\n```c\n{\n  int a = 5;\n  int b = 6;\n  if (a \u003e b)\n    printf(\"a is greater\");\n  else\n    printf(\"maybe b is greater\");\n}\n```\n```lisp\n(let ((int a . 5)\n      (int b . 6))\n  (if (\u003e a b)\n     (block\n       (printf \"a is greater\")\n       (set a (* a b)))\n    (block\n      (printf \"maybe b is greater\")\n      (set b (* b a)))))\n```\n```c\n{\n  int a = 5;\n  int b = 6;\n  if (a \u003e b) {\n    printf(\"a is greater\");\n    a = a * b;\n  } else {\n    printf(\"maybe b is greater\");\n    b = b * a;\n  }\n}\n```\n### switch\n```lisp\n(let ((int a))\n  (printf \"Please enter a number between 1 and 5: \")\n  (scanf \"%d\" (aof a))\n  \n  (switch a\n    (case 1 (printf \"You chose One\")   break)\n    (case 2 (printf \"You chose Two\")   break)\n    (case 3 (printf \"You chose Three\") break)\n    (case 4 (printf \"You chose Four\")  break)\n    (case 5 (printf \"You chose Five\")  break)\n    (default (printf \"Invalid Choice.\"))))\n```\n```c\n{\n  int a;\n  printf(\"Please enter a number between 1 and 5: \");\n  scanf(\"%d\", \u0026a);\n    \n  switch (a) {\n    case 1:\n      printf(\"You chose One\");\n      break;\n    case 2:\n      printf(\"You chose Two\");\n      break;\n    case 3:\n      printf(\"You chose Three\");\n      break;\n    case 4:\n      printf(\"You chose Four\");\n      break;\n    case 5:\n      printf(\"You chose Five.\");\n      break;\n    default:\n      printf(\"Invalid Choice\");\n      break;\n  }\n}\n```\n## Loops\n### while\n```lisp\n(let ((int n . 1)\n      (int times . 5))\n  (while (\u003c= n times)\n    (printf \"lcc while loops: %d\\n\" n)\n    (1+ n)))\n```\n```c\n{\n  int n = 1, times = 5;\n\n  while (n \u003c= times) {\n      printf(\"C while loops: %d\\n\", n);\n      n++;\n  }\n}\n```\n### do\n```lisp\n(let ((int n . 1)\n      (int times . 5))\n  (do\n    (printf \"lcc do loops: %d\\n\" n)\n    (1+ n)\n    (\u003c= n times))) ; last form of do clause checks the condition\n```\n```c\n{\n  int n = 1, times = 5;\n\n  do {\n      printf(\"C do loops: %d\\n\", n);\n      n++;\n  } while (n \u003c= times)\n}\n```\n### for\n```lisp\n(let ((int n)\n      (int times))\n               (for ((n . 1)\n                      (times . 5))     ; initialize\n                  (\u003c= n times)         ; test\n                  ((1+ n))             ; step\n                  (printf \"lcc for loop: %d\\n\" n)))\n\n              (for ((int n . 1)\n                    (times . 2))     ; initialize\n                (\u003c= n times)         ; test\n                ((1+ n))             ; step\n                (printf \"another initialization for loop: %d\\n\" n))\n```\n```c\n  {\n    int n;\n    int times;\n    for ( n = 1, times = 5; (n \u003c= times); (n ++)) {\n      printf (\"lcc for loop: %d\\n\", n);\n    } \n  }\n  for (int n = 1, times = 2; (n \u003c= times); (n ++)) {\n    printf (\"another initialization for loop: %d\\n\", n);\n  } \n```\n## Function\nlcc has some points on functions:\n* Use returns form for setting the return type. returns form must be first form of a function after arguments list. A fucntion without returns form will returns void instead of main which returns int.\n* Function's attributes must set in declaration time. each attribute enclosed in braces or parentheses.\n    * {declare}    \n    * {static}\n    * {inline}\n    * {extern}\n    * {resolve #f) means do not resolve this function\n```lisp\n(source \"main.c\"\n  (:std #t :compile #t :link #t)\n\n  ;; function declaration\n  {decl} (func addition ((int * a) (int * b)) (out int))\n  \n  (func main ()\n        ;; local variable definition\n        (let ((int answer)\n              (int num1 . 10)\n              (int num2 . 5)\n              (func aFuncPtr ((int * _) (int * _)) (out int) . addition)) ; function pointer\n          \n          ;; calling a function to get addition value\n          (set answer (addition (aof num1) (aof num2)))\n          (printf \"The addition of two numbers is: %d\\n\" answer)\n\n          (set answer (aFuncPtr (aof num1) (aof num2)))\n          (printf \"The addition of two numbers by function pointer is: %d\\n\" answer))\n\n        (return 0))\n  \n  ;; function returning the addition of two numbers\n  (func addition ((int * a) (int * b))\n        (out int)\n        (return (+ (cof a) (cof b)))))\n```\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstddef.h\u003e\n#include \u003cstdint.h\u003e\n#include \u003cstdlib.h\u003e\n#include \u003cstdbool.h\u003e\nint addition (int * a, int * b);\nint main () {\n  {\n    int answer;\n    int num1 = 10;\n    int num2 = 5;\n    int (*aFuncPtr) (int * , int * ) = addition;\n    answer  = addition ((\u0026num1), (\u0026num2));\n    printf (\"The addition of two numbers is: %d\\n\", answer);\n    answer  = aFuncPtr ((\u0026num1), (\u0026num2));\n    printf (\"The addition of two numbers by function pointer is: %d\\n\", answer);\n  }\n  return 0;\n}\nint addition (int * a, int * b) {\n  return ((*a) +  (*b));\n}\n```\n* Functions can return multiple values by inline structs.\n```lisp\n(source \"main.c\" (:std #t :compile #t :link #t)\n        (func aMultiReturnFunc ((int x) (int y)) (out '{(int a) (int b)})\n              (return '{ x y }))\n\n        (func aMultiReturnFuncS ((int x) (int y)) (out '{(int a) (int b)})\n              (let (((typeof (aMultiReturnFuncS x y)) s . '{ x y })) \n                (return s)))\n        \n        (func main ()\n              (let ((int n . 3)\n                    (int t . 4)\n                    ((typeof (aMultiReturnFunc 1 1)) mr)\n                    ((typeof (aMultiReturnFuncS 1 1)) mrt))\n                (set mr (aMultiReturnFunc n t))\n                (printf \"a: %d, b: %d\\n\" ($ mr a) ($ mr b))\n                (set mrt (aMultiReturnFuncS (++ n) (++ t)))\n                (printf \"a: %d, b: %d\\n\" ($ mrt a) ($ mrt b)))))\n```\n```c\ntypedef struct __lccStruct_aMultiReturnFunc_177 {\n  int a;\n  int b;\n} __lccStruct_aMultiReturnFunc_177;\n__lccStruct_aMultiReturnFunc_177 aMultiReturnFunc (int x, int y) {\n  return ((__lccStruct_aMultiReturnFunc_177){x , y});\n}\ntypedef struct __lccStruct_aMultiReturnFuncS_178 {\n  int a;\n  int b;\n} __lccStruct_aMultiReturnFuncS_178;\n__lccStruct_aMultiReturnFuncS_178 aMultiReturnFuncS (int x, int y) {\n  { \n    typeof(aMultiReturnFuncS (x , y)) s = {x , y};\n    return ((__lccStruct_aMultiReturnFuncS_178)s);\n  } \n}\nint main () {\n  { \n    int n = 3;\n    int t = 4;\n    typeof(aMultiReturnFunc (1, 1)) mr;\n    typeof(aMultiReturnFuncS (1, 1)) mrt;\n    mr = aMultiReturnFunc (n , t);\n    printf (\"a: %d, b: %d\\n\", (mr . a), (mr . b));\n    mrt = aMultiReturnFuncS ((++n ), (++t ));\n    printf (\"a: %d, b: %d\\n\", (mrt . a), (mrt . b));\n  } \n}\n```\n## Array\n### Define\n```lisp\n(var double amount [5])\n```\n### Initialize\n```lisp\n(var int digits [] . '{ 1 2 3 4 5 })\n(var char hw [][5] . '{ \"Hello\" \"World\" })\n```\n```c\nint digits[] = {1, 2, 3, 4, 5};\nchar hw[][5] = { \"Hello\" \"World\" };\n```\n```lisp\n(var int myArray [5])\n\n;; Initializing elements of array seperately\n(for ((int n . 0))\n  (\u003c n (/ (sizeof myArray) (sizeof int)))\n  ((1+ n))\n  (set (nth n myArray) n))\n```\n```c\nint myArray[5];\n\n// Initializing elements of array seperately\nfor(int n = 0; n \u003c sizeof(myArray) / sizeof(int); n++)\n{\n  myArray[n] = n;\n}\n```\n## String\n```lisp\n(var char name [6] . '{#\\C #\\l #\\o #\\u #\\d #\\Null})\n(var char name []  . \"Cloud\")\n(var char * name   . \"Cloud\")\n```\n```c\nchar name[6] = {'C', 'l', 'o', 'u', 'd', '\\0'};\nchar name[]  = \"Cloud\";\nchar * name  = \"Cloud\";\n```\n### Special Characters\n`#\\Null`\n`#\\Space`\n`#\\Newline`\n`#\\Tab`\n`#\\Page`\n`#\\Rubout`\n`#\\Linefeed`\n`#\\Return`\n`#\\Backspace`\n## Pointer\n```lisp\n(var int * width)\n(var int * letter)\n```\n```c\nint  *width;\nchar *letter;\n```\n```lisp\n(source \"main.c\" ()\n  (include \u003cstdio.h\u003e)\n  \n  (func main ((int argc) (char * argv []))\n    (let ((int n . 20)\n          (int * pntr))  ; actual and pointer variable declaration\n      (set pntr (aof n)) ; store address of n in pointer variable\n      (printf \"Address of n variable: %x\\n\" (aof n))\n      \n      ;; address stored in pointer variable\n      (printf \"Address stored in pntr variable: %x\\n\" pntr)\n\n      ;; access the value using the pointer\n      (printf \"Value of *pntr variable: %d\\n\" (cof pntr)))\n    (return 0))\n```\n```c\n#include\u003cstdio.h\u003e\n\nint main (int argc, char *argv[])\n{\n  {\n    int n = 20, *pntr;  /* actual and pointer variable declaration */\n    pntr = \u0026n;          /* store address of n in pointer variable  */\n    printf(\"Address of n variable: %x\\n\", \u0026n);\n\n    /* address stored in pointer variable */   \n    printf(\"Address stored in pntr variable: %x\\n\", pntr);\n\n    /* access the value using the pointer */   \n    printf(\"Value of *pntr variable: %d\\n\", *pntr);\n  }\n  return 0;\n}\n```\n## Dynamic Memory Allocation\nC dynamic memory allocation functions `malloc()`, `calloc()`, `realloc()`, `free()` are available. Other keyword `alloc` that works in `let` initialization part which automatically defers and freeing allocated memory when the variable gone out of let scope. Auto deferral could be replaced by {defer (aFuncPonter | lambda)} which takes a pointer to pointer variable.\n```lisp\n(let ((char * mem_alloc . #'(malloc (* 15 (sizeof char))))) ; memory allocated dynamically\n  (if (== mem_alloc nil) (printf \"Couldn't able to allocate requested memory\\n\"))\n  (free mem_alloc))\n```\n```c\n{    \n  char * mem_alloc = malloc(15 * sizeof(char)); /* memory allocated dynamically */\n  if (mem_alloc == NULL) {\n    printf(\"Couldn't able to allocate requested memory\\n\");\n  }\n  free(mem_alloc);\n}\n```\nAllocation with `alloc` and equivalent code in C:\n```lisp\n  (func main ()\n        (let ({defer '(lambda ((int * xPtr)) (printf \"x was %d\\n\" (cof xPtr)))}\n              (int x . 6)\n              (int * ax . #'(alloc 5 (sizeof int))))\n          (printf \"x is %d\\n\" x))))\n```\n```c\nvoid __lccLambda_main_178 (int * xPtr) {\n  printf(\"x was %d\\n\", (*xPtr));\n}\nvoid __lccLambda_main_179 (int ** ax) {\n  free((*ax));\n}\nint main () {\n  {\n    int x __attribute__((__cleanup__(__lccLambda_main_178))) = 6;\n    int * ax __attribute__((__cleanup__(__lccLambda_main_179))) = ((int *)calloc(5, sizeof(int)));\n    printf(\"x is %d\\n\", x);\n  }\n}\n```\n```lisp\n(let ((int n_rows . 4)\n      (int n_columns . 5)\n      (int ** matrix . #'(alloc (* (* n_rows n_columns) (sizeof int)))))\n  (printf \"Matrix allocated\\n\"))\n```\n```c\nvoid __lccLambda_main_178 (int *** matrix) {\n  free((*matrix));\n}\nint main () {\n  {\n    int n_rows = 4;\n    int n_columns = 5;\n    int ** matrix __attribute__((__cleanup__(__lccLambda_main_178))) = ((int **)malloc(((n_rows * n_columns) * sizeof(int))));\n    printf (\"Matrix allocated\\n\");\n  }\n}\n```\nAllocation by `alloc` and equivalent `calloc`:\n```lisp\n(let ((char * safe_alloc . #'(alloc 15 (sizeof char))))\n  (printf \"Memory allocated safely\\n\"))\n```\n```c\nvoid __lccLambda_main_178 (char ** safe_alloc) {\n  free((*safe_alloc));\n}\nint main () {\n  {\n    char * safe_alloc __attribute__((__cleanup__(__lccLambda_main_178))) = ((char *)calloc(15, sizeof(char)));\n    printf (\"Memory allocated safely\\n\");\n  }\n}\n```\n## Structure\n`declare` clause is for declaring one or more variable(s) at the end of nested struct declaration just for anonymous structures.\nUse `$` form for struct's member access and `-\u003e` form for member access of pointer of struct. Both `$` and `-\u003e` have other utility if a function defined in source targets and doesn't have `{resolve #f}` attribute. `$` operator resolves attribute access for both instance and pointer variables, also `-\u003e` operator won't work for pointer access instead it resolves to method access for structures. `inline` functions or methods in header files also don't have resolving process. Methods can be defined with `method` clause and naming convention `Struct-\u003eMethod`. All methods have `this` parametr automatically and will receive calling instance or pointer.\n```lisp\n(header \"course.h\" ()\n        (struct Course\n          (member char WebSite [50])\n          (member char Subject [50])\n          (member int  Price))\n\n        {decl} (method Course-\u003ePrint ()))\n\n(source \"course.c\" (:std #t :compile #t :link #t)\n        (include \"course.h\")\n        \n        (var Course c1 . '{\"domain.com\" \"Compilers\" 100})\n        (var Course * pc1 . #'(aof c1))\n        \n        (method Course-\u003ePrint ()\n                (printf \"Course: %s in %s for %d$\\n\" \n                  ($ this Subject) \n                  ($ this WebSite)\n                  ($ this Price)))\n        \n        (func main ()\n              (-\u003e c1 Print) \n              (-\u003e pc1 Print)))\n```\n```c\n// course.h\ntypedef struct Course {\n  char WebSite[50];\n  char Subject[50];\n  int Price;\n} Course;\nvoid Course_Print (Course * this);\n\n// course.c\nCourse c1 = {\"domain.com\", \"Compilers\", 100};\nCourse * pc1 = (\u0026c1);\nvoid Course_Print (Course * this) {\n  printf (\"Course: %s in %s for %d$\\n\", (this -\u003eSubject), (this -\u003eWebSite), (this -\u003ePrice));\n}\nint main () {\n  Course_Print(\u0026c1);\n  Course_Print(pc1);\n}\n```\n## Union\n`declare` form is for declaring one or more variable(s) at the end of nested union declaration just for anonymous unions.\nUse `$` form for union's member access and `-\u003e` form for member access of pointer of union. Union supports resolver like Struct.\n```lisp\n(struct USHAContext\n  (member int whichSha)                 ; which SHA is being used\n  (union\n    (member SHA1Context   sha1Context)\n    (member SHA224Context sha224Context) \n    (member SHA256Context sha256Context)\n    (member SHA384Context sha384Context) \n    (member SHA512Context sha512Context)\n    (declare ctx)))\n```\n```c\ntypedef struct USHAContext {\n  int whichSha;\n  union {\n    SHA1Context sha1Context;\n    SHA224Context sha224Context;\n    SHA256Context sha256Context;\n    SHA384Context sha384Context;\n    SHA512Context sha512Context;\n  } ctx;\n} USHAContext;\n```\n## Enum\n```lisp\n(enum\n  (shaSuccess . 0)\n  (shaNull)            ; Null pointer parameter\n  (shaInputTooLong)    ; input data too long\n  (shaStateError)      ; called Input after FinalBits or Result\n  (shaBadParam))       ; passed a bad parameter\n```\n```c\nenum {\n  shaSuccess = 0,\n  shaNull,\n  shaInputTooLong,\n  shaStateError,\n  shaBadParam\n};\n```\n## Guard\n```lisp\n(guard __STUDENT_H__\n  (struct Student\n    (member char name [50])\n    (member char family [50])\n    (member int  class_no)))\n```\n```c\n#ifndef __STUDENT_H__\n#define __STUDENT_H__\ntypedef struct Student {\n  char name [50];\n  char family [50];\n  int class_no;\n} Student;\n#endif /* __STUDENT_H__ */ \n```\n## Typedef\n```lisp\n(typedef int * intptr_t)\n```\n```c\ntypedef int * intptr_t;\n```\n## lcc.lisp Command Line Arguments\n`sbcl --script /path/to/lcc.lisp /path/to/some-lcc-file.lisp {args}`\nAvailable arguments:\n* --debug : will prints too many details about specifying, resolving and compiling.\n* --verbose : adds `-v` option to `clang` and `libtool` commands to print more details about compiling and linking. usefull when linking many complex libraries.\n\n`{$CWD}` placeholder is available inside `:compile` and `:link` command for every targets. \n## C++ Compiler\nC++ compiler could be used instead of C compiler then some features availables:\n* `\u0026` modifier in function argument for pass by reference.\n* Default value for members of structs.\n* `func` form for defining a member function inside of structs. Call these methods by `$` member access operator `(($ emp Sign) aDoc)`. \n\n# Good Luck!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaman-pasha%2Flcc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaman-pasha%2Flcc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaman-pasha%2Flcc/lists"}