├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── gradle.xml └── misc.xml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── amrdeveloper │ │ └── turtle │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── java │ │ └── com │ │ │ └── amrdeveloper │ │ │ └── turtle │ │ │ ├── TurtleApplication.kt │ │ │ ├── data │ │ │ ├── AppTheme.kt │ │ │ ├── Constants.kt │ │ │ ├── Document.kt │ │ │ ├── DocumentCategory.kt │ │ │ ├── LiloDocuments.kt │ │ │ ├── LiloPackage.kt │ │ │ └── source │ │ │ │ ├── LiloPackageDataSource.kt │ │ │ │ ├── LiloPackageRepository.kt │ │ │ │ └── local │ │ │ │ ├── BaseDao.kt │ │ │ │ ├── LiloPackageDao.kt │ │ │ │ ├── LiloPackageLocalDataSource.kt │ │ │ │ ├── PreloadedLiloPackages.kt │ │ │ │ └── TurtleDatabase.kt │ │ │ ├── di │ │ │ └── AppModule.kt │ │ │ ├── externsions │ │ │ └── TreeNodes.kt │ │ │ ├── ui │ │ │ ├── MainActivity.kt │ │ │ ├── MainViewModel.kt │ │ │ ├── documents │ │ │ │ └── DocumentsFragment.kt │ │ │ ├── editor │ │ │ │ ├── AutoCompleteAdapter.kt │ │ │ │ ├── DiagnosticViewHolder.kt │ │ │ │ ├── EditorFragment.kt │ │ │ │ └── TurtleEditorConfig.kt │ │ │ ├── pack │ │ │ │ ├── PackageFragment.kt │ │ │ │ └── PackageViewModel.kt │ │ │ ├── packages │ │ │ │ ├── ItemSwipeCallback.kt │ │ │ │ ├── PackagesFragment.kt │ │ │ │ └── PackagesViewModel.kt │ │ │ ├── preview │ │ │ │ ├── PreviewFragment.kt │ │ │ │ ├── TurtleCanvasView.kt │ │ │ │ └── TurtlePointer.kt │ │ │ └── settings │ │ │ │ └── SettingsFragment.kt │ │ │ └── util │ │ │ └── UserPreferences.kt │ └── res │ │ ├── drawable │ │ ├── ic_arrow_down.xml │ │ ├── ic_arrow_right.xml │ │ ├── ic_check.xml │ │ ├── ic_close.xml │ │ ├── ic_code.xml │ │ ├── ic_dark_mode.xml │ │ ├── ic_delete.xml │ │ ├── ic_error.xml │ │ ├── ic_github_sponsor.xml │ │ ├── ic_keyword.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_list.xml │ │ ├── ic_play_arrow.xml │ │ ├── ic_preview.xml │ │ ├── ic_problems.xml │ │ ├── ic_replay.xml │ │ ├── ic_resume.xml │ │ ├── ic_save.xml │ │ ├── ic_search.xml │ │ ├── ic_settings.xml │ │ ├── ic_share.xml │ │ ├── ic_snippet.xml │ │ ├── ic_source_code.xml │ │ ├── ic_stop.xml │ │ ├── ic_team.xml │ │ ├── ic_text_snippet.xml │ │ ├── ic_turtle_pack.xml │ │ ├── ic_turtle_pointer.xml │ │ ├── ic_version.xml │ │ └── ic_warning.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── fragment_documents.xml │ │ ├── fragment_editor.xml │ │ ├── fragment_package.xml │ │ ├── fragment_packages.xml │ │ ├── fragment_preview.xml │ │ ├── fragment_settings.xml │ │ ├── list_item_autocomplete.xml │ │ ├── list_item_diagnostic.xml │ │ ├── list_item_document.xml │ │ ├── list_item_document_category.xml │ │ └── list_item_package.xml │ │ ├── menu │ │ ├── menu_bottom_navigation.xml │ │ ├── menu_editor.xml │ │ ├── menu_package.xml │ │ ├── menu_preview.xml │ │ └── menu_search.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ ├── ic_launcher_foreground.webp │ │ └── ic_launcher_round.webp │ │ ├── navigation │ │ └── navigation_graph.xml │ │ ├── raw │ │ └── turtle_flail.json │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_launcher_logo_background.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── amrdeveloper │ └── turtle │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lilo ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── amrdeveloper │ │ └── lilo │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── amrdeveloper │ │ └── lilo │ │ ├── ast │ │ ├── Expressions.kt │ │ ├── Script.kt │ │ ├── Statements.kt │ │ └── Visitors.kt │ │ ├── backend │ │ ├── ExecutionState.kt │ │ ├── Instruction.kt │ │ ├── LiloCallable.kt │ │ ├── LiloEvaluator.kt │ │ ├── LiloFunction.kt │ │ ├── LiloList.kt │ │ ├── LiloScope.kt │ │ └── TurtleObject.kt │ │ ├── fmt │ │ └── LiloFormatter.kt │ │ ├── frontend │ │ ├── LiloParser.kt │ │ ├── LiloTokenizer.kt │ │ ├── Token.kt │ │ ├── TokenPosition.kt │ │ └── TokenType.kt │ │ ├── std │ │ ├── CollectionsModule.kt │ │ ├── LiloModule.kt │ │ └── StandardModules.kt │ │ └── utils │ │ ├── ColorsTable.kt │ │ ├── Diagnostic.kt │ │ ├── LiloDiagnostics.kt │ │ └── LiloException.kt │ └── test │ └── java │ └── com │ └── amrdeveloper │ └── lilo │ └── ExampleUnitTest.kt ├── media ├── screenshots │ ├── screenshot_docs.png │ ├── screenshot_editor.png │ └── screenshot_preview.png └── turtle_graphics_logo.svg └── settings.gradle /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: amrdeveloper -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Smartphone (please complete the following information):** 27 | - Device: [e.g. iPhone6] 28 | - OS: [e.g. iOS8.1] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ========== 3 | 4 | Version 1.6.2 *(2024-07-17)* 5 | ----------------------------- 6 | 7 | * Update SDK to 34. 8 | * Update TreeView to 1.2.0 9 | * Update CodeView to 1.3.9. 10 | 11 | Version 1.6.1 *(2023-09-27)* 12 | ----------------------------- 13 | 14 | * Remove Github Sponsor action 15 | 16 | Version 1.6.0 *(2023-08-21)* 17 | ----------------------------- 18 | 19 | * Add support for `penUp` and `penDown` functions #3 20 | 21 | Version 1.5.3 *(2023-08-18)* 22 | ----------------------------- 23 | 24 | * Add support for comments #2 25 | * Add the new logo 26 | 27 | Version 1.5.1 *(2023-02-27)* 28 | ----------------------------- 29 | 30 | * Fix editor height with keyboard 31 | 32 | Version 1.4.3 *(2022-10-25)* 33 | ----------------------------- 34 | 35 | * Fix Code formatter issues, and improve format for binary expressions 36 | 37 | Version 1.4.2 *(2022-10-21)* 38 | ----------------------------- 39 | 40 | * Introduce Code formatter for Lilo Programming language 41 | * Make diagnostic instance reusable 42 | 43 | Version 1.4.1 *(2022-10-11)* 44 | ----------------------------- 45 | 46 | * Add support for execution seek bar 47 | * Add support for pause and consume menu icons 48 | * hide consume menu icon when execution is finished 49 | * Improve parse logical, factor and term expression 50 | * Add Vibrate circle to the preload examples 51 | 52 | 53 | Version 1.3.2 *(2022-09-23)* 54 | ----------------------------- 55 | 56 | * Add preloaded lilo packages for new users 57 | * Add support for delete on swapping 58 | 59 | Version 1.3.1 *(2022-09-21)* 60 | ----------------------------- 61 | 62 | * Fix Number of parameter when parsing function declaration 63 | * Fix Control flow execution Scope 64 | * Fix Recursion functions 65 | * Add support for `show` keyword 66 | * Add support for `hide` keyword 67 | 68 | Version 1.3.0 *(2022-09-15)* 69 | ----------------------------- 70 | 71 | * Change turtle pointer design to be a small turtle on the screen 72 | * Add support for stop and re execute actions 73 | * Add support for `speed` keyword 74 | * Add support for `sleep` keyword 75 | 76 | Version 1.2.1 *(v-08-30)* 77 | ----------------------------- 78 | 79 | * Fix crash when user type wrong script many times 80 | * Add support for `background` instruction 81 | 82 | Version 1.2.0 *(2022-07-11)* 83 | ----------------------------- 84 | 85 | * Add support for built in functions 86 | * Consume that call expression must end with `TOKEN_CLOSE_PAREN` 87 | 88 | Version 1.1.0 *(2022-07-09)* 89 | ----------------------------- 90 | 91 | * Increase the auto complete item width. 92 | * Add support for array, with index operator. 93 | * Add support for else if and else branches. 94 | * Add support for special assignments *=, -=, *=, /=, %=. 95 | * Add support for reminder operator % 96 | 97 | Version 1.0.0 *(2022-07-02)* 98 | ----------------------------- 99 | 100 | * Init release -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | 3 | ### Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ### Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ### Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ### Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ### Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at amr96@programmer.net. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ### Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Please provide issue report in the format that we request, EACH DETAIL IS A HUGE HELP. 4 | 5 | Issues that are not following the guidelines, 6 | will be processed as last priority or never or simply closed as invalid. 7 | 8 | ## Contributing Guide 9 | 10 | Please note that PRs are looked only for approved issues. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Amr Hesham 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Turtle Graphics


2 | 3 |

4 | 5 |

6 | 7 |

8 | Turtle is an Android Application inspired from the original Turtle Graphics and Logo, Logo is an educational programming language designed in 1967 by Computer scientists Wally Feurzeig, Seymour Papert, and Cynthia Solomon and it known for its use of turtle graphics, 9 | this project has a simple tree walking interpreted language called Lilo (Inspired from Logo too :D), with declarations statements, control flow, collections, and instructions for control the turtle in 2D Space which is our case a custom Android Canvas View and also control colors 10 |

11 | 12 | # Download 13 | 14 | Get it on Google Play 15 | Amazon App Store 16 | Samsung Galaxy Store 17 | Huawei AppGallery 18 | 19 | 20 | ## Screenshots 21 | 22 |

23 | 24 | 25 | 26 |

27 | 28 | ## Features 29 | - Free And open source with no ads. 30 | - Full Text Editor that support auto complete, snippets, highlighter for Lilo. 31 | - Clear diagnostics messages with line number and column position. 32 | - Supports Lexer, Parser errors and Runtime exceptions 33 | - Preview custom view with turtle that show the current direction. 34 | - Full documentation view that teach you how to write your script. 35 | - Save and Update your current script into packages with name. 36 | 37 | ## Declarations 38 | 39 | - Let Declaration to declare variables 40 | 41 | ``` 42 | let c = BLACK 43 | ``` 44 | 45 | - Function Declaration to declare function with 0 or more parameters 46 | 47 | ``` 48 | fun f1 (n) { 49 | return n * 2 50 | } 51 | 52 | fun f2 {} 53 | 54 | fun f3 (n) = n * 2 55 | 56 | fun f4 = 1000 57 | ``` 58 | 59 | ## Control flow 60 | 61 | - If statement to execute block if the condition is true 62 | 63 | ``` 64 | if condition {} 65 | elif condition2 {} 66 | elif condition3 {} 67 | else {} 68 | ``` 69 | 70 | - Repeat statement to execute block n times 71 | 72 | ``` 73 | repeat n { 74 | 75 | } 76 | ``` 77 | 78 | - While statement to execute block while the condition is true 79 | 80 | ``` 81 | while condition { 82 | 83 | } 84 | ``` 85 | - Speed statement, take time in ms to wait before each next instruction 86 | 87 | ``` 88 | speed 100 89 | ``` 90 | 91 | - Sleep statement, take time in ms to wait before the next instruction 92 | 93 | ``` 94 | sleep 100 95 | ``` 96 | 97 | - Show statement, to show turtle pointer 98 | 99 | ``` 100 | show 101 | ``` 102 | 103 | - Hide statement, to hide turtle pointer 104 | 105 | ``` 106 | hide 107 | ``` 108 | 109 | - Stop statement, to stop the current execution 110 | 111 | ``` 112 | stop 113 | ``` 114 | 115 | ## Collections 116 | 117 | - List to collect values 118 | 119 | ``` 120 | let colors = [RED, BLUE, WHITE] 121 | ``` 122 | 123 | - Access list element by index 124 | 125 | ``` 126 | color colors[0] 127 | ``` 128 | 129 | - Update list element 130 | 131 | ``` 132 | colors[0] = YELLOW 133 | ``` 134 | 135 | ## Movement instructions 136 | 137 | - Rotate used to add value to the current turtle pointer degree 138 | 139 | ``` 140 | rotate 90 141 | ``` 142 | 143 | - Forward used to move forward n space 144 | 145 | ``` 146 | forward 90 147 | ``` 148 | 149 | - Backward used to rotate and move backward n space 150 | 151 | ``` 152 | backward 90 153 | ``` 154 | 155 | - Right used to rotate and move right n space 156 | 157 | ``` 158 | right 90 159 | ``` 160 | 161 | - Left used to rotate and move Left n space 162 | 163 | ``` 164 | left 90 165 | ``` 166 | 167 | ## Drawing Instructions 168 | 169 | - Circle used to draw circle around the current position with radius r 170 | 171 | ``` 172 | circle 50 173 | ``` 174 | 175 | - Cube used to draw Cube around the current position with value v 176 | 177 | ``` 178 | cube 50 179 | ``` 180 | 181 | ## Coloring instructions 182 | 183 | - Color Instruction to change the current color 184 | 185 | ``` 186 | color BLUE 187 | ``` 188 | 189 | ### License 190 | ``` 191 | MIT License 192 | 193 | Copyright (c) 2022 Amr Hesham 194 | 195 | Permission is hereby granted, free of charge, to any person obtaining a copy 196 | of this software and associated documentation files (the "Software"), to deal 197 | in the Software without restriction, including without limitation the rights 198 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 199 | copies of the Software, and to permit persons to whom the Software is 200 | furnished to do so, subject to the following conditions: 201 | 202 | The above copyright notice and this permission notice shall be included in all 203 | copies or substantial portions of the Software. 204 | 205 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 206 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 207 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 208 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 209 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 210 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 211 | SOFTWARE. 212 | ``` -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'org.jetbrains.kotlin.android' 4 | id 'androidx.navigation.safeargs.kotlin' 5 | id "dagger.hilt.android.plugin" 6 | id 'kotlin-parcelize' 7 | id 'kotlin-kapt' 8 | } 9 | 10 | android { 11 | compileSdk 34 12 | namespace "com.amrdeveloper.turtle" 13 | 14 | defaultConfig { 15 | applicationId "com.amrdeveloper.turtle" 16 | minSdk 21 17 | targetSdk 34 18 | versionCode 18 19 | versionName "1.6.2" 20 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 21 | setProperty("archivesBaseName", "turtle" + "_v" + versionCode + "(" + versionName + ")") 22 | } 23 | 24 | buildTypes { 25 | release { 26 | minifyEnabled false 27 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 28 | } 29 | } 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | 36 | kotlinOptions { 37 | jvmTarget = '1.8' 38 | } 39 | 40 | buildFeatures { 41 | viewBinding true 42 | } 43 | } 44 | 45 | dependencies { 46 | implementation 'androidx.core:core-ktx:1.8.0' 47 | implementation 'androidx.appcompat:appcompat:1.4.2' 48 | implementation 'com.google.android.material:material:1.6.1' 49 | 50 | // UI Components 51 | implementation 'io.github.amrdeveloper:codeview:1.3.9' 52 | implementation 'io.github.amrdeveloper:treeview:1.2.0' 53 | implementation 'io.github.amrdeveloper:lottiedialog:1.0.0' 54 | 55 | // Adapters Generator 56 | implementation "io.github.amrdeveloper:easyadapter:1.1.1" 57 | kapt "io.github.amrdeveloper:easyadapter-compiler:1.1.1" 58 | 59 | // Navigation Component 60 | implementation "androidx.navigation:navigation-fragment-ktx:2.7.7" 61 | 62 | // LiveData, ViewModel, Fragment Extension 63 | implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1" 64 | implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.1" 65 | implementation "androidx.fragment:fragment-ktx:1.4.1" 66 | 67 | // Room Database 68 | implementation "androidx.room:room-runtime:2.6.1" 69 | implementation "androidx.room:room-ktx:2.6.1" 70 | kapt "androidx.room:room-compiler:2.6.1" 71 | 72 | // DI Framework 73 | implementation "com.google.dagger:hilt-android:2.48" 74 | kapt "com.google.dagger:hilt-android-compiler:2.48" 75 | 76 | // Kotlin Coroutines 77 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1" 78 | 79 | // Lilo Programming Language module 80 | implementation project(path: ':lilo') 81 | 82 | implementation 'androidx.legacy:legacy-support-v4:1.0.0' 83 | 84 | implementation 'com.jakewharton.timber:timber:5.0.1' 85 | debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1' 86 | 87 | testImplementation 'junit:junit:4.13.2' 88 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 89 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 90 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/amrdeveloper/turtle/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.amrdeveloper.turtle 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.amrdeveloper.turtle", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/TurtleApplication.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle 25 | 26 | import android.app.Application 27 | import dagger.hilt.android.HiltAndroidApp 28 | 29 | @HiltAndroidApp 30 | class TurtleApplication : Application() { 31 | 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/AppTheme.kt: -------------------------------------------------------------------------------- 1 | package com.amrdeveloper.turtle.data 2 | 3 | enum class AppTheme { 4 | DARK, 5 | WHITE 6 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/Constants.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data 25 | 26 | const val PACKAGE_NAME = "com.amrdeveloper.turtle" 27 | const val GITHUB_SOURCE = "https://github.com/AmrDeveloper/turtle" 28 | const val GITHUB_CONTRIBUTORS = "$GITHUB_SOURCE/graphs/contributors" 29 | const val GITHUB_ISSUES = "$GITHUB_SOURCE/issues" 30 | const val GOOGLE_PLAY_URL = "https://play.google.com/store/apps/details?id=$PACKAGE_NAME" 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/Document.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data 25 | 26 | import com.amrdeveloper.easyadapter.bind.BindExpandable 27 | import com.amrdeveloper.easyadapter.bind.BindText 28 | 29 | @BindExpandable("list_item_document") 30 | data class Document( 31 | @BindText("document_title_txt") 32 | val title: String, 33 | 34 | @BindText("document_description_txt") 35 | val description: String 36 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/DocumentCategory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data 25 | 26 | import com.amrdeveloper.easyadapter.bind.BindExpandable 27 | import com.amrdeveloper.easyadapter.bind.BindText 28 | 29 | @BindExpandable("list_item_document_category") 30 | data class DocumentCategory( 31 | 32 | @BindText("document_category_txt") 33 | val title: String 34 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/LiloDocuments.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data 25 | 26 | import com.amrdeveloper.easyadapter.adapter.ExpandableAdapter 27 | import com.amrdeveloper.easyadapter.bind.BindExpandableMap 28 | 29 | @ExpandableAdapter("com.amrdeveloper.turtle") 30 | data class LiloDocuments( 31 | @BindExpandableMap 32 | val documents: Map> = liloFullDocuments 33 | ) 34 | 35 | private val liloFullDocuments = mapOf( 36 | DocumentCategory("Declarations") to listOf( 37 | Document("Let Declaration", "Used to declare value with name, let name = value"), 38 | Document("Function Declaration", "Functions used to declare block of code to call it with name and parameters, fun name(params) { }") 39 | ), 40 | DocumentCategory("Control flow") to listOf( 41 | Document("If Statement", "Take condition and body to execute if condition is true, if (condition) {}"), 42 | Document("Else if Statement", "Execute the body if the condition is true and if not executed, elif (condition) {}"), 43 | Document("Else Statement", "Execute the body if all if and elif branches not executed, else {}"), 44 | Document("while Statement", "Take condition and body to execute while condition is true, while (condition) {}"), 45 | Document("Repeat Statement", "Take number n and body to execute it n times, repeat (n) {}"), 46 | ), 47 | DocumentCategory("Instructions") to listOf( 48 | Document("Cube", "Used to draw cube in current position and take size, cube n"), 49 | Document("Circle", "Used to draw Circle in current position and take radius, circle r"), 50 | Document("Move", "Used set the current x and y position, move x, y"), 51 | Document("Move X", "Used set the current x position, movex x"), 52 | Document("Move Y", "Used set the current y position, movey y"), 53 | Document("Color", "Used set the current color, color RED"), 54 | Document("background", "Used set the current background, background RED"), 55 | Document("Speed", "Used set the speed of the execution and take time in ms, sleep 100"), 56 | Document("Sleep", "Used set the sleep at current instruction and take time in ms, sleep 100"), 57 | Document("Show", "Used to show the turtle pointer, show"), 58 | Document("Hide", "Used set hide the turtle pointer, hide"), 59 | Document("Stop", "Used set the stop the execution, stop"), 60 | Document("Rotate", "Used set the update the current degree, rotate n"), 61 | Document("Forward", "Used set move forward with n space, forward n"), 62 | Document("Backward", "Used set move backward with n space, backward n"), 63 | Document("Right", "Used set move right with n space, right n"), 64 | Document("Left", "Used set move left with n space, left n"), 65 | ), 66 | DocumentCategory("Collections") to listOf( 67 | Document("Array", "You can easily create array inside [v1, v2, v3]"), 68 | Document("Get Element from Array", "You can use index operator to get element with index array[i]"), 69 | Document("Set Element from Array", "You can use index operator to set element with index array[i] = v") 70 | ), 71 | DocumentCategory("Constants") to listOf( 72 | Document("Numbers", "Numbers can be integers or real"), 73 | Document("Booleans", "Booleans values can be true or false") 74 | ), 75 | DocumentCategory("Builtin functions") to listOf( 76 | Document("len", "Receive collection for example list and return the size of it, len([1, 2, 3])"), 77 | ) 78 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/LiloPackage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data 25 | 26 | import android.os.Parcelable 27 | import androidx.annotation.Keep 28 | import androidx.room.Entity 29 | import androidx.room.Index 30 | import androidx.room.PrimaryKey 31 | import com.amrdeveloper.easyadapter.adapter.ListAdapter 32 | import com.amrdeveloper.easyadapter.bind.BindListener 33 | import com.amrdeveloper.easyadapter.bind.BindText 34 | import com.amrdeveloper.easyadapter.option.ListenerType 35 | import kotlinx.parcelize.Parcelize 36 | 37 | @Keep 38 | @Parcelize 39 | @BindListener(ListenerType.OnClick) 40 | @BindListener(ListenerType.OnLongClick) 41 | @ListAdapter("com.amrdeveloper.turtle", "list_item_package", "name") 42 | @Entity(tableName = "lilo_package", indices = [Index(value = ["name"], unique = true)]) 43 | data class LiloPackage ( 44 | @BindText("document_title_txt") var name: String, 45 | var sourceCode: String, 46 | var creationTimeStamp: Long = System.currentTimeMillis(), 47 | var updateTimeStamp: Long = -1, 48 | var isUpdated: Boolean = false, 49 | @PrimaryKey(autoGenerate = true) val id: Int = 0, 50 | ) : Parcelable -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/source/LiloPackageDataSource.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data.source 25 | 26 | import com.amrdeveloper.turtle.data.LiloPackage 27 | 28 | interface LiloPackageDataSource { 29 | 30 | suspend fun loadLiloPackages() : Result> 31 | 32 | suspend fun loadLiloPackagesByKeyword(keyword : String) : Result> 33 | 34 | suspend fun insertLiloPackage(liloPackage: LiloPackage): Result 35 | 36 | suspend fun updateLiloPackage(liloPackage: LiloPackage): Result 37 | 38 | suspend fun deleteLiloPackage(liloPackage: LiloPackage): Result 39 | 40 | suspend fun deleteAllLiloPackage(): Result 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/source/LiloPackageRepository.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data.source 25 | 26 | import com.amrdeveloper.turtle.data.LiloPackage 27 | 28 | class LiloPackageRepository(private val liloPackageDataSource: LiloPackageDataSource) { 29 | 30 | suspend fun loadLiloPackages() : Result> { 31 | return liloPackageDataSource.loadLiloPackages() 32 | } 33 | 34 | suspend fun loadLiloPackagesByKeyword(keyword : String) : Result> { 35 | return liloPackageDataSource.loadLiloPackagesByKeyword(keyword) 36 | } 37 | 38 | suspend fun insertLiloPackage(liloPackage: LiloPackage): Result { 39 | return liloPackageDataSource.insertLiloPackage(liloPackage) 40 | } 41 | 42 | suspend fun updateLiloPackage(liloPackage: LiloPackage): Result { 43 | return liloPackageDataSource.updateLiloPackage(liloPackage) 44 | } 45 | 46 | suspend fun deleteLiloPackage(liloPackage: LiloPackage): Result { 47 | return liloPackageDataSource.deleteLiloPackage(liloPackage) 48 | } 49 | 50 | suspend fun deleteAllLiloPackage(): Result { 51 | return liloPackageDataSource.deleteAllLiloPackage() 52 | } 53 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/source/local/BaseDao.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data.source.local 25 | 26 | import androidx.room.Delete 27 | import androidx.room.Insert 28 | import androidx.room.OnConflictStrategy 29 | import androidx.room.Update 30 | 31 | interface BaseDao { 32 | 33 | @Insert(onConflict = OnConflictStrategy.IGNORE) 34 | suspend fun insert(item: T): Long 35 | 36 | @Insert(onConflict = OnConflictStrategy.IGNORE) 37 | suspend fun insert(item: List) : Array 38 | 39 | @Update 40 | suspend fun update(item: T): Int 41 | 42 | @Delete 43 | suspend fun delete(item: T): Int 44 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/source/local/LiloPackageDao.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data.source.local 25 | 26 | import androidx.room.Dao 27 | import androidx.room.Query 28 | import com.amrdeveloper.turtle.data.LiloPackage 29 | 30 | @Dao 31 | interface LiloPackageDao : BaseDao { 32 | 33 | @Query("SELECT * from lilo_package") 34 | suspend fun loadLiloPackages(): List 35 | 36 | @Query("SELECT * from lilo_package WHERE name LIKE '%' || :keyword || '%'") 37 | suspend fun loadLiloPackagesByKeyword(keyword : String): List 38 | 39 | @Query("DELETE FROM lilo_package") 40 | suspend fun deleteAll(): Int 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/source/local/LiloPackageLocalDataSource.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data.source.local 25 | 26 | import com.amrdeveloper.turtle.data.LiloPackage 27 | import com.amrdeveloper.turtle.data.source.LiloPackageDataSource 28 | import kotlinx.coroutines.CoroutineDispatcher 29 | import kotlinx.coroutines.Dispatchers 30 | import kotlinx.coroutines.withContext 31 | 32 | class LiloPackageLocalDataSource( 33 | private val liloPackageDao: LiloPackageDao, 34 | private val dispatcher: CoroutineDispatcher = Dispatchers.IO 35 | ) : LiloPackageDataSource { 36 | 37 | override suspend fun loadLiloPackages(): Result> = 38 | withContext(dispatcher) { 39 | return@withContext try { 40 | Result.success(liloPackageDao.loadLiloPackages()) 41 | } catch (e: Exception) { 42 | Result.failure(e) 43 | } 44 | } 45 | 46 | override suspend fun loadLiloPackagesByKeyword(keyword: String): Result> = 47 | withContext(dispatcher) { 48 | return@withContext try { 49 | Result.success(liloPackageDao.loadLiloPackagesByKeyword(keyword)) 50 | } catch (e: Exception) { 51 | Result.failure(e) 52 | } 53 | } 54 | 55 | override suspend fun insertLiloPackage(liloPackage: LiloPackage): Result = 56 | withContext(dispatcher) { 57 | return@withContext try { 58 | Result.success(liloPackageDao.insert(liloPackage)) 59 | } catch (e: Exception) { 60 | Result.failure(e) 61 | } 62 | } 63 | 64 | override suspend fun updateLiloPackage(liloPackage: LiloPackage): Result = 65 | withContext(dispatcher) { 66 | return@withContext try { 67 | Result.success(liloPackageDao.update(liloPackage)) 68 | } catch (e: Exception) { 69 | Result.failure(e) 70 | } 71 | } 72 | 73 | override suspend fun deleteLiloPackage(liloPackage: LiloPackage): Result = 74 | withContext(dispatcher) { 75 | return@withContext try { 76 | Result.success(liloPackageDao.delete(liloPackage)) 77 | } catch (e: Exception) { 78 | Result.failure(e) 79 | } 80 | } 81 | 82 | override suspend fun deleteAllLiloPackage(): Result = 83 | withContext(dispatcher) { 84 | return@withContext try { 85 | Result.success(liloPackageDao.deleteAll()) 86 | } catch (e: Exception) { 87 | Result.failure(e) 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/source/local/PreloadedLiloPackages.kt: -------------------------------------------------------------------------------- 1 | package com.amrdeveloper.turtle.data.source.local 2 | 3 | import com.amrdeveloper.turtle.data.LiloPackage 4 | 5 | /** 6 | * A list of preloaded lilo packages that inserted into the database once it created 7 | */ 8 | val preloadedLiloPackages = listOf ( 9 | 10 | /** 11 | * A lilo package to draw a Fractal Tree with green color 12 | */ 13 | LiloPackage("Fractal Tree", """ 14 | move 375, 400 15 | let angle = 30 16 | color GREEN 17 | rotate 90 18 | fun draw(size, level) { 19 | if level > 0 { 20 | forward size 21 | rotate angle 22 | draw(0.8 * size, level - 1) 23 | rotate -2 * angle 24 | draw(0.8 * size, level - 1) 25 | rotate angle 26 | forward -size 27 | } 28 | } 29 | draw(80, 7) 30 | """.trimIndent()), 31 | 32 | /** 33 | * A Lilo Package to draw nested stars 34 | */ 35 | LiloPackage("Nested Stars", """ 36 | move 150, 500 37 | color GREEN 38 | 39 | fun drawStar(size) { 40 | if size > 10 { 41 | repeat 5 { 42 | forward size 43 | drawStar(size / 3) 44 | rotate 216 45 | } 46 | } 47 | } 48 | 49 | drawStar(360) 50 | """.trimIndent()), 51 | 52 | /** 53 | * A Lilo Package to draw a red sun 54 | */ 55 | LiloPackage("Red Sun", """ 56 | move 100, 500 57 | color RED 58 | repeat 50 { 59 | forward 500 60 | rotate 170 61 | } 62 | """.trimIndent()), 63 | 64 | /** 65 | * A Lilo package to draw vibrate circle 66 | */ 67 | LiloPackage("Vibrate Circle", """ 68 | move 350, 650 69 | let a = 0 70 | let b = 0 71 | color GREEN 72 | repeat 210 { 73 | forward a 74 | rotate b 75 | a += 3 76 | b += 1 77 | } 78 | """.trimIndent()) 79 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/data/source/local/TurtleDatabase.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.data.source.local 25 | 26 | import android.content.Context 27 | import androidx.room.Database 28 | import androidx.room.Room 29 | import androidx.room.RoomDatabase 30 | import com.amrdeveloper.turtle.data.LiloPackage 31 | import kotlinx.coroutines.Dispatchers 32 | import kotlinx.coroutines.GlobalScope 33 | import kotlinx.coroutines.launch 34 | 35 | private const val DATABASE_NAME = "turtle_database" 36 | private const val DATABASE_VERSION = 1 37 | 38 | @Database(entities = [LiloPackage::class], version = DATABASE_VERSION) 39 | abstract class TurtleDatabase : RoomDatabase() { 40 | 41 | abstract fun liloPackageDao(): LiloPackageDao 42 | 43 | companion object { 44 | 45 | @Volatile 46 | private var INSTANCE: TurtleDatabase? = null 47 | 48 | fun getDatabase(context: Context): TurtleDatabase { 49 | return INSTANCE ?: synchronized(this) { 50 | val instance = Room.databaseBuilder( 51 | context.applicationContext, 52 | TurtleDatabase::class.java, DATABASE_NAME 53 | ).build() 54 | INSTANCE = instance 55 | instance.populateInitialData() 56 | instance 57 | } 58 | } 59 | } 60 | 61 | /** 62 | * Helper function to init default data into db once created 63 | */ 64 | private fun populateInitialData() { 65 | GlobalScope.launch(Dispatchers.Main) { 66 | liloPackageDao().insert(preloadedLiloPackages) 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/di/AppModule.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.di 25 | 26 | import android.content.Context 27 | import com.amrdeveloper.turtle.data.source.LiloPackageDataSource 28 | import com.amrdeveloper.turtle.data.source.LiloPackageRepository 29 | import com.amrdeveloper.turtle.data.source.local.LiloPackageLocalDataSource 30 | import com.amrdeveloper.turtle.data.source.local.TurtleDatabase 31 | import dagger.Module 32 | import dagger.Provides 33 | import dagger.hilt.InstallIn 34 | import dagger.hilt.android.qualifiers.ApplicationContext 35 | import dagger.hilt.components.SingletonComponent 36 | import kotlinx.coroutines.CoroutineDispatcher 37 | import kotlinx.coroutines.Dispatchers 38 | import javax.inject.Singleton 39 | 40 | @Module 41 | @InstallIn(SingletonComponent::class) 42 | class AppModule { 43 | 44 | @Singleton 45 | @Provides 46 | fun provideDatabase(@ApplicationContext context: Context): TurtleDatabase { 47 | return TurtleDatabase.getDatabase(context) 48 | } 49 | 50 | @Singleton 51 | @Provides 52 | fun provideLiloPackageDataSource( 53 | database: TurtleDatabase, 54 | ioDispatcher: CoroutineDispatcher 55 | ): LiloPackageDataSource { 56 | return LiloPackageLocalDataSource(database.liloPackageDao(), ioDispatcher) 57 | } 58 | 59 | @Singleton 60 | @Provides 61 | fun provideLiloPackageRepository(dataSource: LiloPackageDataSource): LiloPackageRepository { 62 | return LiloPackageRepository(dataSource) 63 | } 64 | 65 | @Singleton 66 | @Provides 67 | fun provideIoDispatcher() = Dispatchers.IO 68 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/externsions/TreeNodes.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.externsions 25 | 26 | import com.amrdeveloper.treeview.TreeNode 27 | 28 | fun List.toTreeNodes(layout: Int): List { 29 | return this.map { TreeNode(it, layout) } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/MainActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui 25 | 26 | import android.os.Bundle 27 | import androidx.appcompat.app.AppCompatActivity 28 | import androidx.appcompat.app.AppCompatDelegate 29 | import androidx.navigation.Navigation 30 | import com.amrdeveloper.turtle.R 31 | import com.amrdeveloper.turtle.data.AppTheme 32 | import com.amrdeveloper.turtle.util.UserPreferences 33 | import com.google.android.material.bottomnavigation.BottomNavigationView 34 | import dagger.hilt.android.AndroidEntryPoint 35 | 36 | @AndroidEntryPoint 37 | class MainActivity : AppCompatActivity() { 38 | 39 | override fun onCreate(savedInstanceState: Bundle?) { 40 | super.onCreate(savedInstanceState) 41 | setContentView(R.layout.activity_main) 42 | 43 | handleMultiThemePreferences() 44 | setupNavigationUI() 45 | } 46 | 47 | private fun setupNavigationUI() { 48 | val navController = Navigation.findNavController(this, R.id.nav_host_fragment) 49 | val bottomNavView = findViewById(R.id.bottom_navigation) 50 | 51 | navController.addOnDestinationChangedListener { _, destination, _ -> 52 | bottomNavView.menu.findItem(destination.id)?.let { it.isChecked = true } 53 | } 54 | 55 | bottomNavView.setOnItemSelectedListener { 56 | if (navController.popBackStack(it.itemId, false).not()) { 57 | navController.navigate(it.itemId) 58 | } 59 | true 60 | } 61 | } 62 | 63 | private fun handleMultiThemePreferences() { 64 | val userPreferences = UserPreferences(this) 65 | val currentTheme = userPreferences.getAppTheme() 66 | val themeMode = if (currentTheme == AppTheme.DARK) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO 67 | AppCompatDelegate.setDefaultNightMode(themeMode) 68 | } 69 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/MainViewModel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui 25 | 26 | import androidx.lifecycle.MutableLiveData 27 | import androidx.lifecycle.ViewModel 28 | import com.amrdeveloper.lilo.utils.Diagnostic 29 | import com.amrdeveloper.lilo.utils.LiloDiagnostics 30 | import com.amrdeveloper.lilo.ast.LiloScript 31 | import com.amrdeveloper.lilo.fmt.LiloFormatter 32 | import com.amrdeveloper.lilo.frontend.LiloParser 33 | import com.amrdeveloper.lilo.frontend.LiloTokenizer 34 | import dagger.hilt.android.lifecycle.HiltViewModel 35 | import javax.inject.Inject 36 | 37 | @HiltViewModel 38 | class MainViewModel @Inject constructor() : ViewModel() { 39 | 40 | private val _diagnosticsLiveData = MutableLiveData>() 41 | val diagnosticsLiveData = _diagnosticsLiveData 42 | 43 | private val _liloScript = MutableLiveData() 44 | val liloScript = _liloScript 45 | 46 | private val _previewLiveData = MutableLiveData() 47 | val previewLiveData = _previewLiveData 48 | 49 | private val diagnostics = LiloDiagnostics() 50 | 51 | private val formatter = LiloFormatter() 52 | 53 | fun executeLiloScript(script : String) { 54 | diagnostics.clearErrors() 55 | diagnostics.clearWarns() 56 | val tokenizer = LiloTokenizer(script) 57 | val parser = LiloParser(tokenizer.scanTokens(), diagnostics) 58 | val liloScript = parser.parseScript() 59 | if (diagnostics.errorNumber() > 0) { 60 | _diagnosticsLiveData.value = diagnostics.errorDiagnostics() 61 | return 62 | } 63 | _diagnosticsLiveData.value = listOf() 64 | _previewLiveData.value = true 65 | _liloScript.value = liloScript 66 | } 67 | 68 | fun formatLiloScript(script : String) : String { 69 | diagnostics.clearErrors() 70 | diagnostics.clearWarns() 71 | val tokenizer = LiloTokenizer(script) 72 | val parser = LiloParser(tokenizer.scanTokens(), diagnostics) 73 | val liloScript = parser.parseScript() 74 | if (diagnostics.errorNumber() > 0) { 75 | _diagnosticsLiveData.value = diagnostics.errorDiagnostics() 76 | return "" 77 | } 78 | _diagnosticsLiveData.value = listOf() 79 | return formatter.formatLiloScript(liloScript) 80 | } 81 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/documents/DocumentsFragment.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui.documents 25 | 26 | import android.os.Bundle 27 | import androidx.fragment.app.Fragment 28 | import android.view.LayoutInflater 29 | import android.view.View 30 | import android.view.ViewGroup 31 | import com.amrdeveloper.turtle.data.LiloDocuments 32 | import com.amrdeveloper.turtle.data.LiloDocumentsExpandableAdapter 33 | import com.amrdeveloper.turtle.databinding.FragmentDocumentsBinding 34 | import dagger.hilt.android.AndroidEntryPoint 35 | 36 | private const val TAG = "DocumentsFragment" 37 | 38 | @AndroidEntryPoint 39 | class DocumentsFragment : Fragment() { 40 | 41 | private var _binding: FragmentDocumentsBinding? = null 42 | private val binding get() = _binding!! 43 | 44 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { 45 | _binding = FragmentDocumentsBinding.inflate(inflater, container, false) 46 | setupLiloDocumentations() 47 | return binding.root 48 | } 49 | 50 | private fun setupLiloDocumentations() { 51 | val liloDocuments = LiloDocuments() 52 | val liloDocumentsMap = liloDocuments.documents 53 | val liloDocumentsCategory = liloDocumentsMap.keys.toList() 54 | val liloDocumentsAdapter = LiloDocumentsExpandableAdapter(liloDocumentsCategory, liloDocumentsMap) 55 | binding.documentsExpandableList.setAdapter(liloDocumentsAdapter) 56 | } 57 | 58 | override fun onDestroyView() { 59 | super.onDestroyView() 60 | _binding = null 61 | } 62 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/editor/AutoCompleteAdapter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui.editor 25 | 26 | import android.content.Context 27 | import android.view.LayoutInflater 28 | import android.view.View 29 | import android.view.ViewGroup 30 | import android.widget.ImageView 31 | import android.widget.TextView 32 | import com.amrdeveloper.codeview.Code 33 | import com.amrdeveloper.codeview.CodeViewAdapter 34 | import com.amrdeveloper.codeview.Snippet 35 | import com.amrdeveloper.turtle.R 36 | 37 | class AutoCompleteAdapter( 38 | private val context: Context, 39 | private val codes: List 40 | ) : CodeViewAdapter(context, R.layout.list_item_autocomplete, 0, codes) { 41 | 42 | override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { 43 | val view = convertView ?: LayoutInflater.from(context).inflate(R.layout.list_item_autocomplete, parent, false) 44 | val currentCode = getItem(position) as Code 45 | 46 | val codeTitle = view.findViewById(R.id.code_title) 47 | codeTitle.text = currentCode.codeTitle 48 | 49 | val codeType = view.findViewById(R.id.code_type) 50 | val icon = if (currentCode is Snippet) R.drawable.ic_snippet else R.drawable.ic_keyword 51 | codeType.setImageResource(icon) 52 | 53 | return view 54 | } 55 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/editor/DiagnosticViewHolder.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui.editor 25 | 26 | import android.view.View 27 | import android.widget.ImageView 28 | import android.widget.TextView 29 | import com.amrdeveloper.lilo.utils.Diagnostic 30 | import com.amrdeveloper.lilo.utils.DiagnosticType 31 | import com.amrdeveloper.treeview.TreeNode 32 | import com.amrdeveloper.treeview.TreeViewHolder 33 | import com.amrdeveloper.turtle.R 34 | 35 | class DiagnosticViewHolder(itemView : View) : TreeViewHolder(itemView) { 36 | 37 | private val diagnosticTitle : TextView by lazy { itemView.findViewById(R.id.diagnostic_name) } 38 | private val diagnosticStateIcon : ImageView by lazy { itemView.findViewById(R.id.diagnostic_state_icon) } 39 | private val diagnosticTypeIcon : ImageView by lazy { itemView.findViewById(R.id.diagnostic_type_icon) } 40 | 41 | override fun bindTreeNode(node: TreeNode?) { 42 | super.bindTreeNode(node) 43 | if (node != null && node.value is Diagnostic) { 44 | val diagnostic = node.value as Diagnostic 45 | val position = diagnostic.position 46 | val positionLiteral = "L${position.line} (${position.columnStart}-${position.columnEnd})" 47 | diagnosticTitle.text = "${positionLiteral} :${diagnostic.message}" 48 | 49 | if (diagnostic.type == DiagnosticType.ERROR) { 50 | diagnosticTypeIcon.setImageResource(R.drawable.ic_error) 51 | } else { 52 | diagnosticTypeIcon.setImageResource(R.drawable.ic_warning) 53 | } 54 | 55 | if (node.children.isEmpty()) { 56 | diagnosticStateIcon.visibility = View.INVISIBLE 57 | } else { 58 | diagnosticStateIcon.visibility = View.VISIBLE 59 | val stateIcon = if (node.isExpanded) R.drawable.ic_arrow_down else R.drawable.ic_arrow_right 60 | diagnosticStateIcon.setImageResource(stateIcon) 61 | } 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/editor/TurtleEditorConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui.editor 25 | 26 | import androidx.core.content.ContextCompat 27 | import com.amrdeveloper.codeview.CodeView 28 | import com.amrdeveloper.codeview.Keyword 29 | import com.amrdeveloper.lilo.frontend.LiloTokenizer 30 | import com.amrdeveloper.turtle.R 31 | import java.util.regex.Pattern 32 | 33 | private val turtleKeywords = LiloTokenizer.keywords.keys 34 | private val PATTERN_KEYWORDS = Pattern.compile("\\b(${turtleKeywords.joinToString(separator = "|")})\\b") 35 | private val PATTERN_NUMBERS = Pattern.compile("\\b(\\d*[.]?\\d+)\\b") 36 | private val PATTERN_HASH_COMMENT = Pattern.compile("#(?!TODO )[^\\n]*"); 37 | 38 | fun configCodeViewForLiloScript(codeView: CodeView) { 39 | val context = codeView.context ?: return 40 | 41 | // Config Syntax highlighter 42 | codeView.addSyntaxPattern(PATTERN_KEYWORDS, ContextCompat.getColor(context, R.color.monokia_pro_pink)) 43 | codeView.addSyntaxPattern(PATTERN_NUMBERS, ContextCompat.getColor(context, R.color.monokia_pro_purple)) 44 | codeView.addSyntaxPattern(PATTERN_HASH_COMMENT, ContextCompat.getColor(context, R.color.monokia_pro_grey)) 45 | 46 | // Config Pairs complete 47 | val pairCompleteMap = mapOf('{' to '}', '(' to ')') 48 | codeView.setPairCompleteMap(pairCompleteMap) 49 | codeView.enablePairComplete(true) 50 | codeView.enablePairCompleteCenterCursor(true) 51 | 52 | // Config Auto complete for keywords and snippets 53 | val codes = turtleKeywords.map { Keyword(it) } 54 | val autoCompleteAdapter = AutoCompleteAdapter(context, codes) 55 | codeView.setAdapter(autoCompleteAdapter) 56 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/pack/PackageFragment.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui.pack 25 | 26 | import android.os.Bundle 27 | import android.view.* 28 | import android.widget.Toast 29 | import androidx.fragment.app.Fragment 30 | import androidx.fragment.app.viewModels 31 | import androidx.navigation.fragment.findNavController 32 | import androidx.navigation.fragment.navArgs 33 | import com.amrdeveloper.turtle.R 34 | import com.amrdeveloper.turtle.data.LiloPackage 35 | import com.amrdeveloper.turtle.databinding.FragmentPackageBinding 36 | import dagger.hilt.android.AndroidEntryPoint 37 | 38 | @AndroidEntryPoint 39 | class PackageFragment : Fragment() { 40 | 41 | private var _binding: FragmentPackageBinding? = null 42 | private val binding get() = _binding!! 43 | 44 | private val safeArguments by navArgs() 45 | 46 | private val packageViewModel: PackageViewModel by viewModels() 47 | 48 | private var liloSourceCode : String = "" 49 | private lateinit var currentLiloPackage : LiloPackage 50 | 51 | override fun onCreate(savedInstanceState: Bundle?) { 52 | super.onCreate(savedInstanceState) 53 | setHasOptionsMenu(true) 54 | 55 | safeArguments.sourceCode?.let { liloSourceCode = it } 56 | safeArguments.liloPackage?.let { currentLiloPackage = it } 57 | } 58 | 59 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { 60 | _binding = FragmentPackageBinding.inflate(inflater, container, false) 61 | 62 | if (::currentLiloPackage.isInitialized) { 63 | binding.packageNameText.setText(currentLiloPackage.name) 64 | } 65 | 66 | setupObservers() 67 | 68 | return binding.root 69 | } 70 | 71 | private fun setupObservers() { 72 | packageViewModel.stateMessage.observe(viewLifecycleOwner) { 73 | Toast.makeText(requireContext(), it, Toast.LENGTH_SHORT).show() 74 | } 75 | 76 | packageViewModel.operationState.observe(viewLifecycleOwner) { 77 | if (it) findNavController().navigateUp() 78 | } 79 | } 80 | 81 | override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { 82 | inflater.inflate(R.menu.menu_package, menu) 83 | super.onCreateOptionsMenu(menu, inflater) 84 | } 85 | 86 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 87 | return when (item.itemId) { 88 | R.id.action_save -> { 89 | if (::currentLiloPackage.isInitialized) updateCurrentPackage() 90 | else saveNewPackage() 91 | true 92 | } 93 | R.id.action_close -> { 94 | findNavController().navigateUp() 95 | true 96 | } 97 | else -> super.onOptionsItemSelected(item) 98 | } 99 | } 100 | 101 | private fun saveNewPackage() { 102 | val name = binding.packageNameText.text.toString().trim() 103 | if (name.isEmpty()) { 104 | binding.packageNameText.error = "Name can't be empty" 105 | return 106 | } 107 | val liloPackage = LiloPackage(name, liloSourceCode) 108 | packageViewModel.savePackage(liloPackage) 109 | } 110 | 111 | private fun updateCurrentPackage() { 112 | val name = binding.packageNameText.text.toString().trim() 113 | if (name.isEmpty()) { 114 | binding.packageNameText.error = "Name can't be empty" 115 | return 116 | } 117 | 118 | // Set package name if changed and update it 119 | currentLiloPackage.name = name 120 | currentLiloPackage.updateTimeStamp = System.currentTimeMillis() 121 | currentLiloPackage.isUpdated = true 122 | packageViewModel.updatePackage(currentLiloPackage) 123 | } 124 | 125 | override fun onDestroyView() { 126 | super.onDestroyView() 127 | _binding = null 128 | } 129 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/pack/PackageViewModel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui.pack 25 | 26 | import androidx.lifecycle.MutableLiveData 27 | import androidx.lifecycle.ViewModel 28 | import androidx.lifecycle.viewModelScope 29 | import com.amrdeveloper.turtle.R 30 | import com.amrdeveloper.turtle.data.LiloPackage 31 | import com.amrdeveloper.turtle.data.source.LiloPackageRepository 32 | import dagger.hilt.android.lifecycle.HiltViewModel 33 | import kotlinx.coroutines.launch 34 | import timber.log.Timber 35 | import javax.inject.Inject 36 | 37 | private const val TAG = "PackageViewModel" 38 | 39 | @HiltViewModel 40 | class PackageViewModel @Inject constructor( 41 | private val liloPackageRepository: LiloPackageRepository 42 | ) : ViewModel() { 43 | 44 | private val _stateMessage = MutableLiveData() 45 | val stateMessage = _stateMessage 46 | 47 | private val _operationState = MutableLiveData(false) 48 | val operationState = _operationState 49 | 50 | fun savePackage(liloPackage: LiloPackage) { 51 | viewModelScope.launch { 52 | val result = liloPackageRepository.insertLiloPackage(liloPackage) 53 | if (result.isSuccess && result.getOrDefault(-1) > 0) { 54 | Timber.tag(TAG).d("New lilo package inserted") 55 | _stateMessage.value = R.string.package_inserted_success 56 | _operationState.value = true 57 | } else { 58 | Timber.tag(TAG).d("New lilo package not inserted because ${result.exceptionOrNull()?.message}") 59 | _stateMessage.value = R.string.package_inserted_errors 60 | } 61 | } 62 | } 63 | 64 | fun updatePackage(liloPackage: LiloPackage) { 65 | viewModelScope.launch { 66 | val result = liloPackageRepository.updateLiloPackage(liloPackage) 67 | if (result.isSuccess && result.getOrDefault(-1) > 0) { 68 | Timber.tag(TAG).d("Lilo package updated") 69 | _stateMessage.value = R.string.package_updated_success 70 | _operationState.value = true 71 | } else { 72 | Timber.tag(TAG).d("Lilo package not updated because ${result.exceptionOrNull()?.message}") 73 | _stateMessage.value = R.string.package_updated_errors 74 | } 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/packages/ItemSwipeCallback.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui.packages 25 | 26 | import android.graphics.Canvas 27 | import android.graphics.drawable.ColorDrawable 28 | import android.graphics.drawable.Drawable 29 | import android.view.View 30 | import androidx.recyclerview.widget.ItemTouchHelper 31 | import androidx.recyclerview.widget.RecyclerView 32 | 33 | class ItemSwipeCallback( 34 | private val icon : Drawable?, 35 | private val background : ColorDrawable, 36 | private val onSwipeCallback: (RecyclerView.ViewHolder) -> Unit 37 | ) : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) { 38 | 39 | private val intrinsicHeight = icon!!.intrinsicHeight 40 | private val intrinsicWidth = icon!!.intrinsicWidth 41 | 42 | override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { 43 | onSwipeCallback(viewHolder) 44 | } 45 | 46 | override fun onMove( 47 | recyclerView: RecyclerView, 48 | viewHolder: RecyclerView.ViewHolder, 49 | target: RecyclerView.ViewHolder 50 | ): Boolean = false 51 | 52 | override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, 53 | dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) { 54 | val itemView: View = viewHolder.itemView 55 | val iconMargin: Int = (itemView.height - intrinsicHeight) / 2 56 | val iconTop: Int = itemView.top + (itemView.height - intrinsicHeight) / 2 57 | val iconBottom = iconTop + intrinsicHeight 58 | 59 | when { 60 | // Swipe left 61 | dX > 0 -> { 62 | val iconLeft: Int = itemView.left + iconMargin 63 | val iconRight = iconLeft + intrinsicWidth 64 | icon?.setBounds(iconLeft, iconTop, iconRight, iconBottom) 65 | background.setBounds(itemView.left, itemView.top, itemView.left + dX.toInt(), itemView.bottom) 66 | } 67 | // Swipe right 68 | dX < 0 -> { 69 | val iconLeft: Int = itemView.right - iconMargin - intrinsicWidth 70 | val iconRight: Int = itemView.right - iconMargin 71 | icon?.setBounds(iconLeft, iconTop, iconRight, iconBottom) 72 | background.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom) 73 | } 74 | // Not swiped 75 | else -> { 76 | background.setBounds(0, 0, 0, 0) 77 | icon?.setBounds(0, 0, 0, 0) 78 | } 79 | } 80 | 81 | background.draw(c) 82 | icon?.draw(c) 83 | 84 | super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) 85 | } 86 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/packages/PackagesViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.amrdeveloper.turtle.ui.packages 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.lifecycle.ViewModel 5 | import androidx.lifecycle.viewModelScope 6 | import com.amrdeveloper.turtle.data.LiloPackage 7 | import com.amrdeveloper.turtle.data.source.LiloPackageRepository 8 | import dagger.hilt.android.lifecycle.HiltViewModel 9 | import kotlinx.coroutines.launch 10 | import javax.inject.Inject 11 | 12 | @HiltViewModel 13 | class PackagesViewModel @Inject constructor( 14 | private val liloPackageRepository: LiloPackageRepository 15 | ) : ViewModel() { 16 | 17 | private val _liloPackagesLiveData = MutableLiveData>() 18 | val liloPackagesLiveData = _liloPackagesLiveData 19 | 20 | fun loadLiloPackages() { 21 | viewModelScope.launch { 22 | val result = liloPackageRepository.loadLiloPackages() 23 | if (result.isSuccess) { 24 | _liloPackagesLiveData.value = result.getOrDefault(listOf()) 25 | } 26 | } 27 | } 28 | 29 | fun loadLiloPackagesByKeyword(keyword : String) { 30 | viewModelScope.launch { 31 | val result = liloPackageRepository.loadLiloPackagesByKeyword(keyword) 32 | if (result.isSuccess) { 33 | _liloPackagesLiveData.value = result.getOrDefault(listOf()) 34 | } 35 | } 36 | } 37 | 38 | fun insertLiloPackage(liloPackage: LiloPackage) { 39 | viewModelScope.launch { 40 | liloPackageRepository.insertLiloPackage(liloPackage) 41 | } 42 | } 43 | 44 | fun deleteLiloPackage(liloPackage : LiloPackage) { 45 | viewModelScope.launch { 46 | val result = liloPackageRepository.deleteLiloPackage(liloPackage) 47 | if (result.isSuccess) { 48 | liloPackagesLiveData.value?.toMutableList()?.remove(liloPackage) 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/preview/TurtlePointer.kt: -------------------------------------------------------------------------------- 1 | package com.amrdeveloper.turtle.ui.preview 2 | 3 | import android.graphics.Color 4 | 5 | data class TurtlePointer( 6 | var x: Float, 7 | var y: Float, 8 | var degree: Float, 9 | var color : Int = Color.BLACK, 10 | var isVisible: Boolean = true, 11 | var isPenDown : Boolean = true, 12 | ) -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/ui/settings/SettingsFragment.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.ui.settings 25 | 26 | import android.content.Intent 27 | import android.net.Uri 28 | import android.os.Bundle 29 | import androidx.fragment.app.Fragment 30 | import android.view.LayoutInflater 31 | import android.view.View 32 | import android.view.ViewGroup 33 | import androidx.appcompat.app.AppCompatDelegate 34 | import com.amrdeveloper.turtle.data.AppTheme 35 | import com.amrdeveloper.turtle.data.GITHUB_CONTRIBUTORS 36 | import com.amrdeveloper.turtle.data.GITHUB_ISSUES 37 | import com.amrdeveloper.turtle.data.GITHUB_SOURCE 38 | import com.amrdeveloper.turtle.data.GOOGLE_PLAY_URL 39 | import com.amrdeveloper.turtle.databinding.FragmentSettingsBinding 40 | import com.amrdeveloper.turtle.util.UserPreferences 41 | import dagger.hilt.android.AndroidEntryPoint 42 | 43 | @AndroidEntryPoint 44 | class SettingsFragment : Fragment() { 45 | 46 | private var _binding: FragmentSettingsBinding? = null 47 | private val binding get() = _binding!! 48 | private val userPreferences by lazy { UserPreferences(requireContext()) } 49 | 50 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { 51 | _binding = FragmentSettingsBinding.inflate(inflater, container, false) 52 | 53 | setupSettingsInformation() 54 | setupSettingsListeners() 55 | 56 | return binding.root 57 | } 58 | 59 | private fun setupSettingsInformation() { 60 | // TODO: Check this later 61 | binding.versionTxt.visibility = View.GONE 62 | 63 | val isDarkTheme = userPreferences.getAppTheme() == AppTheme.DARK 64 | binding.themeSwitch.isChecked = isDarkTheme 65 | } 66 | 67 | private fun setupSettingsListeners() { 68 | binding.themeSwitch.setOnCheckedChangeListener { _, isChecked -> 69 | val themeMode = if (isChecked) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO 70 | AppCompatDelegate.setDefaultNightMode(themeMode) 71 | 72 | val theme = if (isChecked) AppTheme.DARK else AppTheme.WHITE 73 | userPreferences.setAppTheme(theme) 74 | } 75 | 76 | binding.sourceCodeTxt.setOnClickListener { 77 | val viewIntent = Intent(Intent.ACTION_VIEW).setData(Uri.parse(GITHUB_SOURCE)) 78 | startActivity(viewIntent) 79 | } 80 | 81 | binding.contributorsTxt.setOnClickListener { 82 | val viewIntent = Intent(Intent.ACTION_VIEW).setData(Uri.parse(GITHUB_CONTRIBUTORS)) 83 | startActivity(viewIntent) 84 | } 85 | 86 | binding.issuesTxt.setOnClickListener { 87 | val viewIntent = Intent(Intent.ACTION_VIEW).setData(Uri.parse(GITHUB_ISSUES)) 88 | startActivity(viewIntent) 89 | } 90 | 91 | binding.shareTxt.setOnClickListener { 92 | val sendIntent = Intent(Intent.ACTION_SEND) 93 | sendIntent.putExtra(Intent.EXTRA_TEXT, GOOGLE_PLAY_URL) 94 | sendIntent.type = "text/plain" 95 | val shareIndent = Intent.createChooser(sendIntent, null) 96 | startActivity(shareIndent) 97 | } 98 | } 99 | 100 | override fun onDestroyView() { 101 | super.onDestroyView() 102 | _binding = null 103 | } 104 | } -------------------------------------------------------------------------------- /app/src/main/java/com/amrdeveloper/turtle/util/UserPreferences.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.turtle.util 25 | 26 | import android.content.Context 27 | import com.amrdeveloper.turtle.data.AppTheme 28 | 29 | private const val SETTINGS_PREFERENCE_NAME = "turtle_preference" 30 | private const val SETTINGS_THEME_KEY = "theme" 31 | private val defaultTheme = AppTheme.DARK 32 | 33 | class UserPreferences(private val context: Context) { 34 | 35 | fun setAppTheme(theme : AppTheme) { 36 | val preferences = context.getSharedPreferences(SETTINGS_PREFERENCE_NAME, Context.MODE_PRIVATE) 37 | val editor = preferences.edit() 38 | editor.putString(SETTINGS_THEME_KEY, theme.name) 39 | editor.apply() 40 | } 41 | 42 | fun getAppTheme() : AppTheme { 43 | val preferences = context.getSharedPreferences(SETTINGS_PREFERENCE_NAME, Context.MODE_PRIVATE) 44 | val themeName = preferences.getString(SETTINGS_THEME_KEY, defaultTheme.name) ?: defaultTheme.name 45 | return AppTheme.valueOf(themeName) 46 | } 47 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_down.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_right.xml: -------------------------------------------------------------------------------- 1 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_close.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_code.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dark_mode.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_error.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_github_sponsor.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyword.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 13 | 14 | 16 | 19 | 22 | 25 | 28 | 31 | 34 | 37 | 40 | 43 | 46 | 49 | 52 | 55 | 58 | 61 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_list.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play_arrow.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_preview.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_replay.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_resume.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_save.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_share.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_snippet.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_stop.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_text_snippet.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_turtle_pack.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_warning.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_documents.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_editor.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 20 | 21 | 29 | 30 | 35 | 36 | 46 | 47 | 54 | 55 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_package.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_packages.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_preview.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 16 | 30 | 31 | 35 | 36 | 47 | 48 | 52 | 53 | 64 | 65 | 69 | 70 | 81 | 82 | 86 | 87 | 98 | 99 | 103 | 104 | 115 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_autocomplete.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 12 | 13 | 24 | 25 | 26 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_diagnostic.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 22 | 23 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_document.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 17 | 18 | 26 | 27 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_document_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_package.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 17 | 18 | 25 | 26 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_bottom_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 12 | 13 | 17 | 18 | 22 | 23 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_editor.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 16 | 17 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_package.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 10 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_preview.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/menu/menu_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/navigation/navigation_graph.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 19 | 20 | 23 | 24 | 27 | 28 | 29 | 34 | 35 | 40 | 41 | 44 | 45 | 48 | 49 | 50 | 55 | 56 | 61 | 62 | 67 | 68 | 69 | 74 | 75 | 80 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 24 | 27 | 28 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FF000000 4 | #FFFFFFFF 5 | #36b34a 6 | #da6958 7 | #8C8C8C 8 | #272822 9 | 10 | 11 | #9ccc6b 12 | #2d2a2e 13 | #fcfcfa 14 | #ff6188 15 | #78dce8 16 | #ffd866 17 | #ab9df2 18 | #727072 19 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 0dp 4 | 5dp 5 | 10dp 6 | 16dp 7 | 24dp 8 | 25dp 9 | 40dp 10 | 45dp 11 | 50dp 12 | 55dp 13 | 75dp 14 | 90dp 15 | 120dp 16 | 17 | 16sp 18 | 20sp 19 | -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #DB9A53 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_logo_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #DB9A53 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Turtle 3 | 4 | 5 | Editor 6 | Preview 7 | Packages 8 | Documents 9 | Settings 10 | Source Code 11 | Contributors 12 | Issues 13 | Share 14 | Dark Theme 15 | Sponsorship 16 | 17 | 18 | Execute 19 | Diagnostics 20 | Turtle Pointer 21 | Package Name 22 | Package Icon 23 | Save 24 | Format 25 | Close 26 | Search 27 | Re Evaluate 28 | stop 29 | undo 30 | 31 | 32 | Lilo package inserted successfully 33 | Lilo package updated successfully 34 | Lilo package deleted successfully 35 | Cannot insert new lilo package 36 | Cannot update lilo package 37 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 22 | 23 | 26 | 27 | 30 | 31 | 35 | 36 | 43 | -------------------------------------------------------------------------------- /app/src/test/java/com/amrdeveloper/turtle/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.amrdeveloper.turtle 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' version '8.7.3' apply false 3 | id 'com.android.library' version '8.7.3' apply false 4 | id 'org.jetbrains.kotlin.android' version '1.9.24' apply false 5 | id 'androidx.navigation.safeargs' version '2.5.0' apply false 6 | id 'com.google.dagger.hilt.android' version '2.48' apply false 7 | } 8 | 9 | task clean(type: Delete) { 10 | delete rootProject.buildDir 11 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Kotlin code style for this project: "official" or "obsolete": 19 | kotlin.code.style=official 20 | # Enables namespacing of each library's R class so that its R class includes only the 21 | # resources declared in the library itself and none from the library's dependencies, 22 | # thereby reducing the size of the R class for that library 23 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jan 24 21:51:41 CET 2025 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | 8 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /lilo/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /lilo/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.library' 3 | id 'org.jetbrains.kotlin.android' 4 | } 5 | 6 | android { 7 | compileSdk 34 8 | namespace "com.amrdeveloper.lilo" 9 | 10 | defaultConfig { 11 | minSdk 21 12 | targetSdk 34 13 | 14 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 15 | consumerProguardFiles "consumer-rules.pro" 16 | } 17 | 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | compileOptions { 25 | sourceCompatibility JavaVersion.VERSION_1_8 26 | targetCompatibility JavaVersion.VERSION_1_8 27 | } 28 | kotlinOptions { 29 | jvmTarget = '1.8' 30 | } 31 | } 32 | 33 | dependencies { 34 | implementation 'androidx.core:core-ktx:1.8.0' 35 | 36 | implementation 'com.jakewharton.timber:timber:5.0.1' 37 | 38 | testImplementation 'junit:junit:4.13.2' 39 | androidTestImplementation 'androidx.test.ext:junit:1.1.3' 40 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' 41 | } -------------------------------------------------------------------------------- /lilo/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/lilo/consumer-rules.pro -------------------------------------------------------------------------------- /lilo/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /lilo/src/androidTest/java/com/amrdeveloper/lilo/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.amrdeveloper.lilo 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.amrdeveloper.lilo.test", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /lilo/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/ast/Expressions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.ast 25 | 26 | import com.amrdeveloper.lilo.frontend.Token 27 | 28 | abstract class Expression { 29 | abstract fun accept(visitor: ExpressionVisitor): R 30 | } 31 | 32 | class GroupExpression( 33 | val expression: Expression 34 | ) : Expression() { 35 | override fun accept(visitor: ExpressionVisitor): R { 36 | return visitor.visit(this) 37 | } 38 | } 39 | 40 | class AssignExpression( 41 | val operator: Token, 42 | val left: Expression, 43 | val value: Expression 44 | ) : Expression() { 45 | override fun accept(visitor: ExpressionVisitor): R { 46 | return visitor.visit(this) 47 | } 48 | } 49 | 50 | class BinaryExpression( 51 | val left: Expression, 52 | val operator: Token, 53 | val right: Expression, 54 | ) : Expression() { 55 | override fun accept(visitor: ExpressionVisitor): R { 56 | return visitor.visit(this) 57 | } 58 | } 59 | 60 | class ComparisonExpression( 61 | val left: Expression, 62 | val operator: Token, 63 | val right: Expression, 64 | ) : Expression() { 65 | override fun accept(visitor: ExpressionVisitor): R { 66 | return visitor.visit(this) 67 | } 68 | } 69 | 70 | class LogicalExpression( 71 | val left: Expression, 72 | val operator: Token, 73 | val right: Expression, 74 | ) : Expression() { 75 | override fun accept(visitor: ExpressionVisitor): R { 76 | return visitor.visit(this) 77 | } 78 | } 79 | 80 | class UnaryExpression( 81 | val operator: Token, 82 | val right: Expression, 83 | ) : Expression() { 84 | override fun accept(visitor: ExpressionVisitor): R { 85 | return visitor.visit(this) 86 | } 87 | } 88 | 89 | class CallExpression( 90 | val callee: Expression, 91 | val paren : Token, 92 | val arguments: List 93 | ) : Expression() { 94 | override fun accept(visitor: ExpressionVisitor): R { 95 | return visitor.visit(this) 96 | } 97 | } 98 | 99 | class DotExpression( 100 | var dot: Token, 101 | val caller: Expression, 102 | val callee: Statement, 103 | ) : Expression() { 104 | override fun accept(visitor: ExpressionVisitor): R { 105 | return visitor.visit(this) 106 | } 107 | } 108 | 109 | class IndexExpression( 110 | val bracket : Token, 111 | val left: Expression, 112 | val index: Expression 113 | ) : Expression() { 114 | override fun accept(visitor: ExpressionVisitor): R { 115 | return visitor.visit(this) 116 | } 117 | } 118 | 119 | class VariableExpression( 120 | val value: Token 121 | ) : Expression() { 122 | override fun accept(visitor: ExpressionVisitor): R { 123 | return visitor.visit(this) 124 | } 125 | } 126 | 127 | class ListExpression( 128 | val values: List 129 | ) : Expression() { 130 | override fun accept(visitor: ExpressionVisitor): R { 131 | return visitor.visit(this) 132 | } 133 | } 134 | 135 | class NumberExpression( 136 | val value: Float 137 | ) : Expression() { 138 | override fun accept(visitor: ExpressionVisitor): R { 139 | return visitor.visit(this) 140 | } 141 | } 142 | 143 | class BooleanExpression( 144 | val value: Boolean 145 | ) : Expression() { 146 | override fun accept(visitor: ExpressionVisitor): R { 147 | return visitor.visit(this) 148 | } 149 | } 150 | 151 | class NewTurtleExpression : Expression() { 152 | override fun accept(visitor: ExpressionVisitor): R { 153 | return visitor.visit(this) 154 | } 155 | } 156 | 157 | class ThieExpression : Expression() { 158 | override fun accept(visitor: ExpressionVisitor): R { 159 | return visitor.visit(this) 160 | } 161 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/ast/Script.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.ast 25 | 26 | data class LiloScript( 27 | val statements: List 28 | ) -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/ast/Visitors.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.ast 25 | 26 | interface StatementVisitor { 27 | fun visit(statement: ExpressionStatement): R 28 | fun visit(statement: FunctionStatement): R 29 | fun visit(statement: ReturnStatement): R 30 | fun visit(statement: BlockStatement): R 31 | fun visit(statement: LetStatement): R 32 | fun visit(statement: IfStatement): R 33 | fun visit(statement: WhileStatement): R 34 | fun visit(statement: RepeatStatement): R 35 | fun visit(statement: CubeStatement): R 36 | fun visit(statement: CircleStatement): R 37 | fun visit(statement: MoveStatement): R 38 | fun visit(statement: MoveXStatement): R 39 | fun visit(statement: MoveYStatement): R 40 | fun visit(statement: ColorStatement): R 41 | fun visit(statement: BackgroundStatement): R 42 | fun visit(statement: SpeedStatement): R 43 | fun visit(statement: SleepStatement): R 44 | fun visit(statement: ShowPointerStatement): R 45 | fun visit(statement: HidePointerStatement): R 46 | fun visit(statement: PenUpStatement): R 47 | fun visit(statement: PenDownStatement): R 48 | fun visit(statement: StopStatement): R 49 | fun visit(statement: RotateStatement): R 50 | fun visit(statement: ForwardStatement): R 51 | fun visit(statement: BackwardStatement): R 52 | fun visit(statement: RightStatement): R 53 | fun visit(statement: LeftStatement): R 54 | } 55 | 56 | interface ExpressionVisitor { 57 | fun visit(expression: AssignExpression): R 58 | fun visit(expression: GroupExpression): R 59 | fun visit(expression: BinaryExpression): R 60 | fun visit(expression: ComparisonExpression): R 61 | fun visit(expression: LogicalExpression): R 62 | fun visit(expression: UnaryExpression): R 63 | fun visit(expression: CallExpression): R 64 | fun visit(expression: DotExpression): R 65 | fun visit(expression: IndexExpression): R 66 | fun visit(expression: ListExpression): R 67 | fun visit(expression: VariableExpression): R 68 | fun visit(expression: NumberExpression): R 69 | fun visit(expression: BooleanExpression): R 70 | fun visit(expression: NewTurtleExpression): R 71 | fun visit(expression: ThieExpression): R 72 | } 73 | 74 | interface TreeVisitor : StatementVisitor, ExpressionVisitor -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/backend/ExecutionState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.backend 25 | 26 | enum class ExecutionState { 27 | SUCCESS, 28 | FAILURE 29 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/backend/Instruction.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.backend 25 | 26 | open class Instruction 27 | 28 | enum class Operator { 29 | EQUAL, 30 | PLUS, 31 | MINUS, 32 | } 33 | 34 | class NewTurtleInst(var id : Int) : Instruction() 35 | 36 | class MoveXInst(val id : Int, val amount : Float) : Instruction() 37 | 38 | class MoveYInst(val id : Int, val amount : Float) : Instruction() 39 | 40 | class DegreeInst(val id : Int, val degree: Float, val op : Operator) : Instruction() 41 | 42 | class ColorInst(val id: Int, val color: Int) : Instruction() 43 | 44 | class RectangleInst(var id : Int, val right: Float, val bottom: Float) : Instruction() 45 | 46 | class CircleInst(val id : Int, val radius : Float) : Instruction() 47 | 48 | class LineInst(var id : Int, val length : Float) : Instruction() 49 | class VisibilityInst(val id : Int, val isVisible : Boolean) : Instruction() 50 | 51 | class PenInst(val id : Int, val isDown : Boolean) : Instruction() 52 | 53 | class SleepInst(val time: Int) : Instruction() 54 | 55 | class SpeedInst ( val time : Int ) : Instruction() -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/backend/LiloCallable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.backend 25 | 26 | interface LiloCallable { 27 | fun arity(): Int 28 | 29 | fun call(interpreter: LiloEvaluator, arguments: List): Any 30 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/backend/LiloFunction.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.backend 25 | 26 | import com.amrdeveloper.lilo.ast.BlockStatement 27 | import com.amrdeveloper.lilo.ast.ExpressionStatement 28 | import com.amrdeveloper.lilo.ast.FunctionStatement 29 | import com.amrdeveloper.lilo.ast.ReturnStatement 30 | 31 | class LiloFunction( 32 | private val declaration: FunctionStatement, 33 | private val closure: LiloScope 34 | ) : LiloCallable { 35 | 36 | override fun arity(): Int { 37 | return declaration.parameters.size 38 | } 39 | 40 | override fun call(interpreter: LiloEvaluator, arguments: List): Any { 41 | val environment = LiloScope(closure) 42 | val paramsSize = declaration.parameters.size 43 | repeat(paramsSize) { 44 | environment.define(declaration.parameters[it].literal, arguments[it]) 45 | } 46 | 47 | val functionBody = declaration.body 48 | if (functionBody is ReturnStatement || functionBody is ExpressionStatement) { 49 | return interpreter.executeBlockInScope(environment, functionBody) 50 | } 51 | 52 | if (functionBody is BlockStatement) { 53 | return interpreter.executeBlockInScope(environment, *functionBody.statements.toTypedArray()) 54 | } 55 | return 0 56 | } 57 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/backend/LiloList.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.backend 25 | 26 | data class LiloList( 27 | val values: MutableList 28 | ) -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/backend/LiloScope.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.backend 25 | 26 | class LiloScope(private val enclosing: LiloScope? = null) { 27 | 28 | private val values = mutableMapOf() 29 | 30 | fun define(name : String, value : Any) { 31 | values[name] = value 32 | } 33 | 34 | fun assign(name : String, value : Any) : Boolean { 35 | if (values.containsKey(name)) { 36 | values[name] = value 37 | return true 38 | } 39 | 40 | if (enclosing != null) { 41 | return enclosing.assign(name, value) 42 | } 43 | 44 | return false 45 | } 46 | 47 | fun lookup(name : String) : Any? { 48 | if (values.containsKey(name)) { 49 | return values[name] 50 | } 51 | 52 | if (enclosing != null) { 53 | return enclosing.lookup(name) 54 | } 55 | 56 | return null 57 | } 58 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/backend/TurtleObject.kt: -------------------------------------------------------------------------------- 1 | package com.amrdeveloper.lilo.backend 2 | 3 | class TurtleObject(val id : Int) -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/frontend/Token.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.frontend 25 | 26 | data class Token ( 27 | val type : TokenType, 28 | val position : TokenPosition, 29 | val literal : String = "", 30 | ) -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/frontend/TokenPosition.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.frontend 25 | 26 | data class TokenPosition ( 27 | var line: Int, 28 | val columnStart: Int, 29 | val columnEnd: Int 30 | ) -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/frontend/TokenType.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.frontend 25 | 26 | enum class TokenType { 27 | TOKEN_LET, 28 | TOKEN_FUN, 29 | TOKEN_IF, 30 | TOKEN_ELIF, 31 | TOKEN_ELSE, 32 | TOKEN_WHILE, 33 | TOKEN_REPEAT, 34 | TOKEN_NEW_TURTLE, 35 | TOKEN_THIS, 36 | 37 | TOKEN_CUBE, 38 | TOKEN_CIRCLE, 39 | TOKEN_MOVE, 40 | TOKEN_MOVE_X, 41 | TOKEN_MOVE_Y, 42 | TOKEN_COLOR, 43 | TOKEN_BACKGROUND, 44 | TOKEN_SPEED, 45 | TOKEN_SLEEP, 46 | TOKEN_POINTER_SHOW, 47 | TOKEN_POINTER_HIDE, 48 | TOKEN_PEN_UP, 49 | TOKEN_PEN_DOWN, 50 | TOKEN_STOP, 51 | TOKEN_ROTATE, 52 | TOKEN_FORWARD, 53 | TOKEN_BACKWARD, 54 | TOKEN_RIGHT, 55 | TOKEN_LEFT, 56 | 57 | TOKEN_OPEN_PAREN, 58 | TOKEN_CLOSE_PAREN, 59 | TOKEN_OPEN_BRACE, 60 | TOKEN_CLOSE_BRACE, 61 | TOKEN_OPEN_BRACKET, 62 | TOKEN_CLOSE_BRACKET, 63 | 64 | TOKEN_DOT, 65 | TOKEN_COMMA, 66 | 67 | TOKEN_EQ, 68 | TOKEN_EQ_EQ, 69 | TOKEN_BANG, 70 | TOKEN_BANG_EQ, 71 | TOKEN_GT, 72 | TOKEN_GT_EQ, 73 | TOKEN_LS, 74 | TOKEN_LS_EQ, 75 | 76 | TOKEN_OR, 77 | TOKEN_AND, 78 | TOKEN_LOGICAL_OR, 79 | TOKEN_LOGICAL_AND, 80 | 81 | TOKEN_PLUS, 82 | TOKEN_PLUS_EQ, 83 | TOKEN_MINUS, 84 | TOKEN_MINUS_EQ, 85 | TOKEN_MUL, 86 | TOKEN_MUL_EQ, 87 | TOKEN_DIV, 88 | TOKEN_DIV_EQ, 89 | TOKEN_REMINDER, 90 | TOKEN_REMINDER_EQ, 91 | 92 | TOKEN_IDENTIFIER, 93 | TOKEN_NUMBER, 94 | TOKEN_TRUE, 95 | TOKEN_FALSE, 96 | 97 | TOKEN_INVALID, 98 | TOKEN_END_OF_INPUT, 99 | } 100 | 101 | /** 102 | * A list of all assignments operators 103 | */ 104 | val assignOperators = mutableSetOf( 105 | TokenType.TOKEN_EQ, 106 | TokenType.TOKEN_PLUS_EQ, 107 | TokenType.TOKEN_MINUS_EQ, 108 | TokenType.TOKEN_MUL_EQ, 109 | TokenType.TOKEN_DIV_EQ, 110 | TokenType.TOKEN_REMINDER_EQ, 111 | ) 112 | 113 | /** 114 | * A Map between special assignment operators and it binary operator 115 | * for example += operator is equal to assignment with binary plus operator 116 | */ 117 | val specialAssignToBinary = mutableMapOf( 118 | TokenType.TOKEN_PLUS_EQ to TokenType.TOKEN_PLUS, 119 | TokenType.TOKEN_MINUS_EQ to TokenType.TOKEN_MINUS, 120 | TokenType.TOKEN_MUL_EQ to TokenType.TOKEN_MUL, 121 | TokenType.TOKEN_DIV_EQ to TokenType.TOKEN_DIV, 122 | TokenType.TOKEN_REMINDER_EQ to TokenType.TOKEN_REMINDER, 123 | ) -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/std/CollectionsModule.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.std 25 | 26 | import com.amrdeveloper.lilo.backend.LiloCallable 27 | import com.amrdeveloper.lilo.backend.LiloEvaluator 28 | import com.amrdeveloper.lilo.backend.LiloList 29 | import com.amrdeveloper.lilo.backend.LiloScope 30 | 31 | class CollectionsModule : LiloModule { 32 | 33 | private val collectionsLength = object : LiloCallable { 34 | 35 | override fun arity(): Int = 1 36 | 37 | override fun call(interpreter: LiloEvaluator, arguments: List): Any { 38 | if (arguments.first() is LiloList) { 39 | return (arguments.first() as LiloList).values.size.toFloat() 40 | } 41 | return 0.0f 42 | } 43 | } 44 | 45 | override fun bindModule(scope: LiloScope) { 46 | scope.define("len", collectionsLength) 47 | } 48 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/std/LiloModule.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.std 25 | 26 | import com.amrdeveloper.lilo.backend.LiloScope 27 | 28 | fun interface LiloModule { 29 | fun bindModule(scope: LiloScope) 30 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/std/StandardModules.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.std 25 | 26 | import com.amrdeveloper.lilo.backend.LiloScope 27 | 28 | val standardModules = listOf( 29 | CollectionsModule() 30 | ) 31 | 32 | fun bindStandardModules(scope : LiloScope) { 33 | standardModules.forEach { it.bindModule(scope) } 34 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/utils/ColorsTable.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.utils 25 | 26 | import android.graphics.Color 27 | import com.amrdeveloper.lilo.backend.LiloScope 28 | 29 | val colorsTable = mapOf ( 30 | "RED" to Color.RED, 31 | "BLUE" to Color.BLUE, 32 | "BLACK" to Color.BLACK, 33 | "CYAN" to Color.CYAN, 34 | "DKGRAY" to Color.DKGRAY, 35 | "GRAY" to Color.GRAY, 36 | "GREEN" to Color.GREEN, 37 | "LTGRAY" to Color.LTGRAY, 38 | "MAGENTA" to Color.MAGENTA, 39 | "WHITE" to Color.WHITE, 40 | "YELLOW" to Color.YELLOW, 41 | ) 42 | 43 | fun bindBuiltinColors(scope: LiloScope) { 44 | colorsTable.forEach { scope.define(it.key, it.value) } 45 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/utils/Diagnostic.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.utils 25 | 26 | import com.amrdeveloper.lilo.frontend.TokenPosition 27 | 28 | enum class DiagnosticType { 29 | ERROR, 30 | WARN 31 | } 32 | 33 | data class Diagnostic ( 34 | val position: TokenPosition, 35 | val message: String, 36 | val type: DiagnosticType 37 | ) -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/utils/LiloDiagnostics.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.utils 25 | 26 | import com.amrdeveloper.lilo.frontend.TokenPosition 27 | 28 | class LiloDiagnostics { 29 | 30 | private val errorDiagnostics = mutableListOf() 31 | private val warnsDiagnostics = mutableListOf() 32 | 33 | fun reportError(position: TokenPosition, message : String) { 34 | errorDiagnostics.add(Diagnostic(position, message, DiagnosticType.ERROR)) 35 | } 36 | 37 | fun reportWarn(position: TokenPosition, message : String) { 38 | warnsDiagnostics.add(Diagnostic(position, message, DiagnosticType.WARN)) 39 | } 40 | 41 | fun errorDiagnostics() : List = errorDiagnostics 42 | 43 | fun warnsDiagnostics() : List = warnsDiagnostics 44 | 45 | fun clearErrors() { 46 | errorDiagnostics.clear() 47 | } 48 | 49 | fun clearWarns() { 50 | warnsDiagnostics.clear() 51 | } 52 | 53 | fun errorNumber() : Int = errorDiagnostics.size 54 | 55 | fun warnsNumber() : Int = warnsDiagnostics.size 56 | } -------------------------------------------------------------------------------- /lilo/src/main/java/com/amrdeveloper/lilo/utils/LiloException.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2022 AmrDeveloper (Amr Hesham) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | * SOFTWARE. 22 | */ 23 | 24 | package com.amrdeveloper.lilo.utils 25 | 26 | import com.amrdeveloper.lilo.frontend.TokenPosition 27 | 28 | data class LiloException( 29 | val position: TokenPosition, 30 | override val message: String 31 | ) : RuntimeException(message) -------------------------------------------------------------------------------- /lilo/src/test/java/com/amrdeveloper/lilo/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.amrdeveloper.lilo 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /media/screenshots/screenshot_docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/media/screenshots/screenshot_docs.png -------------------------------------------------------------------------------- /media/screenshots/screenshot_editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/media/screenshots/screenshot_editor.png -------------------------------------------------------------------------------- /media/screenshots/screenshot_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmrDeveloper/Turtle/5490936ecfd78f371bbaf3e76eef04e5ecb85bb4/media/screenshots/screenshot_preview.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | google() 5 | mavenCentral() 6 | } 7 | } 8 | dependencyResolutionManagement { 9 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | } 15 | rootProject.name = "Turtle" 16 | include ':app' 17 | include ':lilo' 18 | --------------------------------------------------------------------------------