{"id":25794017,"url":"https://github.com/wizardpisces/js-ziju","last_synced_at":"2025-02-27T13:53:24.236Z","repository":{"id":37582417,"uuid":"323851868","full_name":"wizardpisces/js-ziju","owner":"wizardpisces","description":"Compile javascript to LLVM IR, x86 assembly and self interpreting","archived":false,"fork":false,"pushed_at":"2021-09-16T03:27:39.000Z","size":336,"stargazers_count":163,"open_issues_count":0,"forks_count":10,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-03-18T13:01:37.353Z","etag":null,"topics":["assembly","ast","compiler","interpreter","llvm","machine"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wizardpisces.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}},"created_at":"2020-12-23T08:55:38.000Z","updated_at":"2024-03-08T03:03:59.000Z","dependencies_parsed_at":"2022-08-08T21:00:31.755Z","dependency_job_id":null,"html_url":"https://github.com/wizardpisces/js-ziju","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wizardpisces%2Fjs-ziju","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wizardpisces%2Fjs-ziju/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wizardpisces%2Fjs-ziju/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wizardpisces%2Fjs-ziju/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wizardpisces","download_url":"https://codeload.github.com/wizardpisces/js-ziju/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241021140,"owners_count":19895575,"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":["assembly","ast","compiler","interpreter","llvm","machine"],"created_at":"2025-02-27T13:53:23.344Z","updated_at":"2025-02-27T13:53:24.221Z","avatar_url":"https://github.com/wizardpisces.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Project Description\nA compiler for javascript targeting LLVM IR, x86 assembly , self interpreting etc...\n\n## A learning project for you to understand below list\n* How a compiler work and how to build one\n* How does code run from source\n* How to compile code to Assembly or LLVM IR\n\n## Examples\n\n### Interpret\n\n```ts\nimport { \n    Interpreter \n} from './src'\n\n\nlet code = `\nconsole.log('=== MemberExpression evaluated =========');\nfunction fn(){\n    console.log('=== FunctionDeclaration evaluated =====')\n}\nfn()\n`\n\nnew Interpreter(code).interpret()\n\n/* output:\n* === MemberExpression evaluated =========\n* === FunctionDeclaration evaluated =====\n*/\n```\n### X86 MASM Assembly\n\n```js\nimport {Assembler} from './src'\n\nlet kernalCode = `\nfunction printChar($$c){\n    console.log(1,$$c,1)\n}\n\nfunction printHelper(n) {\n    if(n\u003e9){\n        printHelper(n / 10)\n    }\n    // 48 is the ASCII code for '0'\n    printChar(48 + n % 10);\n}\n\nfunction print(n){\n    printHelper(n)\n    printChar(10); // 换行\n}`\n\nlet code = `\nfunction main(){\n    print(231)\n    print(4)\n}`\n\nlet result = new Assembler(kernal+code).compile()\n\n```\nresult.assembly\n```assembly\n  .global _main\n\n  .text\n\nprintChar:\n  PUSH RBP\n  MOV RBP, RSP\n\n  PUSH 1\n  MOV RAX, RBP\n  ADD RAX, 16 # $$c\n  PUSH RAX\n  PUSH 1\n  POP RDX\n  POP RSI\n  POP RDI\n  MOV RAX, 33554436\n  SYSCALL\n  PUSH RAX\n\n  POP RAX\n  POP RBP\n\n  RET\n\nprintHelper:\n  PUSH RBP\n  MOV RBP, RSP\n\n  # If\n    # \u003e\n    PUSH [RBP + 16] # n\n    PUSH 9\n    POP RAX\n    CMP [RSP], RAX\n    MOV RAX, 0\n    MOV DWORD PTR [RSP], 1\n    CMOVA RAX, [RSP]\n    MOV [RSP], RAX\n    # End \u003e\n\n  POP RAX\n  TEST RAX, RAX\n  JZ .else_branch1\n\n  # If then\n    # DIV\n    PUSH [RBP + 16] # n\n    PUSH 10\n    POP RAX\n    XCHG [RSP], RAX\n    XOR RDX, RDX\n    DIV QWORD PTR [RSP]\n    MOV [RSP], RAX\n  CALL printHelper\n  MOV [RSP], RAX\n\n  JMP .after_else_branch1\n\n  # If else\n.else_branch1:\n  PUSH 0 # Null else branch\n.after_else_branch1:\n  # End if\n  POP RAX # Ignore non-final expression\n    # ADD\n    PUSH 48\n      # DIV\n      PUSH [RBP + 16] # n\n      PUSH 10\n      POP RAX\n      XCHG [RSP], RAX\n      XOR RDX, RDX\n      DIV QWORD PTR [RSP]\n      MOV [RSP], RDX\n    POP RAX\n    ADD [RSP], RAX\n    # End ADD\n  CALL printChar\n  MOV [RSP], RAX\n\n  POP RAX\n  POP RBP\n\n  RET\n\nprint:\n  PUSH RBP\n  MOV RBP, RSP\n\n  PUSH [RBP + 16] # n\n  CALL printHelper\n  MOV [RSP], RAX\n\n  POP RAX # Ignore non-final expression\n  PUSH 10\n  CALL printChar\n  MOV [RSP], RAX\n\n  POP RAX\n  POP RBP\n\n  RET\n\nmain:\n  PUSH RBP\n  MOV RBP, RSP\n\n  PUSH 231\n  CALL print\n  MOV [RSP], RAX\n\n  POP RAX # Ignore non-final expression\n  PUSH 4\n  CALL print\n  MOV [RSP], RAX\n\n  POP RAX\n  POP RBP\n\n  RET\n\n_main:\n  CALL main\n  MOV RDI, RAX\n  MOV RAX, 33554433\n  SYSCALL\n\n```\n\n### LLVM\n```js\nimport {Assembler} from './src'\n\nlet kernalCode = `\nfunction printChar($$c){\n    console.log(1,$$c,1)\n}\n\nfunction printHelper(n) {\n    if(n\u003e9){\n        printHelper(n / 10)\n    }\n    // 48 is the ASCII code for '0'\n    printChar(48 + n % 10);\n}\n\nfunction print(n){\n    printHelper(n)\n    printChar(10); // 换行\n}`\n\nlet code = `\nfunction main(){\n    print(311)\n    // print(4)\n}`\n\nlet result = new Assembler(kernal+code).llvmCompile()\n\n```\nresult.assembly\n```llvm\ndefine i64 @printChar(i64 %$$c) {\n  %sym5 = add i64 1, 0\n  %sym7 = add i64 %$$c, 0\n  %sym6 = alloca i64, align 4\n  store i64 %sym7, i64* %sym6, align 4\n  %sym8 = add i64 1, 0\n  %sym9 = add i64 33554436, 0\n  %sym4 = call i64 asm sideeffect \"syscall\", \"=r,{rax},{rdi},{rsi},{rdx},~{dirflag},~{fpsr},~{flags}\" (i64 %sym9, i64 %sym5, i64* %sym6, i64 %sym8)\n}\n\ndefine i64 @printHelper(i64 %n) {\n  %ifresult8 = alloca i64, align 4\n  %sym9 = add i64 %n, 0\n  %sym10 = add i64 9, 0\n  %sym7 = icmp sgt i64 %sym9, %sym10\n  br i1 %sym7, label %iftrue11, label %iffalse12\niftrue11:\n  %sym15 = add i64 %n, 0\n  %sym16 = add i64 10, 0\n  %sym14 = udiv i64 %sym15, %sym16\n  %sym13 = call i64 @printHelper(i64 %sym14)\n  store i64 %sym13, i64* %ifresult8, align 4\n  br label %ifend17\niffalse12:\n  br label %ifend17\nifend17:\n  %sym6 = load i64, i64* %ifresult8, align 4\n  %sym19 = add i64 48, 0\n  %sym21 = add i64 %n, 0\n  %sym22 = add i64 10, 0\n  %sym20 = urem i64 %sym21, %sym22\n  %sym18 = add i64 %sym19, %sym20\n  %sym6 = call i64 @printChar(i64 %sym18)\n}\n\ndefine i64 @print(i64 %n) {\n  %sym9 = add i64 %n, 0\n  %sym8 = call i64 @printHelper(i64 %sym9)\n  %sym10 = add i64 10, 0\n  %sym8 = call i64 @printChar(i64 %sym10)\n}\n\ndefine i64 @main() {\n  %sym10 = add i64 311, 0\n  %sym9 = call i64 @print(i64 %sym10)\n}\n```\n\n### How to test (support node\u003e=12)\n```\nnpm install\n```\n**Prepare \"gcc\" and \"llc\" enviroment or else only interpret.spec.ts could pass the test**\n```\nnpm run test\n```\n\n## Detail\n\nFurther info could reference test cases\n## Refenrece\n### Project\n  * [build a sass compiler from scratch](https://github.com/wizardpisces/tiny-sass-compiler)\n### LLVM\n* Manual\n  * [LLVM](https://llvm.org/docs/LangRef.html)\n### NASM\n* Tutorial\n  * [NASM](https://cs.lmu.edu/~ray/notes/nasmtutorial/)\n### MASM X86 Assembly\n* Manual\n  * [X86-assembly-instructions](https://www.aldeid.com/wiki/X86-assembly/Instructions/mov)\n* Tutorial\n  * [NASM](https://cs.lmu.edu/~ray/notes/nasmtutorial/)\n* Article\n  * [introduction-to-x64-assembly](https://software.intel.com/content/www/us/en/develop/articles/introduction-to-x64-assembly.html)\n### Common\n* Project\n  * [Estree](https://github.com/estree/estree/blob/master/es2015.md)\n* Tools\n  * [online llvm compiler](http://ellcc.org/demo/index.cgi)\n  * [compiler explorer](https://godbolt.org/)\n  * [ast explorer](https://astexplorer.net/#/gist/244e2fb4da940df52bf0f4b94277db44/e79aff44611020b22cfd9708f3a99ce09b7d67a8)\n* Article\n  * [compiler-basics-lisp-to-assembly](https://notes.eatonphil.com/compiler-basics-lisp-to-assembly.html)\n  * [vm-arch](https://www.codeproject.com/Articles/461052/Stack-Based-vs-Register-Based-Virtual-Machine-Arch)\n  * [making-system-calls-from-assembly-in-mac-os-x](https://filippo.io/making-system-calls-from-assembly-in-mac-os-x/)\n  * [ir-is-better-than-assembly](https://idea.popcount.org/2013-07-24-ir-is-better-than-assembly/)\n  * [编程达到一个高的境界就是自制脚本语言](https://cloud.tencent.com/developer/news/305527)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwizardpisces%2Fjs-ziju","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwizardpisces%2Fjs-ziju","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwizardpisces%2Fjs-ziju/lists"}