tact
tact copied to clipboard
New Func backend: First iteration
Closes #526 Closes #619 (FunC grammar & parser by @novusnota)
Main roadmap
- ~~Write AST/formatter, and utilities to generate and emit Func code.~~
- Rewrite the existing codegen using the API created on the step 1. It should be rewritten entirely at this step, since everything is interconnected in the old backend, and there are no any unit tests checking any specific functionality of the generated code.
- Provide differential testing between two backends achieving good code coverage for the new backend. The previous backend is basically untested. It requires to write a number of Tact contracts and setup code coverage to ensure that all the implemented features of the new backend work in the same way as in the old one.
- Refactor the new backend and remove the old backend.
Sub-roadmap of @novusnota
The goal is to create a comprehensive FunC grammar and parsed using the Ohm parsing toolkit. Should cover FunC version 0.4.4:
- [x]
#pragma ...
- [x] Grammar (
grammar.ohm
) - [x] Semantic actions (
semantics.addOperation
) - [x] Unit tests (positive and negative)
- [x] Grammar (
- [x]
#include ...
- [x] Grammar
- [x] Semantic actions
- [x] Unit tests
- [x]
global ...
- [x] Grammar
- [x] Semantic actions
- [x] Unit tests
- [x]
const ...
- [x] Grammar
- [x] Semantic actions
- [x] Unit tests
- [x] Identifiers & Types (unexpectedly tough!)
- [x] Grammar
- [x] Semantic actions
- [x] Unit tests
- [x] Comments and literals
- [x] Grammar
- [x] Semantic actions
- [x] Unit tests
- [x] Functions (declarations & definitions, including asm ones):
- [x] Grammar
- [x] Semantic actions
- [x] Unit tests
- [x] Statements
- [x] Grammar
- [x] Semantic actions
- [x] Unit tests
- [x] Expressions (just like in C++'s parser, with all its precedences matched!)
- [x] Grammar
- [x] Semantic actions
- [x] Unit tests
- [x] Done?
- [x] (maybe) Add tests with .fc files from
ton-blockchain/ton
monorepo
Current progress
- [x] FunC syntax tree (AST + comments)
- [x] FunC syntax iterators
- [ ] FunC formatter (we can skip unit tests for now, as it will be tested as a part of the Tact compiler pipeline)
- [ ] ~~Support JSON dumps for debugging purposes~~
- [x] Support indentation
- [ ] Support parens
- [x] New FunC generators (based on
src/generators/writers/write*.ts
; similar code structure if possible)- [x]
Expression
- [x]
Statement
- [x]
Function
- [x]
Literal
- [x]
Contract
- [x] Interfaces
- [x] Primitives
- [x]
Constant
- [x]
- [x] Rewrite utilities from the current codegen (
WriteContext
)- [x] Type utilities (
src/generators/resolveFunc.*.ts
) - [x] ABI helpers
- [x] Routers
- [x] Receivers
- [x] Getters
- [x] Serializers
- [x] Accessors
- [x] Stdlib
- [x] Init serializers
- [x] Storage functions
- [x] Static functions
- [x] Extenstions
- [x] ~~"used" identifiers~~
- [x] Type utilities (
- [x] Write the dependency management used when emitting code from
WriteContext
. The existing structure based on.context
/.used
calls is too imperative and makes the source code unreadable. Thus, a better design should be developed. - [ ] Write a brief description of the structure of the generated Func code and the high-level overview of the architecture of the codegen (in e.g.
src/codegen/README.md
) - [x] Merge with
main
incorporating upstream changes to the new backend:- https://github.com/tact-lang/tact/pull/615
- [ ] Provide differential testing of two backends
- [ ] ~~Write new unit tests if needed~~ Write unit tests for the codegen, since we don't have any
- [x] Provide functions for differential testing of two backends
- [ ] Configure the fuzzer to support both backends
- [ ] Refactor the new backend
- [ ] Change names and code structure inherited from the original backend
- [ ] Extracts methods where possible; as for now it is unreadable
- [ ] Remove the previous backend
Notes
- Running the new backend:
yarn build && NEW_CODEGEN=1 PRINT_FUNC=1 ./bin/tact --config <project.config.json>
. It will print the generated source in stdout. UnsetNEW_CODEGEN
to run the same with the old backend. - Running the differential test:
yarn test src/codegen/codegen.spec.ts
- All the elements in the AST have the
FuncAst
prefix. When creating a separate packge, we could remove theFunc
part; and add it only to our project. This could be done creating a separate module that includesindex.ts
with public exports like:export { AstComment as FuncAstComment } from '@func-package-name';
- [ ] I have updated CHANGELOG.md
- [ ] I have documented my contribution in Tact Docs: https://github.com/tact-lang/tact-docs/pull/PR-NUMBER
- [ ] I have added tests to demonstrate the contribution is correctly implemented: this usually includes both positive and negative tests, showing the happy path(s) and featuring intentionally broken cases
- [ ] I have run all the tests locally and no test failure was reported
- [ ] I have run the linter, formatter and spellchecker
- [ ] I did not do unrelated and/or undiscussed refactorings