{"_id":"@0xmacro/trim","name":"@0xmacro/trim","dist-tags":{"latest":"0.9.2"},"versions":{"0.9.2":{"name":"@0xmacro/trim","version":"0.9.2","description":"Trim is a opcode-oriented programming language for the Ethereum Virtual Machine (EVM). It offers syntax for writing highly optimized code in a more readable manner, without introducing mental or complexity overhead.","main":"dist/index.js","scripts":{"test":"ospec"},"type":"module","keywords":[],"author":"","repository":{"type":"github","url":"git+https://github.com/0xMacro/trim.git"},"license":"ISC","dependencies":{"@ethersproject/keccak256":"^5.4.0"},"devDependencies":{"@ethereumjs/vm":"^5.5.3","@ethersproject/abi":"^5.5.0","ethers":"^5.5.1","nodemon":"^2.0.13","ospec":"^4.1.1","typescript":"^4.4.3"},"types":"./dist/index.d.ts","gitHead":"5c97a4ee108bd7a660a08553c4d096abbe3416b4","bugs":{"url":"https://github.com/0xMacro/trim/issues"},"homepage":"https://github.com/0xMacro/trim#readme","_id":"@0xmacro/trim@0.9.2","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-d8bOObdmv6ihSOJ63LRFb39VTjoE4uC5R5AxRgf0ntJqn3eBLSCWh3YwyMb/DHjFkff+OaoArEKStOn+gNzcIw==","shasum":"a39e8b03dd5a7fb9a8ee272c35532f6d2e3638b6","tarball":"https://registry.npmjs.org/@0xmacro/trim/-/trim-0.9.2.tgz","fileCount":24,"unpackedSize":32237,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGDk7zlL+xEZ5XxYDN0hxhNObUTC50bAT5NbR28DDqz0AiAp0I1AqjqwkQNQCBHl2uTsXUp/V/rB+CcOt/nHIRjU0g=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJihUg+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq9hA/+IVMoqIGnd/zuTKCpn0qGiSlbE3afMjkdPFkOkUztS29eEKqP\r\nZwO9ASBvrmEQE20xehNtAUgBADb3zmhGsJkXEi3lF4zZxG43SBP9ZLXRMwUq\r\nUK74g5Vc1wxkpVwCztGJJFAY5uY8hUK1MRPUuGjc5dZRqyUpF++DltCbMZPo\r\n5afPUkaEZkou9MzB2dyTTg1YqIZWLh99/cEbDImPtX9myBZ6lZVLM9hNV8hU\r\ncsL/uZDs3qfqfCeyb0UDByoMbYWXg5ww75g0TtlQcOSqzFf7NBCFaNVqK71x\r\nmPj8buVV5DcInCKBfv2gTr5QrgIR2l9OnJeCSRHxPtImS5roeZXbDIdUuG1V\r\nGIReemgVrABkWv2bM1VyIDtgmhmRx4dzsk0wDPzFkYGLJh2PibiHgTs2/WGv\r\nLciMcMkzxfde2ezmuG5VPsBngnhSwmdWvpRVNHA/biIDyjJmwgK3B6IF6bg3\r\nqaqlWcv567S3SRmjirF5PKbq+9JLAMFpMCo9gfoDpLbnWZF0A2MUJE28IBhs\r\n1gyi01ePBF3gwwEjifJ9Cuvrt729y2QYIiun5jeXCKmb0ITyMUsTYXHUzz+n\r\n5JktVnmj6/idYQN6I016f67pfwAO+k9Eaqox3hlOCp4m+kMmQoHYJbx2CPfl\r\ngrUFpDZlkpfEIFl6XJwd301D6BGDHyTaBsE=\r\n=HIpe\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"soundly_typed","email":"gilbertbgarza@gmail.com"},"directories":{},"maintainers":[{"name":"soundly_typed","email":"gilbertbgarza@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/trim_0.9.2_1652901950688_0.6643772281871085"},"_hasShrinkwrap":false}},"time":{"created":"2022-05-18T19:25:50.590Z","0.9.2":"2022-05-18T19:25:50.839Z","modified":"2022-05-18T19:25:51.047Z"},"maintainers":[{"name":"soundly_typed","email":"gilbertbgarza@gmail.com"}],"description":"Trim is a opcode-oriented programming language for the Ethereum Virtual Machine (EVM). It offers syntax for writing highly optimized code in a more readable manner, without introducing mental or complexity overhead.","homepage":"https://github.com/0xMacro/trim#readme","keywords":[],"repository":{"type":"github","url":"git+https://github.com/0xMacro/trim.git"},"bugs":{"url":"https://github.com/0xMacro/trim/issues"},"license":"ISC","readme":"# Trim\n\nTrim is a opcode-oriented programming language for the Ethereum Virtual Machine (EVM). It offers syntax for writing highly optimized code in a more readable manner, without introducing mental or complexity overhead.\n\n- [Try it in your browser!](https://macro.cx/trim/repl)\n- [See the ETH Global Talk](https://www.youtube.com/watch?v=J15hxPRflUg)\n- [Read the slides](./trim-eth-global-2021.pdf)\n\n## Getting Started\n\nFirst install Trim (and ethereumjs/vm as you'll probably use its opcode definitions)\n\n```\nnpm install @0xmacro/trim @ethereumjs/vm\n```\n\nThen just import and compile:\n\n```js\nimport { compileTrim, getOpcodesForTrim } from '@0xmacro/trim'\nimport { getOpcodesForHF } from '@ethereumjs/vm/dist/evm/opcodes'\nimport Common, { Chain, Hardfork } from '@ethereumjs/common'\n\nconst common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Berlin })\nconst opcodes = getOpcodesForTrim(getOpcodesForHF(common))\n\nconst bytecode = compileTrim('(ADD 0x00 0x01)', { opcodes })\n\nconsole.log(\"Compile success! Resulting bytecode:\", bytecode)\n```\n\n## Sample\n\nHere's a template to get started writing a full smart contract with Trim:\n\n```\n(SUB CODESIZE #runtime)\nDUP1\n(CODECOPY 0x00 #runtime _)\n(RETURN 0x00 _)\n\n#runtime\n(CALLDATACOPY 0x1c 0x00 0x04)\n(MLOAD 0x00) ; copy function id onto the stack\n\n(EQ (abi/fn-selector \"hello()\") DUP1)\n(JUMPI #hello _)\n\nREVERT ; No matching function id\n\n#hello\n(MSTORE 0x00 \"Hello, world!\")\n(RETURN 0x00 0x20)\n```\n\n## Syntax\n\nFirst and foremost, Trim is a superset of bare assembly. You can always write opcodes in a plain manner. For example, this is valid Trim:\n\n```\nPUSH1 0x20\nPUSH2 0x1000\nADD\nMLOAD\n```\n\nWhat Trim introduces is **s-expressions**. An s-expression allows you to write in opcode-arguments notation:\n\n```\n(MLOAD (ADD 0x1000 0x20))\n```\n\nThis code is equivalent to the previous example.\n\nYou can also use the top operator (`_`) to refer to the top of the stack. The following examples are all equivalent:\n\n```\n; Example A\nPUSH1 0x20\n(ADD 0x1000 _)\n(MLOAD _)\n\n; Example B\n(ADD 0x1000 0x20)\n(MLOAD _)\n\n; Example C\n(ADD 0x1000 0x20)\nMLOAD\n```\n\nNote how you don't have to write *all* your code in s-expressions.\n\n## Features\n\nWhen you write a Trim s-expression, you gain access to a few features. Aside from defining a label, these features are only accessible within s-expressions.\n\n### Strings\n\nTrim allows you to write double-quoted string literals. For example:\n\n```\n; Old way\nPUSH12 0x48656c6c6f2c205472696d21\nEQ\n\n; New way\n(EQ \"Hello, Trim!\" _)\n```\n\n### Labels\n\nWhen deploying an EVM smart contract, you deploy both the **initialization code** and the **runtime code** as one long sequence of bytes. During this deployment transaction, the EVM will **run** this code, take its **return value**, and then **persist** this return value to the block chain. In other words, the value returned is the bytecode that will always run when future transactions are made to the new contract's address.\n\nUnfortunately, writing in plain opcodes for this task is a big hassle, as it involves manually counting bytes and hardcoding those numbers into your code. Worse, if you add or remove lines of code during development, you will have to recount and update these hardcoded numbers before testing it again.\n\nTrim solves this by introducing **labels**:\n\n```\n(SUB CODESIZE #runtime)\nDUP1\n(CODECOPY 0x00 #runtime _)\n(RETURN 0x00 _)\n\n#runtime\n(MSTORE 0x00 \"Hello, world!\")\n(RETURN 0x00 0x20)\n```\n\nIn the above code, line 6 is a **label definition**, which ends up being 15 bytes:\n\n- 3 bytes for each `#runtime` reference (each get compiled to a `PUSH2` statement)\n- 2 bytes for each `0x00` (each get compiled to a `PUSH1` statement)\n- 1 byte for each other opcode before the `#runtime` definition.\n\n### The #runtime label\n\nTrim treats a label named `#runtime` as a special case. If it's present, all labels defined **after** `#runtime` will automatically be offset by that amount. This is necessary to correct runtime label offsets, compensating for the removal of the init code.\n\n\n## Macros\n\nTrim has some built-in macros. In the future it will have user-defined macros too.\n\n### push\n\nNormally when you want to push literal value, you just simply write it, e.g. `(ADD 0x01 0x02)` or `(EQ \"abc\" _)`.\n\nBut what if you want to push a string onto the stack? Just use the `push` macro:\n\n```\n(\"Hi\")      ; Error, invalid token\n(push \"Hi\") ; Works!\n```\n\n### abi/fn-selector\n\nA convenience macro to output function selector (also known an \"function id\") segment of an [ABI encoded function call](https://docs.soliditylang.org/en/v0.5.3/abi-spec.html#function-selector). Useful for running function-specific code.\n\n```\n(EQ (abi/fn-selector \"foo()\") DUP1)\n(JUMPI #foo _)\n\n; ...\n\n#foo\n; More code here\n```\n\n## Roadmap\n\nThese are some features we're considering adding to Trim. Create an issue to discuss or suggest more!\n\n- [x] User-defined macros\n- [ ] Defining labels with macros\n- [ ] Hardhat integration\n- [ ] More standard ABI macros\n- [ ] Imports\n","readmeFilename":"README.md"}