├── aliflib ├── examples ├── src ├── .prettierrc ├── aliflib │ ├── alif.ico │ ├── libwebui_linux_x86_64.a │ ├── libwebui_win_x86_64.a │ ├── الوقت.alif │ ├── الخوارزميات.alif │ ├── النظام.alif │ ├── utf8.h │ ├── alifstandardlib.alif │ ├── الواجهة.alif │ ├── alifcore.cc │ ├── التشفير.alif │ ├── الملفات.alif │ ├── الرياضيات.alif │ ├── webui.hpp │ └── utf8 │ │ ├── unchecked.h │ │ └── core.h ├── examples │ ├── helloworld.alif │ ├── webui.alif │ └── ui.html ├── utf8.h ├── alif_next_break.hpp ├── alif_if_else.hpp ├── alif_namespace.hpp ├── alif_class.hpp ├── alif_var_g_class.hpp ├── alif_function_call.hpp ├── alif_operator.hpp ├── alif_var.hpp ├── CMakeLists.txt ├── utf8 │ ├── unchecked.h │ ├── core.h │ └── checked.h ├── alif_return.hpp ├── alif_var_g.hpp ├── alif_end.hpp ├── alif_control.hpp └── alif_macro.hpp ├── اختبارات ├── أكواد │ ├── دالة_رئيسية │ │ ├── أساسي.alif │ │ └── أساسي_توقع.yml │ ├── طباعة │ │ ├── اطبع.alif │ │ └── اطبع_توقع.yml │ ├── الإدخال │ │ ├── ادخل_رقما.alif │ │ └── ادخل_رقما_توقع.yml │ ├── كلما │ │ ├── اصغر.alif │ │ ├── اكبر.alif │ │ ├── اصغر_توقع.yml │ │ └── اكبر_توقع.yml │ └── مكتبات │ │ ├── الرياضيات_توقع.yml │ │ └── الرياضيات.alif ├── قالب_التوقع.yml └── مساعدات.py ├── .gitignore ├── makefile ├── إعداد_للتطوير.py ├── .خطافات_جيت └── pre-commit ├── CMakeLists.txt ├── .github └── workflows │ └── بناء-واختبارات.yml └── README.md /aliflib: -------------------------------------------------------------------------------- 1 | src/aliflib/ -------------------------------------------------------------------------------- /examples: -------------------------------------------------------------------------------- 1 | src/examples/ -------------------------------------------------------------------------------- /src/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false 4 | } -------------------------------------------------------------------------------- /اختبارات/أكواد/دالة_رئيسية/أساسي.alif: -------------------------------------------------------------------------------- 1 | #ألف 2 | 3 | دالة رئيسية 4 | 5 | نهاية دالة -------------------------------------------------------------------------------- /اختبارات/أكواد/طباعة/اطبع.alif: -------------------------------------------------------------------------------- 1 | #ألف 2 | 3 | دالة رئيسية 4 | اطبع("سطر") 5 | نهاية دالة -------------------------------------------------------------------------------- /src/aliflib/alif.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alifcommunity/compiler/HEAD/src/aliflib/alif.ico -------------------------------------------------------------------------------- /اختبارات/أكواد/الإدخال/ادخل_رقما.alif: -------------------------------------------------------------------------------- 1 | #ألف 2 | 3 | دالة رئيسية 4 | عدد ع = قراءة_عدد() 5 | اطبع(ع) 6 | نهاية دالة -------------------------------------------------------------------------------- /src/aliflib/libwebui_linux_x86_64.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alifcommunity/compiler/HEAD/src/aliflib/libwebui_linux_x86_64.a -------------------------------------------------------------------------------- /src/aliflib/libwebui_win_x86_64.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alifcommunity/compiler/HEAD/src/aliflib/libwebui_win_x86_64.a -------------------------------------------------------------------------------- /اختبارات/أكواد/كلما/اصغر.alif: -------------------------------------------------------------------------------- 1 | #ألف 2 | دالة رئيسية 3 | عدد أ = 0 4 | كلما أ < 10 5 | أ = أ + 1 6 | اطبع(أ) 7 | نهاية كلما 8 | نهاية دالة 9 | -------------------------------------------------------------------------------- /اختبارات/أكواد/كلما/اكبر.alif: -------------------------------------------------------------------------------- 1 | #ألف 2 | دالة رئيسية 3 | عدد أ = 11 4 | كلما أ > 1 5 | أ = أ - 1 6 | اطبع(أ) 7 | نهاية كلما 8 | نهاية دالة 9 | -------------------------------------------------------------------------------- /اختبارات/أكواد/دالة_رئيسية/أساسي_توقع.yml: -------------------------------------------------------------------------------- 1 | تجميع: 2 | خرج: "" 3 | خطأ: "" 4 | رمز_الخروج: 0 5 | 6 | تنفيذ: 7 | - خرج: "" 8 | خطأ: "" 9 | رمز_الخروج: 0 10 | -------------------------------------------------------------------------------- /اختبارات/أكواد/طباعة/اطبع_توقع.yml: -------------------------------------------------------------------------------- 1 | تجميع: 2 | خرج: "" 3 | خطأ: "" 4 | رمز_الخروج: 0 5 | 6 | تنفيذ: 7 | - خرج: | 8 | سطر 9 | 10 | خطأ: "" 11 | رمز_الخروج: 0 12 | -------------------------------------------------------------------------------- /اختبارات/قالب_التوقع.yml: -------------------------------------------------------------------------------- 1 | تجميع: 2 | خرج: "" 3 | خطأ: "" 4 | رمز_الخروج: 0 5 | 6 | تنفيذ: 7 | - دخل: 8 | - "" 9 | خرج: 10 | - "" 11 | خطأ: 12 | - "" 13 | رمز_الخروج: 0 14 | -------------------------------------------------------------------------------- /src/examples/helloworld.alif: -------------------------------------------------------------------------------- 1 | #ألف 2 | 3 | دالة رئيسية 4 | 5 | اطبع("مرحبا!" + سطر) 6 | اطبع("ماهو إسمك ؟ ") 7 | 8 | نص م = قراءة_نص() 9 | 10 | اطبع("أهلا بك " + م) 11 | 12 | قراءة_نص() 13 | نهاية دالة -------------------------------------------------------------------------------- /اختبارات/أكواد/الإدخال/ادخل_رقما_توقع.yml: -------------------------------------------------------------------------------- 1 | تجميع: 2 | خرج: "" 3 | خطأ: "" 4 | رمز_الخروج: 0 5 | 6 | تنفيذ: 7 | - دخل: 8 | - 123 9 | خرج: 10 | - | 11 | 123 12 | 13 | خطأ: 14 | - "" 15 | رمز_الخروج: 0 16 | -------------------------------------------------------------------------------- /اختبارات/أكواد/مكتبات/الرياضيات_توقع.yml: -------------------------------------------------------------------------------- 1 | تجميع: 2 | خرج: "" 3 | خطأ: "" 4 | رمز_الخروج: 0 5 | 6 | تنفيذ: 7 | - خرج: | 8 | 0 9 | 1 10 | -1.224646799147353e-16 11 | 1 12 | 0.3 13 | 2 14 | 15 | خطأ: "" 16 | رمز_الخروج: 0 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | venv/ 2 | build/ 3 | /اختبارات/أكواد/**/*_تنفيذي 4 | /اختبارات/أكواد/**/*_سجل 5 | 6 | .ccls-cache/ 7 | __pycache__/ 8 | 9 | logs/ 10 | *.logs 11 | *.log 12 | *.سجل 13 | 14 | exe/ 15 | *.exe 16 | 17 | obj/ 18 | *.obj 19 | 20 | o/ 21 | *.o 22 | 23 | *.vscode/ 24 | .vim/ 25 | examples/test.alif.json 26 | -------------------------------------------------------------------------------- /اختبارات/أكواد/كلما/اصغر_توقع.yml: -------------------------------------------------------------------------------- 1 | تجميع: 2 | خرج: "" 3 | خطأ: "" 4 | رمز_الخروج: 0 5 | 6 | تنفيذ: 7 | - خرج: | 8 | 1 9 | 2 10 | 3 11 | 4 12 | 5 13 | 6 14 | 7 15 | 8 16 | 9 17 | 10 18 | 19 | خطأ: "" 20 | دخل: null 21 | رمز_الخروج: 0 22 | -------------------------------------------------------------------------------- /اختبارات/أكواد/كلما/اكبر_توقع.yml: -------------------------------------------------------------------------------- 1 | تجميع: 2 | خرج: "" 3 | خطأ: "" 4 | رمز_الخروج: 0 5 | 6 | تنفيذ: 7 | - خرج: | 8 | 10 9 | 9 10 | 8 11 | 7 12 | 6 13 | 5 14 | 4 15 | 3 16 | 2 17 | 1 18 | 19 | خطأ: "" 20 | دخل: null 21 | رمز_الخروج: 0 22 | -------------------------------------------------------------------------------- /اختبارات/أكواد/مكتبات/الرياضيات.alif: -------------------------------------------------------------------------------- 1 | #ألف 2 | 3 | #مكتبة "الرياضيات" 4 | 5 | دالة رئيسية 6 | اطبع(رياضيات:جا(30 / 180 * رياضيات:ط)) -- 0.5 7 | اطبع(رياضيات:جتا(60 / 180 * رياضيات:ط)) -- 0.5 8 | اطبع(رياضيات:ظا(رياضيات:ط)) -- 0 9 | اطبع(رياضيات:مطلق(-1)) -- 1 10 | اطبع(رياضيات:جا(رياضيات:قجا(0.3))) -- 0.3 11 | اطبع(رياضيات:جذر٣(8)) -- 2 12 | نهاية دالة -------------------------------------------------------------------------------- /src/aliflib/الوقت.alif: -------------------------------------------------------------------------------- 1 | -- ------------------------ 2 | -- مكتبة الوقت 3 | -- ------------------------ 4 | 5 | #ألف 6 | 7 | #إذا ماك أضف_ترجمة_بداية " " 8 | #إذا ماك أضف_تجميع_بداية " " 9 | 10 | #إذا ويندوز أضف_ترجمة_بداية " " 11 | #إذا ويندوز أضف_تجميع_بداية " " 12 | 13 | #إذا لينكس أضف_ترجمة_بداية " " 14 | #إذا لينكس أضف_تجميع_بداية " " 15 | 16 | '---------------------------- 17 | 18 | دالة نم (عدد أجزاء_الثانية) 19 | _س_ 20 | long ms = (long) @أجزاء_الثانية@; 21 | boost::system_time t = boost::get_system_time(); 22 | t += boost::posix_time::milliseconds(ms); 23 | boost::thread::sleep(t); 24 | _س_ 25 | نهاية دالة 26 | 27 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build prepare tests tests-* 2 | 3 | ifeq ($(OS),Windows_NT) 4 | build: 5 | rd /s /q build && mkdir build && cd build && cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release && mingw32-make && mingw32-make install 6 | else 7 | build: 8 | mkdir -p build && cd build && cmake .. && make && sudo make install 9 | endif 10 | 11 | prepare: 12 | python ./إعداد_للتطوير.py 13 | 14 | prepare-tests: 15 | python ./إعداد_للتطوير.py اختبارات 16 | 17 | tests: 18 | python ./اختبارات/اختبر 19 | 20 | tests-syntax: 21 | python ./اختبارات/اختبر -ق 22 | 23 | tests-fill: 24 | python ./اختبارات/اختبر -ك 25 | 26 | tests-renew: 27 | python ./اختبارات/اختبر -ك 28 | -------------------------------------------------------------------------------- /src/examples/webui.alif: -------------------------------------------------------------------------------- 1 | #ألف 2 | 3 | #مكتبة "الواجهة" 4 | #مكتبة "الوقت" 5 | 6 | 7 | #نص شيفرة_إتش_تي_إم_إل "ui.html" 8 | كائن نافذتي = الواجهة (شيفرة_إتش_تي_إم_إل) 9 | 10 | 11 | دالة نافذتي_حدث 12 | 13 | اطبع("Click!" + سطر) 14 | 15 | نهاية دالة 16 | 17 | 18 | دالة رئيسية 19 | 20 | نافذتي : ربط ( "MyButton1" ، نافذتي_حدث ) 21 | نافذتي : إظهار () 22 | 23 | اطبع ("Please wait 1 second.. \n") 24 | نم (1000) 25 | 26 | اطبع ("Please wait another one!.. \n") 27 | نم (1000) 28 | 29 | اطبع ("Run JavaScript.. \n") 30 | نص النتيجة = نافذتي : جافاسكريبت ( " document.getElementById(\"تجربة\").innerHTML = \"مرحبا من ألف !\"; " ) 31 | 32 | نافذتي : إنتظار () 33 | 34 | نهاية دالة -------------------------------------------------------------------------------- /src/aliflib/الخوارزميات.alif: -------------------------------------------------------------------------------- 1 | -- ------------------------ 2 | -- مكتبة الخوارزميات 3 | -- ------------------------ 4 | 5 | #ألف 6 | 7 | #إذا ماك أضف_ترجمة_بداية " " 8 | #إذا ماك أضف_تجميع_بداية " " 9 | 10 | #إذا ويندوز أضف_ترجمة_بداية " " 11 | #إذا ويندوز أضف_تجميع_بداية " " 12 | 13 | #إذا لينكس أضف_ترجمة_بداية " " 14 | #إذا لينكس أضف_تجميع_بداية " " 15 | 16 | '---------------------------- 17 | 18 | دالة نص استبدال (نص الجملة، نص الكلمة، نص الكلمة_الجديدة) 19 | نص م = الجملة 20 | _س_ boost::replace_all(@م@, @الكلمة@, @الكلمة_الجديدة@); _س_ 21 | إرجاع م 22 | نهاية دالة 23 | 24 | '---------------------------- 25 | 26 | دالة نص تقليم_يمين (نص الجملة) 27 | نص م = الجملة 28 | _س_ alifcore_rtrim(@م@); _س_ 29 | إرجاع م 30 | نهاية دالة 31 | 32 | '---------------------------- 33 | 34 | دالة نص تقليم_يسار (نص الجملة) 35 | نص م = الجملة 36 | _س_ alifcore_ltrim(@م@); _س_ 37 | إرجاع م 38 | نهاية دالة 39 | 40 | '---------------------------- 41 | 42 | دالة نص تقليم (نص الجملة) 43 | نص م = الجملة 44 | _س_ alifcore_trim(@م@); _س_ 45 | إرجاع م 46 | نهاية دالة 47 | 48 | '---------------------------- 49 | 50 | -------------------------------------------------------------------------------- /src/aliflib/النظام.alif: -------------------------------------------------------------------------------- 1 | -- ------------------------ 2 | -- مكتبة النظام 3 | -- ------------------------ 4 | 5 | #ألف 6 | 7 | #إذا ماك أضف_ترجمة_بداية " " 8 | #إذا ماك أضف_تجميع_بداية " " 9 | 10 | #إذا ويندوز أضف_ترجمة_بداية " " 11 | #إذا ويندوز أضف_تجميع_بداية " " 12 | 13 | #إذا لينكس أضف_ترجمة_بداية " " 14 | #إذا لينكس أضف_تجميع_بداية " " 15 | 16 | '---------------------------- 17 | 18 | _س_ 19 | // Workaround for a boost/mingw bug. 20 | // This must occur before the inclusion of the boost/process.hpp header. 21 | // Taken from https://github.com/boostorg/process/issues/96 22 | #ifndef __kernel_entry 23 | #define __kernel_entry 24 | #endif 25 | #include 26 | //#include // windows::hide 27 | _س_ 28 | 29 | '---------------------------- 30 | 31 | صنف النظام 32 | 33 | دالة أمر (نص الأمر) 34 | _س_ 35 | boost::process::child c(@الأمر@); 36 | c.wait(); 37 | _س_ 38 | نهاية دالة 39 | 40 | دالة نص نوع_ملف_تطبيق () 41 | نص م 42 | _س_ 43 | @م@ = alifcore_inf.exe_ext; 44 | _س_ 45 | إرجاع م 46 | نهاية دالة 47 | 48 | دالة نص نوع () 49 | نص م 50 | _س_ 51 | #ifdef _WIN32 52 | @م@ = "ويندوز"; 53 | #elif __APPLE__ 54 | @م@ = "ماك"; 55 | #else 56 | @م@ = "لينكس"; 57 | #endif 58 | _س_ 59 | إرجاع م 60 | نهاية دالة 61 | 62 | نهاية صنف 63 | -------------------------------------------------------------------------------- /إعداد_للتطوير.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import os 4 | import subprocess 5 | from اختبارات.مساعدات import run, print_err, print_title 6 | 7 | 8 | path = os.path 9 | sys = os.sys 10 | 11 | 12 | def print_tit(*lines): 13 | print_title(*lines, level=2, indent="", top_line=False) 14 | 15 | 16 | def config_git_hooks(): 17 | print_tit("إعداد خطافات جيت") 18 | cmd = "git config --local core.hooksPath ./.خطافات_جيت" 19 | exit_code = os.system(cmd) 20 | if exit_code: 21 | print_err("حدث مشكلة أثناء إعداد خطافات جيت، يرجى إعدادها يدويها وإعداد المشروع للتطوير مجددا") 22 | print("-" * 35) 23 | print(cmd) 24 | exit(1) 25 | print("تم بنجاح") 26 | 27 | 28 | def prepare_tests(): 29 | print_tit("تجهيز للاختبارات") 30 | 31 | try: 32 | import yaml 33 | import colors 34 | except ImportError: 35 | cmd = "pip install pyyaml ansicolors" 36 | exit_code = os.system(cmd) 37 | if exit_code: 38 | print_err("حدث مشكلة أثناء تنصيب حزمة بيب، يرجى تنصيبها يدويها وإعداد المشروع للتطوير مجددا") 39 | print("-" * 35) 40 | print(cmd) 41 | exit(1) 42 | 43 | print("تم بنجاح") 44 | 45 | 46 | if __name__ == "__main__": 47 | what_to_prepare = sys.argv[1] if len(sys.argv) > 1 else '' 48 | 49 | if what_to_prepare == "اختبارات": 50 | prepare_tests() 51 | exit(0) 52 | 53 | prepare_tests() 54 | config_git_hooks() 55 | 56 | -------------------------------------------------------------------------------- /src/utf8.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 28 | #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | 30 | #include "utf8/checked.h" 31 | #include "utf8/unchecked.h" 32 | 33 | #endif // header guard 34 | -------------------------------------------------------------------------------- /src/aliflib/utf8.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 28 | #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | 30 | #include "utf8/checked.h" 31 | #include "utf8/unchecked.h" 32 | 33 | #endif // header guard 34 | -------------------------------------------------------------------------------- /src/aliflib/alifstandardlib.alif: -------------------------------------------------------------------------------- 1 | -- --------------------------------------------------------- 2 | -- (C)2021 Hassan DRAGA. 3 | -- (C)2021 Alif Community. 4 | -- www.aliflang.org 5 | -- --------------------------------------------------------- 6 | -- The Alif Standard Library - مكتبات ألف القياسية 7 | -- ** This code is released under the GNU LGPLv3 Licence ** 8 | -- --------------------------------------------------------- 9 | 10 | #ألف 11 | 12 | _س_ 13 | 14 | _س_ 15 | 16 | '---------------------------- 17 | 18 | #إذا ماك أضف_ترجمة " " 19 | #إذا ماك أضف_تجميع " " 20 | 21 | #إذا ويندوز أضف_ترجمة " -Wno-deprecated -municode -Wa,-mbig-obj -fvisibility=hidden -Wall -O3 -std=gnu++17 -O3 -DNDEBUG -DBOOST_LOCALE_HIDE_AUTO_PTR " 22 | #إذا ويندوز أضف_تجميع " -Os -static-libgcc -static-libstdc++ -static -m64 -finput-charset=utf-8 -mthreads " 23 | #إذا ويندوز أضف_تجميع " -lboost_thread-mgw8-mt-s-x64-1_76 -lboost_date_time-mgw8-mt-s-x64-1_76 -lboost_filesystem-mgw8-mt-s-x64-1_76 -lboost_regex-mgw8-mt-s-x64-1_76 -lboost_nowide-mgw8-mt-s-x64-1_76 -lboost_locale-mgw8-mt-s-x64-1_76 -liconv " 24 | 25 | #إذا لينكس أضف_ترجمة " -Wall -std=gnu++17 -m64 -finput-charset=utf-8 -O3 -pthread -DNDEBUG -fvisibility=hidden " 26 | #إذا لينكس أضف_تجميع " -std=gnu++17 -Os -m64 -finput-charset=utf-8 -pthread -lboost_filesystem -lboost_system -lboost_thread " 27 | 28 | '---------------------------- 29 | 30 | دالة اطبع (نص الجملة) 31 | _س_ 32 | std::cout << @الجملة@ << std::endl; 33 | _س_ 34 | نهاية دالة 35 | 36 | دالة عدد قراءة_عدد () 37 | عدد م 38 | _س_ 39 | std::cin >> @م@; 40 | _س_ 41 | إرجاع م 42 | نهاية دالة 43 | 44 | دالة نص قراءة_نص () 45 | نص م 46 | _س_ 47 | std::getline (cin, @م@); 48 | _س_ 49 | إرجاع م 50 | نهاية دالة 51 | 52 | '---------------------------- 53 | 54 | 55 | -------------------------------------------------------------------------------- /.خطافات_جيت/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | RED="\e[31m" 3 | GREEN="\e[32m" 4 | NC="\e[0m" 5 | 6 | all_c_like_files=() 7 | all_prettier_files=() 8 | 9 | while read -r file_path; do 10 | file_path="$(printf "${file_path}")" # convert unicode numbers into carachters 11 | file_path="$(eval "echo ${file_path}")" # remove quotation if exists 12 | echo "${file_path}" | 13 | grep -E '.(c|cc|cpp|hpp|h)$' >& /dev/null && 14 | all_c_like_files+=(${file_path}) 15 | echo "${file_path}" | 16 | grep -E '.(yml|yaml|json|js|css|html|md|mdx)$' >& /dev/null && 17 | all_prettier_files+=(${file_path}) 18 | done < <(git diff --cached --diff-filter=d --name-only) 19 | # echo "${all_files[@]}"; exit 0 20 | 21 | if (( ${#all_c_like_files} )); then 22 | clang_format_exit_code=$? 23 | fi 24 | 25 | print_success() { echo -e "${GREEN}✔ $1 succeeded:${NC} Files are formatted [̲̅$̲̅(̲̅ ͡° ͜ʖ ͡°̲̅)̲̅$̲̅]"; } 26 | print_failure() { echo -e "${RED}✘ $1 failed:${NC} failed with code $2, ( ͡ಥ ͜ʖ ͡ಥ)"; } 27 | 28 | if (( ${#all_c_like_files} )); then 29 | clang-format -i "${all_c_like_files[@]}" 30 | clang_format_exit_code=$? 31 | if (( $clang_format_exit_code )); then 32 | print_failure "clang-format" $clang_format_exit_code 33 | exit_code=1 34 | else 35 | print_success "clang-format" 36 | fi 37 | git add -f "${all_c_like_files[@]}" 38 | fi 39 | 40 | if (( ${#all_prettier_files} )); then 41 | prettier -v >& /dev/null 42 | if [ $? = 0 ]; then 43 | prettier -w "${all_prettier_files[@]}" 44 | prettier_exit_code=$? 45 | if (( $prettier_exit_code )); then 46 | print_failure "prettier" $prettier_exit_code 47 | exit_code=1 48 | else 49 | print_success "prettier" 50 | fi 51 | git add -f "${all_prettier_files[@]}" 52 | fi 53 | fi 54 | 55 | 56 | exit $exit_code 57 | -------------------------------------------------------------------------------- /src/alif_next_break.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_NextBreak(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | // التالي - كسر 27 | 28 | if (!o_tokens->TOKENS_PREDEFINED) 29 | return; // continue; 30 | 31 | if (!IsInsideFunction) 32 | ErrorCode("يجب استعمال ' " + Token[1] + " ' داخل دالة", o_tokens); 33 | 34 | if (ALIF_LOOP_STATUS < 1) 35 | ErrorCode("يجب استعمال ' " + Token[1] + " ' داخل جملة تكرارية \"كلما\" ", 36 | o_tokens); 37 | 38 | if (Token[2] != "") 39 | ErrorCode("أمر غير معروف : ' " + Token[2] + 40 | " '، على العموم لايجب وضع أي شيئ بعد ' " + Token[1] + " ' ' ", 41 | o_tokens); 42 | 43 | if (Token[1] == "التالي") 44 | { 45 | if (DEBUG) 46 | DEBUG_MESSAGE("[Continue] \n\n", o_tokens); // DEBUG 47 | 48 | // *** Generate Code *** 49 | if (!IsInsideNamespace) 50 | { 51 | // Global Fun IF 52 | CPP_GLOBAL_FUN.append("\n continue; \n "); 53 | } 54 | else 55 | { 56 | // Local Fun IF 57 | cpp_AddScript(TheFunction, "\n continue; \n "); 58 | } 59 | // *** *** *** *** *** *** 60 | } 61 | else 62 | { 63 | if (DEBUG) 64 | DEBUG_MESSAGE("[Break] \n\n", o_tokens); // DEBUG 65 | 66 | // *** Generate Code *** 67 | if (!IsInsideNamespace) 68 | { 69 | // Global Fun IF 70 | CPP_GLOBAL_FUN.append("\n break; \n "); 71 | } 72 | else 73 | { 74 | // Local Fun IF 75 | cpp_AddScript(TheFunction, "\n break; \n "); 76 | } 77 | // *** *** *** *** *** *** 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13.0) 2 | 3 | # --[ Alif version ] --------------------------------------------------------------- 4 | 5 | project(AlifProject VERSION 3.0.33 DESCRIPTION "Alif Programming Language - Compiler.") 6 | message("-- [ Alif version ${CMAKE_PROJECT_VERSION} ]") 7 | 8 | # --[ Uninstall ] ------------------------------------------------------------------ 9 | 10 | if(TARGET uninstall) 11 | message("[!] By default, CMake does not provide the 'uninstall' target.") 12 | message("[!] If you want to uninstall your project You need to delete the files listed in 'install_manifest.txt' file.") 13 | return() 14 | endif() 15 | 16 | # --[ C++ Compiler ] --------------------------------------------------------------- 17 | 18 | if (WIN32) 19 | if(EXISTS "C:/Alif3/") 20 | 21 | # Windows - MinGW64 - Boost 22 | message("[*] Switch default compiler to 'C:/Alif3/gcc'") 23 | set(CMAKE_C_COMPILER "C:/Alif3/gcc/bin/gcc.exe") 24 | set(CMAKE_C_COMPILER:FILEPATH "C:/Alif3/gcc/bin/gcc.exe") 25 | set(CMAKE_CXX_COMPILER "C:/Alif3/gcc/bin/g++.exe") 26 | set(CMAKE_CXX_COMPILER:FILEPATH "C:/Alif3/gcc/bin/g++.exe") 27 | 28 | endif() 29 | endif() 30 | 31 | # --[ Boost ] ---------------------------------------------------------------------- 32 | 33 | set(Boost_Version_Needed "1.74.0") 34 | 35 | if (WIN32) 36 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 37 | 38 | IF(EXISTS "C:/Alif3/") 39 | # Windows - MinGW64 - Boost 40 | set(Boost_Root "C:/Alif3/boost/include") 41 | set(Boost_Lib "C:/Alif3/boost/lib") 42 | endif() 43 | 44 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") 45 | 46 | # Remove this line to force building Alif compiler using MSVC. 47 | message("[!] Sorry. Alif don't support Microsoft C++ compiler on Windows, Please use MinGW64.") 48 | return() 49 | 50 | IF(EXISTS "C:/Alif3/") 51 | # Windows - Microsoft C++ - Boost 52 | set(Boost_Root "C:/Alif3/boost/include") 53 | set(Boost_Lib "C:/Alif3/boost/lib") 54 | endif() 55 | 56 | endif() 57 | endif() 58 | 59 | # --[ C++ ] ------------------------------------------------------------------------ 60 | 61 | set(CMAKE_CXX_STANDARD 17) 62 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 63 | 64 | # --[ Directories ] ---------------------------------------------------------------- 65 | 66 | # Alif Compiler Source Code 67 | add_subdirectory(${AlifProject_SOURCE_DIR}/src Alif) 68 | -------------------------------------------------------------------------------- /src/alif_if_else.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_IfElse(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | // وإلا 27 | 28 | if (!o_tokens->TOKENS_PREDEFINED) 29 | return; // continue; 30 | 31 | if (!IsInsideFunction) 32 | ErrorCode("يجب استعمال الشرط داخل دالة", o_tokens); 33 | 34 | if (ALIF_IF_STATUS < 1) 35 | ErrorCode("لايمكن إستعمال ' وإلا ' من دون فتح شرط، ربمى تقصد ' إذا ' ", 36 | o_tokens); 37 | 38 | if (Token[2] == "إذا") 39 | ErrorCode("شرط غير صحيح، هل تقصد ' أو إذا ' ؟ ", o_tokens); 40 | 41 | if (Token[2] != "") 42 | ErrorCode( 43 | "أمر غير معروف : ' " + Token[2] + 44 | " '، على العموم إذا كنت تقصد شرط جديد المرجو إستعمال ' إذا ' ", 45 | o_tokens); 46 | 47 | if (DEBUG) 48 | DEBUG_MESSAGE("[ELSE " + IntToString(ALIF_IF_STATUS) + "] \n\n", 49 | o_tokens); // DEBUG 50 | 51 | // TODO: show error when double Else 52 | // if ... 53 | // else ... 54 | // else ... 55 | // end if 56 | 57 | /* 58 | // *** Generate Code *** 59 | if (!IsInsideNamespace) 60 | { 61 | // Global Fun IF 62 | CPP_GLOBAL_FUN.append("\n } else { \n "); 63 | } 64 | else 65 | { 66 | // Local Fun IF 67 | cpp_AddScript(TheFunction, "\n } else { \n "); 68 | } 69 | // *** *** *** *** *** *** 70 | */ 71 | 72 | if (IsInsideClass) 73 | { 74 | // just for fixing this ... 75 | // *** Generate Code *** 76 | CPP_CLASS.append("\n } else { "); 77 | // *** *** *** *** *** *** 78 | } 79 | else if (!IsInsideNamespace) 80 | { 81 | // Global Fun IF 82 | CPP_GLOBAL_FUN.append("\n } else { "); 83 | } 84 | else 85 | { 86 | // Local Fun IF 87 | cpp_AddScript(TheFunction, "\n } else { "); 88 | } 89 | // *** *** *** *** *** *** 90 | 91 | return; // continue; 92 | } 93 | -------------------------------------------------------------------------------- /src/alif_namespace.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_new_namespace(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | 27 | // namespace abc 28 | 29 | if (IsInsideNamespace) 30 | ErrorCode("لا يمكن انشاء مجال داخل مجال، المجال الحالية : " + TheNamespace, 31 | o_tokens); 32 | 33 | if (IsInsideClass) 34 | ErrorCode("لا يمكن انشاء مجال داخل صنف : " + TheClass, o_tokens); 35 | 36 | if (IsInsideFunction) 37 | ErrorCode("لا يمكن انشاء مجال داخل دالة : " + TheFunction, o_tokens); 38 | 39 | if (Token[2] == "") 40 | ErrorCode("يجب تحديد اسم المجال", o_tokens); 41 | 42 | if (Token[3] != "") 43 | ErrorCode("أمر غير معروف : ' " + Token[3] + " ' ", o_tokens); 44 | 45 | // temporary set because this namespace 46 | // did not get created yet, but we need 47 | // his Generated ID now. 48 | // TheNamespace = Token[2]; 49 | 50 | if (!IsValidName(Token[2], o_tokens)) 51 | ErrorCode("اسم غير مقبول : ' " + Token[2] + " ' ", o_tokens); 52 | 53 | CheckForSameGlobalID(Token[2], o_tokens); 54 | 55 | if (!o_tokens->TOKENS_PREDEFINED) 56 | { 57 | 58 | if (namespace_is_set[Token[2]]) 59 | ErrorCode("المجال ' " + Token[2] + " ' تم انشاؤها مسبقا في السطر : " + 60 | namespace_at_line[Token[2]], 61 | o_tokens); 62 | 63 | namespace_is_set[Token[2]] = true; 64 | namespace_at_line[Token[2]] = IntToString(o_tokens->Line); 65 | SET_GLOBAL_C_NAME( 66 | Token[2]); // TODO: is okay (SET_C_NAME -> SET_GLOBAL_C_NAME) ? 67 | 68 | IsInsideNamespace = true; // Need by Tokens Predefined 69 | TheNamespace = Token[2]; // Need by Tokens Predefined 70 | 71 | // temporary end 72 | // TheNamespace = ""; 73 | 74 | return; // continue; 75 | } 76 | 77 | IsInsideNamespace = true; 78 | TheNamespace = Token[2]; 79 | 80 | if (DEBUG) 81 | DEBUG_MESSAGE("[NAMESPACE] [" + Token[2] + "] \n\n", o_tokens); // DEBUG 82 | 83 | // CPP_GLOBAL.append(" bool WINDOW_IS_SHOW_" + ID[Token[2]] + " = false; \n"); 84 | CPP_GLOBAL_FUN.append(" namespace NS_" + ID[Token[2]] + " { \n"); 85 | } 86 | -------------------------------------------------------------------------------- /src/alif_class.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_Class(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | //صنف 27 | 28 | if (IsInsideClass) 29 | ErrorCode("لا يمكن إنشاء صنف داخل صنف، الصنف الحالي : " + TheClass, 30 | o_tokens); 31 | 32 | if (IsInsideFunction) 33 | ErrorCode("لا يمكن أنشاء صنف داخل دالة، يجب إنشائها في المجال عام فقط", 34 | o_tokens); 35 | 36 | if (IsInsideNamespace) 37 | ErrorCode("لا يمكن أنشاء صنف داخل مجال، يجب إنشائها في المجال عام فقط", 38 | o_tokens); 39 | 40 | if (Token[2] == "") 41 | ErrorCode("يجب اعطاء اسم لهدا الصنف الجديدة", o_tokens); 42 | 43 | if (Token[3] != "" && Token[3] != "(") 44 | ErrorCode("أمر غير معروف : ' " + Token[3] + " ' ", o_tokens); 45 | 46 | if (Token[3] == "(") 47 | ErrorCode("الصنف لا يقبل خصائص ' ( ' ", o_tokens); 48 | 49 | if (!IsValidName(Token[2], o_tokens)) 50 | ErrorCode("تعريف غير مقبول : ' " + Token[2] + " ' ", o_tokens); 51 | 52 | // TODO: Check if extended from other class 53 | 54 | if (!o_tokens->TOKENS_PREDEFINED) 55 | { 56 | if (CLASS_IS_SET[Token[2]]) 57 | ErrorCode("الصنف ' " + Token[2] + " ' تم انشاؤه مسبقا في السطر رقم : " + 58 | CLASS_AT_LINE[Token[2]], 59 | o_tokens); 60 | 61 | // if already any other type of global var exist 62 | CheckForSameGlobalID(Token[2], o_tokens); 63 | 64 | // Add New Class 65 | CLASS_IS_SET[Token[2]] = true; 66 | CLASS_AT_LINE[Token[2]] = IntToString(o_tokens->Line); 67 | 68 | IsInsideClass = true; 69 | TheClass = Token[2]; 70 | 71 | SET_GLOBAL_C_NAME(Token[2]); 72 | 73 | return; // continue; 74 | } 75 | 76 | IsInsideClass = true; 77 | TheClass = Token[2]; 78 | 79 | // TheNamespace = TheClass; // < ======================================= TODO: 80 | // TO BE CHECK IF THIS WORKAROUND WORK FINE !!!!!! 81 | 82 | if (DEBUG) 83 | DEBUG_MESSAGE("[NEW CLASS] [" + Token[2] + "] \n\n", o_tokens); // DEBUG 84 | 85 | // *** Generate Code *** 86 | // New Class 87 | CPP_CLASS.append(" class CLASS_" + Global_ID[Token[2]] + " { \n"); 88 | // *** *** *** *** *** *** 89 | 90 | return; // continue; 91 | } 92 | -------------------------------------------------------------------------------- /src/examples/ui.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 76 | 77 | 78 | 79 |
80 |
81 |

من فظلك إنتظر ثانية..

82 |
83 |

إضغط على الزر لتنفيذ دلة نافذتي_حدث()

84 | 85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /.github/workflows/بناء-واختبارات.yml: -------------------------------------------------------------------------------- 1 | name: بناء واختبارات 2 | 3 | on: 4 | push: 5 | branches: # all branches 6 | - "**" 7 | tags-ignore: # ignore pushing tags 8 | - "**" 9 | paths-ignore: 10 | - "README.md" 11 | 12 | pull_request: 13 | branches: 14 | - main 15 | tags-ignore: # ignore pushing tags 16 | - "**" 17 | paths-ignore: 18 | - "README.md" 19 | 20 | release: 21 | types: 22 | - published 23 | 24 | workflow_dispatch: 25 | inputs: 26 | allTests: 27 | description: "اختبارات كاملة ترجمةً وتنفيذًا؟ (نعم/لا)" 28 | required: true 29 | default: "نعم" 30 | 31 | env: 32 | BUILD_TYPE: Release 33 | BOOST_VER: 1.79.0 34 | BOOST_LIBS: filesystem program_options system locale date_time regex nowide thread 35 | 36 | jobs: 37 | GCC-Linux: 38 | runs-on: ubuntu-latest 39 | 40 | steps: 41 | - uses: actions/checkout@v2 42 | 43 | - name: تخبئة بوست 44 | uses: actions/cache@v2 45 | with: 46 | path: "${{ runner.workspace }}/boost_*.tar.gz" 47 | key: "boost-${{env.BOOST_VER}}" 48 | 49 | - name: بناء بوست 50 | id: boost 51 | uses: egor-tensin/build-boost@v1 52 | with: 53 | version: ${{env.BOOST_VER}} 54 | libraries: ${{env.BOOST_LIBS}} 55 | platform: x64 56 | configuration: ${{env.BUILD_TYPE}} 57 | 58 | - name: صنع بيئة للبناء 59 | run: | 60 | sudo cp -r ${{steps.boost.outputs.root}}/boost /usr/include/boost 61 | sudo cp -r ${{steps.boost.outputs.librarydir}}/* /usr/lib/ 62 | sudo ldconfig 63 | cmake -E make_directory ${{github.workspace}}/build 64 | 65 | - name: إعداد CMake 66 | env: 67 | BOOST_ROOT: ${{steps.boost.outputs.root}} 68 | BOOST_LIBRARYDIR: ${{steps.boost.outputs.librarydir}} 69 | working-directory: ${{github.workspace}}/build 70 | run: cmake $GITHUB_WORKSPACE 71 | 72 | - name: بناء المترجم 73 | working-directory: ${{github.workspace}}/build 74 | run: | 75 | make 76 | sudo make install 77 | 78 | - name: تجهيز للاختبارات 79 | run: make prepare-tests 80 | 81 | - name: اختبارات القواعد 82 | run: make tests-syntax 83 | 84 | - name: اختبارات كاملة 85 | if: ${{ github.event_name == 'release' || github.event.inputs.allTests == 'نعم' }} 86 | run: make tests 87 | 88 | MinGW-Windows: 89 | runs-on: windows-latest 90 | 91 | steps: 92 | - uses: actions/checkout@v2 93 | 94 | - name: Cache Boost 95 | uses: actions/cache@v2 96 | with: 97 | path: "${{ runner.workspace }}/boost_*.tar.gz" 98 | key: "boost-${{env.BOOST_VER}}" 99 | 100 | - name: Build Boost 101 | id: boost 102 | uses: egor-tensin/build-boost@v1 103 | with: 104 | version: ${{env.BOOST_VER}} 105 | libraries: ${{env.BOOST_LIBS}} 106 | platform: x64 107 | configuration: ${{env.BUILD_TYPE}} 108 | toolset: mingw 109 | static: 1 110 | static-runtime: 1 111 | directory: ${{github.workspace}}/boost 112 | 113 | - name: Create Build Environment 114 | run: cmake -E make_directory ${{github.workspace}}/build 115 | 116 | - name: Configure CMake 117 | env: 118 | BOOST_ROOT: ${{steps.boost.outputs.root}} 119 | BOOST_LIBRARYDIR: ${{steps.boost.outputs.librarydir}} 120 | working-directory: ${{github.workspace}}/build 121 | shell: cmd 122 | run: | 123 | cmake ${{github.workspace}} -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 124 | 125 | - name: Build 126 | working-directory: ${{github.workspace}}/build 127 | shell: cmd 128 | run: | 129 | mingw32-make 130 | -------------------------------------------------------------------------------- /اختبارات/مساعدات.py: -------------------------------------------------------------------------------- 1 | import os 2 | import subprocess 3 | from os import path, sys 4 | 5 | 6 | def run(cmd, return_prcss=False, inputs=None): 7 | process = subprocess.Popen(cmd, shell=True, 8 | stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 9 | if return_prcss: 10 | return process 11 | if inputs: 12 | stdouts = [] 13 | stderrs = [] 14 | for i in inputs: 15 | out, err = process.communicate(str(i).encode()) 16 | stdouts.append(out.decode()) 17 | stderrs.append(err.decode()) 18 | return stdouts, stderrs, process.returncode 19 | out, err = process.communicate() 20 | return out.decode(), err.decode(), process.returncode 21 | 22 | 23 | def print_title(*lines, level=1, indent=None, 24 | top_line=True, bottom_line=True, 25 | file=sys.stdout, align="center", 26 | min_width=35, max_width=0): 27 | """ 28 | print something like this, with customizations like `indent` and `level`: 29 | --------------------------- 30 | هذا سطر 31 | --------------------------- 32 | """ 33 | try: 34 | term_w = os.get_terminal_size().columns 35 | except: 36 | term_w = 100000000 37 | # min width is 35 and max width is term_w, otherwise the width will be the max length of `lines` 38 | width = min(term_w, max(min_width, *map(lambda l: len(l), lines))) 39 | # total printed line width has to be less than the terminal width 40 | if indent: 41 | width = width if len(indent) + width < term_w else term_w - len(indent) 42 | else: 43 | width = width if width < term_w else term_w 44 | levels = ["=", "-", "."] 45 | if type(level) == int: 46 | level = levels[level-1] 47 | if indent == None: 48 | if term_w < 200: 49 | a = term_w - width 50 | # `>> 1` means divide by 2 and truncate, numbers here are experimental, nothing make sense 51 | indent = ((a >> 1) - 5) * ' ' if a > 10 else '' 52 | else: 53 | indent = " " * 15 54 | if not len(indent) < term_w - 10: 55 | raise Exception( 56 | "Indentation must be smaller than term width by more than 10 chars") 57 | 58 | def print_these_lines(): 59 | nonlocal max_width 60 | max_width = max_width or term_w - len(indent) 61 | for l in lines: 62 | # if the length of a line is greater than term_w, 63 | # split it into smaller lines 64 | if len(l) > max_width: 65 | ll = [] 66 | while l: 67 | ll.append(l[0:max_width]) 68 | l = l[max_width:] 69 | l = ll 70 | l = [l] if type(l) != list else l 71 | for ll in l: 72 | indent_to_center_text = \ 73 | (width - len(ll) >> 1) * " " if align == "center" else \ 74 | (width - len(ll)) * " " if align == "end" else "" 75 | print(indent + indent_to_center_text + ll, file=file) 76 | 77 | if top_line: 78 | print(indent + level * width, file=file) 79 | print_these_lines() 80 | if bottom_line: 81 | print(indent + level * width, file=file) 82 | 83 | 84 | def print_indented(text, indent="", file=sys.stdout): 85 | """ 86 | put intial indent to the text and print the indented text 87 | """ 88 | lines = str(text).split("\n") 89 | try: 90 | term_w = os.get_terminal_size().columns 91 | except: 92 | term_w = 100000000 93 | max_width = term_w - len(indent) 94 | for l in lines: 95 | # if the length of a line is greater than term_w, 96 | # split it into smaller lines 97 | if len(l) > max_width: 98 | ll = [] 99 | while l: 100 | ll.append(l[0:max_width]) 101 | l = l[max_width:] 102 | l = ll 103 | l = [l] if type(l) != list else l 104 | for ll in l: 105 | print(indent + ll, file=file) 106 | 107 | 108 | def print_err(*msgs): 109 | """ 110 | print to the STDERR 111 | """ 112 | print(*msgs, file=sys.stderr) 113 | 114 | 115 | def is_equal(obj1, obj2): 116 | if type(obj1) == list and type(obj2) == list: 117 | for i in range(len(obj1)): 118 | if not is_equal(obj1[i], obj2[i]): 119 | return False 120 | return True 121 | elif type(obj1) == dict and type(obj2) == dict: 122 | for p in obj1: 123 | if not is_equal(obj1.get(p), obj2.get(p)): 124 | return False 125 | return True 126 | 127 | return obj1 == obj2 128 | -------------------------------------------------------------------------------- /src/aliflib/الواجهة.alif: -------------------------------------------------------------------------------- 1 | 2 | -- ------------------------ 3 | -- WebUI Library (Wraper) 4 | -- مكتبة الواجهة 5 | -- ------------------------ 6 | 7 | #ألف 8 | 9 | #إذا ماك أضف_ترجمة_بداية " " 10 | #إذا ماك أضف_تجميع_بداية " " 11 | 12 | #إذا ويندوز أضف_ترجمة_بداية " " 13 | #إذا ويندوز أضف_تجميع_بداية " -lwebui_win_x86_64 -lws2_32 -lwsock32 " 14 | 15 | #إذا لينكس أضف_ترجمة_بداية " " 16 | #إذا لينكس أضف_تجميع_بداية " -lwebui_linux_x86_64 -L/usr/local/lib " 17 | 18 | _س_ 19 | #include 20 | std::map func_ref; 21 | 22 | void __alif_webui_events(webui::event e){ 23 | 24 | // std::cout << "__alif_webui_events: Window ID: " << e.window_id << std::endl; 25 | // std::cout << "__alif_webui_events: Element ID: " << e.element_id << std::endl; 26 | // std::cout << "__alif_webui_events: Element Name: " << e.element_name << std::endl << std::endl; 27 | 28 | std::string buf; 29 | buf.append(std::to_string(e.window_id)); 30 | buf.append("_"); 31 | buf.append(e.element_name); 32 | 33 | if(func_ref[buf]) 34 | func_ref[buf](); 35 | } 36 | _س_ 37 | 38 | صنف الواجهة 39 | 40 | عدد كروم = 1 41 | عدد فايرفوكس = 2 42 | عدد إدج = 3 43 | عدد سافاري = 4 44 | 45 | _س_ 46 | private: webui::window o_window; 47 | private: std::string html; 48 | private: unsigned short window_id; 49 | _س_ 50 | 51 | دالة بناء (نص ن) 52 | إذا ن = "" 53 | _س_ 54 | html = ""; 55 | _س_ 56 | وإلا 57 | _س_ 58 | html = @ن@; 59 | _س_ 60 | نهاية إذا 61 | _س_ 62 | window_id = o_window.get_window_id(); 63 | o_window.bind_all(__alif_webui_events); 64 | _س_ 65 | نهاية دالة 66 | 67 | دالة ربط (نص ن، مؤشر_دالة م) 68 | _س_ 69 | std::string buf; 70 | buf.append(std::to_string(window_id)); 71 | buf.append("_"); 72 | buf.append(@ن@); 73 | func_ref[buf] = @م@; 74 | _س_ 75 | نهاية دالة 76 | 77 | دالة إظهار () 78 | _س_ 79 | if(!o_window.show(&html, webui::browser::chrome)) 80 | o_window.show(&html); 81 | _س_ 82 | نهاية دالة 83 | 84 | دالة إظهار_متصفح ( عدد المتصفح ) 85 | إذا المتصفح = 1 86 | _س_ 87 | if(!o_window.show(&html, webui::browser::chrome)) 88 | o_window.show(&html); 89 | _س_ 90 | أو إذا المتصفح = 2 91 | _س_ 92 | if(!o_window.show(&html, webui::browser::firefox)) 93 | o_window.show(&html); 94 | _س_ 95 | أو إذا المتصفح = 3 96 | _س_ 97 | if(!o_window.show(&html, webui::browser::edge)) 98 | o_window.show(&html); 99 | _س_ 100 | أو إذا المتصفح = 4 101 | _س_ 102 | if(!o_window.show(&html, webui::browser::safari)) 103 | o_window.show(&html); 104 | _س_ 105 | وإلا 106 | _س_ 107 | if(!o_window.show(&html, webui::browser::chrome)) 108 | o_window.show(&html); 109 | _س_ 110 | نهاية إذا 111 | نهاية دالة 112 | 113 | دالة إظهار_متصفح_مع_مسار ( عدد المتصفح، نص مسار) 114 | إذا المتصفح = 1 115 | _س_ 116 | o_window.open_window(@مسار@, webui::browser::chrome); 117 | _س_ 118 | أو إذا المتصفح = 2 119 | _س_ 120 | o_window.open_window(@مسار@, webui::browser::firefox); 121 | _س_ 122 | أو إذا المتصفح = 3 123 | _س_ 124 | o_window.open_window(@مسار@, webui::browser::edge); 125 | _س_ 126 | أو إذا المتصفح = 4 127 | _س_ 128 | o_window.open_window(@مسار@, webui::browser::safari); 129 | _س_ 130 | وإلا 131 | _س_ 132 | o_window.open_window(@مسار@, webui::browser::chrome); 133 | _س_ 134 | نهاية إذا 135 | نهاية دالة 136 | 137 | دالة نص إخدم_مجلد (نص مجلد) 138 | نص عنوان_الخادم 139 | _س_ 140 | o_window.serve_folder(@مجلد@); 141 | webui::set_timeout_sec(0); 142 | o_window.allow_multi_serving(true); 143 | @عنوان_الخادم@ = o_window.new_server(); 144 | _س_ 145 | إرجاع عنوان_الخادم 146 | نهاية دالة 147 | 148 | دالة إنتظار() 149 | _س_ 150 | std::thread ui(webui::loop); 151 | ui.join(); 152 | _س_ 153 | نهاية دالة 154 | 155 | دالة نص المسار_الحالي () 156 | نص المسار 157 | _س_ 158 | @المسار@ = webui::get_current_path(); 159 | _س_ 160 | إرجاع المسار 161 | نهاية دالة 162 | 163 | دالة نص جافاسكريبت (نص ج) 164 | نص النتيجة 165 | _س_ 166 | @النتيجة@ = o_window.run_js(@ج@); 167 | _س_ 168 | إرجاع النتيجة 169 | نهاية دالة 170 | 171 | دالة إغلاق () 172 | _س_ 173 | o_window.close(); 174 | _س_ 175 | نهاية دالة 176 | 177 | دالة إغلاق_شامل () 178 | _س_ 179 | webui::exit(); 180 | _س_ 181 | نهاية دالة 182 | 183 | دالة تغيير_نص_أداة (نص الأداة، نص النص) 184 | _س_ 185 | o_window.set_value(@الأداة@, @النص@); 186 | _س_ 187 | نهاية دالة 188 | 189 | دالة نص قرأة_نص_أداة (نص الأداة) 190 | نص القيمة 191 | _س_ 192 | @القيمة@ = o_window.get_value(@الأداة@); 193 | _س_ 194 | إرجاع القيمة 195 | نهاية دالة 196 | 197 | دالة رسالة (نص النص) 198 | جافاسكريبت ( "alert('" + النص + "');" ) 199 | نهاية دالة 200 | 201 | نهاية صنف 202 | -------------------------------------------------------------------------------- /src/alif_var_g_class.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_VarGlobalClass(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | 27 | // Global Class var 28 | // g1 = 1 + 2 29 | 30 | if (!o_tokens->TOKENS_PREDEFINED) 31 | return; // continue; 32 | 33 | if (!IsInsideFunction) 34 | ErrorCode("يجب استعمال المتغير داخل دالة ' " + Token[1] + " ' ", o_tokens); 35 | 36 | if (Token[2] != "=") 37 | ErrorCode("يجب اضافة ' = ' بعد اسم المتغير", o_tokens); 38 | 39 | if (Token[3] == "") 40 | ErrorCode("يجب اضافه قيمة بعد ' = ' ", o_tokens); 41 | 42 | if (CLASS_G_VAR_TYPE[std::make_pair(TheClass, Token[1])] == "عدد") 43 | { 44 | // if (CLASS_G_VAR_IS_CONST[std::make_pair(TheClass, Token[1])] == "ثابت") 45 | // ErrorCode("لا يمكن تغيير قيمة المتغير ' " + G_VAR_WITHOUT_ + " ' لأنه من 46 | // نوع ثابت ", o_tokens); 47 | 48 | if (DEBUG) 49 | DEBUG_MESSAGE("[CLASS-GLOBAL-INT (" + Token[1] + ")] = ", 50 | o_tokens); // DEBUG 51 | 52 | // *** Generate Code *** 53 | CPP_CLASS.append(" " + Global_ID[Token[1]] + " = "); 54 | // *** *** *** *** *** *** 55 | } 56 | else if (CLASS_G_VAR_TYPE[std::make_pair(TheClass, Token[1])] == "نص") 57 | { 58 | // if (CLASS_G_VAR_IS_CONST[std::make_pair(TheClass, Token[1])] == "ثابت") 59 | // ErrorCode("لا يمكن تغيير قيمة المتغير ' " + G_VAR_WITHOUT_ + " ' لأنه من 60 | // نوع ثابت ", o_tokens); 61 | 62 | if (DEBUG) 63 | DEBUG_MESSAGE("[CLASS-GLOBAL-STRING (" + Token[1] + ")] = ", 64 | o_tokens); // DEBUG 65 | 66 | // *** Generate Code *** 67 | CPP_CLASS.append(" " + Global_ID[Token[1]] + " = "); 68 | // *** *** *** *** *** *** 69 | } 70 | else if (CLASS_G_VAR_TYPE[std::make_pair(TheClass, Token[1])] == "منطق") 71 | { 72 | // if (CLASS_G_VAR_IS_CONST[std::make_pair(TheClass, Token[1])] == "ثابت") 73 | // ErrorCode("لا يمكن تغيير قيمة المتغير ' " + G_VAR_WITHOUT_ + " ' لأنه من 74 | // نوع ثابت ", o_tokens); 75 | 76 | if (DEBUG) 77 | DEBUG_MESSAGE("[CLASS-GLOBAL-BOOL (" + Token[1] + ")] = ", 78 | o_tokens); // DEBUG 79 | 80 | // *** Generate Code *** 81 | CPP_CLASS.append(" " + Global_ID[Token[1]] + " = "); 82 | // *** *** *** *** *** *** 83 | } 84 | 85 | TempTokenCount = 0; 86 | 87 | for (int p = 2; p <= o_tokens->TOTAL[o_tokens->Line]; p++) 88 | { 89 | if (Token[p] != "") 90 | { 91 | TempToken[TempTokenCount] = Token[p]; 92 | TempTokenCount++; 93 | } 94 | } 95 | 96 | // Local var Syntax 97 | // a = 1 + a * (_g - 3) ... 98 | 99 | ScriptSyntaxBuffer = CheckForSyntax( 100 | CLASS_G_VAR_TYPE[std::make_pair(TheClass, Token[1])], // OBJECTIF_TYPE 101 | true, // Accept Using Reference to Namespace:Controls 102 | true, // Accept Using Reference to Namespace:Function 103 | true, // Accept Using Reference to Global Functions 104 | true, // Accept Using Reference to Local Functions 105 | true, // Accept Using Reference to Global VAR 106 | true, // Accept Using Reference to Local VAR 107 | false, // Accept Convertion from String To Int 108 | true, // Accept Convertion from Int To String 109 | TempToken, // SYNTAX[] std::string 110 | (TempTokenCount - 1), // SYNTAX_LONG int 111 | TheClass, // TMP_WINDOW_NAME 112 | TheFunction, // TMP_FUNCTION_NAME 113 | o_tokens); 114 | 115 | if (DEBUG) 116 | DEBUG_MESSAGE("\n\n", o_tokens); // DEBUG 117 | 118 | // *** Generate Code *** 119 | CPP_CLASS.append(ScriptSyntaxBuffer + " ; \n"); 120 | // *** *** *** *** *** *** 121 | 122 | return; // continue; 123 | } 124 | -------------------------------------------------------------------------------- /src/aliflib/alifcore.cc: -------------------------------------------------------------------------------- 1 | /* 2 | This is the core used in every app 3 | compiled by Alif 3.x Series, which 4 | conain all functions and tools needed 5 | by the app in the runtimes. 6 | File: [Alif folder]/alifcore/alifcore.cc 7 | Version: Alif Core 1.0.2 8 | */ 9 | 10 | #ifndef UNICODE 11 | #define UNICODE 12 | #endif 13 | 14 | #ifndef _UNICODE 15 | #define _UNICODE 16 | #endif 17 | 18 | #define _HAS_STD_BYTE 0 // Fixing 'byte': ambiguous symbol 19 | 20 | #ifdef _WIN32 21 | #include 22 | #include 23 | #include 24 | #elif __APPLE__ 25 | // ... 26 | #else 27 | // ... 28 | #endif 29 | 30 | // Standard 31 | #include // Standard replace() 32 | #include // Wait.. 33 | #include // conversion from wide 'wchar_t' to 'string' bytes 34 | #include // Remove files 35 | #include // Initializ time, for rand() 36 | #include // 37 | #include // O/I files 38 | #include // std::setprecision 39 | #include // O/I 40 | #include // 41 | #include // 42 | #include // vectors 43 | #include // stringstream 44 | #include // mblen, mbtowc, wchar_t(C) 45 | #include // 46 | #include // strings 47 | #include // Treading 48 | #include // UTF8, Vectors 49 | 50 | // Boost 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | 64 | // UTF-8 65 | #include "utf8.h" 66 | 67 | using namespace std; 68 | 69 | // -- Alif v2 ------------------------------------------------------------- 70 | 71 | const static std::string ALIFCORE_NEW_LINE = "\n"; 72 | 73 | // IDs 74 | int Generated_ID = 10000; 75 | int ALIFCORE_ID_GENERATOR() { return Generated_ID++; } 76 | 77 | // int to string 78 | std::string alifcore_IntToString(double INT_VAL) 79 | { 80 | 81 | std::stringstream STRING_STREAM_BUFFER; 82 | STRING_STREAM_BUFFER << std::setprecision(16) << INT_VAL; 83 | std::string STRING_BUFFER = STRING_STREAM_BUFFER.str(); 84 | return STRING_BUFFER; 85 | } 86 | 87 | double alifcore_StringToInt(std::string s) 88 | { 89 | 90 | std::string::size_type sz; 91 | return std::stod(s, &sz); 92 | } 93 | 94 | bool alifcore_StringToBool(std::string Value) 95 | { 96 | 97 | if (Value == "true" || Value == "TRUE" || Value == "1" || Value == "نعم" || 98 | Value == "صحيح" || Value == "True") 99 | return true; 100 | 101 | else 102 | return false; 103 | } 104 | 105 | std::string alifcore_BoolToString(bool Value) 106 | { 107 | 108 | if (Value) 109 | return "true"; 110 | else 111 | return "false"; 112 | } 113 | 114 | // -- Alif v3 ------------------------------------------------------------- 115 | 116 | struct _alifcore_inf 117 | { 118 | 119 | #ifdef _WIN32 120 | std::string exe_ext = ".exe"; 121 | std::string path_sep = "\\"; 122 | #elif __APPLE__ 123 | std::string exe_ext = ".app"; 124 | std::string path_sep = "/"; 125 | #else 126 | std::string exe_ext = ""; 127 | std::string path_sep = "/"; 128 | #endif 129 | 130 | } alifcore_inf; 131 | 132 | unsigned char *alifcore_malloc(size_t size) 133 | { 134 | 135 | // return NULL; 136 | if (size > 0) 137 | return (unsigned char *)malloc(size); 138 | else 139 | return NULL; 140 | } 141 | 142 | void *alifcore_memset(void *s, int c, size_t n) 143 | { 144 | 145 | // return s; 146 | if (s != NULL) 147 | return memset(s, c, n); 148 | else 149 | return NULL; 150 | } 151 | 152 | void alifcore_free(void *ptr) 153 | { 154 | 155 | if (ptr != NULL) 156 | free(ptr); 157 | } 158 | 159 | std::string &alifcore_ltrim(std::string &s) 160 | { 161 | 162 | auto it = std::find_if(s.begin(), s.end(), [](char c) 163 | { return !std::isspace(c, std::locale::classic()); }); 164 | 165 | s.erase(s.begin(), it); 166 | 167 | return s; 168 | } 169 | 170 | std::string &alifcore_rtrim(std::string &s) 171 | { 172 | 173 | auto it = std::find_if(s.rbegin(), s.rend(), [](char c) 174 | { return !std::isspace(c, std::locale::classic()); }); 175 | 176 | s.erase(it.base(), s.end()); 177 | 178 | return s; 179 | } 180 | 181 | std::string &alifcore_trim(std::string &s) 182 | { 183 | 184 | return alifcore_ltrim(alifcore_rtrim(s)); 185 | } 186 | 187 | void alifcore_initialization() 188 | { 189 | 190 | #ifdef _WIN32 191 | // Create and install global locale 192 | std::locale::global(boost::locale::generator().generate("")); 193 | #endif 194 | 195 | // Make boost.filesystem use it 196 | boost::filesystem::path::imbue(std::locale()); 197 | } 198 | 199 | std::string alifcore_wchar_to_str(wchar_t wstr) 200 | { 201 | 202 | std::wstring_convert> converter; 203 | return converter.to_bytes(wstr); 204 | } 205 | 206 | std::string alifcore_wchar_to_str(wchar_t wstr[]) 207 | { 208 | 209 | std::wstring_convert> converter; 210 | return converter.to_bytes(wstr); 211 | } 212 | -------------------------------------------------------------------------------- /src/aliflib/التشفير.alif: -------------------------------------------------------------------------------- 1 | 2 | -- ------------------------ 3 | -- مكتبة التشفير 4 | -- ------------------------ 5 | 6 | #ألف 7 | 8 | #إذا ماك أضف_ترجمة_بداية " " 9 | #إذا ماك أضف_تجميع_بداية " " 10 | 11 | #إذا ويندوز أضف_ترجمة_بداية " " 12 | #إذا ويندوز أضف_تجميع_بداية " " 13 | 14 | #إذا لينكس أضف_ترجمة_بداية " " 15 | #إذا لينكس أضف_تجميع_بداية " " 16 | 17 | _س_ 18 | 19 | static const unsigned char base64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 20 | 21 | /** 22 | * base64_encode - Base64 encode 23 | * src: Data to be encoded 24 | * len: Length of the data to be encoded 25 | * out_len: Pointer to output length variable, or %NULL if not used 26 | * Returns: Allocated buffer of out_len bytes of encoded data, 27 | * or %NULL on failure 28 | * 29 | * Caller is responsible for freeing the returned buffer. Returned buffer is 30 | * nul terminated to make it easier to use as a C string. The nul terminator is 31 | * not included in out_len. 32 | */ 33 | unsigned char * _base64_encode(const unsigned char *src, size_t len, size_t *out_len){ 34 | 35 | unsigned char *out, *pos; 36 | const unsigned char *end, *in; 37 | size_t olen; 38 | int line_len; 39 | 40 | olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ 41 | olen += olen / 72; /* line feeds */ 42 | olen++; /* nul termination */ 43 | if (olen < len) 44 | return NULL; /* integer overflow */ 45 | out = alifcore_malloc(olen); 46 | if (out == NULL) 47 | return NULL; 48 | 49 | end = src + len; 50 | in = src; 51 | pos = out; 52 | line_len = 0; 53 | while (end - in >= 3) { 54 | *pos++ = base64_table[in[0] >> 2]; 55 | *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; 56 | *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; 57 | *pos++ = base64_table[in[2] & 0x3f]; 58 | in += 3; 59 | line_len += 4; 60 | if (line_len >= 72) { 61 | *pos++ = '\n'; 62 | line_len = 0; 63 | } 64 | } 65 | 66 | if (end - in) { 67 | *pos++ = base64_table[in[0] >> 2]; 68 | if (end - in == 1) { 69 | *pos++ = base64_table[(in[0] & 0x03) << 4]; 70 | *pos++ = '='; 71 | } else { 72 | *pos++ = base64_table[((in[0] & 0x03) << 4) | 73 | (in[1] >> 4)]; 74 | *pos++ = base64_table[(in[1] & 0x0f) << 2]; 75 | } 76 | *pos++ = '='; 77 | line_len += 4; 78 | } 79 | 80 | if (line_len) 81 | *pos++ = '\n'; 82 | 83 | *pos = '\0'; 84 | if (out_len) 85 | *out_len = pos - out; 86 | return out; 87 | } 88 | 89 | /** 90 | * base64_decode - Base64 decode 91 | * src: Data to be decoded 92 | * len: Length of the data to be decoded 93 | * out_len: Pointer to output length variable 94 | * Returns: Allocated buffer of out_len bytes of decoded data, 95 | * or %NULL on failure 96 | * 97 | * Caller is responsible for freeing the returned buffer. 98 | */ 99 | unsigned char * _base64_decode(const unsigned char *src, size_t len, size_t *out_len){ 100 | 101 | unsigned char dtable[256], *out, *pos, block[4], tmp; 102 | size_t i, count, olen; 103 | int pad = 0; 104 | 105 | alifcore_memset(dtable, 0x80, 256); 106 | for (i = 0; i < sizeof(base64_table) - 1; i++) 107 | dtable[base64_table[i]] = (unsigned char) i; 108 | dtable['='] = 0; 109 | 110 | count = 0; 111 | for (i = 0; i < len; i++) { 112 | if (dtable[src[i]] != 0x80) 113 | count++; 114 | } 115 | 116 | if (count == 0 || count % 4) 117 | return NULL; 118 | 119 | olen = count / 4 * 3; 120 | pos = out = alifcore_malloc(olen); 121 | if (out == NULL) 122 | return NULL; 123 | 124 | count = 0; 125 | for (i = 0; i < len; i++) { 126 | tmp = dtable[src[i]]; 127 | if (tmp == 0x80) 128 | continue; 129 | 130 | if (src[i] == '=') 131 | pad++; 132 | block[count] = tmp; 133 | count++; 134 | if (count == 4) { 135 | *pos++ = (block[0] << 2) | (block[1] >> 4); 136 | *pos++ = (block[1] << 4) | (block[2] >> 2); 137 | *pos++ = (block[2] << 6) | block[3]; 138 | count = 0; 139 | if (pad) { 140 | if (pad == 1) 141 | pos--; 142 | else if (pad == 2) 143 | pos -= 2; 144 | else { 145 | /* Invalid padding */ 146 | alifcore_free(out); 147 | return NULL; 148 | } 149 | break; 150 | } 151 | } 152 | } 153 | 154 | *out_len = pos - out; 155 | return out; 156 | } 157 | 158 | std::string base64_encode(std::string data){ 159 | 160 | // Encode 161 | 162 | std::string buf = ""; 163 | size_t len = 0; 164 | unsigned char * pbuf = NULL; 165 | 166 | pbuf = _base64_encode((const unsigned char *) data.c_str(), data.length(), &len); 167 | buf = reinterpret_cast(pbuf); 168 | alifcore_trim(buf); 169 | 170 | alifcore_free(pbuf); 171 | 172 | //std::cout << "Encode: [" << data << "] -> [" << buf << "] (" << len << " Bytes) \n"; 173 | 174 | return buf; 175 | } 176 | 177 | std::string base64_decode(std::string data){ 178 | 179 | // Decode 180 | 181 | std::string buf = ""; 182 | size_t len = 0; 183 | unsigned char * pbuf = NULL; 184 | 185 | pbuf = _base64_decode((const unsigned char *) data.c_str(), data.length(), &len); 186 | buf = reinterpret_cast(pbuf); 187 | alifcore_trim(buf); 188 | 189 | alifcore_free(pbuf); 190 | 191 | //std::cout << "Decode: [" << data << "] -> [" << buf << "] (" << len << " Bytes) \n"; 192 | 193 | return buf; 194 | } 195 | _س_ 196 | 197 | صنف التشفير 198 | 199 | دالة نص ترميز_أساس_64 (نص النص) 200 | نص شفيرة 201 | _س_ 202 | @شفيرة@ = base64_encode(@النص@); 203 | _س_ 204 | إرجاع شفيرة 205 | نهاية دالة 206 | 207 | دالة نص فك_أساس_64 (نص النص) 208 | نص شفيرة 209 | _س_ 210 | @شفيرة@ = base64_decode(@النص@); 211 | _س_ 212 | إرجاع شفيرة 213 | نهاية دالة 214 | 215 | نهاية صنف 216 | -------------------------------------------------------------------------------- /src/aliflib/الملفات.alif: -------------------------------------------------------------------------------- 1 | 2 | -- ------------------------ 3 | -- مكتبة الملفات 4 | -- ------------------------ 5 | 6 | #ألف 7 | 8 | #إذا ماك أضف_ترجمة_بداية " " 9 | #إذا ماك أضف_تجميع_بداية " " 10 | 11 | #إذا ويندوز أضف_ترجمة_بداية " " 12 | #إذا ويندوز أضف_تجميع_بداية " -lComdlg32 " 13 | 14 | #إذا لينكس أضف_ترجمة_بداية " `pkg-config --cflags gtk+-3.0` " 15 | #إذا لينكس أضف_تجميع_بداية " `pkg-config --libs gtk+-3.0` " 16 | 17 | _س_ 18 | #ifdef _WIN32 19 | #include "commdlg.h" 20 | // Windows ------------------------------------------- 21 | std::wstring string_to_wstring(const std::string& s){ 22 | int len; 23 | int slength = (int)s.length() + 1; 24 | len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 25 | wchar_t* buf = new wchar_t[len]; 26 | MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); 27 | std::wstring r(buf); 28 | delete[] buf; 29 | return r; 30 | } 31 | #elif __APPLE__ 32 | // macOS --------------------------------------------- 33 | // ... 34 | #else 35 | // Linux --------------------------------------------- 36 | #include 37 | std::string alif_gtk_openfile_buf; 38 | static void alif_gtk_openfile (GtkApplication* app,gpointer user_data){ 39 | GtkWidget *dialog; 40 | GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; 41 | gint res; 42 | dialog = gtk_file_chooser_dialog_new ("Open File",GTK_WINDOW(NULL),action,("_Cancel"),GTK_RESPONSE_CANCEL,("_Open"),GTK_RESPONSE_ACCEPT,NULL); 43 | res = gtk_dialog_run (GTK_DIALOG (dialog)); 44 | if (res == GTK_RESPONSE_ACCEPT){ 45 | char *filename; 46 | GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog); 47 | filename = gtk_file_chooser_get_filename (chooser); 48 | alif_gtk_openfile_buf = filename; 49 | g_free (filename); 50 | } 51 | gtk_widget_destroy (dialog); 52 | } 53 | #endif 54 | 55 | bool is_file_exists(std::string f) { 56 | 57 | boost::nowide::ifstream infile(f); 58 | return infile.good(); 59 | } 60 | 61 | 62 | _س_ 63 | 64 | صنف الملفات 65 | 66 | دالة بناء () 67 | 68 | نهاية دالة 69 | 70 | دالة نص فتح_ملف (نص العنوان) 71 | نص المسار = "" 72 | _س_ 73 | #ifdef _WIN32 74 | // Windows 75 | wchar_t szFile[MAX_PATH] = { 0 }; 76 | OPENFILENAMEW ofn; 77 | ZeroMemory(&ofn, sizeof(ofn)); 78 | ofn.lpstrFile = szFile; 79 | ofn.nMaxFile = sizeof(szFile); 80 | ofn.lStructSize = sizeof(ofn); 81 | ofn.lpstrFileTitle = NULL; 82 | //std::wstring w_type = string_to_wstring( أنواع ); 83 | //LPCWSTR lp_type = w_type.c_str(); 84 | //ofn.lpstrFilter = lp_type; 85 | //ofn.nFilterIndex = 1; 86 | //std::wstring w_title = string_to_wstring(@العنوان@); 87 | //LPCWSTR lp_title = w_title.c_str(); 88 | //ofn.lpstrTitle = lp_title; 89 | ofn.nMaxFileTitle = 0; 90 | ofn.lpstrInitialDir = NULL; 91 | ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; 92 | //ofn.hwndOwner = hWnd; 93 | if (GetOpenFileNameW(&ofn) == TRUE){ 94 | 95 | std::string buf = alifcore_wchar_to_str(szFile); 96 | 97 | if(buf != "") 98 | @المسار@ = buf; 99 | 100 | /* 101 | WCHAR szPath[MAX_PATH+1] = {0}; 102 | DWORD retval = GetFullPathNameW(ofn.lpstrFile, MAX_PATH, szPath, NULL); 103 | if ((retval != 0) && (retval < MAX_PATH)){ 104 | std::wstring wpath(szPath, retval); 105 | std::string path(wpath.begin(), wpath.end()); 106 | //std::cout << path; 107 | @المسار@ = path; 108 | } 109 | */ 110 | } 111 | #elif __APPLE__ 112 | // macOS 113 | // ... 114 | #else 115 | // Linux 116 | GtkApplication *alif_app; 117 | alif_app = gtk_application_new ("org.gtk.alif", G_APPLICATION_FLAGS_NONE); 118 | g_signal_connect (alif_app, "activate", G_CALLBACK (alif_gtk_openfile), NULL); 119 | g_application_run (G_APPLICATION (alif_app), 0, NULL); 120 | g_object_unref (alif_app); 121 | //std::cout << alif_gtk_openfile_buf << std::endl; 122 | @المسار@ = alif_gtk_openfile_buf; 123 | #endif 124 | _س_ 125 | إرجاع المسار 126 | نهاية دالة 127 | 128 | دالة نص نوع_ملف (نص المسار) 129 | نص نوع 130 | _س_ 131 | boost::filesystem::path p(@المسار@); 132 | @نوع@ = p.extension().string(); 133 | _س_ 134 | إرجاع نوع 135 | نهاية دالة 136 | 137 | دالة نص إسم_ملف (نص المسار) 138 | نص إسم 139 | _س_ 140 | boost::filesystem::path p(@المسار@); 141 | @إسم@ = p.stem().string(); 142 | _س_ 143 | إرجاع إسم 144 | نهاية دالة 145 | 146 | دالة نص مسار_المجلد (نص المسار) 147 | نص إسم 148 | _س_ 149 | boost::filesystem::path p(@المسار@); 150 | @إسم@ = p.parent_path().string() + alifcore_inf.path_sep; 151 | _س_ 152 | إرجاع إسم 153 | نهاية دالة 154 | 155 | دالة منطق حفظ_ملف (نص المسار، نص محتوى) 156 | منطق هل_ثم_الحفظ = خطأ 157 | _س_ 158 | boost::nowide::ofstream file(@المسار@); 159 | if(file){ 160 | file << @محتوى@; 161 | file.close(); 162 | @هل_ثم_الحفظ@ = true; 163 | } 164 | _س_ 165 | إرجاع هل_ثم_الحفظ 166 | نهاية دالة 167 | 168 | دالة نص محتوى_ملف (نص المسار) 169 | نص محتوى 170 | _س_ 171 | 172 | if (!is_file_exists(@المسار@)) 173 | return ""; 174 | 175 | boost::nowide::ifstream file(@المسار@); 176 | 177 | // Method 1 178 | //std::size_t sz = static_cast(boost::filesystem::file_size(@المسار@)); 179 | //@محتوى@.resize(sz, '\0'); 180 | //file.read(&@محتوى@[0], sz); // This add null bytes at end 181 | 182 | // Method 2 183 | std::string line; 184 | while (getline(file, line)){ 185 | @محتوى@.append(line); 186 | @محتوى@.append("\n"); 187 | } 188 | 189 | file.close(); 190 | _س_ 191 | إرجاع محتوى 192 | نهاية دالة 193 | 194 | دالة منطق هل_موجود (نص المسار) 195 | منطق موجود 196 | _س_ 197 | @موجود@ = is_file_exists(@المسار@); 198 | _س_ 199 | إرجاع موجود 200 | نهاية دالة 201 | 202 | نهاية صنف 203 | -------------------------------------------------------------------------------- /src/alif_function_call.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_FunctionCall(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | 27 | // *myfunction(a, b, c..) 28 | 29 | if (!o_tokens->TOKENS_PREDEFINED) 30 | return; 31 | 32 | // --- Check for errors --------------------------------------- 33 | 34 | if (!IsInsideFunction) 35 | ErrorCode("لايمكن مناداة على دالة من خارج دالة '" + Token[1] + "()' ", 36 | o_tokens); 37 | 38 | if (Token[2] == "") 39 | ErrorCode("يجب اضافه '(' بعد اسم الدالة ' " + Token[1] + " ' ", o_tokens); 40 | 41 | if (Token[2] != "(") 42 | ErrorCode("من أجل نداء الدالة العامة ' " + Token[1] + 43 | "() ' يجب إضافة الإشارة ' ( ' قبل ' " + Token[2] + " ' ", 44 | o_tokens); // TODO: Whats is this? 45 | 46 | if (Token[o_tokens->TOTAL[o_tokens->Line] - 1] != ")") 47 | ErrorCode("يجب انهاء السطر بالإشارة ')' ", o_tokens); 48 | 49 | // --- Set current parent --------------------------------------- 50 | 51 | std::string CurrentParent = ""; 52 | 53 | if (IsInsideClass) 54 | CurrentParent = TheClass; 55 | else if (IsInsideNamespace) 56 | CurrentParent = TheNamespace; 57 | 58 | // --- Initializing --------------------------------------------- 59 | 60 | bool CallClassFun = false; 61 | bool CallGlobalFun = false; 62 | std::string FuncParent = ""; 63 | std::string FunName = ""; 64 | std::string FunType = ""; 65 | 66 | // --- Identify ------------------------------------------------- 67 | 68 | if (L_FUN_IS_SET[std::make_pair(CurrentParent, Token[1])]) 69 | { 70 | 71 | // Local 72 | 73 | FuncParent = CurrentParent; 74 | FunName = Token[1]; 75 | FunType = L_FUN_TYPE[std::make_pair(CurrentParent, Token[1])]; 76 | 77 | // Debug 78 | if (DEBUG) 79 | DEBUG_MESSAGE("Call Local-function [" + Token[1] + "] (", o_tokens); 80 | } 81 | else if (CLASS_FUN_IS_SET[std::make_pair(CurrentParent, Token[1])]) 82 | { 83 | 84 | // Local Class 85 | 86 | CallClassFun = true; 87 | FuncParent = CurrentParent; 88 | FunName = Token[1]; 89 | FunType = CLASS_FUN_TYPE[std::make_pair(CurrentParent, Token[1])]; 90 | 91 | // Debug 92 | if (DEBUG) 93 | DEBUG_MESSAGE("Call Class-function [" + Token[1] + "] (", o_tokens); 94 | } 95 | else if (G_FUN_IS_SET[(Token[1])]) 96 | { 97 | 98 | // Global 99 | 100 | CallGlobalFun = true; 101 | FunName = Token[1]; 102 | FunType = G_FUN_TYPE[(Token[1])]; 103 | 104 | // Debug 105 | if (DEBUG) 106 | DEBUG_MESSAGE("Call Global-function [" + Token[1] + "] (", o_tokens); 107 | } 108 | else 109 | { 110 | 111 | // Error 112 | ErrorCode("علة: نوع الدالة غير معروف'" + Token[1] + "' ", o_tokens); 113 | } 114 | 115 | // --- Check ------------------------------------------------- 116 | 117 | // if (IsDataType(FunType)) 118 | // ErrorCode("الدالة المحلية ' " + FunName + "()' من نوع " + FunType + ", 119 | //لذلك أنت بحاجة إلى متغير للحصول على قيمة الرجوع", o_tokens); 120 | 121 | // --- ARGV ------------------------------------------------- 122 | 123 | if (o_tokens->TOTAL[o_tokens->Line] > 3) 124 | { 125 | 126 | TempTokenCount = 0; 127 | for (int p = 3; p <= o_tokens->TOTAL[o_tokens->Line]; p++) 128 | { 129 | 130 | // ... [a, b + 2, c(...), d*x)] 131 | 132 | if (Token[p] != "") 133 | { 134 | 135 | TempToken[TempTokenCount] = Token[p]; 136 | TempTokenCount++; 137 | } 138 | } 139 | 140 | ScriptSyntaxBuffer = CHECK_CALL_FUN_ARG( 141 | CallGlobalFun, FuncParent, FunName, CallClassFun, CurrentParent, 142 | TheFunction, TempToken, (TempTokenCount - 1), o_tokens); 143 | } 144 | 145 | // DEBUG 146 | if (DEBUG) 147 | DEBUG_MESSAGE(") ", o_tokens); 148 | 149 | // --- Gen. Code ------------------------------------------------- 150 | 151 | if (CallGlobalFun) 152 | { 153 | 154 | // Call a Global func 155 | ScriptBuffer = 156 | " FUNCTION_" + Global_ID[FunName] + "( " + ScriptSyntaxBuffer + "); \n"; 157 | } 158 | else if (CallClassFun) 159 | { 160 | 161 | // Call a Local-Class func 162 | ScriptBuffer = 163 | " ClassFUNCTION_" + ID[FunName] + "(" + ScriptSyntaxBuffer + "); \n"; 164 | } 165 | else 166 | { 167 | 168 | // Call a Local func 169 | ScriptBuffer = " NS_" + ID[TheNamespace] + "::FUNCTION_" + ID[FunName] + 170 | "(" + ScriptSyntaxBuffer + "); \n"; 171 | } 172 | 173 | // --- Add. Code ------------------------------------------------- 174 | 175 | if (IsInsideClass) 176 | { 177 | 178 | // Class 179 | CPP_CLASS.append(ScriptBuffer); 180 | } 181 | else if (IsInsideNamespace) 182 | { 183 | 184 | // Local func 185 | cpp_AddScript(TheFunction, ScriptBuffer); 186 | } 187 | else if (IsInsideFunction) 188 | { 189 | 190 | // Global func 191 | CPP_GLOBAL_FUN.append(ScriptBuffer); 192 | } 193 | else 194 | { 195 | 196 | // Global 197 | // CPP_GLOBAL.append(ScriptBuffer); 198 | 199 | ErrorCode("علة: لايمكن مناداة على دالة في مكان عام", o_tokens); 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/alif_operator.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_TwoPointOperator(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | 27 | // --------------------------------------------------------------------------------- 28 | // : (Operator between members) 29 | // --------------------------------------------------------------------------------- 30 | 31 | // namespace:local_func(a, b) | namespace:my_func(a, b) 32 | // namespace:local_var | namespace:my_var 33 | 34 | // namespace_name : local_func ( ... ) 35 | // 1 2 3 4 5 6 36 | 37 | if (!o_tokens->TOKENS_PREDEFINED) 38 | return; // continue; 39 | 40 | if (!IsInsideFunction) 41 | ErrorCode("يجب استعمال المجال داخل دالة", o_tokens); 42 | 43 | if (namespace_is_set[Token[1]]) 44 | { 45 | // namespace:local_func(a, b) | win:my_func(a, b) 46 | 47 | if (Token[2] != ":") 48 | ErrorCode("يجب اضافه ' : ' بعد ' " + Token[1] + " ' ", o_tokens); 49 | 50 | if (Token[3] == "") 51 | ErrorCode("يجب اضافه عضو تابع ل ' " + Token[1] + " ' بعد ':' ", o_tokens); 52 | 53 | if (Token[4] == "") 54 | ErrorCode("يجب اضافه ':' أو '()' أو '=' بعد ' " + Token[1] + " " + 55 | Token[2] + " " + Token[3] + " ' ", 56 | o_tokens); 57 | 58 | if (Token[4] != "(" && Token[4] != ":" && Token[4] != "=") 59 | ErrorCode("أمر غير معروف ' " + Token[4] + 60 | " ', يجب اضافه ':' أو '()' أو '=' ", 61 | o_tokens); 62 | 63 | if (L_FUN_IS_SET[std::make_pair(Token[1], Token[3])] && Token[4] != "(") 64 | ErrorCode("من اجل نداء الدالة ' " + Token[3] + 65 | " ' يجب اضافه '()' بعد ' " + Token[1] + " " + Token[2] + 66 | " " + Token[3] + " ' ", 67 | o_tokens); 68 | 69 | if (Token[4] == "(") 70 | { 71 | // ----------------------- 72 | // namespace:win-local_func() 73 | // ----------------------- 74 | 75 | if (L_FUN_IS_SET[std::make_pair(Token[1], Token[3])]) 76 | { 77 | if (Token[o_tokens->TOTAL[o_tokens->Line] - 1] != ")") 78 | ErrorCode("يجب انهاء السطر بالإشارة ')' ", o_tokens); 79 | 80 | if (DEBUG) 81 | DEBUG_MESSAGE("[NS'" + Token[1] + " ':LOCAL_FUNC'" + Token[3] + 82 | " ' ( ", 83 | o_tokens); // DEBUG 84 | 85 | // // *** Generate Code *** 86 | // if (!IsInsideNamespace) 87 | // // Call other namespace local_func from global func 88 | // CPP_GLOBAL_FUN.append(CG_WIN_MEMBER(Token[1], ID[Token[3]] + " 89 | // (")); else 90 | // // Call other namespace local_func from local func 91 | // cpp_AddScript(TheFunction, CG_WIN_MEMBER(Token[1], ID[Token[3]] 92 | // + " (")); 93 | // // *** *** *** *** *** *** 94 | 95 | TempTokenCount = 0; 96 | for (int p = 5; p <= o_tokens->TOTAL[o_tokens->Line]; 97 | p++) // | a, b + 2, c) | 98 | { 99 | if (Token[p] != "") 100 | { 101 | TempToken[TempTokenCount] = Token[p]; 102 | TempTokenCount++; 103 | } 104 | } 105 | 106 | // Check local fun Args and Syntax : fun (a + c, 2 * (b - 1)) 107 | ScriptSyntaxBuffer = CHECK_CALL_FUN_ARG( 108 | false, Token[1], Token[3], 0, TheNamespace, TheFunction, TempToken, 109 | (TempTokenCount - 1), o_tokens); 110 | 111 | if (DEBUG) 112 | DEBUG_MESSAGE(")] \n\n", o_tokens); // DEBUG 113 | 114 | // // *** Generate Code *** 115 | // if (!IsInsideNamespace) 116 | // // Call other win-local_func from global func 117 | // CPP_GLOBAL_FUN.append(ScriptSyntaxBuffer + " ); \n } \n"); 118 | // else 119 | // // Call other win-local_func from local func 120 | // cpp_AddScript(TheFunction, ScriptSyntaxBuffer + " ); \n } \n"); 121 | // // *** *** *** *** *** *** 122 | 123 | // *** Generate Code *** 124 | ScriptBuffer = " NS_" + ID[Token[1]] + "::FUNCTION_" + ID[Token[3]] + 125 | "(" + ScriptSyntaxBuffer + "); \n"; 126 | 127 | if (!IsInsideNamespace) 128 | // Call other win-local_func from global func 129 | CPP_GLOBAL_FUN.append(ScriptBuffer + " \n"); 130 | else 131 | // Call other win-local_func from local func 132 | cpp_AddScript(TheFunction, ScriptBuffer + " \n"); 133 | // *** *** *** *** *** *** 134 | 135 | return; // continue; 136 | } 137 | // --------------------------------------------------------------------------------- 138 | else 139 | ErrorCode("المجال ' " + Token[1] + 140 | " ' لا تحتوي على دالة محليه بإسم ' " + Token[3] + " ' ", 141 | o_tokens); 142 | 143 | // Exception! 144 | return; // continue; 145 | } 146 | else 147 | { 148 | // Exception ! 149 | ErrorCode("يجب اضافه ':' أو '()' أو '=' بعد ' " + Token[1] + " " + 150 | Token[2] + " " + Token[3] + " ' ", 151 | o_tokens); 152 | } 153 | } 154 | else 155 | { 156 | // Exception ! 157 | ErrorCode("أمر غير معروف ' " + Token[1] + " ', يجب أن تكون فقط مجال", 158 | o_tokens); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ## The Arabic Programming Language, Alif - لغة البرمجة العربية، ألف 4 | 5 | ## كيف يعمل مترجم ألف ؟ 6 | 7 | مترجم ألف يقوم بترجمة لغة ألف إلى لغة سي++ مع استعمال مكتبات [بوست](https://boost.org) 8 | 9 | > **_[ ! ] تنبيه_** 10 | > 11 | > مشروع ألف نسخة 3 هو قيد التطوير ولا يصلح حاليا للاستخدام، لكن يمكنك استعمال وتجربة ألف النسخة 2 عبر تحميله من الموقع الرسمي https://aliflang.org 12 | 13 | ## طريقة ترجمة الشيفرة المصدرية للمشروع 14 | 15 | ### المتطلبات 16 | 17 | 1. مترجم مناسب، مثل مترجم gcc الإصدار رقم 8 على الأقل 18 | 2. مكتبات بوست، على الأقل الإصدار رقم 1.74 19 | 20 | ### استنساخ الكود لجهازك 21 | 22 |
23 | 24 | ```bash 25 | git clone --depth=1 -b main --single-branch https://github.com/alifcommunity/compiler.git 26 | cd compiler 27 | mkdir build 28 | cd build 29 | ``` 30 | 31 |
32 | 33 | ### البناء 34 | 35 | للبناء المشروع على أي نظام تشغيل باستخدام `make` 36 | 37 |
38 | 39 | ```bash 40 | make build 41 | ``` 42 | 43 |
44 | 45 | #### Windows 46 | 47 | البناء باستخدام **_GCC (MinGW64)_**. 48 | 49 |
50 | 51 | ```bash 52 | cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release 53 | mingw32-make 54 | mingw32-make install 55 | ``` 56 | 57 |
58 | 59 | البناء باستخدام **_Microsoft build tools 2019_**. 60 | 61 |
62 | 63 | ```bash 64 | cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release 65 | nmake 66 | ``` 67 | 68 |
69 | 70 | #### Linux 71 | 72 | تنصيب مترجم GCC & GTK3 73 | 74 |
75 | 76 | ``` 77 | sudo apt install build-essential libgtk-3-dev 78 | ``` 79 | 80 |
81 | 82 | تنصيب مكتبات Boost +1.74 83 | 84 | إن لم تكن موجودة بالفعل في المتسودع الرسمي لحزم توزيعة اللينوكس، قم بتنصيبها يدويا: 85 | 86 |
87 | 88 | ``` 89 | wget https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.gz 90 | tar -xzf boost_1_76_0.tar.gz 91 | cd boost_1_76_0 92 | ./bootstrap.sh 93 | sudo ./b2 install address-model=64 variant=release link=shared runtime-link=shared warnings=off --with-filesystem --with-program_options --with-system --with-locale --with-date_time --with-regex --with-nowide --with-thread 94 | ``` 95 | 96 |
97 | 98 | بناء مترجم ألف باستخدام GCC. 99 | 100 |
101 | 102 | ```bash 103 | cmake .. 104 | make && sudo make install 105 | ``` 106 | 107 |
108 | 109 | ## المساهمة في تطوير اللغة 110 | 111 | قال صلى الله عليه وسلم : "يد الله مع الجماعة". بدأت اللغة كعمل فردي ومبادرة من حسن دراجة، لكن اللغة تنمو بالمساهمين والمطورين الذي يريدون رؤية اللغة العربية على رأس اللغات وأفضلهم. 112 | 113 | ### المتطلبات 114 | 115 | 1. أنت بحاجة لتوفية متطلبات البناء في الجزء الخاص ببناء المترجم، _هذا بديهي_ 😅 116 | 2. على الأقل أنت بحاجة لـ "جيت" الإصدار 2.9.0 لاستعمال الخطافات، [المصدر](https://stackoverflow.com/questions/39332407/git-hooks-applying-git-config-core-hookspath) 117 | 3. قم بتنصيب clang-format، تأتي ضمن مترجم ال clang 118 | 4. مفسر لغة بايثون، حيث يٌتطلب وجود `python`، `pip`، `venv` لإجراء الاختبارات 119 | 5. (خياريا وليس إلزاما)، لتنسيق ملفات `yaml, json, ...`، يجب توافر أداة prettier التي يمكن تنصيبها من npm والتي تأتي مع ال NodeJs. للتنصيب: `npm i -g prettier` 120 | 6. تشغيل الكود الخاص بإعداد المشروع للتطوير، انظر التعليمات بالأسفل 121 | 122 | ### استنساخ الكود وإعداده 123 | 124 |
125 | 126 | ``` 127 | git clone https://github.com/alifcommunity/compiler.git alif-compiler 128 | ``` 129 | 130 | ``` 131 | python ./إعداد_للتطوير.py 132 | ``` 133 | 134 |
135 | 136 | ### إجراء الاختبارات 137 | 138 | الاختبارات على الكود يتم تنفيذها من خلل كود بايثون، وستكون مستقبلا بلغة ألف إن شاء الله، لذا يتطلب تصطيب بايثون أولا 139 | 140 | **لتشغيل الاختبارات** 141 | 142 | - يمكنك الإعداد إن لم تكن قد أعددت المشروع للتطوير مسبقا: `python إعداد_للتطوير.py اختبارات` ، أو `make prepare-tests` 143 | - يمكنك أن تشغل الاختبارات من خلال `make tests` 144 | 145 | ``` 146 | > ./اختبارات/اختبر --مساعدة 147 | الاستخدام: اجراء_الاختبارات [--مساعدة] [--تكميل] [--القواعد-فقط] [--تجديد] 148 | [--مسار مسار] 149 | 150 | إجراء اختبارات لمترجم ألف. 151 | 152 | أَسْناد غير إلزامية: 153 | --مساعدة, -م احصل على رسالة المساعدة هذه 154 | --تكميل, -ك بانتاج ملفات التوقع الغير موجودة من خلال ما يحدث فعلا 155 | عند ترجمة وتنفيذ الكود 156 | --القواعد-فقط, -ق اختبار القواعد فقط بدون الخَرج أو الترجمة الكاملة 157 | --تجديد, -ج إعادة انتاج كل التوقعات من الكود وإهمال القديم. هذه 158 | الأمر لابد أن تكون واعيا بتبعاته 159 | --مسار مسار, -س مسار تحديد مسار لجمع الاختبارات منه ومن المسارات الفرعية 160 | بداخلة 161 | ``` 162 | 163 | **إنشاء اختبارات جديدة** 164 | 165 | قم بوضع ملف فيه كود لألف في المسار `./اختبارات/أكواد`، ويمكن وضع ملف الكود في أي مسار فرعي بداخله، كما يمكنك أن تضع المتوقع من الكود في ملف يحمل نفس الإسم وفي نفس المكان مع إضافة `_توقع.yml` 166 | 167 | فمثلا لو أردت أن تعمل بال TDD، سنقوم بعمل مثل الختبارات الموجودة بالفعل ووضع السلوك المتوقع قبل أن يُعمل على المترجم نفسه لوضع الخاصية، فلنقل أن الإدخال لم يكن موجودا ونريد أن نعمل على الدالة `قراءة_عدد` في alifstandardlib.alif، هكذا ستكون هيكلية الملفات: 168 | 169 | ``` 170 | - <أكواد ألف> 171 | - اختبارات 172 | - أكواد 173 | - الإدخال 174 | - ادخل_رقما.ألف 175 | - ادخل_رقما_توقع.json 176 | ``` 177 | 178 | الملف `./اختبارات/أكواد/الإدخال/ادخل_رقما.ألف` 179 | 180 | ``` 181 | #ألف 182 | 183 | دالة رئيسية 184 | عدد ع = قراءة_عدد() 185 | اطبع(ع) 186 | نهاية دالة 187 | ``` 188 | 189 | الآن لنأخذ قالب التوقع من `./اختبارات/قالب_التوقع.yml`، الملف `./اختبارات/أكواد/الإدخال/ادخل_رقما_توقع.yml` سيكون بنفس محتوى القالب، إلا أننا سنغير خانة `تنفيذ.دخل` ونضع فيها رقم متبوعا بسطر جديد (حتى تتم قراءة الرقم)، ونجعل خانة `تنفيذ.خرج` هي القيمة المطبوعة، وهي نفس القيمة المدخلة متبوعة بسطر جديد. 190 | 191 | > ملاحطة: شغلت الاختبارات بملف كود ألف فقط (بدون ملف التوقع) سيتم إنشاء ملف التوقع تلقائيا وملؤه بما يحدث عند الترجمة والتنفيذ 192 | 193 | ``` 194 | تجميع: 195 | خرج: "" 196 | خطأ: "" 197 | رمز_الخروج: 0 198 | 199 | تنفيذ: 200 | - دخل: 201 | - "123" 202 | خرج: 203 | - "123 204 | 205 | " 206 | خطأ: 207 | - "" 208 | رمز_الخروج: 0 209 | ``` 210 | -------------------------------------------------------------------------------- /src/aliflib/الرياضيات.alif: -------------------------------------------------------------------------------- 1 | #ألف 2 | 3 | صنف رياضيات__ 4 | 5 | -- طور الدالة الجيبية المسمى Pi 6 | عدد ط = 3.1415926535897932384626433832795028841971 7 | -- الثابت الأسي e للدالة الأسية 8 | عدد هـ = 2.7182818284590452353602874713526624977572 9 | 10 | --------------------------------------------- 11 | -------------- الدوال المثلثية -------------- 12 | --------------------------------------------- 13 | 14 | دالة عدد جيب ( عدد أ) 15 | عدد حقيقي 16 | _س_ @حقيقي@ = sin(@أ@); _س_ 17 | إرجاع حقيقي 18 | نهاية دالة 19 | 20 | دالة عدد جيب_تمام ( عدد أ ) 21 | عدد حقيقي 22 | _س_ @حقيقي@ = cos(@أ@); _س_ 23 | إرجاع حقيقي 24 | نهاية دالة 25 | 26 | دالة عدد ظل ( عدد زاوية ) 27 | عدد حقيقي 28 | _س_ @حقيقي@ = tan(@زاوية@); _س_ 29 | إرجاع حقيقي 30 | نهاية دالة 31 | 32 | دالة عدد قاطع ( عدد أ ) 33 | عدد حقيقي 34 | _س_ @حقيقي@ = 1 / cos(@أ@); _س_ 35 | إرجاع حقيقي 36 | نهاية دالة 37 | 38 | دالة عدد قاطع_تمام ( عدد زاوية ) 39 | عدد حقيقي 40 | _س_ @حقيقي@ = 1 / sin(@زاوية@); _س_ 41 | إرجاع حقيقي 42 | نهاية دالة 43 | 44 | دالة عدد ظل_تمام ( عدد زاوية ) 45 | عدد حقيقي 46 | _س_ @حقيقي@ = 1 / tan(@زاوية@); _س_ 47 | إرجاع حقيقي 48 | نهاية دالة 49 | 50 | دالة عدد قوس_جيب ( عدد أ ) 51 | عدد حقيقي 52 | _س_ @حقيقي@ = asin(@أ@); _س_ 53 | إرجاع حقيقي 54 | نهاية دالة 55 | 56 | دالة عدد قوس_جيب_تمام ( عدد أ ) 57 | عدد حقيقي 58 | _س_ @حقيقي@ = acos(@أ@); _س_ 59 | إرجاع حقيقي 60 | نهاية دالة 61 | 62 | دالة عدد قوس_ظل ( عدد أ ) 63 | عدد حقيقي 64 | _س_ @حقيقي@ = atan(@أ@) ; _س_ 65 | إرجاع حقيقي 66 | نهاية دالة 67 | 68 | دالة عدد قوس_ظل2 ( عدد أ، عدد ب ) 69 | عدد حقيقي 70 | _س_ @حقيقي@ = atan2(@أ@, @ب@) ; _س_ 71 | إرجاع حقيقي 72 | نهاية دالة 73 | 74 | دالة عدد قوس_ظل٢ ( عدد أ، عدد ب ) 75 | عدد حقيقي 76 | _س_ @حقيقي@ = atan2(@أ@, @ب@) ; _س_ 77 | إرجاع حقيقي 78 | نهاية دالة 79 | 80 | -------- الاختصارات -------- 81 | 82 | دالة عدد جا ( عدد أ) 83 | عدد حقيقي 84 | _س_ @حقيقي@ = sin(@أ@); _س_ 85 | إرجاع حقيقي 86 | نهاية دالة 87 | 88 | دالة عدد جتا ( عدد أ ) 89 | عدد حقيقي 90 | _س_ @حقيقي@ = cos(@أ@); _س_ 91 | إرجاع حقيقي 92 | نهاية دالة 93 | 94 | دالة عدد ظا ( عدد زاوية ) 95 | عدد حقيقي 96 | _س_ @حقيقي@ = tan(@زاوية@); _س_ 97 | إرجاع حقيقي 98 | نهاية دالة 99 | 100 | دالة عدد قا ( عدد أ ) 101 | عدد حقيقي 102 | _س_ @حقيقي@ = 1 / cos(@أ@); _س_ 103 | إرجاع حقيقي 104 | نهاية دالة 105 | 106 | دالة عدد قتا ( عدد زاوية ) 107 | عدد حقيقي 108 | _س_ @حقيقي@ = 1 / sin(@زاوية@); _س_ 109 | إرجاع حقيقي 110 | نهاية دالة 111 | 112 | دالة عدد ظتا ( عدد زاوية ) 113 | عدد حقيقي 114 | _س_ @حقيقي@ = 1 / tan(@زاوية@); _س_ 115 | إرجاع حقيقي 116 | نهاية دالة 117 | 118 | دالة عدد قجا ( عدد أ ) 119 | عدد حقيقي 120 | _س_ @حقيقي@ = asin(@أ@); _س_ 121 | إرجاع حقيقي 122 | نهاية دالة 123 | 124 | دالة عدد قجتا ( عدد أ ) 125 | عدد حقيقي 126 | _س_ @حقيقي@ = acos(@أ@); _س_ 127 | إرجاع حقيقي 128 | نهاية دالة 129 | 130 | دالة عدد قظا ( عدد أ ) 131 | عدد حقيقي 132 | _س_ @حقيقي@ = atan(@أ@) ; _س_ 133 | إرجاع حقيقي 134 | نهاية دالة 135 | 136 | دالة عدد قظا2 ( عدد أ، عدد ب ) 137 | عدد حقيقي 138 | _س_ @حقيقي@ = atan2(@أ@, @ب@) ; _س_ 139 | إرجاع حقيقي 140 | نهاية دالة 141 | 142 | دالة عدد قظا٢ ( عدد أ، عدد ب ) 143 | عدد حقيقي 144 | _س_ @حقيقي@ = atan2(@أ@, @ب@) ; _س_ 145 | إرجاع حقيقي 146 | نهاية دالة 147 | 148 | --------------------------------------------- 149 | -------------- الدوال الزائدية -------------- 150 | --------------------------------------------- 151 | 152 | دالة عدد جيب_زائدي ( عدد أ ) 153 | عدد حقيقي 154 | _س_ @حقيقي@ = sinh(@أ@) ; _س_ 155 | إرجاع حقيقي 156 | نهاية دالة 157 | 158 | دالة عدد جيب_تمام_زائدي ( عدد أ ) 159 | عدد حقيقي 160 | _س_ @حقيقي@ = cosh(@أ@) ; _س_ 161 | إرجاع حقيقي 162 | نهاية دالة 163 | 164 | دالة عدد ظل_زائدي ( عدد أ ) 165 | عدد حقيقي 166 | _س_ @حقيقي@ = tanh(@أ@) ; _س_ 167 | إرجاع حقيقي 168 | نهاية دالة 169 | 170 | -------- الاختصارات -------- 171 | 172 | دالة عدد زجا ( عدد أ ) 173 | عدد حقيقي 174 | _س_ @حقيقي@ = sinh(@أ@) ; _س_ 175 | إرجاع حقيقي 176 | نهاية دالة 177 | 178 | دالة عدد زجتا ( عدد أ ) 179 | عدد حقيقي 180 | _س_ @حقيقي@ = cosh(@أ@) ; _س_ 181 | إرجاع حقيقي 182 | نهاية دالة 183 | 184 | دالة عدد زظا ( عدد أ ) 185 | عدد حقيقي 186 | _س_ @حقيقي@ = tanh(@أ@) ; _س_ 187 | إرجاع حقيقي 188 | نهاية دالة 189 | 190 | ------------------------------------------------- 191 | -------------- الدوال اللوغاريتمية -------------- 192 | ------------------------------------------------- 193 | 194 | دالة عدد لوغاريتم ( عدد أ ) 195 | عدد حقيقي 196 | _س_ @حقيقي@ = log(@أ@) ; _س_ 197 | إرجاع حقيقي 198 | نهاية دالة 199 | 200 | دالة عدد لوغاريتم10 ( عدد أ ) 201 | عدد حقيقي 202 | _س_ @حقيقي@ = log10(@أ@) ; _س_ 203 | إرجاع حقيقي 204 | نهاية دالة 205 | 206 | دالة عدد لوغاريتم١٠ ( عدد أ ) 207 | عدد حقيقي 208 | _س_ @حقيقي@ = log10(@أ@) ; _س_ 209 | إرجاع حقيقي 210 | نهاية دالة 211 | 212 | دالة عدد لوغاريتم2 ( عدد أ ) 213 | عدد حقيقي 214 | _س_ @حقيقي@ = log2(@أ@) ; _س_ 215 | إرجاع حقيقي 216 | نهاية دالة 217 | 218 | دالة عدد لوغاريتم٢ ( عدد أ ) 219 | عدد حقيقي 220 | _س_ @حقيقي@ = log2(@أ@) ; _س_ 221 | إرجاع حقيقي 222 | نهاية دالة 223 | 224 | -------- الاختصارات -------- 225 | 226 | دالة عدد لو ( عدد أ ) 227 | عدد حقيقي 228 | _س_ @حقيقي@ = log(@أ@) ; _س_ 229 | إرجاع حقيقي 230 | نهاية دالة 231 | 232 | دالة عدد لو10 ( عدد أ ) 233 | عدد حقيقي 234 | _س_ @حقيقي@ = log10(@أ@) ; _س_ 235 | إرجاع حقيقي 236 | نهاية دالة 237 | 238 | دالة عدد لو١٠ ( عدد أ ) 239 | عدد حقيقي 240 | _س_ @حقيقي@ = log10(@أ@) ; _س_ 241 | إرجاع حقيقي 242 | نهاية دالة 243 | 244 | دالة عدد لو2 ( عدد أ ) 245 | عدد حقيقي 246 | _س_ @حقيقي@ = log2(@أ@) ; _س_ 247 | إرجاع حقيقي 248 | نهاية دالة 249 | 250 | دالة عدد لو٢ ( عدد أ ) 251 | عدد حقيقي 252 | _س_ @حقيقي@ = log2(@أ@) ; _س_ 253 | إرجاع حقيقي 254 | نهاية دالة 255 | 256 | ------------------------------------------------- 257 | -------------- دوال أخرى -------------- 258 | ------------------------------------------------- 259 | 260 | دالة عدد جذر_تربيعي ( عدد أ ) 261 | عدد حقيقي 262 | _س_ @حقيقي@ = sqrt(@أ@) ; _س_ 263 | إرجاع حقيقي 264 | نهاية دالة 265 | 266 | دالة عدد جذر3 ( عدد أ ) 267 | عدد حقيقي 268 | _س_ @حقيقي@ = cbrt(@أ@) ; _س_ 269 | إرجاع حقيقي 270 | نهاية دالة 271 | 272 | دالة عدد جذر٣ ( عدد أ ) 273 | عدد حقيقي 274 | _س_ @حقيقي@ = cbrt(@أ@) ; _س_ 275 | إرجاع حقيقي 276 | نهاية دالة 277 | 278 | دالة عدد أس ( عدد أ ، عدد ب) 279 | عدد حقيقي 280 | _س_ @حقيقي@ = pow( @أ@ , @ب@ ) ; _س_ 281 | إرجاع حقيقي 282 | نهاية دالة 283 | 284 | دالة عدد مطلق ( عدد أ ) 285 | عدد حقيقي 286 | _س_ @حقيقي@ = fabs(@أ@) ; _س_ 287 | إرجاع حقيقي 288 | نهاية دالة 289 | 290 | دالة عدد أرض ( عدد أ ) 291 | عدد حقيقي 292 | _س_ @حقيقي@ = floor(@أ@) ; _س_ 293 | إرجاع حقيقي 294 | نهاية دالة 295 | 296 | دالة عدد سقف ( عدد أ ) 297 | عدد حقيقي 298 | _س_ @حقيقي@ = ceil(@أ@) ; _س_ 299 | إرجاع حقيقي 300 | نهاية دالة 301 | 302 | -------- الاختصارات -------- 303 | 304 | دالة عدد جذر ( عدد أ ) 305 | عدد حقيقي 306 | _س_ @حقيقي@ = sqrt(@أ@) ; _س_ 307 | إرجاع حقيقي 308 | نهاية دالة 309 | 310 | نهاية صنف 311 | 312 | كائن رياضيات = رياضيات__() 313 | -------------------------------------------------------------------------------- /src/alif_var.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | #include // vector 24 | // ---------------------------------- 25 | 26 | void parser_Var(std::string Token[2048], CLASS_TOKEN *o_tokens) 27 | { 28 | 29 | // Local var 30 | // a = 1 + 2 31 | 32 | // Note: Parsing Local var must be first, and global after. 33 | 34 | if (!o_tokens->TOKENS_PREDEFINED) 35 | return; // continue; 36 | 37 | if (!IsInsideFunction) 38 | ErrorCode("يجب استعمال المتغير داخل دالة ' " + Token[1] + " ' ", o_tokens); 39 | 40 | if (Token[2] == ":") 41 | ErrorCode("ليس كائن ' " + Token[1] + " ' ", o_tokens); 42 | 43 | if (Token[2] != "=") 44 | ErrorCode("يجب اضافة ' = ' بعد اسم المتغير", o_tokens); 45 | 46 | if (Token[3] == "") 47 | ErrorCode("يجب اضافه قيمة بعد ' = ' ", o_tokens); 48 | 49 | std::string CLASS_OR_WIN; 50 | if (IsInsideClass) 51 | CLASS_OR_WIN = TheClass; 52 | else 53 | CLASS_OR_WIN = TheNamespace; 54 | 55 | if (L_VAR_TYPE[std::make_pair(CLASS_OR_WIN + TheFunction, Token[1])] == 56 | "عدد") 57 | { 58 | // if (L_VAR_IS_CONST[std::make_pair(CLASS_OR_WIN + TheFunction, Token[1])] 59 | // == "ثابت") ErrorCode("لا يمكن تغيير قيمة المتغير ' " + Token[1] + " ' لأنه 60 | // من نوع ثابت ", o_tokens); 61 | 62 | if (DEBUG) 63 | DEBUG_MESSAGE("[LOCAL-INT (" + Token[1] + ")] = ", o_tokens); // DEBUG 64 | 65 | // *** Generate Code *** 66 | // Local INT = ... 67 | if (IsInsideClass) 68 | { 69 | CPP_CLASS.append(" " + ID[Token[1]] + " = "); 70 | } 71 | else if (!IsInsideNamespace) 72 | { 73 | // global func 74 | CPP_GLOBAL_FUN.append(" " + ID[Token[1]] + " = "); 75 | } 76 | else 77 | { 78 | // local func 79 | cpp_AddScript(TheFunction, " " + ID[Token[1]] + " = "); 80 | } 81 | // *** *** *** *** *** *** 82 | } 83 | else if (L_VAR_TYPE[std::make_pair(CLASS_OR_WIN + TheFunction, Token[1])] == 84 | "نص") 85 | { 86 | // if (L_VAR_IS_CONST[std::make_pair(CLASS_OR_WIN + TheFunction, Token[1])] 87 | // == "ثابت") ErrorCode("لا يمكن تغيير قيمة المتغير ' " + Token[1] + " ' لأنه 88 | // من نوع ثابت ", o_tokens); 89 | 90 | if (DEBUG) 91 | DEBUG_MESSAGE("[LOCAL-STRING (" + Token[1] + ")] = ", o_tokens); // DEBUG 92 | 93 | // *** Generate Code *** 94 | // Local STRING = ... 95 | if (IsInsideClass) 96 | { 97 | CPP_CLASS.append(" " + ID[Token[1]] + " = "); 98 | } 99 | else if (!IsInsideNamespace) 100 | { 101 | // global func 102 | CPP_GLOBAL_FUN.append(" " + ID[Token[1]] + " = "); 103 | } 104 | else 105 | { 106 | // local func 107 | cpp_AddScript(TheFunction, " " + ID[Token[1]] + " = "); 108 | } 109 | // *** *** *** *** *** *** 110 | } 111 | else if (L_VAR_TYPE[std::make_pair(CLASS_OR_WIN + TheFunction, Token[1])] == 112 | "منطق") 113 | { 114 | // if (L_VAR_IS_CONST[std::make_pair(CLASS_OR_WIN + TheFunction, Token[1])] 115 | // == "ثابت") ErrorCode("لا يمكن تغيير قيمة المتغير ' " + Token[1] + " ' لأنه 116 | // من نوع ثابت ", o_tokens); 117 | 118 | if (DEBUG) 119 | DEBUG_MESSAGE("[LOCAL-BOOL (" + Token[1] + ")] = ", o_tokens); // DEBUG 120 | 121 | // *** Generate Code *** 122 | // Local BOOL = ... 123 | if (IsInsideClass) 124 | { 125 | CPP_CLASS.append(" " + ID[Token[1]] + " = "); 126 | } 127 | else if (!IsInsideNamespace) 128 | { 129 | CPP_GLOBAL_FUN.append(" " + ID[Token[1]] + " = "); 130 | } 131 | else 132 | { 133 | cpp_AddScript(TheFunction, " " + ID[Token[1]] + " = "); 134 | } 135 | // *** *** *** *** *** *** 136 | } 137 | 138 | /* 139 | if (!IsInsideNamespace && IsInsideFunction) 140 | { 141 | // *** Generate Code *** 142 | // Global Function 143 | CPP_GLOBAL_FUN.append(" " + ID[Token[1]] + " = "); 144 | // *** *** *** *** *** *** 145 | } 146 | else if (IsInsideNamespace && IsInsideFunction) 147 | { 148 | // *** Generate Code *** 149 | // Local Function 150 | cpp_AddScript(TheFunction, " " + ID[Token[1]] + " = "); 151 | // *** *** *** *** *** *** 152 | } 153 | */ 154 | 155 | TempTokenCount = 0; 156 | 157 | for (int p = 2; p <= o_tokens->TOTAL[o_tokens->Line]; p++) 158 | { 159 | if (Token[p] != "") 160 | { 161 | TempToken[TempTokenCount] = Token[p]; 162 | TempTokenCount++; 163 | } 164 | } 165 | 166 | // Local var Syntax 167 | // a = 1 + a * (_g - 3) ... 168 | 169 | ScriptSyntaxBuffer = 170 | CheckForSyntax(L_VAR_TYPE[std::make_pair(CLASS_OR_WIN + TheFunction, 171 | Token[1])], // OBJECTIF_TYPE 172 | true, // Accept Using Reference to Namespace:Controls 173 | true, // Accept Using Reference to Namespace:Function 174 | true, // Accept Using Reference to Global Functions 175 | true, // Accept Using Reference to Local Functions 176 | true, // Accept Using Reference to Global VAR 177 | true, // Accept Using Reference to Local VAR 178 | false, // Accept Convertion from String To Int 179 | true, // Accept Convertion from Int To String 180 | TempToken, // SYNTAX[] std::string 181 | (TempTokenCount - 1), // SYNTAX_LONG int 182 | CLASS_OR_WIN, // TMP_WINDOW_NAME 183 | TheFunction, // TMP_FUNCTION_NAME 184 | o_tokens); 185 | 186 | if (DEBUG) 187 | DEBUG_MESSAGE("\n\n", o_tokens); // DEBUG 188 | 189 | // *** Generate Code *** 190 | // Local A = ... 191 | if (IsInsideClass) 192 | { 193 | CPP_CLASS.append(ScriptSyntaxBuffer + " ; \n"); 194 | } 195 | else if (!IsInsideNamespace) 196 | { 197 | // from global func 198 | CPP_GLOBAL_FUN.append(ScriptSyntaxBuffer + " ; \n"); 199 | } 200 | else 201 | { 202 | // from local func 203 | cpp_AddScript(TheFunction, ScriptSyntaxBuffer + " ; \n"); 204 | } 205 | // *** *** *** *** *** *** 206 | 207 | return; // continue; 208 | } 209 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | add_definitions( -DINSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} ) 3 | 4 | # Info 5 | set(Info_Title "Alif Compiler") 6 | set(Info_Source "alif.cpp") 7 | set(Info_App "alif") 8 | 9 | # Working directory for Debugin & Testing 10 | set(WD_Windows "C:\\Alif3") 11 | 12 | # --[ Alif ] ------------------------------------------------------------------- 13 | 14 | link_directories(${AlifProject_BIN_DIR}/alif) 15 | 16 | # --[ International Components for Unicode (ICU) ] ----------------------------- 17 | 18 | # /lib/x86_64-linux-gnu/libicuuc.a 19 | 20 | if(UNIX) 21 | message("[*] Using installed copy of ICU Library on Linux.") 22 | 23 | find_package(ICU 60.0 COMPONENTS io i18n REQUIRED) 24 | 25 | if(ICU_FOUND) 26 | include_directories(${ICU_INCLUDE_DIRS}) 27 | link_directories(${ICU_LIBRARY_DIRS}) 28 | else() 29 | message("[!] Please install ICU +66.0 libraries.") 30 | return() 31 | endif() 32 | else() 33 | message("[*] No need for ICU on Windows. Skip..") 34 | endif() 35 | 36 | # --[ Boost ] ----------------------------------------------------------------- 37 | 38 | message("[*] Initializing Boost for ${Info_Title}...") 39 | 40 | set(Boost_NO_WARN_NEW_VERSIONS ON) 41 | 42 | if (WIN32) 43 | set(BOOST_ROOT ${Boost_Root}) 44 | set(Boost_LIBRARY_DIR ${Boost_Lib}) 45 | message("[*] Using Boost root: ${BOOST_ROOT}") 46 | message("[*] Using Boost lib: ${Boost_LIBRARY_DIR}") 47 | 48 | set(Boost_ARCHITECTURE "-x64") 49 | set(Boost_USE_STATIC_LIBS ON) 50 | set(Boost_USE_MULTITHREADED ON) 51 | set(Boost_USE_STATIC_RUNTIME ON) 52 | # set(Boost_COMPILER "-mgw8") 53 | 54 | # set(Boost_DETAILED_FAILURE_MSG OFF) 55 | # set(Boost_DEBUG OFF) 56 | # set(Boost_THREADAPI "win32") 57 | # set(Boost_COMPILER "-vc142") 58 | # add_definitions( -DBOOST_ALL_NO_LIB ) 59 | else() 60 | # set(Boost_DEBUG OFF) 61 | set(Boost_USE_STATIC_LIBS OFF) 62 | set(Boost_USE_MULTITHREADED ON) 63 | set(Boost_USE_STATIC_RUNTIME OFF) 64 | # set(Boost_ARCHITECTURE "-x64") 65 | # set(Boost_THREADAPI "pthread") 66 | # set(Boost_DETAILED_FAILURE_MSG ON) 67 | # set(Boost_COMPILER "-gcc") 68 | add_definitions( -DBOOST_ALL_NO_LIB ) 69 | endif() 70 | 71 | message("[*] Searching for Boost libs...") 72 | 73 | find_package(Boost ${Boost_Version_Needed} REQUIRED COMPONENTS date_time filesystem regex nowide program_options locale thread) 74 | 75 | if(Boost_FOUND) 76 | include_directories(${Boost_INCLUDE_DIRS}) 77 | link_directories(${Boost_LIBRARY_DIRS}) 78 | else() 79 | message("[!] Please install Boost lib.") 80 | return() 81 | endif() 82 | 83 | # --[ pThread ] --------------------------------------------------------------- 84 | 85 | if(UNIX) 86 | message("[*] Using POSIX threading (pThread).") 87 | set(THREADS_PREFER_PTHREAD_FLAG ON) 88 | find_package(Threads REQUIRED) 89 | endif (UNIX) 90 | 91 | # --[ Target ] ------------------------------------------------------------------ 92 | 93 | add_executable(${Info_App} ${Info_Source}) 94 | 95 | if(UNIX) 96 | # message("[*] Setting working directory to ${WD_Linux}...") 97 | # set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${WD_Linux}) 98 | # set(EXECUTABLE_OUTPUT_PATH ${WD_Linux}) 99 | # set_target_properties(${Info_App} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${WD_Linux}) 100 | # set_target_properties(${Info_App} PROPERTIES CMAKE_RUNTIME_OUTPUT_DIRECTORY ${WD_Linux}) 101 | # set_target_properties(${Info_App} PROPERTIES EXECUTABLE_OUTPUT_PATH_DEBUG ${WD_Linux}) 102 | # set_target_properties(${Info_App} PROPERTIES CMAKE_EXECUTABLE_OUTPUT_PATH ${WD_Linux}) 103 | else() 104 | message("[*] Setting working directory to ${WD_Windows}...") 105 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${WD_Windows}) 106 | set(EXECUTABLE_OUTPUT_PATH ${WD_Windows}) 107 | set_target_properties(${Info_App} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${WD_Windows}) 108 | set_target_properties(${Info_App} PROPERTIES CMAKE_RUNTIME_OUTPUT_DIRECTORY ${WD_Windows}) 109 | set_target_properties(${Info_App} PROPERTIES EXECUTABLE_OUTPUT_PATH_DEBUG ${WD_Windows}) 110 | set_target_properties(${Info_App} PROPERTIES CMAKE_EXECUTABLE_OUTPUT_PATH ${WD_Windows}) 111 | endif () 112 | 113 | # --[ Compiler flags ] ---------------------------------------------------------- 114 | 115 | if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 116 | 117 | # using Clang 118 | if(UNIX) 119 | message("[*] Initializing '${Info_Title}' settings for Clang.") 120 | else() 121 | message("[!] Sorry. Alif don't support Clang on Windows, Please use Microsoft C++ compiler.") 122 | return() 123 | endif () 124 | 125 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 126 | 127 | if (WIN32) 128 | 129 | # using MinGW/GCC Windows 130 | message("[*] Initializing '${Info_Title}' settings for MinGW/GCC (Windows).") 131 | 132 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -fvisibility=hidden -w -O3 -std=gnu++17 -Wno-deprecated -municode") 133 | target_link_libraries(${Info_App} ${Boost_LIBRARIES} iconv pthread -static) 134 | 135 | else() 136 | 137 | # using GCC Linux 138 | message("[*] Initializing '${Info_Title}' settings for GCC (Linux).") 139 | 140 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -w -O3 -std=gnu++17 -Wno-deprecated" ) 141 | target_link_libraries(${Info_App} ${Boost_LIBRARIES} pthread) 142 | 143 | endif() 144 | 145 | # Flags 146 | # set_target_properties(${Info_App} PROPERTIES LINK_FLAGS_RELEASE -s) 147 | # set(CMAKE_CXX_FLAGS_RELEASE " -O3 ") 148 | # set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s -m64 ") 149 | #add_definitions(-DBOOST_SYSTEM_NO_DEPRECATED=1) 150 | 151 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel") 152 | 153 | # using Intel C++ 154 | if(UNIX) 155 | message("[!] Sorry. Alif don't support Intel C++ on Linux, Please install GCC or Clang.") 156 | else() 157 | message("[!] Sorry. Alif don't support Intel C++ on Windows, Please install Microsoft C++ compiler.") 158 | endif () 159 | 160 | return() 161 | 162 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") 163 | 164 | # Microsoft build tools 165 | if(UNIX) 166 | message("[!] Sorry. Alif don't support Microsoft C++ compiler on Linux, Please install GCC or Clang.") 167 | return() 168 | else() 169 | message("[*] Initializing '${Info_Title}' settings for Microsoft C++ compiler.") 170 | endif () 171 | 172 | # Flags 173 | add_link_options("/SUBSYSTEM:CONSOLE") 174 | set_target_properties(${Info_App} PROPERTIES LINK_FLAGS /SUBSYSTEM:CONSOLE) 175 | 176 | endif() 177 | 178 | # --[ Build ] ------------------------------------------------------------------- 179 | 180 | if(UNIX) 181 | target_link_libraries(${Info_App} ${ICU_LIBRARIES} 182 | -licuuc -licudata -licui18n 183 | ${Boost_LIBRARIES}) 184 | else() 185 | target_link_libraries(${Info_App} ${Boost_LIBRARIES}) 186 | endif() 187 | 188 | # --[ Install ] ----------------------------------------------------------------- 189 | 190 | if(UNIX) 191 | message("[*] Initializing installation settings...") 192 | install (TARGETS ${Info_App} 193 | ARCHIVE DESTINATION lib 194 | LIBRARY DESTINATION lib 195 | RUNTIME DESTINATION bin) 196 | install (DIRECTORY aliflib DESTINATION lib) 197 | endif (UNIX) 198 | 199 | if(WIN32) 200 | message("[*] Initializing installation settings...") 201 | install (TARGETS ${Info_App} DESTINATION C:/Alif3) 202 | install (DIRECTORY aliflib DESTINATION C:/Alif3) 203 | endif () 204 | 205 | # --[ Copy Examples ] ------------------------------------------------------------ 206 | 207 | file(COPY examples DESTINATION ${CMAKE_BINARY_DIR}/) 208 | -------------------------------------------------------------------------------- /src/aliflib/webui.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | WebUI Library 3 | - - - - - - - 4 | http://webui.me 5 | https://github.com/alifcommunity/webui 6 | Licensed under GNU General Public License v3.0. 7 | Copyright (C)2020 Hassan DRAGA . 8 | */ 9 | 10 | #pragma once 11 | #ifndef WEBUI_H 12 | #define WEBUI_H 13 | 14 | // -- C++ Standard ----------------------------- 15 | #include // 16 | #include // 17 | #include // Standard threading 18 | #include // 19 | #ifdef __linux__ 20 | #include // POSIX threading 21 | #endif 22 | 23 | namespace webui 24 | { 25 | 26 | namespace browser 27 | { 28 | 29 | unsigned short chrome = 1; 30 | unsigned short firefox = 2; 31 | unsigned short edge = 3; 32 | unsigned short safari = 4; 33 | unsigned short custom = 99; 34 | } // namespace browser 35 | 36 | struct event 37 | { 38 | 39 | unsigned short window_id = 0; 40 | unsigned short element_id = 0; 41 | std::string element_name = ""; 42 | }; 43 | 44 | struct custom_browser_t 45 | { 46 | 47 | std::string app; 48 | std::string arg; 49 | bool link = true; 50 | }; 51 | 52 | void ini(); 53 | void loop(); 54 | void exit(); 55 | bool any_is_show(); 56 | void set_custom_browser(const webui::custom_browser_t *b); 57 | void set_timeout_sec(unsigned short s); 58 | std::string get_current_path(); 59 | 60 | // -- Class ---- 61 | class _window 62 | { 63 | public: 64 | _window(); 65 | ~_window(); 66 | struct 67 | { 68 | std::thread *webserver_thread = nullptr; 69 | std::thread *websocket_thread = nullptr; 70 | std::string number_s; 71 | unsigned short number = 0; 72 | bool webserver_running = false; 73 | bool websocket_running = false; 74 | bool webserver_served = false; 75 | bool webserver_allow_multi = false; 76 | bool webserver_local_files = false; 77 | std::string webserver_local_root; 78 | std::string webserver_port = "0"; 79 | std::string websocket_port = "0"; 80 | const std::string *html = nullptr; 81 | const std::string *icon = nullptr; 82 | std::string icon_type; 83 | std::array key_action_all; 84 | bool is_bind_all = false; 85 | } settings; 86 | void receive(std::vector &packets_v); 87 | void send(std::vector &packets_v) const; 88 | void event(const std::string &id, const std::string &element); 89 | void websocket_session_clean(); 90 | unsigned short bind(std::string key_id, 91 | void (*function_ref)(webui::event e)) const; 92 | void bind_all(void (*function_ref)(webui::event e)); 93 | bool window_show(const std::string *html, unsigned short browser); 94 | void set_window_icon(const std::string *icon_s, const std::string type_s); 95 | void allow_multi_access(bool status); 96 | void set_root_folder(std::string local_path); 97 | std::string new_server(const std::string *html); 98 | unsigned short get_window_number() const; 99 | bool window_is_running() const; 100 | bool any_window_is_running() const; 101 | void destroy(); 102 | std::string run(std::string js, unsigned short seconds) const; 103 | void open_window(std::string link, unsigned short browser); 104 | }; 105 | 106 | class window 107 | { 108 | 109 | private: 110 | union 111 | { 112 | 113 | //_window o_win = _window::_window(); 114 | _window o_win = _window(); 115 | }; 116 | 117 | const std::string *p_html = nullptr; 118 | 119 | public: 120 | window() { webui::ini(); } 121 | 122 | ~window() { o_win.~_window(); } 123 | 124 | // -- Window ----------------------------- 125 | 126 | bool is_show() const { return o_win.window_is_running(); } 127 | 128 | bool any_is_show() const { return o_win.any_window_is_running(); } 129 | 130 | bool show(const std::string *html) 131 | { 132 | 133 | // if(o_win.window_is_running()) 134 | // return true; 135 | 136 | this->p_html = html; 137 | return o_win.window_show(this->p_html, 0); 138 | } 139 | 140 | bool show(const std::string *html, unsigned short browser) 141 | { 142 | 143 | // if(o_win.window_is_running()) 144 | // return true; 145 | 146 | this->p_html = html; 147 | return o_win.window_show(this->p_html, browser); 148 | } 149 | 150 | bool show(const std::string html) 151 | { 152 | 153 | std::string *_html = new std::string(html); 154 | 155 | // return this->show(_html, 0); 156 | return o_win.window_show(_html, 0); 157 | } 158 | 159 | bool show(const std::string *html, const webui::custom_browser_t *b) 160 | { 161 | 162 | // if(o_win.window_is_running()) 163 | // return true; 164 | 165 | // Update custom browser reference 166 | webui::set_custom_browser(b); 167 | 168 | this->p_html = html; 169 | return o_win.window_show(this->p_html, webui::browser::custom); 170 | } 171 | 172 | unsigned short bind(const std::string &id, 173 | void (*func_ref)(webui::event e)) const 174 | { 175 | 176 | return o_win.bind(id, func_ref); 177 | } 178 | 179 | unsigned short get_window_id() const { return o_win.get_window_number(); } 180 | 181 | void bind_all(void (*func_ref)(webui::event e)) { o_win.bind_all(func_ref); } 182 | 183 | void serve_folder(std::string p) { o_win.set_root_folder(p); } 184 | 185 | void serve_folder() { o_win.set_root_folder(""); } 186 | 187 | void close() 188 | { 189 | 190 | o_win.run(" webui_close_window(); ", 1); 191 | 192 | // if(o_win.window_is_running()) 193 | // o_win.destroy(); 194 | } 195 | 196 | void allow_multi_serving(bool b) { o_win.allow_multi_access(b); } 197 | 198 | void set_favicon(const std::string *icon, const std::string &type) 199 | { 200 | 201 | o_win.set_window_icon(icon, type); 202 | } 203 | 204 | std::string new_server(const std::string *html) 205 | { 206 | 207 | return o_win.new_server(html); 208 | } 209 | 210 | std::string new_server() { return o_win.new_server(nullptr); } 211 | 212 | std::string get_current_path() { return webui::get_current_path(); } 213 | 214 | void open_window(std::string link, unsigned short browser) 215 | { 216 | 217 | o_win.open_window(link, browser); 218 | } 219 | 220 | // -- JavaScript ------------------------------------------ 221 | 222 | std::string run_js(const std::string &js) const 223 | { 224 | 225 | if (!o_win.window_is_running()) 226 | return ""; 227 | 228 | return o_win.run(js, 1); 229 | } 230 | 231 | std::string run_js(const std::string &js, unsigned short s) const 232 | { 233 | 234 | if (!o_win.window_is_running()) 235 | return ""; 236 | 237 | return o_win.run(js, s); 238 | } 239 | 240 | std::string get_value(const std::string &id) const 241 | { 242 | 243 | if (!o_win.window_is_running()) 244 | return ""; 245 | 246 | std::string buf; 247 | buf.append(" return String(document.getElementById('"); 248 | buf.append(id); 249 | buf.append("').value); "); 250 | 251 | return o_win.run(buf, 1); 252 | } 253 | 254 | std::string set_value(const std::string &id, const std::string &data) 255 | { 256 | 257 | if (!o_win.window_is_running()) 258 | return ""; 259 | 260 | std::string buf; 261 | buf.append(" const rawdata = String.raw`"); 262 | buf.append(data); 263 | buf.append("`; document.getElementById('"); 264 | buf.append(id); 265 | buf.append("').value = `${rawdata}`; "); 266 | 267 | return o_win.run(buf, 1); 268 | } 269 | }; 270 | } // namespace webui 271 | 272 | #endif -------------------------------------------------------------------------------- /src/utf8/unchecked.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 28 | #define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | 30 | #include "core.h" 31 | 32 | namespace utf8 33 | { 34 | namespace unchecked 35 | { 36 | template 37 | octet_iterator append(uint32_t cp, octet_iterator result) 38 | { 39 | if (cp < 0x80) // one octet 40 | *(result++) = static_cast(cp); 41 | else if (cp < 0x800) 42 | { // two octets 43 | *(result++) = static_cast((cp >> 6) | 0xc0); 44 | *(result++) = static_cast((cp & 0x3f) | 0x80); 45 | } 46 | else if (cp < 0x10000) 47 | { // three octets 48 | *(result++) = static_cast((cp >> 12) | 0xe0); 49 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); 50 | *(result++) = static_cast((cp & 0x3f) | 0x80); 51 | } 52 | else 53 | { // four octets 54 | *(result++) = static_cast((cp >> 18) | 0xf0); 55 | *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); 56 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); 57 | *(result++) = static_cast((cp & 0x3f) | 0x80); 58 | } 59 | return result; 60 | } 61 | 62 | template 63 | uint32_t next(octet_iterator &it) 64 | { 65 | uint32_t cp = utf8::internal::mask8(*it); 66 | typename std::iterator_traits::difference_type length = 67 | utf8::internal::sequence_length(it); 68 | switch (length) 69 | { 70 | case 1: 71 | break; 72 | case 2: 73 | it++; 74 | cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); 75 | break; 76 | case 3: 77 | ++it; 78 | cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); 79 | ++it; 80 | cp += (*it) & 0x3f; 81 | break; 82 | case 4: 83 | ++it; 84 | cp = ((cp << 18) & 0x1fffff) + 85 | ((utf8::internal::mask8(*it) << 12) & 0x3ffff); 86 | ++it; 87 | cp += (utf8::internal::mask8(*it) << 6) & 0xfff; 88 | ++it; 89 | cp += (*it) & 0x3f; 90 | break; 91 | } 92 | ++it; 93 | return cp; 94 | } 95 | 96 | template 97 | uint32_t peek_next(octet_iterator it) 98 | { 99 | return utf8::unchecked::next(it); 100 | } 101 | 102 | template 103 | uint32_t prior(octet_iterator &it) 104 | { 105 | while (utf8::internal::is_trail(*(--it))) 106 | ; 107 | octet_iterator temp = it; 108 | return utf8::unchecked::next(temp); 109 | } 110 | 111 | // Deprecated in versions that include prior, but only for the sake of 112 | // consistency (see utf8::previous) 113 | template 114 | inline uint32_t previous(octet_iterator &it) 115 | { 116 | return utf8::unchecked::prior(it); 117 | } 118 | 119 | template 120 | void advance(octet_iterator &it, distance_type n) 121 | { 122 | for (distance_type i = 0; i < n; ++i) 123 | utf8::unchecked::next(it); 124 | } 125 | 126 | template 127 | typename std::iterator_traits::difference_type 128 | distance(octet_iterator first, octet_iterator last) 129 | { 130 | typename std::iterator_traits::difference_type dist; 131 | for (dist = 0; first < last; ++dist) 132 | utf8::unchecked::next(first); 133 | return dist; 134 | } 135 | 136 | template 137 | octet_iterator utf16to8(u16bit_iterator start, u16bit_iterator end, 138 | octet_iterator result) 139 | { 140 | while (start != end) 141 | { 142 | uint32_t cp = utf8::internal::mask16(*start++); 143 | // Take care of surrogate pairs first 144 | if (utf8::internal::is_lead_surrogate(cp)) 145 | { 146 | uint32_t trail_surrogate = utf8::internal::mask16(*start++); 147 | cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; 148 | } 149 | result = utf8::unchecked::append(cp, result); 150 | } 151 | return result; 152 | } 153 | 154 | template 155 | u16bit_iterator utf8to16(octet_iterator start, octet_iterator end, 156 | u16bit_iterator result) 157 | { 158 | while (start < end) 159 | { 160 | uint32_t cp = utf8::unchecked::next(start); 161 | if (cp > 0xffff) 162 | { // make a surrogate pair 163 | *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); 164 | *result++ = 165 | static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); 166 | } 167 | else 168 | *result++ = static_cast(cp); 169 | } 170 | return result; 171 | } 172 | 173 | template 174 | octet_iterator utf32to8(u32bit_iterator start, u32bit_iterator end, 175 | octet_iterator result) 176 | { 177 | while (start != end) 178 | result = utf8::unchecked::append(*(start++), result); 179 | 180 | return result; 181 | } 182 | 183 | template 184 | u32bit_iterator utf8to32(octet_iterator start, octet_iterator end, 185 | u32bit_iterator result) 186 | { 187 | while (start < end) 188 | (*result++) = utf8::unchecked::next(start); 189 | 190 | return result; 191 | } 192 | 193 | // The iterator class 194 | template 195 | class iterator 196 | : public std::iterator 197 | { 198 | octet_iterator it; 199 | 200 | public: 201 | iterator() {} 202 | explicit iterator(const octet_iterator &octet_it) : it(octet_it) {} 203 | // the default "big three" are OK 204 | octet_iterator base() const { return it; } 205 | uint32_t operator*() const 206 | { 207 | octet_iterator temp = it; 208 | return utf8::unchecked::next(temp); 209 | } 210 | bool operator==(const iterator &rhs) const { return (it == rhs.it); } 211 | bool operator!=(const iterator &rhs) const { return !(operator==(rhs)); } 212 | iterator &operator++() 213 | { 214 | ::std::advance(it, utf8::internal::sequence_length(it)); 215 | return *this; 216 | } 217 | iterator operator++(int) 218 | { 219 | iterator temp = *this; 220 | ::std::advance(it, utf8::internal::sequence_length(it)); 221 | return temp; 222 | } 223 | iterator &operator--() 224 | { 225 | utf8::unchecked::prior(it); 226 | return *this; 227 | } 228 | iterator operator--(int) 229 | { 230 | iterator temp = *this; 231 | utf8::unchecked::prior(it); 232 | return temp; 233 | } 234 | }; // class iterator 235 | 236 | } // namespace unchecked 237 | } // namespace utf8 238 | 239 | #endif // header guard 240 | -------------------------------------------------------------------------------- /src/aliflib/utf8/unchecked.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 28 | #define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | 30 | #include "core.h" 31 | 32 | namespace utf8 33 | { 34 | namespace unchecked 35 | { 36 | template 37 | octet_iterator append(uint32_t cp, octet_iterator result) 38 | { 39 | if (cp < 0x80) // one octet 40 | *(result++) = static_cast(cp); 41 | else if (cp < 0x800) 42 | { // two octets 43 | *(result++) = static_cast((cp >> 6) | 0xc0); 44 | *(result++) = static_cast((cp & 0x3f) | 0x80); 45 | } 46 | else if (cp < 0x10000) 47 | { // three octets 48 | *(result++) = static_cast((cp >> 12) | 0xe0); 49 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); 50 | *(result++) = static_cast((cp & 0x3f) | 0x80); 51 | } 52 | else 53 | { // four octets 54 | *(result++) = static_cast((cp >> 18) | 0xf0); 55 | *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); 56 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); 57 | *(result++) = static_cast((cp & 0x3f) | 0x80); 58 | } 59 | return result; 60 | } 61 | 62 | template 63 | uint32_t next(octet_iterator &it) 64 | { 65 | uint32_t cp = utf8::internal::mask8(*it); 66 | typename std::iterator_traits::difference_type length = 67 | utf8::internal::sequence_length(it); 68 | switch (length) 69 | { 70 | case 1: 71 | break; 72 | case 2: 73 | it++; 74 | cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); 75 | break; 76 | case 3: 77 | ++it; 78 | cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); 79 | ++it; 80 | cp += (*it) & 0x3f; 81 | break; 82 | case 4: 83 | ++it; 84 | cp = ((cp << 18) & 0x1fffff) + 85 | ((utf8::internal::mask8(*it) << 12) & 0x3ffff); 86 | ++it; 87 | cp += (utf8::internal::mask8(*it) << 6) & 0xfff; 88 | ++it; 89 | cp += (*it) & 0x3f; 90 | break; 91 | } 92 | ++it; 93 | return cp; 94 | } 95 | 96 | template 97 | uint32_t peek_next(octet_iterator it) 98 | { 99 | return utf8::unchecked::next(it); 100 | } 101 | 102 | template 103 | uint32_t prior(octet_iterator &it) 104 | { 105 | while (utf8::internal::is_trail(*(--it))) 106 | ; 107 | octet_iterator temp = it; 108 | return utf8::unchecked::next(temp); 109 | } 110 | 111 | // Deprecated in versions that include prior, but only for the sake of 112 | // consistency (see utf8::previous) 113 | template 114 | inline uint32_t previous(octet_iterator &it) 115 | { 116 | return utf8::unchecked::prior(it); 117 | } 118 | 119 | template 120 | void advance(octet_iterator &it, distance_type n) 121 | { 122 | for (distance_type i = 0; i < n; ++i) 123 | utf8::unchecked::next(it); 124 | } 125 | 126 | template 127 | typename std::iterator_traits::difference_type 128 | distance(octet_iterator first, octet_iterator last) 129 | { 130 | typename std::iterator_traits::difference_type dist; 131 | for (dist = 0; first < last; ++dist) 132 | utf8::unchecked::next(first); 133 | return dist; 134 | } 135 | 136 | template 137 | octet_iterator utf16to8(u16bit_iterator start, u16bit_iterator end, 138 | octet_iterator result) 139 | { 140 | while (start != end) 141 | { 142 | uint32_t cp = utf8::internal::mask16(*start++); 143 | // Take care of surrogate pairs first 144 | if (utf8::internal::is_lead_surrogate(cp)) 145 | { 146 | uint32_t trail_surrogate = utf8::internal::mask16(*start++); 147 | cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; 148 | } 149 | result = utf8::unchecked::append(cp, result); 150 | } 151 | return result; 152 | } 153 | 154 | template 155 | u16bit_iterator utf8to16(octet_iterator start, octet_iterator end, 156 | u16bit_iterator result) 157 | { 158 | while (start < end) 159 | { 160 | uint32_t cp = utf8::unchecked::next(start); 161 | if (cp > 0xffff) 162 | { // make a surrogate pair 163 | *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); 164 | *result++ = 165 | static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); 166 | } 167 | else 168 | *result++ = static_cast(cp); 169 | } 170 | return result; 171 | } 172 | 173 | template 174 | octet_iterator utf32to8(u32bit_iterator start, u32bit_iterator end, 175 | octet_iterator result) 176 | { 177 | while (start != end) 178 | result = utf8::unchecked::append(*(start++), result); 179 | 180 | return result; 181 | } 182 | 183 | template 184 | u32bit_iterator utf8to32(octet_iterator start, octet_iterator end, 185 | u32bit_iterator result) 186 | { 187 | while (start < end) 188 | (*result++) = utf8::unchecked::next(start); 189 | 190 | return result; 191 | } 192 | 193 | // The iterator class 194 | template 195 | class iterator 196 | : public std::iterator 197 | { 198 | octet_iterator it; 199 | 200 | public: 201 | iterator() {} 202 | explicit iterator(const octet_iterator &octet_it) : it(octet_it) {} 203 | // the default "big three" are OK 204 | octet_iterator base() const { return it; } 205 | uint32_t operator*() const 206 | { 207 | octet_iterator temp = it; 208 | return utf8::unchecked::next(temp); 209 | } 210 | bool operator==(const iterator &rhs) const { return (it == rhs.it); } 211 | bool operator!=(const iterator &rhs) const { return !(operator==(rhs)); } 212 | iterator &operator++() 213 | { 214 | ::std::advance(it, utf8::internal::sequence_length(it)); 215 | return *this; 216 | } 217 | iterator operator++(int) 218 | { 219 | iterator temp = *this; 220 | ::std::advance(it, utf8::internal::sequence_length(it)); 221 | return temp; 222 | } 223 | iterator &operator--() 224 | { 225 | utf8::unchecked::prior(it); 226 | return *this; 227 | } 228 | iterator operator--(int) 229 | { 230 | iterator temp = *this; 231 | utf8::unchecked::prior(it); 232 | return temp; 233 | } 234 | }; // class iterator 235 | 236 | } // namespace unchecked 237 | } // namespace utf8 238 | 239 | #endif // header guard 240 | -------------------------------------------------------------------------------- /src/alif_return.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_Return(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | // إرجاع 27 | // func int () 28 | // return 1 + 2 29 | 30 | // Note: Parsing Local var must be first, and global after. 31 | 32 | if (!o_tokens->TOKENS_PREDEFINED) 33 | return; // continue; 34 | 35 | if (!IsInsideFunction) 36 | ErrorCode("يجب استعمال ' إرجاع ' داخل دالة", o_tokens); 37 | 38 | if (TheFunction_TYPE == "عادم") 39 | { 40 | // ErrorCode("لا يمكن استعمال ' إرجاع ' في دالة من نوع عادم", o_tokens); 41 | 42 | if (Token[2] != "") 43 | ErrorCode("لا يمكن إرجاع قيمة، لأن الدالة ' " + TheFunction + 44 | " ' من نوع عادم، المرجو عدم كتابة أي شيئ بعد ' إرجاع '، أو " 45 | "تغيير نوع الدالة", 46 | o_tokens); 47 | 48 | if (IsInsideClass) 49 | { 50 | // void return in class func 51 | 52 | if (DEBUG) 53 | DEBUG_MESSAGE("[VOID-RETURN-CLASS-FUN] \n\n", o_tokens); // DEBUG 54 | 55 | // *** Generate Code *** 56 | CPP_CLASS.append("\n return; \n"); 57 | // *** *** *** *** *** *** 58 | 59 | return; // continue; 60 | } 61 | else if (!IsInsideNamespace) 62 | { 63 | // void return in global func 64 | 65 | if (DEBUG) 66 | DEBUG_MESSAGE("[VOID-RETURN-GLOBAL-FUN] \n\n", o_tokens); // DEBUG 67 | 68 | // *** Generate Code *** 69 | CPP_GLOBAL_FUN.append("\n return; \n"); 70 | // *** *** *** *** *** *** 71 | 72 | return; // continue; 73 | } 74 | else 75 | { 76 | // void return in local func 77 | 78 | if (DEBUG) 79 | DEBUG_MESSAGE("[VOID-RETURN-LOCAL-FUN] \n\n", o_tokens); // DEBUG 80 | 81 | // *** Generate Code *** 82 | cpp_AddScript(TheFunction, "\n return; \n"); 83 | // *** *** *** *** *** *** 84 | 85 | return; // continue; 86 | } 87 | } 88 | else 89 | { 90 | // return int 91 | // return std::string 92 | // return bool 93 | 94 | if (Token[2] == "") 95 | ErrorCode("يجب اضافه قيمة بعد ' إرجاع ' لأن الدالة ' " + TheFunction + 96 | " ' من نوع " + TheFunction_TYPE, 97 | o_tokens); 98 | } 99 | 100 | // std::string FUN_TYPE; 101 | 102 | if (IsInsideClass) 103 | { 104 | // return in class func 105 | 106 | if (TheFunction_TYPE == "عدد") 107 | { 108 | if (DEBUG) 109 | DEBUG_MESSAGE("[RETURN-CLASS-INT] ", o_tokens); // DEBUG 110 | } 111 | else if (TheFunction_TYPE == "نص") 112 | { 113 | if (DEBUG) 114 | DEBUG_MESSAGE("[RETURN-CLASS-STRING] ", o_tokens); // DEBUG 115 | } 116 | else if (TheFunction_TYPE == "منطق") 117 | { 118 | if (DEBUG) 119 | DEBUG_MESSAGE("[RETURN-CLASS-BOOL] ", o_tokens); // DEBUG 120 | } 121 | 122 | // *** Generate Code *** 123 | CPP_CLASS.append("\n return ( "); 124 | // *** *** *** *** *** *** 125 | 126 | if (ALIF_IF_STATUS > 0 && 127 | RETURN_FUN[std::make_pair(TheClass, TheFunction)] == "") 128 | RETURN_FUN[std::make_pair(TheClass, TheFunction)] = "IF"; 129 | else 130 | RETURN_FUN[std::make_pair(TheClass, TheFunction)] = "OK"; 131 | } 132 | else if (!IsInsideNamespace) 133 | { 134 | // return in global func 135 | 136 | if (TheFunction_TYPE == "عدد") 137 | { 138 | if (DEBUG) 139 | DEBUG_MESSAGE("[RETURN-GLOBAL-INT] ", o_tokens); // DEBUG 140 | } 141 | else if (TheFunction_TYPE == "نص") 142 | { 143 | if (DEBUG) 144 | DEBUG_MESSAGE("[RETURN-GLOBAL-STRING] ", o_tokens); // DEBUG 145 | } 146 | else if (TheFunction_TYPE == "منطق") 147 | { 148 | if (DEBUG) 149 | DEBUG_MESSAGE("[RETURN-GLOABL-BOOL] ", o_tokens); // DEBUG 150 | } 151 | 152 | // *** Generate Code *** 153 | // Global Func Return 154 | CPP_GLOBAL_FUN.append("\n return ( "); 155 | // *** *** *** *** *** *** 156 | 157 | if (ALIF_IF_STATUS > 0 && RETURN_FUN[std::make_pair("", TheFunction)] == "") 158 | RETURN_FUN[std::make_pair("", TheFunction)] = "IF"; 159 | else 160 | RETURN_FUN[std::make_pair("", TheFunction)] = "OK"; 161 | } 162 | else 163 | { 164 | // return in local func 165 | 166 | if (TheFunction_TYPE == "عدد") 167 | { 168 | if (DEBUG) 169 | DEBUG_MESSAGE("[RETURN-INT] ", o_tokens); // DEBUG 170 | } 171 | else if (TheFunction_TYPE == "نص") 172 | { 173 | if (DEBUG) 174 | DEBUG_MESSAGE("[RETURN-STRING] ", o_tokens); // DEBUG 175 | } 176 | else if (TheFunction_TYPE == "منطق") 177 | { 178 | if (DEBUG) 179 | DEBUG_MESSAGE("[RETURN-BOOL] ", o_tokens); // DEBUG 180 | } 181 | 182 | // *** Generate Code *** 183 | // Local Func Return 184 | cpp_AddScript(TheFunction, "\n return ( "); 185 | // *** *** *** *** *** *** 186 | 187 | if (ALIF_IF_STATUS > 0 && 188 | RETURN_FUN[std::make_pair(TheNamespace, TheFunction)] == "") 189 | RETURN_FUN[std::make_pair(TheNamespace, TheFunction)] = "IF"; 190 | else 191 | RETURN_FUN[std::make_pair(TheNamespace, TheFunction)] = "OK"; 192 | } 193 | 194 | if (Token[2] == "صحيح") 195 | { 196 | // Return Syntax 197 | // return true. 198 | 199 | ScriptSyntaxBuffer = " true "; 200 | if (DEBUG) 201 | DEBUG_MESSAGE("[true] ", o_tokens); // DEBUG 202 | } 203 | else if (Token[2] == "خطأ") 204 | { 205 | // Return Syntax 206 | // return false. 207 | 208 | ScriptSyntaxBuffer = " false "; 209 | if (DEBUG) 210 | DEBUG_MESSAGE("[false] ", o_tokens); // DEBUG 211 | } 212 | else 213 | { 214 | 215 | // Return Syntax 216 | // return a + 1 + a * (_g - 3) ... 217 | 218 | TempToken[0] = "="; 219 | TempTokenCount = 1; 220 | 221 | for (int p = 2; p <= o_tokens->TOTAL[o_tokens->Line]; p++) 222 | { 223 | if (Token[p] != "") 224 | { 225 | TempToken[TempTokenCount] = Token[p]; 226 | TempTokenCount++; 227 | } 228 | } 229 | 230 | std::string WIN_OR_CLASS; 231 | if (IsInsideClass) 232 | WIN_OR_CLASS = TheClass; 233 | else 234 | WIN_OR_CLASS = TheNamespace; 235 | 236 | ScriptSyntaxBuffer = 237 | CheckForSyntax(TheFunction_TYPE, // OBJECTIF_TYPE 238 | true, // Accept Using Reference to Namespace:Controls 239 | true, // Accept Using Reference to Namespace:Function 240 | true, // Accept Using Reference to Global Functions 241 | true, // Accept Using Reference to Local Functions 242 | true, // Accept Using Reference to Global VAR 243 | true, // Accept Using Reference to Local VAR 244 | false, // Accept Convertion from String To Int 245 | true, // Accept Convertion from Int To String 246 | TempToken, // SYNTAX[] std::string 247 | (TempTokenCount - 1), // SYNTAX_LONG int 248 | WIN_OR_CLASS, // TMP_WINDOW_NAME 249 | TheFunction, // TMP_FUNCTION_NAME 250 | o_tokens); 251 | } 252 | 253 | // return 254 | // if (condition) 255 | // return 256 | // else 257 | // return 258 | 259 | // *** Generate Code *** 260 | if (IsInsideClass) 261 | { 262 | // Class Func return 263 | CPP_CLASS.append(ScriptSyntaxBuffer + " ); \n"); 264 | } 265 | else if (!IsInsideNamespace) 266 | { 267 | // Global Func Return 268 | CPP_GLOBAL_FUN.append(ScriptSyntaxBuffer + " ); \n"); 269 | } 270 | else 271 | { 272 | // Local Func Return 273 | cpp_AddScript(TheFunction, ScriptSyntaxBuffer + " ); \n"); 274 | } 275 | // *** *** *** *** *** *** 276 | 277 | if (DEBUG) 278 | DEBUG_MESSAGE("\n\n", o_tokens); // DEBUG 279 | 280 | return; // continue; 281 | } 282 | -------------------------------------------------------------------------------- /src/alif_var_g.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_VarGlobal(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | 27 | // Global var 28 | // _g1 = 1 + 2 29 | // g1 = 1 + 2 30 | 31 | if (!o_tokens->TOKENS_PREDEFINED) 32 | return; // continue; 33 | 34 | if (!IsInsideFunction) 35 | ErrorCode("يجب استعمال المتغير العام داخل دالة ' " + Token[1] + " ' ", 36 | o_tokens); 37 | 38 | // if (IsInsideNamespace && !IsInsideFunction) // C++ cant do this ! 39 | // ErrorCode("Using vars must set outside window for global, or inside 40 | // function for local.", o_tokens); 41 | 42 | std::string G_VAR_WITHOUT_; 43 | 44 | if (substr_utf8(Token[1], 0, 1) == "_") 45 | G_VAR_WITHOUT_ = 46 | substr_utf8(Token[1], 1, CharCount_utf8(Token[1], o_tokens)); 47 | else 48 | G_VAR_WITHOUT_ = Token[1]; 49 | 50 | if (!G_VAR_IS_SET[(G_VAR_WITHOUT_)]) 51 | ErrorCode("ليس متغير عام ' " + Token[1] + " ' ", o_tokens); 52 | 53 | if (Token[2] != "=") 54 | ErrorCode("يجب اضافة ' = ' بعد اسم المتغير", o_tokens); 55 | 56 | if (Token[3] == "") 57 | ErrorCode("يجب اضافه قيمة بعد ' = ' ", o_tokens); 58 | 59 | // if (!IsInsideFunction) 60 | // ErrorCode("Your are in global area, so you dont need to use '_' for the 61 | // global var : " + Token[1], o_tokens); 62 | 63 | if (IsInsideFunction) 64 | { 65 | // if (substr_utf8(Token[1], 0, 1) != "_") 66 | // ErrorCode("متغير محلي غير موجود, من اجل استعمال المتغير العام ' " + 67 | // Token[1] + " ' يجب اضافه خط قبل اسم المتغير على سبيل المثال : _" + 68 | // Token[1], o_tokens); 69 | 70 | if (G_VAR_TYPE[(G_VAR_WITHOUT_)] == "عدد") 71 | { 72 | // if (G_VAR_IS_CONST[(G_VAR_WITHOUT_)] == "ثابت") 73 | // ErrorCode("لا يمكن تغيير قيمة المتغير ' " + G_VAR_WITHOUT_ + " ' لأنه 74 | // من نوع ثابت ", o_tokens); 75 | 76 | if (DEBUG) 77 | DEBUG_MESSAGE("[GLOBAL-INT (" + G_VAR_WITHOUT_ + ")] = ", 78 | o_tokens); // DEBUG 79 | 80 | // *** Generate Code *** 81 | if (!IsInsideNamespace) 82 | // Global Function 83 | // global-int = ... 84 | CPP_GLOBAL_FUN.append(Global_ID[G_VAR_WITHOUT_] + " = "); 85 | else 86 | // Local Function 87 | // global-int = ... 88 | cpp_AddScript(TheFunction, Global_ID[G_VAR_WITHOUT_] + " = "); 89 | // *** *** *** *** *** *** 90 | } 91 | else if (G_VAR_TYPE[(G_VAR_WITHOUT_)] == "نص") 92 | { 93 | // if (G_VAR_IS_CONST[(G_VAR_WITHOUT_)] == "ثابت") 94 | // ErrorCode("لا يمكن تغيير قيمة المتغير ' " + G_VAR_WITHOUT_ + " ' لأنه 95 | // من نوع ثابت ", o_tokens); 96 | 97 | if (DEBUG) 98 | DEBUG_MESSAGE("[GLOBAL-STRING (" + G_VAR_WITHOUT_ + ")] = ", 99 | o_tokens); // DEBUG 100 | 101 | // *** Generate Code *** 102 | if (!IsInsideNamespace) 103 | // Global Function 104 | // global-std::string = ... 105 | CPP_GLOBAL_FUN.append(Global_ID[G_VAR_WITHOUT_] + " = "); 106 | else 107 | // Local Function 108 | // global-std::string = ... 109 | cpp_AddScript(TheFunction, Global_ID[G_VAR_WITHOUT_] + " = "); 110 | // *** *** *** *** *** *** 111 | } 112 | else if (G_VAR_TYPE[(G_VAR_WITHOUT_)] == "منطق") 113 | { 114 | // if (G_VAR_IS_CONST[(G_VAR_WITHOUT_)] == "ثابت") 115 | // ErrorCode("لا يمكن تغيير قيمة المتغير ' " + G_VAR_WITHOUT_ + " ' لأنه 116 | // من نوع ثابت ", o_tokens); 117 | 118 | if (DEBUG) 119 | DEBUG_MESSAGE("[GLOBAL-BOOL (" + G_VAR_WITHOUT_ + ")] = ", 120 | o_tokens); // DEBUG 121 | 122 | // *** Generate Code *** 123 | if (!IsInsideNamespace) 124 | // Global Function 125 | // global-BOOL = ... 126 | CPP_GLOBAL_FUN.append(Global_ID[G_VAR_WITHOUT_] + " = "); 127 | else 128 | // Local Function 129 | // global-BOOL = ... 130 | cpp_AddScript(TheFunction, Global_ID[G_VAR_WITHOUT_] + " = "); 131 | // *** *** *** *** *** *** 132 | } 133 | } 134 | else 135 | { 136 | if (G_VAR_TYPE[(G_VAR_WITHOUT_)] == "عدد") 137 | { 138 | // if (G_VAR_IS_CONST[(G_VAR_WITHOUT_)] == "ثابت") 139 | // ErrorCode("لا يمكن تغيير قيمة المتغير ' " + G_VAR_WITHOUT_ + " ' لأنه 140 | // من نوع ثابت ", o_tokens); 141 | 142 | if (DEBUG) 143 | DEBUG_MESSAGE("[GLOBAL-INT (" + G_VAR_WITHOUT_ + ")] = ", 144 | o_tokens); // DEBUG 145 | 146 | // *** Generate Code *** 147 | // Global Area 148 | // global-int = ... 149 | CPP_GLOBAL.append(Global_ID[G_VAR_WITHOUT_] + " = "); 150 | // *** *** *** *** *** *** 151 | } 152 | else if (G_VAR_TYPE[(G_VAR_WITHOUT_)] == "نص") 153 | { 154 | // if (G_VAR_IS_CONST[(G_VAR_WITHOUT_)] == "ثابت") 155 | // ErrorCode("لا يمكن تغيير قيمة المتغير ' " + G_VAR_WITHOUT_ + " ' لأنه 156 | // من نوع ثابت ", o_tokens); 157 | 158 | if (DEBUG) 159 | DEBUG_MESSAGE("[GLOBAL-STRING (" + G_VAR_WITHOUT_ + ")] = ", 160 | o_tokens); // DEBUG 161 | 162 | // *** Generate Code *** 163 | // Global Area 164 | // global-std::string = ... 165 | CPP_GLOBAL.append(Global_ID[G_VAR_WITHOUT_] + " = "); 166 | // *** *** *** *** *** *** 167 | } 168 | else if (G_VAR_TYPE[(G_VAR_WITHOUT_)] == "منطق") 169 | { 170 | // if (G_VAR_IS_CONST[(G_VAR_WITHOUT_)] == "ثابت") 171 | // ErrorCode("لا يمكن تغيير قيمة المتغير ' " + G_VAR_WITHOUT_ + " ' لأنه 172 | // من نوع ثابت ", o_tokens); 173 | 174 | if (DEBUG) 175 | DEBUG_MESSAGE("[GLOBAL-BOOL (" + G_VAR_WITHOUT_ + ")] = ", 176 | o_tokens); // DEBUG 177 | 178 | // *** Generate Code *** 179 | // Global Area 180 | // global-BOOL = ... 181 | CPP_GLOBAL.append(Global_ID[G_VAR_WITHOUT_] + " = "); 182 | // *** *** *** *** *** *** 183 | } 184 | } 185 | 186 | TempTokenCount = 0; 187 | for (int p = 2; p <= o_tokens->TOTAL[o_tokens->Line]; p++) 188 | { 189 | if (Token[p] != "") 190 | { 191 | TempToken[TempTokenCount] = Token[p]; 192 | TempTokenCount++; 193 | } 194 | } 195 | 196 | // Global var Syntax 197 | // _a = 1 + (_a * 3) ... 198 | 199 | ScriptSyntaxBuffer = 200 | CheckForSyntax(G_VAR_TYPE[(G_VAR_WITHOUT_)], // OBJECTIF_TYPE 201 | true, // Accept Using Reference to Namespace:Controls 202 | true, // Accept Using Reference to Namespace:Function 203 | true, // Accept Using Reference to Global Functions 204 | true, // Accept Using Reference to Local Functions 205 | true, // Accept Using Reference to Global VAR 206 | true, // Accept Using Reference to Local VAR 207 | false, // Accept Convertion from String To Int 208 | true, // Accept Convertion from Int To String 209 | TempToken, // SYNTAX[] std::string 210 | (TempTokenCount - 1), // SYNTAX_LONG int 211 | TheNamespace, // TMP_WINDOW_NAME 212 | TheFunction, // TMP_FUNCTION_NAME 213 | o_tokens); 214 | 215 | if (DEBUG) 216 | DEBUG_MESSAGE("\n\n", o_tokens); // DEBUG 217 | 218 | // *** Generate Code *** 219 | if (IsInsideFunction) 220 | { 221 | if (!IsInsideNamespace) 222 | // Global Function 223 | CPP_GLOBAL_FUN.append(ScriptSyntaxBuffer + " ; \n"); 224 | else 225 | // Local Function 226 | cpp_AddScript(TheFunction, ScriptSyntaxBuffer + " ; \n"); 227 | } 228 | else 229 | { 230 | // Global Area 231 | CPP_GLOBAL.append(ScriptSyntaxBuffer + " ; \n"); 232 | } 233 | // *** *** *** *** *** *** 234 | 235 | return; // continue; 236 | } 237 | -------------------------------------------------------------------------------- /src/alif_end.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_End(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | // نهاية 27 | 28 | if (Token[2] == "") 29 | ErrorCode("نهايه من دون تحديد المستهدف", o_tokens); 30 | 31 | if (Token[3] != "") 32 | ErrorCode("أمر غير معروف : ' " + Token[3] + " ' ", o_tokens); 33 | 34 | if (Token[2] == "دالة") 35 | { 36 | if (!IsInsideFunction) 37 | ErrorCode("يجب استعمال نهايه داخل داله", o_tokens); 38 | 39 | if (ALIF_IF_STATUS > 0) 40 | ErrorCode("مازال هناك " + IntToString(ALIF_IF_STATUS) + 41 | " شروط مازالت مفتوحه", 42 | o_tokens); 43 | 44 | if (ALIF_LOOP_STATUS > 0) 45 | ErrorCode("مازال هناك " + IntToString(ALIF_LOOP_STATUS) + 46 | " كلما مازالت مفتوحه", 47 | o_tokens); 48 | 49 | if (IsInsideClass) 50 | { 51 | if (!o_tokens->TOKENS_PREDEFINED) 52 | { 53 | IsInsideFunction = false; // Need by Tokens Predefined 54 | TheFunction = ""; // Need by Tokens Predefined 55 | return; // continue; 56 | } 57 | 58 | if (RETURN_FUN[std::make_pair(TheClass, TheFunction)] == "") 59 | ErrorCode("يجب تعيين إرجاع للدالة ' " + TheFunction + " ' ", o_tokens); 60 | 61 | if (RETURN_FUN[std::make_pair(TheClass, TheFunction)] == "IF") 62 | ErrorCode("لقد عينت إرجاع مشروطه للدالة ' " + TheFunction + " ' ", 63 | o_tokens); 64 | 65 | if (DEBUG) 66 | DEBUG_MESSAGE("[END CLASS-FUNCTION] {" + TheFunction + "} \n\n", 67 | o_tokens); // DEBUG 68 | 69 | // *** Generate Code *** 70 | // End Class Func() 71 | CPP_CLASS.append(" \n } \n"); 72 | // *** *** *** *** *** *** 73 | } 74 | else if (!IsInsideNamespace) 75 | { 76 | if (!o_tokens->TOKENS_PREDEFINED) 77 | { 78 | IsInsideFunction = false; // Need by Tokens Predefined 79 | TheFunction = ""; // Need by Tokens Predefined 80 | return; // continue; 81 | } 82 | 83 | if (RETURN_FUN[std::make_pair("", TheFunction)] == "") 84 | ErrorCode("يجب تعيين إرجاع للدالة ' " + TheFunction + " ' ", o_tokens); 85 | 86 | if (RETURN_FUN[std::make_pair("", TheFunction)] == "IF") 87 | ErrorCode("لقد عينت إرجاع مشروطه للدالة ' " + TheFunction + " ' ", 88 | o_tokens); 89 | 90 | if (DEBUG) 91 | DEBUG_MESSAGE("[END GLOBAL-FUNCTION] {" + TheFunction + "} \n\n", 92 | o_tokens); // DEBUG 93 | 94 | // *** Generate Code *** 95 | // End Global Func() <-- Alif 2 96 | CPP_GLOBAL_FUN.append(" \n } \n"); 97 | 98 | // Alif 3 99 | // if(TheFunction != "رئيسية") 100 | // CPP_GLOBAL_FUN.append(" \n } \n"); 101 | // *** *** *** *** *** *** 102 | } 103 | else 104 | { 105 | if (!o_tokens->TOKENS_PREDEFINED) 106 | { 107 | IsInsideFunction = false; // Need by Tokens Predefined 108 | TheFunction = ""; // Need by Tokens Predefined 109 | return; // continue; 110 | } 111 | 112 | if (RETURN_FUN[std::make_pair(TheNamespace, TheFunction)] == "") 113 | ErrorCode("يجب تعيين إرجاع للدالة ' " + TheFunction + " ' ", o_tokens); 114 | if (RETURN_FUN[std::make_pair(TheNamespace, TheFunction)] == "IF") 115 | ErrorCode("لقد عينت إرجاع مشروطه للدالة ' " + TheFunction + " ' ", 116 | o_tokens); 117 | 118 | if (DEBUG) 119 | DEBUG_MESSAGE("[END FUNCTION] {" + TheFunction + "} \n\n", 120 | o_tokens); // DEBUG 121 | 122 | // *** Generate Code *** 123 | // End Local Func() 124 | if (TheFunction != "رئيسية") 125 | CPP_GLOBAL_FUN.append(" \n } \n"); 126 | // *** *** *** *** *** *** 127 | } 128 | 129 | IsInsideFunction = false; 130 | TheFunction = ""; 131 | return; // continue; 132 | } 133 | else if (Token[2] == "إذا") 134 | { 135 | if (!o_tokens->TOKENS_PREDEFINED) 136 | return; // continue; 137 | 138 | if (ALIF_IF_STATUS < 1) 139 | ErrorCode("بدايه الشرط غير موجود", o_tokens); 140 | 141 | if (DEBUG) 142 | DEBUG_MESSAGE("[END IF " + IntToString(ALIF_IF_STATUS) + "] \n\n", 143 | o_tokens); // DEBUG 144 | 145 | if (IsInsideClass) 146 | { 147 | // just for fixing this ... 148 | // *** Generate Code *** 149 | CPP_CLASS.append("\n } \n "); 150 | // *** *** *** *** *** *** 151 | } 152 | else if (!IsInsideNamespace) 153 | // global func 154 | CPP_GLOBAL_FUN.append("\n } \n "); 155 | else 156 | // local func 157 | cpp_AddScript(TheFunction, "\n } \n "); 158 | // *** *** *** *** *** *** 159 | 160 | ALIF_IF_STATUS--; 161 | return; // continue; 162 | } 163 | else if (Token[2] == "كلما") 164 | { 165 | if (!o_tokens->TOKENS_PREDEFINED) 166 | return; // continue; 167 | 168 | if (ALIF_LOOP_STATUS < 1) 169 | ErrorCode("بدايه كلما غير موجود", o_tokens); 170 | 171 | if (DEBUG) 172 | DEBUG_MESSAGE("[END LOOP " + IntToString(ALIF_LOOP_STATUS) + "] \n\n", 173 | o_tokens); // DEBUG 174 | 175 | if (IsInsideClass) 176 | { 177 | // just for fixing this ... 178 | // *** Generate Code *** 179 | CPP_CLASS.append("\n } \n "); 180 | // *** *** *** *** *** *** 181 | } 182 | else if (!IsInsideNamespace) 183 | // global func 184 | CPP_GLOBAL_FUN.append("\n } \n "); 185 | else 186 | // local func 187 | cpp_AddScript(TheFunction, "\n } \n "); 188 | // *** *** *** *** *** *** 189 | 190 | ALIF_LOOP_STATUS--; 191 | return; // continue; 192 | } 193 | else if (Token[2] == "مجال") 194 | { 195 | if (!IsInsideNamespace) 196 | ErrorCode("يجب ان تكون داخل مجال", o_tokens); 197 | 198 | if (IsInsideFunction) 199 | ErrorCode("يجب اغلاق الدالة : " + TheFunction, o_tokens); 200 | 201 | if (!o_tokens->TOKENS_PREDEFINED) 202 | { 203 | IsInsideNamespace = false; // Need by Tokens Predefined 204 | TheNamespace = ""; // Need by Tokens Predefined 205 | return; // continue; 206 | } 207 | 208 | if (DEBUG) 209 | DEBUG_MESSAGE("[END NAMESPACE] {" + TheNamespace + "} \n\n", 210 | o_tokens); // DEBUG 211 | 212 | CPP_GLOBAL_FUN.append("\n }; \n "); // Close the namespace. 213 | 214 | IsInsideNamespace = false; 215 | TheNamespace = ""; 216 | return; // continue; 217 | } 218 | else if (Token[2] == "صنف") 219 | { 220 | if (!IsInsideClass) 221 | ErrorCode("يجب أن تكون داخل صنف", o_tokens); 222 | 223 | if (IsInsideFunction) 224 | ErrorCode("يجب اغلاق الدالة : " + TheFunction, o_tokens); 225 | 226 | if (!o_tokens->TOKENS_PREDEFINED) 227 | { 228 | IsInsideClass = false; // Need by Tokens Predefined 229 | TheClass = ""; // Need by Tokens Predefined 230 | return; // continue; 231 | } 232 | 233 | if (DEBUG) 234 | DEBUG_MESSAGE("[END CLASS] {" + TheClass + "} \n\n", o_tokens); // DEBUG 235 | 236 | // *** Generate Code *** 237 | /* 238 | if (!IsInsideFunction) 239 | CPP_GLOBAL.append(" }; \n "); 240 | else 241 | cpp_AddScript(TheFunction, " }; \n "); 242 | */ 243 | CPP_CLASS.append("\n }; \n "); // Close the Class. 244 | CPP_CLASS.append(OBJ_GLOBAL_DECLARATION[TheClass] + 245 | " \n "); // Add all global objs related to this class. 246 | // *** *** *** *** *** *** 247 | 248 | IsInsideClass = false; 249 | OBJ_GLOBAL_DECLARATION[TheClass] = ""; 250 | TheClass = ""; 251 | return; // continue; 252 | } 253 | else 254 | { 255 | if (Token[2] == "ادا" || Token[2] == "إدا" || Token[2] == "أدا" || 256 | Token[2] == "اذا" || Token[2] == "أذا") 257 | { 258 | ErrorCode("أمر غير معروف : ' " + Token[2] + 259 | " '، هل تقصد ' نهاية إذا ' ؟ ", 260 | o_tokens); 261 | } 262 | else 263 | ErrorCode("أمر غير معروف : ' " + Token[2] + " ' ", o_tokens); 264 | 265 | // TODO: More doyo mean ?! 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /src/alif_control.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void parser_Control(std::string Token[2048], CLASS_TOKEN *o_tokens) 25 | { 26 | //أداة 27 | 28 | if (IsInsideNamespace || IsInsideFunction || IsInsideClass) 29 | ErrorCode("يجب انشاء الادوات في المنطقة العامة", o_tokens); 30 | 31 | if (Token[2] == "مجال") 32 | { 33 | if (Token[3] != "(") 34 | ErrorCode("إشارة مفقودة '(' قبل ' " + Token[3] + " ' ", o_tokens); 35 | if (Token[5] != ",") 36 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[5] + " ' ", o_tokens); 37 | if (Token[7] != ",") 38 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[7] + " ' ", o_tokens); 39 | if (Token[9] != ",") 40 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[9] + " ' ", o_tokens); 41 | if (Token[11] != ",") 42 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[11] + " ' ", o_tokens); 43 | if (Token[13] != ",") 44 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[13] + " ' ", o_tokens); 45 | if (Token[15] != ")") 46 | ErrorCode("إشارة مفقودة ')' بعد ' " + Token[14] + " ' ", o_tokens); 47 | 48 | if (!IsValidName(Token[4], o_tokens)) 49 | ErrorCode("تعريف غير مقبول : ' " + Token[4] + " ' ", o_tokens); 50 | 51 | // if already any other type of global var exist 52 | CheckForSameGlobalID(Token[6], o_tokens); 53 | 54 | if (!o_tokens->TOKENS_PREDEFINED) 55 | { 56 | if (CONTROL_WIN_IS_SET[Token[4]]) 57 | ErrorCode("النافذة ' " + Token[4] + 58 | " ' تم انشاؤها مسبقا في السطر رقم : " + 59 | CONTROL_WIN_AT_LINE[(Token[4])], 60 | o_tokens); 61 | 62 | CONTROL_WIN_IS_SET[Token[4]] = true; 63 | WIN_IS_WEB[Token[4]] = false; 64 | CONTROL_WIN_AT_LINE[(Token[4])] = IntToString(o_tokens->Line); 65 | CPP_WINDOW[std::make_pair(Token[4], "شكل")] = 66 | " wxMINIMIZE_BOX | wxSYSTEM_MENU | wxCAPTION | wxCLOSE_BOX | " 67 | "wxCLIP_CHILDREN "; 68 | APP_TYPE = "PC_GUI"; 69 | 70 | SET_C_NAME(Token[4]); 71 | return; // continue; 72 | } 73 | 74 | if (DEBUG) 75 | DEBUG_MESSAGE("[CONTROL] [NAMESPACE] ['" + Token[4] + " '] \n\n", 76 | o_tokens); // DEBUG 77 | 78 | // *** Generate Code *** 79 | // New Namespace 80 | CPP_WINDOW[std::make_pair(Token[4], "افصول")] = Token[6]; 81 | CPP_WINDOW[std::make_pair(Token[4], "ارتوب")] = Token[8]; 82 | CPP_WINDOW[std::make_pair(Token[4], "عرض")] = Token[10]; 83 | CPP_WINDOW[std::make_pair(Token[4], "ارتفاع")] = Token[12]; 84 | CPP_WINDOW[std::make_pair(Token[4], "نص")] = 85 | remove_quote(Token[14], o_tokens); 86 | if (Token[4] != "رئيسية") 87 | { 88 | Namespace_Total++; 89 | Namespace_Total_Names[Namespace_Total] = Token[4]; 90 | CPP_ID_DECLARATION.append(" int ID_WINDOW_" + ID[Token[4]] + 91 | " = ALIFCORE_ID_GENERATOR(); \n"); 92 | CPP_GLOBAL.append(" bool WINDOW_IS_SHOW_" + ID[Token[4]] + 93 | " = false; \n"); 94 | CPP_GLOBAL.append(" bool WINDOW_IS_CONSTRUCTION_" + ID[Token[4]] + 95 | " = false; \n"); 96 | CPP_GLOBAL.append(" void WINDOW_LOAD_" + ID[Token[4]] + "(); \n"); 97 | } 98 | // *** *** *** *** *** *** 99 | 100 | return; // continue; 101 | } 102 | else if (Token[2] == "زر" || Token[2] == "نص" || Token[2] == "ملصق") 103 | { 104 | if (Token[3] != "(") 105 | ErrorCode("إشارة مفقودة '(' قبل ' " + Token[3] + " ' ", o_tokens); 106 | if (Token[5] != ",") 107 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[5] + " ' ", o_tokens); 108 | if (Token[7] != ",") 109 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[7] + " ' ", o_tokens); 110 | if (Token[9] != ",") 111 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[9] + " ' ", o_tokens); 112 | if (Token[11] != ",") 113 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[11] + " ' ", o_tokens); 114 | if (Token[13] != ",") 115 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[13] + " ' ", o_tokens); 116 | if (Token[15] != ",") 117 | ErrorCode("إشارة مفقودة ',' قبل ' " + Token[15] + " ' ", o_tokens); 118 | if (Token[17] != ")") 119 | ErrorCode("إشارة مفقودة ')' بعد ' " + Token[16] + " ' ", o_tokens); 120 | 121 | if (!CONTROL_WIN_IS_SET[Token[4]] && Token[4] != "رئيسية") 122 | ErrorCode("مجال غير موجوده : ' " + Token[4] + " ' ", o_tokens); 123 | 124 | if (!IsValidName(Token[6], o_tokens)) 125 | ErrorCode("تعريف غير مقبول : ' " + Token[6] + " ' ", o_tokens); 126 | 127 | // if already any other type of global var exist 128 | CheckForSameGlobalID(Token[6], o_tokens); 129 | 130 | if (!o_tokens->TOKENS_PREDEFINED) 131 | { 132 | if (CONTROL_IS_SET[std::make_pair(Token[4], Token[6])]) 133 | ErrorCode("الأداة ' " + Token[6] + 134 | " ' تم انشاؤها مسبقا في السطر رقم : " + 135 | CONTROL_AT_LINE[std::make_pair(Token[4], Token[6])], 136 | o_tokens); 137 | 138 | CONTROL_IS_SET[std::make_pair(Token[4], Token[6])] = true; 139 | CONTROL_AT_LINE[std::make_pair(Token[4], Token[6])] = 140 | IntToString(o_tokens->Line); 141 | CONTROL_TYPE[std::make_pair(Token[4], Token[6])] = Token[2]; 142 | 143 | SET_CONTROL_C_NAME(Token[6]); 144 | return; // continue; 145 | } 146 | 147 | if (DEBUG) 148 | DEBUG_MESSAGE("[CONTROL] ['" + Token[6] + " '] ['" + Token[2] + 149 | " '] \n\n", 150 | o_tokens); // DEBUG 151 | 152 | // *** Generate Code *** 153 | // New CTR 154 | CBUFER_ID = "ID_CTR_" + ID[Token[4]] + "_" + Control_ID[Token[6]]; 155 | CBUFER_OBJ = "OBJ_CTR_" + ID[Token[4]] + "_" + Control_ID[Token[6]]; 156 | CPP_ID_DECLARATION.append(" int " + CBUFER_ID + 157 | " = ALIFCORE_ID_GENERATOR(); \n"); 158 | if (Token[2] == "زر") 159 | { 160 | CPP_OBJ_DECLARATION.append(" wxButton* " + CBUFER_OBJ + "; \n"); 161 | CBUFER = CPP_WINDOW[std::make_pair(Token[4], "CTR_CONSTRUCTOR")]; 162 | CPP_WINDOW[std::make_pair(Token[4], "CTR_CONSTRUCTOR")] = 163 | CBUFER + " \n" + CBUFER_OBJ + " = new wxButton (P, " + CBUFER_ID + 164 | ", (\"" + remove_quote(Token[16], o_tokens) + "\"), wxPoint(" + 165 | Token[8] + "," + Token[10] + "), wxSize(" + Token[12] + ", " + 166 | Token[14] + ")); \n"; 167 | } 168 | else if (Token[2] == "نص") 169 | { 170 | // TODO: AppendText -> أضف 171 | // SetLabel -> نص 172 | // what about wxTE_MULTILINE ? 173 | 174 | CPP_OBJ_DECLARATION.append(" wxTextCtrl* " + CBUFER_OBJ + "; \n"); 175 | CBUFER = CPP_WINDOW[std::make_pair(Token[4], "CTR_CONSTRUCTOR")]; 176 | CPP_WINDOW[std::make_pair(Token[4], "CTR_CONSTRUCTOR")] = 177 | CBUFER + " \n" + CBUFER_OBJ + " = new wxTextCtrl (P, " + CBUFER_ID + 178 | ", (\"" + remove_quote(Token[16], o_tokens) + "\"), wxPoint(" + 179 | Token[8] + "," + Token[10] + "), wxSize(" + Token[12] + ", " + 180 | Token[14] + "), wxTE_MULTILINE | wxTE_RIGHT); \n"; 181 | } 182 | else if (Token[2] == "ملصق") 183 | { 184 | CPP_OBJ_DECLARATION.append(" wxStaticText* " + CBUFER_OBJ + "; \n"); 185 | CBUFER = CPP_WINDOW[std::make_pair(Token[4], "CTR_CONSTRUCTOR")]; 186 | CPP_WINDOW[std::make_pair(Token[4], "CTR_CONSTRUCTOR")] = 187 | CBUFER + " \n" + CBUFER_OBJ + " = new wxStaticText (P, " + CBUFER_ID + 188 | ", (\"" + remove_quote(Token[16], o_tokens) + "\"), wxPoint(" + 189 | Token[8] + "," + Token[10] + "), wxSize(" + Token[12] + ", " + 190 | Token[14] + 191 | "), wxST_NO_AUTORESIZE | wxALIGN_RIGHT | wxST_ELLIPSIZE_END); \n"; 192 | } 193 | else 194 | { 195 | ErrorCode("علة: نوع الأداة غير معروف ' " + Token[2] + " ' ", o_tokens); 196 | } 197 | // *** *** *** *** *** *** 198 | 199 | return; // continue; 200 | } 201 | else 202 | { 203 | if (Token[2] == "مجال") 204 | ErrorCode("نوع الأداة غير معروف ' " + Token[2] + 205 | " '، هل تقصد ' مجال ' ؟ ", 206 | o_tokens); 207 | else 208 | ErrorCode("نوع الأداة غير معروف ' " + Token[2] + " ' ", o_tokens); 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /src/alif_macro.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The Alif Programming Language 3 | Version 3.x Series 4 | (C)2021 Hassan DRAGA 5 | www.aliflang.org 6 | 7 | This file is part of Alif compiler. 8 | 9 | Alif compiler is free software; you can redistribute it and/or modify it 10 | under the terms of the GNU General Public License as published by the Free 11 | Software Foundation; either version 3, or (at your option) any later 12 | version. 13 | 14 | Alif compiler is distributed in the hope that it will be useful, but 15 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 | for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with Alif compiler; see the file COPYING3. If not see 21 | . 22 | */ 23 | 24 | void check_macro_alif(CLASS_TOKEN *o_tokens) 25 | { 26 | 27 | if (!ALIF_FLAG_FILE[o_tokens->PATH_FULL_SOURCE]) 28 | ErrorCode("يجب الإعلان عن ماكرو ألف اولا، المرجو اضافة ' #ألف ' في الأعلى", 29 | o_tokens); 30 | } 31 | 32 | void parser_macro_ui(std::string Token[2048], CLASS_TOKEN *o_tokens) 33 | { 34 | 35 | if (Token[2] == "") 36 | ErrorCode("الماكرو غير محدد ' # '", o_tokens); 37 | 38 | if (IsInsideNamespace || IsInsideFunction) 39 | ErrorCode("يجب استعمال الماكرو ' # ' في مكان عام", o_tokens); 40 | 41 | // --[ Macro - Alif ] ----------------------------------------------------- 42 | 43 | if (Token[2] == "ألف") 44 | { 45 | 46 | if (Token[3] != "") 47 | ErrorCode("أمر غير معروف : ' " + Token[3] + " ' ", o_tokens); 48 | 49 | if (!o_tokens->TOKENS_PREDEFINED) 50 | { 51 | 52 | if (ALIF_FLAG_FILE[o_tokens->PATH_FULL_SOURCE]) 53 | ErrorCode("تم الاعلان عن ماكرو ألف مسبقا في السطر : " + 54 | ALIF_FLAG_AT_LINE_FILE[o_tokens->PATH_FULL_SOURCE], 55 | o_tokens); 56 | 57 | ALIF_FLAG_FILE[o_tokens->PATH_FULL_SOURCE] = true; 58 | ALIF_FLAG_AT_LINE_FILE[o_tokens->PATH_FULL_SOURCE] = 59 | IntToString(o_tokens->Line); 60 | } 61 | 62 | if (DEBUG) 63 | DEBUG_MESSAGE("[#ALIF]\n", o_tokens); 64 | 65 | return; 66 | } 67 | 68 | // --[ Macro - Confidtions ] ---------------------------------------------- 69 | 70 | if (Token[2] == "إذا") 71 | { 72 | 73 | if (Token[3] == "لينكس") 74 | { 75 | 76 | // #إذا لينكس ... 77 | 78 | #ifdef _WIN32 79 | return; 80 | #elif __APPLE__ 81 | return; 82 | #else 83 | // Point to after : #إذا لينكس 84 | str_arr_remove_elem(Token, 2, o_tokens->TOTAL[o_tokens->Line]); // إذا 85 | str_arr_remove_elem(Token, 2, o_tokens->TOTAL[o_tokens->Line]); // لينكس 86 | #endif 87 | } 88 | else if (Token[3] == "ويندوز") 89 | { 90 | 91 | // #إذا ويندوز ... 92 | 93 | #ifdef _WIN32 94 | // Point to after : #إذا ويندوز 95 | str_arr_remove_elem(Token, 2, o_tokens->TOTAL[o_tokens->Line]); // إذا 96 | str_arr_remove_elem(Token, 2, o_tokens->TOTAL[o_tokens->Line]); // ويندوز 97 | #elif __APPLE__ 98 | return; 99 | #else 100 | return; 101 | #endif 102 | } 103 | else if (Token[3] == "ماك") 104 | { 105 | 106 | // #إذا ماك ... 107 | 108 | #ifdef _WIN32 109 | return; 110 | #elif __APPLE__ 111 | // Point to after : #إذا ماك 112 | str_arr_remove_elem(Token, 2, o_tokens->TOTAL[o_tokens->Line]); // إذا 113 | str_arr_remove_elem(Token, 2, o_tokens->TOTAL[o_tokens->Line]); // ماك 114 | #else 115 | return; 116 | #endif 117 | } 118 | else 119 | { 120 | 121 | ErrorCode("ماكرو شرطي غير معروف : ' " + Token[3] + " ' ", o_tokens); 122 | } 123 | 124 | // Check line 125 | if (Token[2] == "#") 126 | ErrorCode("ليس هناك حاجة لإضافة # ثاني", o_tokens); 127 | } 128 | 129 | // --[ Macro - Library ] -------------------------------------------------- 130 | 131 | if (Token[2] == "مكتبة") 132 | { 133 | 134 | check_macro_alif(o_tokens); 135 | 136 | if (Token[3] == "") 137 | ErrorCode("مسار الملف غير محدد" + Token[2], o_tokens); 138 | 139 | if (!IsValidStringFormat(Token[3], o_tokens)) 140 | ErrorCode("مسار الملف غير صائب : ' " + Token[3] + " ' ", o_tokens); 141 | 142 | if (Token[4] != "") 143 | ErrorCode("أمر غير معروف : ' " + Token[4] + " ' ", o_tokens); 144 | 145 | if (remove_quote(Token[3], o_tokens) == "البايثون") 146 | PythonSetEnvirenment(); 147 | 148 | AlifLexerParser(remove_quote(Token[3], o_tokens), "ALIFLIB", false, 149 | o_tokens->TOKENS_PREDEFINED); 150 | 151 | if (DEBUG) 152 | DEBUG_MESSAGE("[#INCLUDE " + Token[3] + " . ALIF LIB] ... \n\n", 153 | o_tokens); 154 | } 155 | 156 | // --[ Macro - Include ] -------------------------------------------------- 157 | 158 | else if (Token[2] == "أضف") 159 | { 160 | 161 | check_macro_alif(o_tokens); 162 | 163 | if (Token[3] == "") 164 | ErrorCode("مسار الملف غير محدد" + Token[2], o_tokens); 165 | 166 | if (!IsValidStringFormat(Token[3], o_tokens)) 167 | ErrorCode("مسار الملف غير صائب : ' " + Token[3] + " ' ", o_tokens); 168 | 169 | if (Token[4] != "") 170 | ErrorCode("أمر غير معروف : ' " + Token[4] + " ' ", o_tokens); 171 | 172 | AlifLexerParser(remove_quote(Token[3], o_tokens), "ALIF", false, 173 | o_tokens->TOKENS_PREDEFINED); 174 | 175 | if (DEBUG) 176 | DEBUG_MESSAGE("[#INCLUDE " + Token[3] + " . ALIF] ... \n\n", o_tokens); 177 | } 178 | 179 | // --[ Macro - UI (WebUI) ] ------------------------------------------------ 180 | 181 | else if (Token[2] == "نص") 182 | { 183 | 184 | // This macro basically read a file 185 | // and save it into a const std string. 186 | // Struct: 187 | // # نص my_str "my_file" 188 | 189 | check_macro_alif(o_tokens); 190 | 191 | if (Token[3] == "") 192 | ErrorCode("يجب تحديد اسم المتغير", o_tokens); 193 | 194 | if (Token[4] == "") 195 | ErrorCode("يجب تحديد اسم الملف", o_tokens); 196 | 197 | if (!IsValidStringFormat(Token[4], o_tokens)) 198 | ErrorCode("خطأ في كتابة إسم الملف: " + Token[4], o_tokens); 199 | 200 | if (Token[5] != "") 201 | ErrorCode("أمر غير معروف : ' " + Token[5] + " ' ", o_tokens); 202 | 203 | if (!o_tokens->TOKENS_PREDEFINED) 204 | { 205 | 206 | SET_GLOBAL_C_NAME(Token[3]); 207 | SetNewVar(true, "", "", Token[3], "نص", false, false, o_tokens->Line, 208 | o_tokens); 209 | return; 210 | } 211 | 212 | std::string path = remove_quote(Token[4], o_tokens); 213 | 214 | if (!is_file_exists(path)) 215 | { 216 | 217 | // Try second path 218 | std::string second_path = argument.input.path; // [/home/folder/] 219 | second_path.append(path); // [test] 220 | 221 | if (is_file_exists(second_path)) 222 | path = second_path; 223 | else 224 | { 225 | 226 | // Search in all include path's 227 | bool found = false; 228 | for (auto inc_path : argument.input.includes) 229 | { 230 | 231 | if (is_file_exists(inc_path + path)) 232 | { 233 | 234 | path = inc_path + path; 235 | found = true; 236 | break; 237 | } 238 | else if (is_file_exists(inc_path + path + ".alif")) 239 | { 240 | 241 | path = inc_path + path + ".alif"; 242 | found = true; 243 | break; 244 | } 245 | } 246 | 247 | if (!found) 248 | ErrorCode("ملف غير موجود : ' " + path + " ' ", o_tokens); 249 | } 250 | } 251 | 252 | std::string buf; 253 | 254 | file_embed(path, buf, o_tokens); 255 | 256 | CPP_GLOBAL.append(" const std::string " + Global_ID[Token[3]] + 257 | " = R\"V0G0N(\n" + buf + "\n)V0G0N\"; \n"); 258 | 259 | if (DEBUG) 260 | DEBUG_MESSAGE("[#نص] [" + Token[3] + "] [" + Token[4] + "] ", 261 | o_tokens); // DEBUG 262 | } 263 | 264 | // --[ Macro - Extra Compile / Link ] ------------------------------------- 265 | 266 | else if (Token[2] == "أضف_ترجمة" || Token[2] == "أضف_ترجمة_بداية" || 267 | Token[2] == "أضف_تجميع" || Token[2] == "أضف_تجميع_بداية") 268 | { 269 | 270 | // #أضف_ترجمة " -O3 -z " 271 | // #أضف_تجميع " -lfoo " 272 | 273 | if (!o_tokens->TOKENS_PREDEFINED) 274 | { 275 | 276 | check_macro_alif(o_tokens); 277 | 278 | if (!IsValidStringFormat(Token[3], o_tokens)) 279 | ErrorCode("خطأ في كتابة إسم الأمر: " + Token[3], o_tokens); 280 | 281 | if (Token[4] != "") 282 | ErrorCode("أمر غير معروف : ' " + Token[4] + " ' ", o_tokens); 283 | 284 | if (Token[2] == "أضف_ترجمة") 285 | add_extra_arg_to_compiler(remove_quote(Token[3], o_tokens)); 286 | else if (Token[2] == "أضف_ترجمة_بداية") 287 | add_extra_arg_to_compiler_beginning(remove_quote(Token[3], o_tokens)); 288 | 289 | else if (Token[2] == "أضف_تجميع") 290 | add_extra_arg_to_linker(remove_quote(Token[3], o_tokens)); 291 | else if (Token[2] == "أضف_تجميع_بداية") 292 | add_extra_arg_to_linker_beginning(remove_quote(Token[3], o_tokens)); 293 | 294 | else 295 | ErrorCode("علة: نوع أضف غير معروف ' " + Token[2] + " ' ", o_tokens); 296 | } 297 | } 298 | 299 | // --[ Macro - Python ] --------------------------------------------------- 300 | 301 | else if (Token[2] == "البايثون_مسار_عناوين") 302 | { 303 | 304 | check_macro_alif(o_tokens); 305 | 306 | if (!IsValidStringFormat(Token[3], o_tokens)) 307 | ErrorCode("الأمر غير صائب : ' " + Token[3] + " ' ", o_tokens); 308 | 309 | PythonInclude_path = remove_quote(Token[3], o_tokens); 310 | 311 | if (DEBUG) 312 | DEBUG_MESSAGE("[Setting Python Include '" + 313 | remove_quote(Token[3], o_tokens) + "' ] \n\n", 314 | o_tokens); 315 | } 316 | else if (Token[2] == "البايثون_مسار_مكتبات") 317 | { 318 | 319 | check_macro_alif(o_tokens); 320 | 321 | if (!IsValidStringFormat(Token[3], o_tokens)) 322 | ErrorCode("الأمر غير صائب : ' " + Token[3] + " ' ", o_tokens); 323 | 324 | PythonLib_path = remove_quote(Token[3], o_tokens); 325 | 326 | if (DEBUG) 327 | DEBUG_MESSAGE("[Setting Python Lib '" + remove_quote(Token[3], o_tokens) + 328 | "' ] \n\n", 329 | o_tokens); 330 | } 331 | else if (Token[2] == "البايثون_مكتبات") 332 | { 333 | 334 | check_macro_alif(o_tokens); 335 | 336 | if (!IsValidStringFormat(Token[3], o_tokens)) 337 | ErrorCode("الأمر غير صائب : ' " + Token[3] + " ' ", o_tokens); 338 | 339 | PythonLibName = remove_quote(Token[3], o_tokens); 340 | 341 | if (DEBUG) 342 | DEBUG_MESSAGE("[Setting Python LibName '" + 343 | remove_quote(Token[3], o_tokens) + "' ] \n\n", 344 | o_tokens); 345 | } 346 | 347 | // --[ Macro - Unknow ] --------------------------------------------------- 348 | 349 | else 350 | { 351 | 352 | if (Token[2] == "الف" || Token[2] == "ا" || Token[2] == "أ" || 353 | Token[2] == "الألف" || Token[2] == "الالف") 354 | { 355 | 356 | ErrorCode("ماكرو غير معروف : ' " + Token[2] + " '، هل تقصد ' ألف ' ؟ ", 357 | o_tokens); 358 | } 359 | else 360 | { 361 | 362 | if (Token[2] == "") 363 | ErrorCode("الماكرو غير محدد ' # '", o_tokens); 364 | else 365 | ErrorCode("ماكرو غير معروف : ' " + Token[2] + " ' ", o_tokens); 366 | } 367 | } 368 | } 369 | -------------------------------------------------------------------------------- /src/utf8/core.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 28 | #define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | 30 | #include 31 | 32 | namespace utf8 33 | { 34 | // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers 35 | // You may need to change them to match your system. 36 | // These typedefs have the same names as ones from cstdint, or boost/cstdint 37 | typedef unsigned char uint8_t; 38 | typedef unsigned short uint16_t; 39 | typedef unsigned int uint32_t; 40 | 41 | // Helper code - not intended to be directly called by the library users. May be 42 | // changed at any time 43 | namespace internal 44 | { 45 | // Unicode constants 46 | // Leading (high) surrogates: 0xd800 - 0xdbff 47 | // Trailing (low) surrogates: 0xdc00 - 0xdfff 48 | const uint16_t LEAD_SURROGATE_MIN = 0xd800u; 49 | const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; 50 | const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; 51 | const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; 52 | const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); 53 | const uint32_t SURROGATE_OFFSET = 54 | 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; 55 | 56 | // Maximum valid value for a Unicode code point 57 | const uint32_t CODE_POINT_MAX = 0x0010ffffu; 58 | 59 | template 60 | inline uint8_t mask8(octet_type oc) 61 | { 62 | return static_cast(0xff & oc); 63 | } 64 | template 65 | inline uint16_t mask16(u16_type oc) 66 | { 67 | return static_cast(0xffff & oc); 68 | } 69 | template 70 | inline bool is_trail(octet_type oc) 71 | { 72 | return ((utf8::internal::mask8(oc) >> 6) == 0x2); 73 | } 74 | 75 | template 76 | inline bool is_lead_surrogate(u16 cp) 77 | { 78 | return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); 79 | } 80 | 81 | template 82 | inline bool is_trail_surrogate(u16 cp) 83 | { 84 | return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); 85 | } 86 | 87 | template 88 | inline bool is_surrogate(u16 cp) 89 | { 90 | return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); 91 | } 92 | 93 | template 94 | inline bool is_code_point_valid(u32 cp) 95 | { 96 | return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); 97 | } 98 | 99 | template 100 | inline typename std::iterator_traits::difference_type 101 | sequence_length(octet_iterator lead_it) 102 | { 103 | uint8_t lead = utf8::internal::mask8(*lead_it); 104 | if (lead < 0x80) 105 | return 1; 106 | else if ((lead >> 5) == 0x6) 107 | return 2; 108 | else if ((lead >> 4) == 0xe) 109 | return 3; 110 | else if ((lead >> 3) == 0x1e) 111 | return 4; 112 | else 113 | return 0; 114 | } 115 | 116 | template 117 | inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length) 118 | { 119 | if (cp < 0x80) 120 | { 121 | if (length != 1) 122 | return true; 123 | } 124 | else if (cp < 0x800) 125 | { 126 | if (length != 2) 127 | return true; 128 | } 129 | else if (cp < 0x10000) 130 | { 131 | if (length != 3) 132 | return true; 133 | } 134 | 135 | return false; 136 | } 137 | 138 | enum utf_error 139 | { 140 | UTF8_OK, 141 | NOT_ENOUGH_ROOM, 142 | INVALID_LEAD, 143 | INCOMPLETE_SEQUENCE, 144 | OVERLONG_SEQUENCE, 145 | INVALID_CODE_POINT 146 | }; 147 | 148 | /// Helper for get_sequence_x 149 | template 150 | utf_error increase_safely(octet_iterator &it, octet_iterator end) 151 | { 152 | if (++it == end) 153 | return NOT_ENOUGH_ROOM; 154 | 155 | if (!utf8::internal::is_trail(*it)) 156 | return INCOMPLETE_SEQUENCE; 157 | 158 | return UTF8_OK; 159 | } 160 | 161 | #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) \ 162 | { \ 163 | utf_error ret = increase_safely(IT, END); \ 164 | if (ret != UTF8_OK) \ 165 | return ret; \ 166 | } 167 | 168 | /// get_sequence_x functions decode utf-8 sequences of the length x 169 | template 170 | utf_error get_sequence_1(octet_iterator &it, octet_iterator end, 171 | uint32_t &code_point) 172 | { 173 | if (it == end) 174 | return NOT_ENOUGH_ROOM; 175 | 176 | code_point = utf8::internal::mask8(*it); 177 | 178 | return UTF8_OK; 179 | } 180 | 181 | template 182 | utf_error get_sequence_2(octet_iterator &it, octet_iterator end, 183 | uint32_t &code_point) 184 | { 185 | if (it == end) 186 | return NOT_ENOUGH_ROOM; 187 | 188 | code_point = utf8::internal::mask8(*it); 189 | 190 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 191 | 192 | code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); 193 | 194 | return UTF8_OK; 195 | } 196 | 197 | template 198 | utf_error get_sequence_3(octet_iterator &it, octet_iterator end, 199 | uint32_t &code_point) 200 | { 201 | if (it == end) 202 | return NOT_ENOUGH_ROOM; 203 | 204 | code_point = utf8::internal::mask8(*it); 205 | 206 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 207 | 208 | code_point = ((code_point << 12) & 0xffff) + 209 | ((utf8::internal::mask8(*it) << 6) & 0xfff); 210 | 211 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 212 | 213 | code_point += (*it) & 0x3f; 214 | 215 | return UTF8_OK; 216 | } 217 | 218 | template 219 | utf_error get_sequence_4(octet_iterator &it, octet_iterator end, 220 | uint32_t &code_point) 221 | { 222 | if (it == end) 223 | return NOT_ENOUGH_ROOM; 224 | 225 | code_point = utf8::internal::mask8(*it); 226 | 227 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 228 | 229 | code_point = ((code_point << 18) & 0x1fffff) + 230 | ((utf8::internal::mask8(*it) << 12) & 0x3ffff); 231 | 232 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 233 | 234 | code_point += (utf8::internal::mask8(*it) << 6) & 0xfff; 235 | 236 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 237 | 238 | code_point += (*it) & 0x3f; 239 | 240 | return UTF8_OK; 241 | } 242 | 243 | #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR 244 | 245 | template 246 | utf_error validate_next(octet_iterator &it, octet_iterator end, 247 | uint32_t &code_point) 248 | { 249 | // Save the original value of it so we can go back in case of failure 250 | // Of course, it does not make much sense with i.e. stream iterators 251 | octet_iterator original_it = it; 252 | 253 | uint32_t cp = 0; 254 | // Determine the sequence length based on the lead octet 255 | typedef typename std::iterator_traits::difference_type 256 | octet_difference_type; 257 | const octet_difference_type length = utf8::internal::sequence_length(it); 258 | 259 | // Get trail octets and calculate the code point 260 | utf_error err = UTF8_OK; 261 | switch (length) 262 | { 263 | case 0: 264 | return INVALID_LEAD; 265 | case 1: 266 | err = utf8::internal::get_sequence_1(it, end, cp); 267 | break; 268 | case 2: 269 | err = utf8::internal::get_sequence_2(it, end, cp); 270 | break; 271 | case 3: 272 | err = utf8::internal::get_sequence_3(it, end, cp); 273 | break; 274 | case 4: 275 | err = utf8::internal::get_sequence_4(it, end, cp); 276 | break; 277 | } 278 | 279 | if (err == UTF8_OK) 280 | { 281 | // Decoding succeeded. Now, security checks... 282 | if (utf8::internal::is_code_point_valid(cp)) 283 | { 284 | if (!utf8::internal::is_overlong_sequence(cp, length)) 285 | { 286 | // Passed! Return here. 287 | code_point = cp; 288 | ++it; 289 | return UTF8_OK; 290 | } 291 | else 292 | err = OVERLONG_SEQUENCE; 293 | } 294 | else 295 | err = INVALID_CODE_POINT; 296 | } 297 | 298 | // Failure branch - restore the original value of the iterator 299 | it = original_it; 300 | return err; 301 | } 302 | 303 | template 304 | inline utf_error validate_next(octet_iterator &it, octet_iterator end) 305 | { 306 | uint32_t ignored; 307 | return utf8::internal::validate_next(it, end, ignored); 308 | } 309 | 310 | } // namespace internal 311 | 312 | /// The library API - functions intended to be called by the users 313 | 314 | // Byte order mark 315 | const uint8_t bom[] = {0xef, 0xbb, 0xbf}; 316 | 317 | template 318 | octet_iterator find_invalid(octet_iterator start, octet_iterator end) 319 | { 320 | octet_iterator result = start; 321 | while (result != end) 322 | { 323 | utf8::internal::utf_error err_code = 324 | utf8::internal::validate_next(result, end); 325 | if (err_code != internal::UTF8_OK) 326 | return result; 327 | } 328 | return result; 329 | } 330 | 331 | template 332 | inline bool is_valid(octet_iterator start, octet_iterator end) 333 | { 334 | return (utf8::find_invalid(start, end) == end); 335 | } 336 | 337 | template 338 | inline bool starts_with_bom(octet_iterator it, octet_iterator end) 339 | { 340 | return (((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && 341 | ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && 342 | ((it != end) && (utf8::internal::mask8(*it)) == bom[2])); 343 | } 344 | 345 | // Deprecated in release 2.3 346 | template 347 | inline bool is_bom(octet_iterator it) 348 | { 349 | return ((utf8::internal::mask8(*it++)) == bom[0] && 350 | (utf8::internal::mask8(*it++)) == bom[1] && 351 | (utf8::internal::mask8(*it)) == bom[2]); 352 | } 353 | } // namespace utf8 354 | 355 | #endif // header guard 356 | -------------------------------------------------------------------------------- /src/aliflib/utf8/core.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 28 | #define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | 30 | #include 31 | 32 | namespace utf8 33 | { 34 | // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers 35 | // You may need to change them to match your system. 36 | // These typedefs have the same names as ones from cstdint, or boost/cstdint 37 | typedef unsigned char uint8_t; 38 | typedef unsigned short uint16_t; 39 | typedef unsigned int uint32_t; 40 | 41 | // Helper code - not intended to be directly called by the library users. May be 42 | // changed at any time 43 | namespace internal 44 | { 45 | // Unicode constants 46 | // Leading (high) surrogates: 0xd800 - 0xdbff 47 | // Trailing (low) surrogates: 0xdc00 - 0xdfff 48 | const uint16_t LEAD_SURROGATE_MIN = 0xd800u; 49 | const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; 50 | const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; 51 | const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; 52 | const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); 53 | const uint32_t SURROGATE_OFFSET = 54 | 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; 55 | 56 | // Maximum valid value for a Unicode code point 57 | const uint32_t CODE_POINT_MAX = 0x0010ffffu; 58 | 59 | template 60 | inline uint8_t mask8(octet_type oc) 61 | { 62 | return static_cast(0xff & oc); 63 | } 64 | template 65 | inline uint16_t mask16(u16_type oc) 66 | { 67 | return static_cast(0xffff & oc); 68 | } 69 | template 70 | inline bool is_trail(octet_type oc) 71 | { 72 | return ((utf8::internal::mask8(oc) >> 6) == 0x2); 73 | } 74 | 75 | template 76 | inline bool is_lead_surrogate(u16 cp) 77 | { 78 | return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); 79 | } 80 | 81 | template 82 | inline bool is_trail_surrogate(u16 cp) 83 | { 84 | return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); 85 | } 86 | 87 | template 88 | inline bool is_surrogate(u16 cp) 89 | { 90 | return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); 91 | } 92 | 93 | template 94 | inline bool is_code_point_valid(u32 cp) 95 | { 96 | return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); 97 | } 98 | 99 | template 100 | inline typename std::iterator_traits::difference_type 101 | sequence_length(octet_iterator lead_it) 102 | { 103 | uint8_t lead = utf8::internal::mask8(*lead_it); 104 | if (lead < 0x80) 105 | return 1; 106 | else if ((lead >> 5) == 0x6) 107 | return 2; 108 | else if ((lead >> 4) == 0xe) 109 | return 3; 110 | else if ((lead >> 3) == 0x1e) 111 | return 4; 112 | else 113 | return 0; 114 | } 115 | 116 | template 117 | inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length) 118 | { 119 | if (cp < 0x80) 120 | { 121 | if (length != 1) 122 | return true; 123 | } 124 | else if (cp < 0x800) 125 | { 126 | if (length != 2) 127 | return true; 128 | } 129 | else if (cp < 0x10000) 130 | { 131 | if (length != 3) 132 | return true; 133 | } 134 | 135 | return false; 136 | } 137 | 138 | enum utf_error 139 | { 140 | UTF8_OK, 141 | NOT_ENOUGH_ROOM, 142 | INVALID_LEAD, 143 | INCOMPLETE_SEQUENCE, 144 | OVERLONG_SEQUENCE, 145 | INVALID_CODE_POINT 146 | }; 147 | 148 | /// Helper for get_sequence_x 149 | template 150 | utf_error increase_safely(octet_iterator &it, octet_iterator end) 151 | { 152 | if (++it == end) 153 | return NOT_ENOUGH_ROOM; 154 | 155 | if (!utf8::internal::is_trail(*it)) 156 | return INCOMPLETE_SEQUENCE; 157 | 158 | return UTF8_OK; 159 | } 160 | 161 | #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) \ 162 | { \ 163 | utf_error ret = increase_safely(IT, END); \ 164 | if (ret != UTF8_OK) \ 165 | return ret; \ 166 | } 167 | 168 | /// get_sequence_x functions decode utf-8 sequences of the length x 169 | template 170 | utf_error get_sequence_1(octet_iterator &it, octet_iterator end, 171 | uint32_t &code_point) 172 | { 173 | if (it == end) 174 | return NOT_ENOUGH_ROOM; 175 | 176 | code_point = utf8::internal::mask8(*it); 177 | 178 | return UTF8_OK; 179 | } 180 | 181 | template 182 | utf_error get_sequence_2(octet_iterator &it, octet_iterator end, 183 | uint32_t &code_point) 184 | { 185 | if (it == end) 186 | return NOT_ENOUGH_ROOM; 187 | 188 | code_point = utf8::internal::mask8(*it); 189 | 190 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 191 | 192 | code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); 193 | 194 | return UTF8_OK; 195 | } 196 | 197 | template 198 | utf_error get_sequence_3(octet_iterator &it, octet_iterator end, 199 | uint32_t &code_point) 200 | { 201 | if (it == end) 202 | return NOT_ENOUGH_ROOM; 203 | 204 | code_point = utf8::internal::mask8(*it); 205 | 206 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 207 | 208 | code_point = ((code_point << 12) & 0xffff) + 209 | ((utf8::internal::mask8(*it) << 6) & 0xfff); 210 | 211 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 212 | 213 | code_point += (*it) & 0x3f; 214 | 215 | return UTF8_OK; 216 | } 217 | 218 | template 219 | utf_error get_sequence_4(octet_iterator &it, octet_iterator end, 220 | uint32_t &code_point) 221 | { 222 | if (it == end) 223 | return NOT_ENOUGH_ROOM; 224 | 225 | code_point = utf8::internal::mask8(*it); 226 | 227 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 228 | 229 | code_point = ((code_point << 18) & 0x1fffff) + 230 | ((utf8::internal::mask8(*it) << 12) & 0x3ffff); 231 | 232 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 233 | 234 | code_point += (utf8::internal::mask8(*it) << 6) & 0xfff; 235 | 236 | UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) 237 | 238 | code_point += (*it) & 0x3f; 239 | 240 | return UTF8_OK; 241 | } 242 | 243 | #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR 244 | 245 | template 246 | utf_error validate_next(octet_iterator &it, octet_iterator end, 247 | uint32_t &code_point) 248 | { 249 | // Save the original value of it so we can go back in case of failure 250 | // Of course, it does not make much sense with i.e. stream iterators 251 | octet_iterator original_it = it; 252 | 253 | uint32_t cp = 0; 254 | // Determine the sequence length based on the lead octet 255 | typedef typename std::iterator_traits::difference_type 256 | octet_difference_type; 257 | const octet_difference_type length = utf8::internal::sequence_length(it); 258 | 259 | // Get trail octets and calculate the code point 260 | utf_error err = UTF8_OK; 261 | switch (length) 262 | { 263 | case 0: 264 | return INVALID_LEAD; 265 | case 1: 266 | err = utf8::internal::get_sequence_1(it, end, cp); 267 | break; 268 | case 2: 269 | err = utf8::internal::get_sequence_2(it, end, cp); 270 | break; 271 | case 3: 272 | err = utf8::internal::get_sequence_3(it, end, cp); 273 | break; 274 | case 4: 275 | err = utf8::internal::get_sequence_4(it, end, cp); 276 | break; 277 | } 278 | 279 | if (err == UTF8_OK) 280 | { 281 | // Decoding succeeded. Now, security checks... 282 | if (utf8::internal::is_code_point_valid(cp)) 283 | { 284 | if (!utf8::internal::is_overlong_sequence(cp, length)) 285 | { 286 | // Passed! Return here. 287 | code_point = cp; 288 | ++it; 289 | return UTF8_OK; 290 | } 291 | else 292 | err = OVERLONG_SEQUENCE; 293 | } 294 | else 295 | err = INVALID_CODE_POINT; 296 | } 297 | 298 | // Failure branch - restore the original value of the iterator 299 | it = original_it; 300 | return err; 301 | } 302 | 303 | template 304 | inline utf_error validate_next(octet_iterator &it, octet_iterator end) 305 | { 306 | uint32_t ignored; 307 | return utf8::internal::validate_next(it, end, ignored); 308 | } 309 | 310 | } // namespace internal 311 | 312 | /// The library API - functions intended to be called by the users 313 | 314 | // Byte order mark 315 | const uint8_t bom[] = {0xef, 0xbb, 0xbf}; 316 | 317 | template 318 | octet_iterator find_invalid(octet_iterator start, octet_iterator end) 319 | { 320 | octet_iterator result = start; 321 | while (result != end) 322 | { 323 | utf8::internal::utf_error err_code = 324 | utf8::internal::validate_next(result, end); 325 | if (err_code != internal::UTF8_OK) 326 | return result; 327 | } 328 | return result; 329 | } 330 | 331 | template 332 | inline bool is_valid(octet_iterator start, octet_iterator end) 333 | { 334 | return (utf8::find_invalid(start, end) == end); 335 | } 336 | 337 | template 338 | inline bool starts_with_bom(octet_iterator it, octet_iterator end) 339 | { 340 | return (((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && 341 | ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && 342 | ((it != end) && (utf8::internal::mask8(*it)) == bom[2])); 343 | } 344 | 345 | // Deprecated in release 2.3 346 | template 347 | inline bool is_bom(octet_iterator it) 348 | { 349 | return ((utf8::internal::mask8(*it++)) == bom[0] && 350 | (utf8::internal::mask8(*it++)) == bom[1] && 351 | (utf8::internal::mask8(*it)) == bom[2]); 352 | } 353 | } // namespace utf8 354 | 355 | #endif // header guard 356 | -------------------------------------------------------------------------------- /src/utf8/checked.h: -------------------------------------------------------------------------------- 1 | // Copyright 2006 Nemanja Trifunovic 2 | 3 | /* 4 | Permission is hereby granted, free of charge, to any person or organization 5 | obtaining a copy of the software and accompanying documentation covered by 6 | this license (the "Software") to use, reproduce, display, distribute, 7 | execute, and transmit the Software, and to prepare derivative works of the 8 | Software, and to permit third-parties to whom the Software is furnished to 9 | do so, all subject to the following: 10 | 11 | The copyright notices in the Software and this entire statement, including 12 | the above license grant, this restriction and the following disclaimer, 13 | must be included in all copies of the Software, in whole or in part, and 14 | all derivative works of the Software, unless such copies or derivative 15 | works are solely in the form of machine-executable object code generated by 16 | a source language processor. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 21 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 22 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 23 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24 | DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 28 | #define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 29 | 30 | #include "core.h" 31 | #include 32 | 33 | namespace utf8 34 | { 35 | // Base for the exceptions that may be thrown from the library 36 | class exception : public ::std::exception 37 | { 38 | }; 39 | 40 | // Exceptions that may be thrown from the library functions. 41 | class invalid_code_point : public exception 42 | { 43 | uint32_t cp; 44 | 45 | public: 46 | invalid_code_point(uint32_t cp) : cp(cp) {} 47 | virtual const char *what() const throw() { return "Invalid code point"; } 48 | uint32_t code_point() const { return cp; } 49 | }; 50 | 51 | class invalid_utf8 : public exception 52 | { 53 | uint8_t u8; 54 | 55 | public: 56 | invalid_utf8(uint8_t u) : u8(u) {} 57 | virtual const char *what() const throw() { return "Invalid UTF-8"; } 58 | uint8_t utf8_octet() const { return u8; } 59 | }; 60 | 61 | class invalid_utf16 : public exception 62 | { 63 | uint16_t u16; 64 | 65 | public: 66 | invalid_utf16(uint16_t u) : u16(u) {} 67 | virtual const char *what() const throw() { return "Invalid UTF-16"; } 68 | uint16_t utf16_word() const { return u16; } 69 | }; 70 | 71 | class not_enough_room : public exception 72 | { 73 | public: 74 | virtual const char *what() const throw() { return "Not enough space"; } 75 | }; 76 | 77 | /// The library API - functions intended to be called by the users 78 | 79 | template 80 | octet_iterator append(uint32_t cp, octet_iterator result) 81 | { 82 | if (!utf8::internal::is_code_point_valid(cp)) 83 | throw invalid_code_point(cp); 84 | 85 | if (cp < 0x80) // one octet 86 | *(result++) = static_cast(cp); 87 | else if (cp < 0x800) 88 | { // two octets 89 | *(result++) = static_cast((cp >> 6) | 0xc0); 90 | *(result++) = static_cast((cp & 0x3f) | 0x80); 91 | } 92 | else if (cp < 0x10000) 93 | { // three octets 94 | *(result++) = static_cast((cp >> 12) | 0xe0); 95 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); 96 | *(result++) = static_cast((cp & 0x3f) | 0x80); 97 | } 98 | else 99 | { // four octets 100 | *(result++) = static_cast((cp >> 18) | 0xf0); 101 | *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); 102 | *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); 103 | *(result++) = static_cast((cp & 0x3f) | 0x80); 104 | } 105 | return result; 106 | } 107 | 108 | template 109 | output_iterator replace_invalid(octet_iterator start, octet_iterator end, 110 | output_iterator out, uint32_t replacement) 111 | { 112 | while (start != end) 113 | { 114 | octet_iterator sequence_start = start; 115 | internal::utf_error err_code = utf8::internal::validate_next(start, end); 116 | switch (err_code) 117 | { 118 | case internal::UTF8_OK: 119 | for (octet_iterator it = sequence_start; it != start; ++it) 120 | *out++ = *it; 121 | break; 122 | case internal::NOT_ENOUGH_ROOM: 123 | throw not_enough_room(); 124 | case internal::INVALID_LEAD: 125 | out = utf8::append(replacement, out); 126 | ++start; 127 | break; 128 | case internal::INCOMPLETE_SEQUENCE: 129 | case internal::OVERLONG_SEQUENCE: 130 | case internal::INVALID_CODE_POINT: 131 | out = utf8::append(replacement, out); 132 | ++start; 133 | // just one replacement mark for the sequence 134 | while (start != end && utf8::internal::is_trail(*start)) 135 | ++start; 136 | break; 137 | } 138 | } 139 | return out; 140 | } 141 | 142 | template 143 | inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, 144 | output_iterator out) 145 | { 146 | static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd); 147 | return utf8::replace_invalid(start, end, out, replacement_marker); 148 | } 149 | 150 | template 151 | uint32_t next(octet_iterator &it, octet_iterator end) 152 | { 153 | uint32_t cp = 0; 154 | internal::utf_error err_code = utf8::internal::validate_next(it, end, cp); 155 | switch (err_code) 156 | { 157 | case internal::UTF8_OK: 158 | break; 159 | case internal::NOT_ENOUGH_ROOM: 160 | throw not_enough_room(); 161 | case internal::INVALID_LEAD: 162 | case internal::INCOMPLETE_SEQUENCE: 163 | case internal::OVERLONG_SEQUENCE: 164 | throw invalid_utf8(*it); 165 | case internal::INVALID_CODE_POINT: 166 | throw invalid_code_point(cp); 167 | } 168 | return cp; 169 | } 170 | 171 | template 172 | uint32_t peek_next(octet_iterator it, octet_iterator end) 173 | { 174 | return utf8::next(it, end); 175 | } 176 | 177 | template 178 | uint32_t prior(octet_iterator &it, octet_iterator start) 179 | { 180 | // can't do much if it == start 181 | if (it == start) 182 | throw not_enough_room(); 183 | 184 | octet_iterator end = it; 185 | // Go back until we hit either a lead octet or start 186 | while (utf8::internal::is_trail(*(--it))) 187 | if (it == start) 188 | throw invalid_utf8(*it); // error - no lead byte in the sequence 189 | return utf8::peek_next(it, end); 190 | } 191 | 192 | /// Deprecated in versions that include "prior" 193 | template 194 | uint32_t previous(octet_iterator &it, octet_iterator pass_start) 195 | { 196 | octet_iterator end = it; 197 | while (utf8::internal::is_trail(*(--it))) 198 | if (it == pass_start) 199 | throw invalid_utf8(*it); // error - no lead byte in the sequence 200 | octet_iterator temp = it; 201 | return utf8::next(temp, end); 202 | } 203 | 204 | template 205 | void advance(octet_iterator &it, distance_type n, octet_iterator end) 206 | { 207 | for (distance_type i = 0; i < n; ++i) 208 | utf8::next(it, end); 209 | } 210 | 211 | template 212 | typename std::iterator_traits::difference_type 213 | distance(octet_iterator first, octet_iterator last) 214 | { 215 | typename std::iterator_traits::difference_type dist; 216 | for (dist = 0; first < last; ++dist) 217 | utf8::next(first, last); 218 | return dist; 219 | } 220 | 221 | template 222 | octet_iterator utf16to8(u16bit_iterator start, u16bit_iterator end, 223 | octet_iterator result) 224 | { 225 | while (start != end) 226 | { 227 | uint32_t cp = utf8::internal::mask16(*start++); 228 | // Take care of surrogate pairs first 229 | if (utf8::internal::is_lead_surrogate(cp)) 230 | { 231 | if (start != end) 232 | { 233 | uint32_t trail_surrogate = utf8::internal::mask16(*start++); 234 | if (utf8::internal::is_trail_surrogate(trail_surrogate)) 235 | cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; 236 | else 237 | throw invalid_utf16(static_cast(trail_surrogate)); 238 | } 239 | else 240 | throw invalid_utf16(static_cast(cp)); 241 | } 242 | // Lone trail surrogate 243 | else if (utf8::internal::is_trail_surrogate(cp)) 244 | throw invalid_utf16(static_cast(cp)); 245 | 246 | result = utf8::append(cp, result); 247 | } 248 | return result; 249 | } 250 | 251 | template 252 | u16bit_iterator utf8to16(octet_iterator start, octet_iterator end, 253 | u16bit_iterator result) 254 | { 255 | while (start != end) 256 | { 257 | uint32_t cp = utf8::next(start, end); 258 | if (cp > 0xffff) 259 | { // make a surrogate pair 260 | *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); 261 | *result++ = 262 | static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); 263 | } 264 | else 265 | *result++ = static_cast(cp); 266 | } 267 | return result; 268 | } 269 | 270 | template 271 | octet_iterator utf32to8(u32bit_iterator start, u32bit_iterator end, 272 | octet_iterator result) 273 | { 274 | while (start != end) 275 | result = utf8::append(*(start++), result); 276 | 277 | return result; 278 | } 279 | 280 | template 281 | u32bit_iterator utf8to32(octet_iterator start, octet_iterator end, 282 | u32bit_iterator result) 283 | { 284 | while (start != end) 285 | (*result++) = utf8::next(start, end); 286 | 287 | return result; 288 | } 289 | 290 | // The iterator class 291 | template 292 | class iterator 293 | : public std::iterator 294 | { 295 | octet_iterator it; 296 | octet_iterator range_start; 297 | octet_iterator range_end; 298 | 299 | public: 300 | iterator() {} 301 | explicit iterator(const octet_iterator &octet_it, 302 | const octet_iterator &range_start, 303 | const octet_iterator &range_end) 304 | : it(octet_it), range_start(range_start), range_end(range_end) 305 | { 306 | if (it < range_start || it > range_end) 307 | throw std::out_of_range("Invalid utf-8 iterator position"); 308 | } 309 | // the default "big three" are OK 310 | octet_iterator base() const { return it; } 311 | uint32_t operator*() const 312 | { 313 | octet_iterator temp = it; 314 | return utf8::next(temp, range_end); 315 | } 316 | bool operator==(const iterator &rhs) const 317 | { 318 | if (range_start != rhs.range_start || range_end != rhs.range_end) 319 | throw std::logic_error( 320 | "Comparing utf-8 iterators defined with different ranges"); 321 | return (it == rhs.it); 322 | } 323 | bool operator!=(const iterator &rhs) const { return !(operator==(rhs)); } 324 | iterator &operator++() 325 | { 326 | utf8::next(it, range_end); 327 | return *this; 328 | } 329 | iterator operator++(int) 330 | { 331 | iterator temp = *this; 332 | utf8::next(it, range_end); 333 | return temp; 334 | } 335 | iterator &operator--() 336 | { 337 | utf8::prior(it, range_start); 338 | return *this; 339 | } 340 | iterator operator--(int) 341 | { 342 | iterator temp = *this; 343 | utf8::prior(it, range_start); 344 | return temp; 345 | } 346 | }; // class iterator 347 | 348 | } // namespace utf8 349 | 350 | #endif // header guard 351 | --------------------------------------------------------------------------------