11 |
12 |
13 |
14 | # Photon
15 | Linguagem de programação extremamente rápida e portátil do Will!
16 |
17 | # O que é Photon?
18 |
19 | Photon é uma linguagem de programação com uma sintaxe bem amigável e parecida com Python, porém muuuiitoo mais rápida :)
20 | É uma linguagem que pode ser compilada para todas as plataformas e também possui um interpretador (REPL).
21 |
22 | Basicamente, o objetivo da linguagem é preencher as lacunas do Python em performance e portabilidade. Atualmente o Wlang já tem uma performance muito superior ao Python e pode ser compilada e distribuída para qualquer plataforma, de forma nativa ou não, e utilizando diversos frameworks para parte gráfica como Kha, Cordova, Flutter e Raylib.
23 |
24 | # Demonstração
25 |
26 | Para ter uma idéia de como é a linguagem e como ela se compara as outras, veja esse vídeo [aqui](https://www.youtube.com/watch?v=_8xtTyCTPXI).
27 |
28 | # Estágio ALPHA
29 |
30 | Esta é uma linguagem em desenvolvimento e ainda não está disponível para o público.
31 |
32 | Ta ansioso para testar?? Eu também to ansioso para lançar! Mas infelizmente tenho que dar prioridade a outros projetos que me sustentam. Caso queira ajudar e tornar esse projeto realidade o quanto antes, considere fazer uma doação, virar um membro do canal ou até se inscrever no canal que já ajuda bastante :)
33 |
34 | Para outras formas de contribuição, envie um email para digameoquepensas@gmail.com
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
Photon
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Documentation in English
13 |
14 | Lightning fast and portable programming language!
15 |
16 | ## What is Photon?
17 |
18 | Photon is a programming language aimed at filling the gaps of the Python language with respect to performance and portability. I love Python, but I cannot use it anywhere I want because it is not a supported language of the platform, lacks performance or is very cumbersome to actually package it or deploy it.
19 | Photon applications can run in any platform. Some examples are: Windows, Linux, MacOS, BSD, Android, IOs, RaspberryPi, HTML5, Xbox, Playstation, etc.
20 |
21 | ## I want to see it!
22 |
23 | Devlog is available [here](https://www.youtube.com/watch?v=Seu5q_hc6go&list=PL89TmjrkwpOfteQJRptqmK-y8pr6uJdlc).
24 | I also uploaded a video on my portuguese channel comparing it to Python and C, check it out [here](https://youtu.be/_8xtTyCTPXI).
25 |
26 | ## Quickstart
27 |
28 | Download or clone (preferred) the repository where you want to install it. Execute the windowsInstaller.bat if you are in Windows or linuxInstaller.sh if you are in Linux. After the installation process, you should have photon installed and available in your PATH.
29 | Now you can write this simple Hello World, with any text editor of your choice.
30 |
31 | ```python
32 | print("Hello World!")
33 | ```
34 |
35 | Save it as hello.w and then execute it in your cmd or powershell with
36 |
37 | ```
38 | photon hello.w
39 | ```
40 |
41 | And you should see the Hello World! output in your console!
42 |
43 | In the devlog 1, I show how to install and create your first hello world program. [Click here to see it.](https://www.youtube.com/watch?v=5QtISBpOlr0)
44 |
45 | ## ALPHA Stage
46 |
47 | Photon is currently in early alpha.
48 | If you like this project and want to contribute, please consider donating or subscribing to my youtube [channel](https://www.youtube.com/channel/UChE5M9BAsdtlllOpfhIu8Tw), where I'll post a dev log of this language ([devlog](https://www.youtube.com/watch?v=Seu5q_hc6go&list=PL89TmjrkwpOfteQJRptqmK-y8pr6uJdlc)).
49 | Also, join the discussion here on github about the future and your thoughts on the language!
50 |
51 |
52 |
53 | Documentação em português
54 | Linguagem de programação extremamente rápida e portátil!
55 |
56 | ## O que é Photon?
57 |
58 | Photon é uma linguagem de programação que visa preencher as lacunas da linguagem Python no que diz respeito ao desempenho e portabilidade. Eu amo Python, mas não posso usá-lo em qualquer lugar que eu queira porque não é uma nativamente suportada, não tem desempenho suficiente ou aprensenta muitas complicações para distribuir um executável na plataforma de destino.
59 | Por outro lado, os aplicativos Photon podem ser facilmente executados em qualquer plataforma. Alguns exemplos são: Windows, Linux, MacOS, BSD, Android, IOs, RaspberryPi, HTML5, Xbox, Playstation, etc.
60 |
61 | ## Quero ver!
62 |
63 | O Devlog está disponível [aqui](https://www.youtube.com/watch?v=Seu5q_hc6go&list=PL89TmjrkwpOfteQJRptqmK-y8pr6uJdlc).
64 | Também carreguei um vídeo no meu canal português comparando-o com Python e C, confira [aqui](https://youtu.be/_8xtTyCTPXI).
65 |
66 | ## Começo rápido
67 |
68 | Baixe ou clone (preferencialmente) o repositório onde deseja instalá-lo. Execute o windowsInstaller.bat se você estiver no Windows ou linuxInstaller.sh se você estiver no Linux. Após o processo de instalação, você deve ter o photon instalado e disponível na sua PATH (como variável do seu sistema).
69 | Agora você pode escrever este simples Hello World, com qualquer editor de texto de sua escolha.
70 |
71 | ```python
72 | print("Olá, mundo!")
73 | ```
74 |
75 | Salve-o como hello.w e execute-o em seu cmd ou powershell com
76 |
77 | ```
78 | photon hello.w
79 | ```
80 |
81 | E você deverá ver o Hello World! em seu console!
82 |
83 | No devlog 1, mostro como instalar e criar seu primeiro programa hello world. [Clique aqui para ver.](Https://www.youtube.com/watch?v=5QtISBpOlr0)
84 |
85 |
86 | ## Estágio ALPHA
87 |
88 | Photon está atualmente em alfa.
89 | Se você gosta deste projeto e deseja contribuir, considere doar ou se inscrever no meu [canal youtube](https://www.youtube.com/channel/UChE5M9BAsdtlllOpfhIu8Tw) , onde postarei um dev log desta linguagem ([devlog](https://www.youtube.com/watch?v=Seu5q_hc6go&list=PL89TmjrkwpOfteQJRptqmK-y8pr6uJdlc)).
90 | Além disso, participe da discussão aqui no github sobre o futuro e sua opinião sobre a linguagem!
91 |
92 |
93 |
94 |
95 |
96 | Documentación en español
97 | ¡Lenguaje de programación extremadamente rápido y portátil!
98 |
99 | ## ¿Qué es Photon?
100 |
101 | Photon es un lenguaje de programación que tiene como objetivo llenar los vacíos en el lenguaje Python con respecto al rendimiento y la portabilidad. Me encanta Python, pero no puedo usarlo en cualquier lugar que quiera porque no es compatible de forma nativa, no tiene suficiente rendimiento o tiene muchas complicaciones para distribuir un ejecutable en la plataforma de destino.
102 | Por otro lado, las aplicaciones Photon se pueden ejecutar fácilmente en cualquier plataforma. Algunos ejemplos son: Windows, Linux, MacOS, BSD, Android, IOs, RaspberryPi, HTML5, Xbox, Playstation, etc.
103 |
104 | ## ¡Quiero ver!
105 |
106 | El Devlog está disponible [aquí](https://www.youtube.com/watch?v=Your5q_hc6go&list=PL89TmjrkwpOfteQJRptqmK-y8pr6uJdlc).
107 | También subí un video en mi canal portugués comparándolo con Python y C, compruébalo [aquí](https://youtu.be/_8xtTyCTPXI).
108 |
109 | ## Etapa ALPHA
110 |
111 | Photon se encuentra actualmente en alfa.
112 | Si te gusta este proyecto y quieres contribuir, considera hacer una donación o suscribirte a mi [canal de youtube](https://www.youtube.com/channel/UChE5M9BAsdtlllOpfhIu8Tw), donde publicaré un registro de desarrollo de este idioma [devlog](https://www.youtube.com/watch?v=Your5q_hc6go&list=PL89TmjrkwpOfteQJRptqmK-y8pr6uJdlc)
113 | ¡Además, participa en la discusión aquí en github sobre el futuro y tu opinión sobre el lenguaje!
114 |
115 |
116 |
--------------------------------------------------------------------------------
/VimSyntaxHighlight/vim/filetype.vim:
--------------------------------------------------------------------------------
1 | " my filetype file
2 | if exists("did_load_filetypes")
3 | finish
4 | endif
5 |
6 | augroup filetypedetect
7 | au! BufRead,BufNewFile *.w setfiletype w
8 | augroup END
9 |
--------------------------------------------------------------------------------
/VimSyntaxHighlight/vim/ftdetect/w.vim:
--------------------------------------------------------------------------------
1 | autocmd BufRead,BufNewFile *.w setf=w
2 |
--------------------------------------------------------------------------------
/VimSyntaxHighlight/vim/syntax/w.vim:
--------------------------------------------------------------------------------
1 | " Wlang syntax highlight for Vim - Version 0.1
2 | " Author: Will - HashLDash
3 |
4 | set termguicolors
5 |
6 | " Quit when a syntax file was already loaded.
7 | if exists('b:current_syntax') | finish| endif
8 |
9 | syntax match wVar "\k\+"
10 | syntax match wNumber "\v<\d+>"
11 | syntax match wNumber "\v<\d+\.\d+>"
12 | syntax match wNumber "\v<\d*\.?\d+([Ee]-?)?\d+>"
13 | syntax match wNumber "\v<0x\x+([Pp]-?)?\x+>"
14 | syntax match wNumber "\v<0b[01]+>"
15 | syntax match wNumber "\v<0o\o+>"
16 | syntax match wNumber " *True"
17 | syntax match wNumber " *False"
18 | syntax match wNumber " *null"
19 | syntax region wString start=/\v"/ skip=/\v(\\[\\"]){-1}/ end=/\v"/
20 | syntax region wString start=/\v'/ end=/\v'/
21 | syntax match wComment " *#.*$"
22 | syntax match wFuncName "\v[[:alpha:]_.]+\ze(\s?\()"
23 | syntax keyword wStatement class def cdef if elif else for in return not while and or break continue del
24 | syntax match wBuiltinFunc "\v(len|print|time|open|collidedRecs|collidedPointRec|uniform|randInt|choose|post|chop|exitApp|localSetItem|localGetItem|localClear|abs|decimal|pass)+\ze(\s?\()"
25 | syntax keyword wBuiltinFunc native import from
26 | syntax keyword wTypes str cstr int float func struct const char double
27 | syntax keyword wPlatforms android Android HTML5 html5 linux Linux Web C c Python python Py py JS js JavaScript
28 |
29 | hi def link wVar ModeMsg
30 | hi def link wString String
31 | hi wNumber ctermfg=Magenta guifg=#FFAAFF cterm=bold
32 | hi wComment ctermfg=DarkGray
33 | hi wFuncName ctermfg=Cyan guifg=#33BBCC cterm=bold
34 | hi wStatement ctermfg=Yellow guifg=#FFFF77 cterm=bold
35 | hi wTypes ctermfg=Blue guifg=#8888FF cterm=bold
36 | hi wBuiltinFunc ctermfg=Blue guifg=#4466FF cterm=bold
37 | hi def link wPlatforms Type
38 |
39 | let b:current_syntax = 'w'
40 |
--------------------------------------------------------------------------------
/art/Guidelines.txt:
--------------------------------------------------------------------------------
1 |
2 | English:
3 | - Logos must be unique
4 | - Don't use images from the internet in the design
5 | - Logos that are similar to other logos will not be added
6 | - Save your logo ideas into a separate svg file (You can add as many ideas as you want in your svg file)
7 | - If you followed all of these guidelines, send a PR
8 |
9 | Português:
10 | - Os logotipos devem ser únicos
11 | - Não use imagens da internet no design
12 | - Logotipos semelhantes a outros logotipos não serão adicionados
13 | - Salve suas ideias de logotipo em um arquivo SVG separado (você pode adicionar quantas ideias quiser em seu arquivo SVG)
14 | - Se você seguiu todas essas diretrizes, envie um PR
15 |
--------------------------------------------------------------------------------
/art/logo1.svg:
--------------------------------------------------------------------------------
1 |
2 |
264 |
--------------------------------------------------------------------------------
/core/assets/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/core/assets/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HashLDash/Photon/bfd206db3b91b695139cbde47bc39ba59057d122/core/assets/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/core/assets/Roboto-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HashLDash/Photon/bfd206db3b91b695139cbde47bc39ba59057d122/core/assets/Roboto-BoldItalic.ttf
--------------------------------------------------------------------------------
/core/assets/Roboto-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HashLDash/Photon/bfd206db3b91b695139cbde47bc39ba59057d122/core/assets/Roboto-Italic.ttf
--------------------------------------------------------------------------------
/core/builder.py:
--------------------------------------------------------------------------------
1 | # Photon builder
2 | # This script is used to generate a Photon project
3 | # according to the target platform and preferences
4 | # Each target is handled by its Toolchain
5 |
6 | import sys
7 |
8 | class Builder():
9 | def __init__(self, platform, filename="main.w", standardLibs='', **kwargs):
10 | print(f'Platform: {platform}')
11 | print(f'Filename: {filename}')
12 | if platform == 'shared':
13 | from toolchains.shared import Toolchain
14 | else:
15 | print('This platform is not supported yet.')
16 | sys.exit()
17 | Toolchain(platform, filename=filename, standardLibs=standardLibs).getBuildFiles()
18 | Toolchain(platform, filename=filename, standardLibs=standardLibs).transpile()
19 | Toolchain(platform, filename=filename, standardLibs=standardLibs).prepare()
20 | Toolchain(platform, filename=filename, standardLibs=standardLibs).make()
21 | Toolchain(platform, filename=filename, standardLibs=standardLibs).runProject()
22 |
--------------------------------------------------------------------------------
/core/dependencies.py:
--------------------------------------------------------------------------------
1 | ''' Install all dependencies for running projects with
2 | the corresponding language on the target platform. '''
3 |
4 | import os
5 | import sys
6 |
7 | UPDATED_REPO = False
8 |
9 | def commandName(package):
10 | ''' Return the command line name of the given package '''
11 | if package == 'nodejs':
12 | return 'node'
13 | return package
14 |
15 | def haveDependencies(lang, platform):
16 | ''' Return True if all dependencies are installed
17 | for the corresponding lang and platform or
18 | False otherwise. '''
19 | for dep in deps[(lang, platform)]:
20 | if not programIsInstalled(dep):
21 | break
22 | else:
23 | return True
24 | print('Some dependencies must be installed for this target language.')
25 | return False
26 |
27 | def resolveDependencies(lang, platform):
28 | ''' Run the corresponding dependency solver. '''
29 | global solver
30 | solver[(lang, platform)]()
31 | #TODO: Check if the installation was successful
32 | # or print the error message and terminate the program
33 |
34 | def getSystem():
35 | ''' Obtains a simple description of the current operating system platform. '''
36 | if sys.platform in {'linux', 'linux2', 'darwin'}:
37 | return "unix"
38 | elif os.name == "nt" or os.environ.get('OS', '') != 'Windows_NT' or sys.platform in {'win32', 'cygwin', 'msys'}:
39 | return "win"
40 | return None
41 |
42 | def programIsInstalled(name):
43 | ''' Verify if program is installed it system. '''
44 | try:
45 | platform_os = getSystem()
46 | if platform_os == "win":
47 | return str(os.popen(f'where /q {name} && echo %ERRORLEVEL%').read()).strip() == "0"
48 | elif platform_os == "unix":
49 | return str(os.popen(f'command -v {name}').read()).strip() != ""
50 | else:
51 | raise Exception('`platform_os` not supported')
52 | except Exception as e:
53 | print(f"error: {e}")
54 | return False
55 |
56 | # INIT - Installer for Win32/Windows (Chocolatey)
57 | def powershellIsInstalled():
58 | if programIsInstalled("powershell"):
59 | print("# PowerShell is installed!")
60 | return True
61 | else:
62 | print("# PowerShell was not found!")
63 | return False
64 |
65 | def chocoIsInstalled():
66 | if programIsInstalled("choco"):
67 | print("# Chocolatey is installed!")
68 | return True
69 | else:
70 | print("# Chocolatey was not found!")
71 | return False
72 |
73 | def chocoInstall():
74 | if not powershellIsInstalled():
75 | return False
76 | if chocoIsInstalled():
77 | return True
78 | shell_exec_cmd = "powershell -Command \"Start-Process powershell -Verb RunAs -PassThru -Wait -ArgumentList \\\"/c Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')); ; timeout /t 5; exit\\\"\""
79 | print('# Installing Chocolatey - Command: \r\n')
80 | print(f'{shell_exec_cmd}\r\n')
81 | print('# Result:')
82 | print(str(os.popen(shell_exec_cmd).read()))
83 | return chocoIsInstalled()
84 |
85 | def chocoInstaller(name):
86 | if not chocoInstall():
87 | return False
88 | shell_exec_cmd = "powershell -Command \"Start-Process powershell -Verb RunAs -PassThru -Wait -ArgumentList \\\"/c choco install " + name + "; timeout /t 5; exit\\\"\""
89 | print('# Installing dependency with Chocolatey - Command: \r\n')
90 | print(f'{shell_exec_cmd}\r\n')
91 | print('# Result:')
92 | print(str(os.popen(shell_exec_cmd).read()))
93 | return True
94 |
95 | # INIT - Installer for Darwin/macOS (HomeBrew)
96 |
97 | def brewInstall():
98 | if not programIsInstalled('bash'):
99 | return False
100 | if programIsInstalled('brew'):
101 | return True
102 | shell_exec_cmd = '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"'
103 | print('# Installing HomeBrew - Command: \r\n')
104 | print(f'{shell_exec_cmd}\r\n')
105 | print('# Result:')
106 | print(str(os.popen(shell_exec_cmd).read()))
107 | return brewIsInstalled()
108 |
109 | def brewInstaller(name):
110 | shell_exec_cmd = ""
111 | if not brewInstall():
112 | return False
113 | if name == "dart":
114 | shell_exec_cmd = "brew tap dart-lang/dart; "
115 | shell_exec_cmd += f'brew install {name}'
116 | print('# Installing dependency with HomeBrew - Command: \r\n')
117 | print(f'{shell_exec_cmd}\r\n')
118 | print('# Result:')
119 | print(str(os.popen(shell_exec_cmd).read()))
120 | return True
121 |
122 | # INIT - Installers for Linux (APT, PACMAN, EMERGE, ZYPPER and DNF)
123 | linux_cmds = {'dmd': 'curl https://dlang.org/install.sh | bash -s || (mkdir -p ~/dlang && wget '
124 | 'https://dlang.org/install.sh -O ~/dlang/install.sh && chmod +x ~/dlang/install.sh && '
125 | '~/dlang/install.sh)'}
126 | linux_cmds['node prompt-sync'] = 'sudo npm install -g prompt-sync'
127 | win_cmds = {'node prompt-sync': 'npm install prompt-sync'}
128 | linux_cmds['deno'] = 'curl -fsSL https://deno.land/x/install/install.sh | sudo DENO_INSTALL=/usr/local sh'
129 | if os.path.exists('/etc/debian_version'): # debian, ubuntu, pop!_os, zorin os
130 | linux_cmds['before'] = 'sudo apt-get update'
131 | linux_cmds['gcc'] = 'sudo apt install build-essential'
132 | linux_cmds['dmd'] = 'sudo wget https://netcologne.dl.sourceforge.net/project/d-apt/files/d-apt.list -O ' \
133 | '/etc/apt/sources.list.d/d-apt.list && sudo apt-get update --allow-insecure-repositories && ' \
134 | 'sudo apt-get -y --allow-unauthenticated install --reinstall d-apt-keyring && sudo apt-get ' \
135 | 'update && sudo apt install dmd-compiler dub libcurl3 libphobos2-79 libphobos2-dev '
136 | linux_cmds['haxe'] = 'sudo apt-get install haxe && mkdir ~/haxelib && haxelib setup ~/haxelib'
137 | linux_cmds['nodejs'] = 'sudo apt install nodejs'
138 | linux_cmds['dart'] = "sudo apt-get install apt-transport-https && sudo sh -c 'wget -qO- " \
139 | "https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -' && sudo sh -c 'wget " \
140 | "-qO- https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > " \
141 | "/etc/apt/sources.list.d/dart_stable.list' && sudo apt-get update && sudo apt-get install " \
142 | "dart "
143 | elif os.path.exists('/etc/arch-release'): # arch, manjaro
144 | linux_cmds['before'] = 'sudo pacman -Syy'
145 | linux_cmds['gcc'] = 'sudo pacman -S gcc'
146 | linux_cmds['dmd'] = 'sudo pacman -S dmd'
147 | linux_cmds['haxe'] = 'sudo pacman -S haxe'
148 | linux_cmds['nodejs'] = 'sudo pacman -S nodejs'
149 | linux_cmds['deno'] = 'sudo pacman -S deno'
150 | linux_cmds['npm'] = 'sudo pacman -S npm'
151 | linux_cmds['dart'] = 'sudo pacman -S dart'
152 | elif os.path.exists('/etc/gentoo-release'): # gentoo
153 | linux_cmds['before'] = 'sudo emerge --sync'
154 | linux_cmds['gcc'] = 'sudo emerge sys-devel/gcc'
155 | linux_cmds['dmd'] = 'sudo emerge app-portage/layman && sudo layman -f -a dlang && sudo emerge dev-lang/dmd'
156 | linux_cmds['nodejs'] = 'sudo emerge nodejs'
157 | elif os.path.exists('/etc/SuSE-release'): # opensuse
158 | linux_cmds['before'] = 'sudo zypper refresh'
159 | linux_cmds['gcc'] = 'sudo zypper install gcc'
160 | linux_cmds['haxe'] = 'sudo zypper install haxe && mkdir ~/haxelib && haxelib setup ~/haxelib'
161 | linux_cmds['nodejs'] = 'sudo zypper install nodejs4'
162 | elif os.path.exists('/etc/redhat-release'): # red hat, centos, fedora
163 | linux_cmds['before'] = 'sudo dnf check-update; sudo yum check-update'
164 | linux_cmds['gcc'] = 'sudo dnf install gcc || sudo yum install gcc'
165 | linux_cmds['haxe'] = '(sudo dnf install haxe || (sudo yum install epel-release; sudo yum install haxe)) && mkdir ' \
166 | '~/haxelib && haxelib setup ~/haxelib'
167 | linux_cmds['nodejs'] = 'sudo dnf module install nodejs:12'
168 |
169 | def linuxInstaller(package):
170 | global UPDATED_REPO
171 | if package in linux_cmds:
172 | if 'before' in linux_cmds and not UPDATED_REPO:
173 | os.system(f'sh -c "{linux_cmds["before"]}"')
174 | UPDATED_REPO = True
175 |
176 | shell_exec_cmd = f'sh -c "{linux_cmds[package]}"'
177 | print('# Installing dependency - Command: \r\n')
178 | print(f'{shell_exec_cmd}\r\n')
179 | print('# Result:')
180 | os.system(shell_exec_cmd)
181 | else:
182 | print(f"We couldn't try to automatically install `{package}`, please install it manually.")
183 | return False
184 |
185 | if programIsInstalled(commandName(package)):
186 | print(f'Dependency `{package}` has been successfully installed!')
187 | return True
188 | else:
189 | print(f'Dependency `{package}` was not found.')
190 | return False
191 |
192 | # INIT - Linux
193 | def resolveCLinux():
194 | ''' Install gcc '''
195 | return linuxInstaller('gcc')
196 |
197 | def resolvePyLinux():
198 | ''' Install python '''
199 | return linuxInstaller('python')
200 |
201 | def resolveDLinux():
202 | ''' Install dmd '''
203 | return linuxInstaller('dmd')
204 |
205 | def resolveHaxeLinux():
206 | ''' Install haxe '''
207 | return linuxInstaller('haxe')
208 |
209 | def resolveJsLinux():
210 | ''' Install nodejs and deps '''
211 | return linuxInstaller('nodejs') and linuxInstaller('npm') and linuxInstaller('node prompt-sync')
212 |
213 | def resolveTsLinux():
214 | ''' Install deno and deps '''
215 | return linuxInstaller('deno')
216 |
217 | def resolveDartLinux():
218 | ''' Install dart '''
219 | return linuxInstaller('dart')
220 |
221 | # INIT - Win32
222 | def resolveCWin32():
223 | ''' Install gcc '''
224 | chocoInstaller("mingw")
225 | return programIsInstalled("gcc")
226 |
227 | def resolvePyWin32():
228 | ''' Install python '''
229 | chocoInstaller("python")
230 | return programIsInstalled("python")
231 |
232 | def resolveDWin32():
233 | ''' Install dmd '''
234 | chocoInstaller("dmd")
235 | return programIsInstalled("dmd")
236 |
237 | def resolveHaxeWin32():
238 | ''' Install haxe '''
239 | chocoInstaller("haxe")
240 | return programIsInstalled("haxe")
241 |
242 | def resolveJsWin32():
243 | ''' Install nodejs '''
244 | chocoInstaller("nodejs") # npm is also installed with nodejs
245 | os.system(win_cmds["node prompt-sync"])
246 | return programIsInstalled("node") and programIsInstalled("npm")
247 |
248 | def resolveTsWin32():
249 | ''' Install deno '''
250 | chocoInstaller("deno")
251 | return programIsInstalled("deno")
252 |
253 | def resolveDartWin32():
254 | ''' Install dart '''
255 | chocoInstaller("dart-sdk")
256 | return programIsInstalled("dart")
257 |
258 | # INIT - Darwin
259 | def resolveCDarwin():
260 | ''' Install gcc '''
261 | brewInstaller("gcc")
262 | return programIsInstalled("gcc")
263 |
264 | def resolvePyDarwin():
265 | ''' Install gcc '''
266 | brewInstaller("gcc")
267 | return programIsInstalled("gcc")
268 |
269 | def resolveDDarwin():
270 | ''' Install dmd '''
271 | brewInstaller("dmd")
272 | return programIsInstalled("dmd")
273 |
274 | def resolveHaxeDarwin():
275 | ''' Install haxe '''
276 | brewInstaller("haxe")
277 | return programIsInstalled("haxe")
278 |
279 | def resolveJsDarwin():
280 | ''' Install nodejs '''
281 | brewInstaller("nodejs")
282 | brewInstaller("npm")
283 | os.system(linux_cmds["node prompt-sync"])
284 | return programIsInstalled("node") and programIsInstalled("npm")
285 |
286 | def resolveTsDarwin():
287 | ''' Install deno '''
288 | brewInstaller("deno")
289 | return programIsInstalled("deno")
290 |
291 | def resolveDartDarwin():
292 | ''' Install dart '''
293 | brewInstaller("dart")
294 | return programIsInstalled("dart")
295 |
296 | solver = {
297 | ('c', 'linux'): resolveCLinux,
298 | ('c', 'win32'): resolveCWin32,
299 | ('c', 'darwin'): resolveCDarwin,
300 | ('python', 'linux'): resolvePyLinux,
301 | ('python', 'win32'): resolvePyWin32,
302 | ('python', 'darwin'): resolvePyDarwin,
303 | ('d', 'linux'): resolveDLinux,
304 | ('d', 'win32'): resolveDWin32,
305 | ('d', 'darwin'): resolveDDarwin,
306 | ('haxe', 'linux'): resolveHaxeLinux,
307 | ('haxe', 'win32'): resolveHaxeWin32,
308 | ('haxe', 'darwin'): resolveHaxeDarwin,
309 | ('js', 'linux'): resolveJsLinux,
310 | ('js', 'win32'): resolveJsWin32,
311 | ('js', 'darwin'): resolveJsDarwin,
312 | ('ts', 'linux'): resolveTsLinux,
313 | ('ts', 'win32'): resolveTsWin32,
314 | ('ts', 'darwin'): resolveTsDarwin,
315 | ('dart', 'linux'): resolveDartLinux,
316 | ('dart', 'win32'): resolveDartWin32,
317 | ('dart', 'darwin'): resolveDartDarwin,
318 | }
319 |
320 | deps = {
321 | ('c', 'linux'): ['gcc'],
322 | ('c', 'win32'): ['gcc'],
323 | ('c', 'darwin'): ['gcc'],
324 | ('python', 'linux'): ['python'],
325 | ('python', 'win32'): ['python'],
326 | ('python', 'darwin'): ['python'],
327 | ('d', 'linux'): ['dmd'],
328 | ('d', 'win32'): ['dmd'],
329 | ('d', 'darwin'): ['dmd'],
330 | ('haxe', 'linux'): ['haxe'],
331 | ('haxe', 'win32'): ['haxe'],
332 | ('haxe', 'darwin'): ['haxe'],
333 | ('js', 'linux'): ['node','npm'],
334 | ('js', 'win32'): ['node','npm'],
335 | ('js', 'darwin'): ['node','npm'],
336 | ('ts', 'linux'): ['deno'],
337 | ('ts', 'win32'): ['deno'],
338 | ('ts', 'darwin'): ['deno'],
339 | ('dart', 'linux'): ['dart'],
340 | ('dart', 'win32'): ['dart'],
341 | ('dart', 'darwin'): ['dart'],
342 | }
343 |
--------------------------------------------------------------------------------
/core/engines/pyEngine.py:
--------------------------------------------------------------------------------
1 | from transpilers.pyTranspiler import Transpiler
2 | from transpilers.pyTokens import Sequence, Print
3 | import os
4 |
5 | def debug(*args):
6 | #print(*args)
7 | pass
8 |
9 | class Engine():
10 | def __init__(self, filename, **kwargs):
11 | self.transpiler = Transpiler(filename, **kwargs)
12 | self.globals = {}
13 | self.importedLibs = set()
14 |
15 | def process(self, token):
16 | if token:
17 | self.transpiler.process(token)
18 | for lib in self.transpiler.imports - self.importedLibs:
19 | bytecode = compile(lib,'','exec')
20 | exec(bytecode, self.globals, self.globals)
21 | self.importedLibs.add(lib)
22 | try:
23 | if token['token'] in {'expr'}:
24 | code = repr(Print(args=[self.transpiler.sequence[-1]]))
25 | bytecode = compile(code,'','exec')
26 | exec(bytecode, self.globals, self.globals)
27 | else:
28 | code = repr(self.transpiler.sequence[-1])
29 | bytecode = compile(code,'','exec')
30 | exec(code, self.globals, self.globals)
31 | except Exception as e:
32 | print(f'RuntimeError: {e}')
33 | #self.transpiler.sequence = Sequence()
34 | #self.transpiler.imports = set()
35 |
--------------------------------------------------------------------------------
/core/grammar/genGrammar.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import re
3 | from itertools import product
4 | from pprint import pprint
5 |
6 | try:
7 | grammar = sys.argv[1]
8 | except:
9 | print('Please, provide a grammar')
10 | sys.exit()
11 |
12 | def genRules(val):
13 | vals = [ i for i in re.split('(\W)', val) if not (i=='' or i==' ' or i=='\n') ]
14 | terms = []
15 | current = []
16 | inGroup = False
17 | for v in vals:
18 | if v == ')':
19 | terms.append(tuple(current))
20 | current = []
21 | inGroup = False
22 | elif v == '(':
23 | inGroup = True
24 | elif inGroup:
25 | current.append(v)
26 | else:
27 | terms.append((v,))
28 | return list(product(*terms))
29 |
30 | def createGrammar(grammar):
31 | with open('generatedGrammar.py', 'w') as g:
32 | g.write('patterns = {\n')
33 | for feature, patterns in grammar.items():
34 | for pattern in patterns:
35 | g.write(f' {pattern}: {feature},\n')
36 | g.write('}')
37 |
38 | with open(grammar, 'r') as g:
39 | generated = {}
40 | inDefinition = ''
41 | patterns = []
42 | for l in g:
43 | if l.startswith('#'):
44 | continue
45 | if '=' in l:
46 | if patterns:
47 | generated[inDefinition] = list(patterns)
48 | patterns = []
49 | definition, val = l.split('=')
50 | inDefinition = definition.strip()
51 | patterns += genRules(val)
52 | elif l.strip().startswith('|'):
53 | patterns += genRules(l.strip()[1:])
54 | if patterns:
55 | generated[inDefinition] = list(patterns)
56 | patterns = []
57 | createGrammar(generated)
58 |
--------------------------------------------------------------------------------
/core/grammar/generatedGrammar.py:
--------------------------------------------------------------------------------
1 | patterns = {
2 | ('hashtag',): comment,
3 | ('singleQuote',): string,
4 | ('doubleQuote',): string,
5 | ('type', 'lbracket', 'rbracket', 'var'): arrayType,
6 | ('type', 'lbracket', 'rbracket', 'space'): arrayType,
7 | ('var', 'lbracket', 'rbracket', 'var'): arrayType,
8 | ('var', 'lbracket', 'rbracket', 'space'): arrayType,
9 | ('expr', 'lbracket', 'rbracket', 'var'): arrayType,
10 | ('expr', 'lbracket', 'rbracket', 'space'): arrayType,
11 | ('type', 'lbracket', 'num', 'rbracket', 'var'): arrayType,
12 | ('type', 'lbracket', 'num', 'rbracket', 'space'): arrayType,
13 | ('var', 'lbracket', 'num', 'rbracket', 'var'): arrayType,
14 | ('var', 'lbracket', 'num', 'rbracket', 'space'): arrayType,
15 | ('expr', 'lbracket', 'num', 'rbracket', 'var'): arrayType,
16 | ('expr', 'lbracket', 'num', 'rbracket', 'space'): arrayType,
17 | ('type', 'beginBlock', 'type'): mapType,
18 | ('type', 'beginBlock', 'var'): mapType,
19 | ('var', 'beginBlock', 'type'): mapType,
20 | ('var', 'beginBlock', 'var'): mapType,
21 | ('var', 'underline', 'var'): var,
22 | ('underline', 'var'): var,
23 | ('var', 'underline'): var,
24 | ('underline',): var,
25 | ('num', 'dot', 'num'): floatNumber,
26 | ('num', 'dot'): floatNumber,
27 | ('expr', 'dot', 'expr'): dotAccess,
28 | ('type', 'space', 'dot', 'expr'): dotAccess,
29 | ('expr', 'space', 'dot', 'expr'): dotAccess,
30 | ('dot', 'expr'): dotAccess,
31 | ('type', 'var'): typeDeclaration,
32 | ('expr', 'var'): typeDeclaration,
33 | ('lparen', 'expr', 'rparen'): group,
34 | ('equal', 'equal'): operator,
35 | ('equal', 'operator'): operator,
36 | ('operator', 'equal'): operator,
37 | ('operator', 'operator'): operator,
38 | ('type', 'lparen', 'expr', 'rparen'): cast,
39 | ('expr', 'lparen', 'rparen'): call,
40 | ('expr', 'lparen', 'expr', 'rparen'): call,
41 | ('expr', 'lparen', 'args', 'rparen'): call,
42 | ('expr', 'lparen', 'assign', 'rparen'): call,
43 | ('expr', 'lparen', 'kwargs', 'rparen'): call,
44 | ('expr', 'lparen', 'expr', 'comma', 'assign', 'rparen'): call,
45 | ('expr', 'lparen', 'expr', 'comma', 'kwargs', 'rparen'): call,
46 | ('expr', 'lparen', 'args', 'comma', 'assign', 'rparen'): call,
47 | ('expr', 'lparen', 'args', 'comma', 'kwargs', 'rparen'): call,
48 | ('num',): expr,
49 | ('floatNumber',): expr,
50 | ('var',): expr,
51 | ('dotAccess',): expr,
52 | ('group',): expr,
53 | ('num', 'operator', 'num'): expr,
54 | ('num', 'operator', 'var'): expr,
55 | ('num', 'operator', 'expr'): expr,
56 | ('var', 'operator', 'num'): expr,
57 | ('var', 'operator', 'var'): expr,
58 | ('var', 'operator', 'expr'): expr,
59 | ('expr', 'operator', 'num'): expr,
60 | ('expr', 'operator', 'var'): expr,
61 | ('expr', 'operator', 'expr'): expr,
62 | ('operator', 'expr'): expr,
63 | ('expr', 'beginBlock', 'expr'): keyVal,
64 | ('keyVals', 'comma', 'keyVal'): keyVals,
65 | ('keyVals', 'comma', 'keyVals'): keyVals,
66 | ('keyVal', 'comma', 'keyVal'): keyVals,
67 | ('keyVal', 'comma', 'keyVals'): keyVals,
68 | ('expr', 'lbracket', 'expr', 'rbracket'): indexAccess,
69 | ('lbracket', 'args', 'rbracket'): array,
70 | ('lbracket', 'expr', 'rbracket'): array,
71 | ('lbracket', 'rbracket'): array,
72 | ('lbrace', 'rbrace'): hashmap,
73 | ('lbrace', 'keyVal', 'rbrace'): hashmap,
74 | ('lbrace', 'keyVals', 'rbrace'): hashmap,
75 | ('returnStatement',): funcReturn,
76 | ('returnStatement', 'expr'): funcReturn,
77 | ('expr', 'dot', 'dot', 'expr'): rangeExpr,
78 | ('expr', 'dot', 'dot', 'expr', 'dot', 'dot', 'expr'): rangeExpr,
79 | ('ifStatement', 'expr', 'beginBlock'): ifelif,
80 | ('elifStatement', 'expr', 'beginBlock'): ifelif,
81 | ('forStatement', 'args', 'inStatement', 'range', 'beginBlock'): forLoop,
82 | ('forStatement', 'args', 'inStatement', 'expr', 'beginBlock'): forLoop,
83 | ('forStatement', 'expr', 'inStatement', 'range', 'beginBlock'): forLoop,
84 | ('forStatement', 'expr', 'inStatement', 'expr', 'beginBlock'): forLoop,
85 | ('forStatement', 'expr', 'beginBlock'): forTarget,
86 | ('whileStatement', 'expr', 'beginBlock'): whileLoop,
87 | ('args', 'comma', 'args'): args,
88 | ('args', 'comma', 'expr'): args,
89 | ('expr', 'comma', 'args'): args,
90 | ('expr', 'comma', 'expr'): args,
91 | ('assign', 'comma', 'assign'): kwargs,
92 | ('assign', 'comma', 'kwargs'): kwargs,
93 | ('kwargs', 'comma', 'assign'): kwargs,
94 | ('kwargs', 'comma', 'kwargs'): kwargs,
95 | ('expr', 'operator', 'equal', 'expr'): augAssign,
96 | ('expr', 'equal', 'expr'): assign,
97 | ('fromStatement', 'expr', 'importStatement', 'expr'): fromImport,
98 | ('fromStatement', 'expr', 'importStatement', 'args'): fromImport,
99 | ('fromStatement', 'expr', 'importStatement', 'operator'): fromImport,
100 | ('nativeStatement', 'importStatement', 'expr'): imports,
101 | ('importStatement', 'expr'): imports,
102 | ('delStatement', 'expr'): delete,
103 | ('defStatement', 'expr', 'lparen', 'expr', 'rparen', 'beginBlock'): function,
104 | ('defStatement', 'expr', 'lparen', 'args', 'rparen', 'beginBlock'): function,
105 | ('defStatement', 'expr', 'lparen', 'assign', 'rparen', 'beginBlock'): function,
106 | ('defStatement', 'expr', 'lparen', 'kwargs', 'rparen', 'beginBlock'): function,
107 | ('defStatement', 'expr', 'lparen', 'expr', 'comma', 'assign', 'rparen', 'beginBlock'): function,
108 | ('defStatement', 'expr', 'lparen', 'expr', 'comma', 'kwargs', 'rparen', 'beginBlock'): function,
109 | ('defStatement', 'expr', 'lparen', 'args', 'comma', 'assign', 'rparen', 'beginBlock'): function,
110 | ('defStatement', 'expr', 'lparen', 'args', 'comma', 'kwargs', 'rparen', 'beginBlock'): function,
111 | ('defStatement', 'expr', 'lparen', 'rparen', 'beginBlock'): function,
112 | ('classStatement', 'expr', 'lparen', 'rparen', 'beginBlock'): classDefinition,
113 | ('classStatement', 'expr', 'lparen', 'expr', 'rparen', 'beginBlock'): classDefinition,
114 | ('classStatement', 'expr', 'lparen', 'args', 'rparen', 'beginBlock'): classDefinition,
115 | ('open', 'lparen', 'args', 'rparen'): openFunc,
116 | ('open', 'lparen', 'expr', 'rparen'): openFunc,
117 | ('input', 'lparen', 'expr', 'rparen'): inputFunc,
118 | ('input', 'lparen', 'rparen'): inputFunc,
119 | }
--------------------------------------------------------------------------------
/core/grammar/grammar:
--------------------------------------------------------------------------------
1 | comment = hashtag
2 |
3 | string = singleQuote
4 | | doubleQuote
5 |
6 | arrayType = (type var expr) lbracket rbracket (var space)
7 | | (type var expr) lbracket num rbracket (var space)
8 |
9 | mapType = (type var) beginBlock (type var)
10 |
11 | var = var underline var
12 | | underline var
13 | | var underline
14 | | underline
15 |
16 | floatNumber = num dot num
17 | | num dot
18 |
19 | dotAccess = expr dot expr
20 | | (type expr) space dot expr
21 | | dot expr
22 |
23 | typeDeclaration = (type expr) var
24 |
25 | group = lparen expr rparen
26 |
27 | operator = (equal operator) (equal operator)
28 |
29 | cast = type lparen (expr) rparen
30 |
31 | call = expr lparen rparen
32 | | expr lparen (expr args assign kwargs) rparen
33 | | expr lparen (expr args) comma (assign kwargs) rparen
34 |
35 | expr = num
36 | | floatNumber
37 | | var
38 | | dotAccess
39 | | group
40 | | (num var expr) operator (num var expr)
41 | | operator (expr)
42 |
43 | keyVal = expr beginBlock expr
44 |
45 | keyVals = (keyVals keyVal) comma (keyVal keyVals)
46 |
47 | indexAccess = expr lbracket (expr) rbracket
48 |
49 | array = lbracket (args expr) rbracket
50 | | lbracket rbracket
51 |
52 | hashmap = lbrace rbrace
53 | | lbrace (keyVal keyVals) rbrace
54 |
55 | funcReturn = returnStatement
56 | | returnStatement expr
57 |
58 | rangeExpr = expr dot dot expr
59 | | expr dot dot expr dot dot expr
60 |
61 | ifelif = (ifStatement elifStatement) expr beginBlock
62 |
63 | forLoop = forStatement (args expr) inStatement (range expr) beginBlock
64 |
65 | forTarget = forStatement expr beginBlock
66 |
67 | whileLoop = whileStatement expr beginBlock
68 |
69 | args = (args expr) comma (args expr)
70 |
71 | kwargs = (assign kwargs) comma (assign kwargs)
72 |
73 | augAssign = expr operator equal expr
74 |
75 | assign = expr equal expr
76 |
77 | fromImport = fromStatement expr importStatement (expr args operator)
78 |
79 | imports = nativeStatement importStatement expr
80 | | importStatement expr
81 |
82 | delete = delStatement expr
83 |
84 | function = defStatement expr lparen (expr args assign kwargs) rparen beginBlock
85 | | defStatement expr lparen (expr args) comma (assign kwargs) rparen beginBlock
86 | | defStatement expr lparen rparen beginBlock
87 |
88 | classDefinition = classStatement expr lparen rparen beginBlock
89 | | classStatement expr lparen (expr args) rparen beginBlock
90 |
91 | openFunc = open lparen (args expr) rparen
92 |
93 | inputFunc = input lparen (expr) rparen
94 | | input lparen rparen
95 |
--------------------------------------------------------------------------------
/core/interpreter.py:
--------------------------------------------------------------------------------
1 | # Photon Interpreter
2 | #
3 | # This script funcion is:
4 | # - Get lines of code from a file or interpreter
5 | # - Call the parser to generate tokens and the struct
6 | # - Call the engine to Process the struct
7 | # - Run the processed struct
8 |
9 | from photonParser import parse, assembly, showError
10 | from photonParser import debug as debugFunc
11 | import sys
12 |
13 | class Interpreter():
14 | def __init__(self, filename='', lang='c', platform=sys.platform, framework='', module=False, standardLibs='', debug=False, transpileOnly=False):
15 | self.debug = debug
16 | if lang == 'c':
17 | from transpilers.cTranspiler import Transpiler
18 | elif lang in {'py', 'python'}:
19 | from transpilers.pyTranspiler import Transpiler
20 | elif lang == 'dart':
21 | from transpilers.dartTranspiler import Transpiler
22 | elif lang in ['js', 'javascript']:
23 | from transpilers.jsTranspiler import Transpiler
24 | elif lang == 'ts':
25 | from transpilers.tsTranspiler import Transpiler
26 | elif lang == 'haxe':
27 | from transpilers.haxeTranspiler import Transpiler
28 | elif lang == 'd':
29 | from transpilers.dTranspiler import Transpiler
30 | else:
31 | print(f'Invalid language {lang}')
32 | sys.exit()
33 | self.filename = filename
34 | if filename:
35 | self.engine = Transpiler(filename=filename, platform=platform, framework=framework, module=module, standardLibs=standardLibs, debug=debug)
36 | self.input = self.file
37 | try:
38 | # Read utf8 but write as the default on the OS
39 | with open(filename,'r',encoding='utf8') as f:
40 | self.source = [line for line in f]
41 | except UnicodeDecodeError:
42 | with open(filename,'r') as f:
43 | self.source = [line for line in f]
44 | except FileNotFoundError as e:
45 | print(f"File not found: can't open file {filename}: {e}")
46 | sys.exit()
47 | else:
48 | try:
49 | import readline
50 | except ModuleNotFoundError:
51 | # Windows doesn't have readline
52 | try:
53 | import pyreadline
54 | except ModuleNotFoundError:
55 | # Run without history and arrow key functionality
56 | pass
57 | from engines.pyEngine import Engine
58 | self.engine = Engine(filename=filename, platform=platform, framework=framework, module=module, standardLibs=standardLibs)
59 | self.input = self.console
60 | self.end = False
61 | self.processing = True
62 | self.transpileOnly = transpileOnly
63 | self.lineNumber = 0
64 |
65 | def console(self, glyph='>>> '):
66 | return input(glyph)
67 |
68 | def file(self, *args):
69 | try:
70 | line = self.source.pop(0)
71 | self.lineNumber += 1
72 | while line.strip() == '':
73 | line = self.source.pop(0)
74 | self.lineNumber += 1
75 | rest = ''
76 | count = 1 # checking where is the end of the function call. When it ends, count is 0
77 | while line[-2:] in {'(\n',',\n','{\n','[\n'} or rest.lstrip() in {')\n',']\n','}\n'} and count > 0:
78 | line = line.replace('\n','')
79 | rest = self.source.pop(0).lstrip()
80 | self.lineNumber += 1
81 | while rest.strip() == '':
82 | rest = self.source.pop(0)
83 | self.lineNumber += 1
84 | if rest.lstrip() in {')\n',']\n','}\n'}:
85 | if ')' in rest:
86 | count -= 1
87 | if line[-1] == ',':
88 | line = line[:-1]
89 | rest = rest.lstrip()
90 | line += rest
91 | return line
92 | except IndexError:
93 | if self.processing:
94 | return ''
95 | else:
96 | if not self.transpileOnly:
97 | self.engine.run()
98 | sys.exit()
99 | else:
100 | self.engine.write()
101 | self.classes = self.engine.classes
102 | return 'exit'
103 |
104 | def getBlock(self, indent):
105 | ''' Return a list of code corresponding to the indentation level
106 | '''
107 | self.line = self.input('... ')
108 | debugFunc('In a block', center=True)
109 | blockTokenized = parse(self.line, filename=self.filename,
110 | no=self.lineNumber, debug=self.debug)
111 | blockIndent = blockTokenized[0]['indent']
112 | block = []
113 | if blockIndent > indent:
114 | struct, nextLine = self.handleTokenized(blockTokenized)
115 | block.append(struct)
116 | if not nextLine:
117 | self.line = self.input('... ')
118 | blockTokenized = parse(self.line, filename=self.filename,
119 | no=self.lineNumber, debug=self.debug)
120 | while blockTokenized[0]['indent'] == blockIndent:
121 | struct, nextLine = self.handleTokenized(blockTokenized)
122 | block.append(struct)
123 | if not nextLine:
124 | self.line = self.input('... ')
125 | blockTokenized = parse(self.line, filename=self.filename,
126 | no=self.lineNumber, debug=self.debug)
127 | debugFunc('Out of a block', center=True)
128 | return block, blockTokenized
129 | else:
130 | debugFunc('Out of a block', center=True)
131 | return block, blockTokenized
132 | raise SyntaxError(f'Expecting an indented block here.\nLine: {self.line}')
133 |
134 | def handleBlock(self, tokenized):
135 | ''' Return a struct with a block and possibly modifiers '''
136 | indent = tokenized[0]['indent']
137 | block, nextTokenized = self.getBlock(indent)
138 | tokenized = assembly(tokenized, block=block)
139 | if len(nextTokenized) > 1:
140 | while nextTokenized[1]['token'] in {'elifStatement','elseStatement'} and nextTokenized[0]['indent'] == indent:
141 | block, afterTokenized = self.getBlock(indent)
142 | nextTokenized = assembly(nextTokenized, block=block)
143 | tokenized = assembly(tokenized, modifier=nextTokenized)
144 | nextTokenized = afterTokenized
145 | if len(nextTokenized) == 1:
146 | break
147 | struct = assembly(tokenized)
148 | return struct
149 |
150 | def handleTokenized(self, tokenized):
151 | ''' Return a struct to be processed by the VM '''
152 | ''' And if there is a line to be processed in the buffer (self.line) '''
153 | if tokenized[-1]['token'] == 'beginBlock':
154 | struct = self.handleBlock(tokenized)
155 | return struct, True
156 | else:
157 | struct = assembly(tokenized)
158 | return struct, False
159 |
160 | def run(self):
161 | nextLine = False
162 | while True:
163 | if not nextLine or self.line == '':
164 | self.line = self.input('>>> ')
165 | self.processing = True
166 | if self.line == 'exit':
167 | break
168 | try:
169 | tokenized = parse(self.line, filename=self.filename, no=self.lineNumber, debug=self.debug)
170 | struct, nextLine = self.handleTokenized(tokenized)
171 | except Exception as e:
172 | showError(e)
173 | self.engine.process(struct)
174 | self.processing = False
175 |
176 | if __name__ == "__main__":
177 | try:
178 | filename = sys.argv[1]
179 | except IndexError:
180 | filename = ''
181 | Interpreter(filename).run()
182 |
--------------------------------------------------------------------------------
/core/libs/http/server.w:
--------------------------------------------------------------------------------
1 | native import _httpserver
2 |
3 | def run():
4 | _httpserver.photon_run_http_server()
5 |
--------------------------------------------------------------------------------
/core/libs/lol/test.w:
--------------------------------------------------------------------------------
1 | print('hey')
2 |
--------------------------------------------------------------------------------
/core/libs/native/c/_httpserver.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | int photon_run_http_server(char* addr, int port) {
8 | int server_fd, new_socket;
9 | struct sockaddr_in address;
10 | int addrlen = sizeof(address);
11 | char buffer[1024] = {0};
12 |
13 | // Creating socket file descriptor
14 | if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
15 | perror("Socket failed");
16 | exit(EXIT_FAILURE);
17 | }
18 |
19 | // Setting up the address structure
20 | address.sin_family = AF_INET;
21 | address.sin_addr.s_addr = INADDR_ANY;
22 | address.sin_port = htons(port);
23 |
24 | // Binding the socket to the specified port
25 | if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
26 | perror("Bind failed");
27 | close(server_fd);
28 | exit(EXIT_FAILURE);
29 | }
30 |
31 | // Start listening for incoming connections
32 | if (listen(server_fd, 3) < 0) {
33 | perror("Listen failed");
34 | close(server_fd);
35 | exit(EXIT_FAILURE);
36 | }
37 |
38 | printf("Server is listening on port %d\n", PORT);
39 |
40 | while (1) {
41 | // Accept a new connection
42 | if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
43 | perror("Accept failed");
44 | close(server_fd);
45 | exit(EXIT_FAILURE);
46 | }
47 |
48 | // Read the incoming HTTP request
49 | read(new_socket, buffer, 1024);
50 | printf("Received request:\n%s\n", buffer);
51 |
52 | // Send the HTTP response
53 | write(new_socket, http_response, strlen(http_response));
54 |
55 | // Close the socket for this connection
56 | close(new_socket);
57 | }
58 |
59 | // Close the server socket
60 | close(server_fd);
61 | return 0;
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/core/libs/native/c/_requests.h:
--------------------------------------------------------------------------------
1 | //PHOTON_FLAGS -lcurl
2 | //PHOTON_INCLUDES asprintf.h
3 | #include
4 | #include
5 | #include "asprintf.h"
6 |
7 | size_t get_data(char* buffer, size_t itemsize, size_t nitems, void* obj) {
8 | char** old = (char**) obj;
9 | asprintf(old, "%s%s", *old, buffer);
10 | return itemsize * nitems;
11 | }
12 |
13 | char* get(char* url) {
14 | CURL* curl;
15 | CURLcode resp;
16 |
17 | curl = curl_easy_init();
18 | if (curl) {
19 | curl_easy_setopt(curl, CURLOPT_URL, url);
20 | curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
21 | char* result = "";
22 | curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
23 | curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, get_data);
24 |
25 | resp = curl_easy_perform(curl);
26 | if (resp != CURLE_OK) {
27 | printf("GET failed: %s\n", curl_easy_strerror(resp));
28 | }
29 |
30 | curl_easy_cleanup(curl);
31 | return result;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/core/libs/native/c/asprintf.h:
--------------------------------------------------------------------------------
1 | #ifndef __asprintf
2 | # define __asprintf
3 |
4 | #include /* needed for vsnprintf */
5 | #include /* needed for malloc-free */
6 | #include /* needed for va_list */
7 |
8 | #ifndef _vscprintf
9 | /* For some reason, MSVC fails to honour this #ifndef. */
10 | /* Hence function renamed to _vscprintf_so(). */
11 | int _vscprintf_so(const char* format, va_list pargs) {
12 | int retval;
13 | va_list argcopy;
14 | va_copy(argcopy, pargs);
15 | retval = vsnprintf(NULL, 0, format, argcopy);
16 | va_end(argcopy);
17 | return retval;
18 | }
19 | #endif // _vscprintf
20 |
21 | #ifndef vasprintf
22 | int vasprintf(char** strp, const char* fmt, va_list ap) {
23 | int len = _vscprintf_so(fmt, ap);
24 | if (len == -1) return -1;
25 | char* str = malloc((size_t) len + 1);
26 | if (!str) return -1;
27 | int r = vsnprintf(str, len + 1, fmt, ap); /* "secure" version of vsprintf */
28 | if (r == -1) return free(str), -1;
29 | *strp = str;
30 | return r;
31 | }
32 | #endif // vasprintf
33 |
34 | #ifndef asprintf
35 | int asprintf(char* strp[], const char* fmt, ...) {
36 | va_list ap;
37 | va_start(ap, fmt);
38 | int r = vasprintf(strp, fmt, ap);
39 | va_end(ap);
40 | return r;
41 | }
42 | #endif
43 | // asprintf
44 |
45 | #ifndef __photon_format_str
46 | char* __photon_format_str(const char* fmt, ...) {
47 | char* str = malloc(sizeof(char));
48 | if (!str) return "";
49 | va_list ap;
50 | va_start(ap, fmt);
51 | vasprintf(&str, fmt, ap);
52 | va_end(ap);
53 | return str;
54 | }
55 | #endif
56 | // __photon_format_str
57 | #endif
58 |
--------------------------------------------------------------------------------
/core/libs/native/c/dict_int.template:
--------------------------------------------------------------------------------
1 | #ifndef __dict_int_!@valType@!
2 | #define __dict_int_!@valType@!
3 | #include "main.h"
4 | #include "asprintf.h"
5 |
6 | typedef struct dict_int_!@valType@!_entry {
7 | int prehash;
8 | long key;
9 | !@valNativeType@! val;
10 | } dict_int_!@valType@!_entry;
11 |
12 | typedef struct dict_int_!@valType@! {
13 | int len;
14 | int size;
15 | int* indices;
16 | dict_int_!@valType@!_entry* entries;
17 | } dict_int_!@valType@!;
18 |
19 | !@valNativeType@! dict_int_!@valType@!_get(dict_int_!@valType@!* self, long key) {
20 | int size = self->size;
21 | int index = key % size;
22 | if (self->indices[index] != -1) {
23 | while (self->entries[self->indices[index]].key != key) {
24 | index = (index + 1) % size;
25 | if (self->indices[index] == -1) {
26 | printf("KeyError: The key %ld was not found.\n", key);
27 | exit(-1);
28 | }
29 | }
30 | } else {
31 | printf("KeyError: The key %ld was not found.\n", key);
32 | exit(-1);
33 | }
34 | return self->entries[self->indices[index]].val;
35 | }
36 |
37 | void dict_int_!@valType@!_set(dict_int_!@valType@!* self, long key, !@valNativeType@! value) {
38 | // Check if key already exists
39 | int size = self->size;
40 | int index = key % size;
41 | while (self->indices[index] != -1) {
42 | if (self->entries[self->indices[index]].key == key) {
43 | // found, just update its value
44 | self->entries[self->indices[index]].val = value;
45 | return;
46 | }
47 | index = (index + 1) % size;
48 | }
49 | // Insert new key and val
50 | int dictLen = self->len;
51 | self->indices[index] = dictLen;
52 | self->entries[dictLen].prehash = key;
53 | self->entries[dictLen].key = key;
54 | self->entries[dictLen].val = value;
55 | self->len += 1;
56 | dictLen++;
57 | if (dictLen == self->size) {
58 | self->size *= 2;
59 | int size = self->size;
60 | // recompute entries
61 | self->indices = realloc(self->indices, sizeof(int)*size);
62 | self->entries = realloc(self->entries, sizeof(dict_int_!@valType@!_entry)*size);
63 | for (int i=0; iindices[i] = -1; // -1 is None
65 | }
66 | for (int i=0; ientries[i].prehash % size;
68 | while (self->indices[index] != -1) {
69 | index = (index + 1) % size;
70 | }
71 | self->indices[index] = i;
72 | }
73 | }
74 | }
75 |
76 | dict_int_!@valType@!* dict_int_!@valType@!_constructor(int len, int size, ...) {
77 | dict_int_!@valType@!* dict = malloc(sizeof(dict_int_!@valType@!));
78 | dict->len = 0;
79 | dict->size = size;
80 | dict->entries = malloc(sizeof(dict_int_!@valType@!_entry)*size);
81 | dict->indices = malloc(sizeof(int)*size);
82 | for (int i = 0; i < size; i++) {
83 | dict->indices[i] = -1;
84 | }
85 |
86 | va_list ptr;
87 | va_start(ptr, size); // size is the last argument before the ellipsis
88 |
89 | for (int i = 0; i < len; i++) {
90 | long tempKey = va_arg(ptr, long);
91 | !@valNativeType@! tempVal = va_arg(ptr, !@valNativeType@!);
92 | dict_int_!@valType@!_set(dict, tempKey, tempVal);
93 | }
94 | va_end(ptr);
95 | return dict;
96 | }
97 |
98 | void dict_int_!@valType@!_del(dict_int_!@valType@!* self, long key) {
99 | int size = self->size;
100 | int index = key % size;
101 | while (self->entries[self->indices[index]].key != key) {
102 | index = (index + 1) % size;
103 | if (self->indices[index] == -1) {
104 | printf("KeyError: The key %ld was not found.\n", key);
105 | exit(-1);
106 | }
107 | }
108 | int dictLen = self->len - 1;
109 | int removedPos = self->indices[index];
110 | self->indices[index] = -2; // flag as deleted
111 | // put the last entry in this spot
112 | if (removedPos != dictLen) {
113 | self->entries[removedPos] = self->entries[dictLen];
114 | // update index for this entry
115 | index = self->entries[removedPos].key % size;
116 | while (self->indices[index] != dictLen) {
117 | index++;
118 | }
119 | self->indices[index] = removedPos;
120 | }
121 |
122 | if (dictLen > 10 && dictLen < size/4) {
123 | size /= 2;
124 | // Clear indices at the new size
125 | for (int i=0; i < size; i++) {
126 | self->indices[i] = -1;
127 | }
128 | // Recompute entries;
129 | for (int i=0; ientries[i].prehash % size;
131 | while (self->indices[index] != -1) {
132 | index = (index + 1) % size;
133 | }
134 | self->indices[index] = i;
135 | }
136 | // Reallocate indices and entries
137 | self->indices = realloc(self->indices, sizeof(int)*size);
138 | self->entries = realloc(self->entries, sizeof(dict_int_!@valType@!_entry)*size);
139 | self->size = size;
140 | }
141 | self->len--;
142 | }
143 |
144 | char* dict_int_!@valType@!_str(dict_int_!@valType@!* self) {
145 | int dictLen = self->len-1;
146 | char* out = "{";
147 | for (int i=0; ientries[i].key, self->entries[i].val);
149 | }
150 | if (dictLen > -1) {
151 | asprintf(&out, "%s%ld: !@formatCode@!}", out, self->entries[dictLen].key, self->entries[dictLen].val);
152 | } else {
153 | asprintf(&out, "%s}", out);
154 | }
155 | return out;
156 | }
157 |
158 | void dict_int_!@valType@!_repr(dict_int_!@valType@!* self) {
159 | int dictLen = self->len-1;
160 | printf("{\n");
161 | for (int i=0; ientries[i].key, self->entries[i].val);
163 | }
164 | if (dictLen > -1) {
165 | printf(" %ld: !@formatCode@!\n", self->entries[dictLen].key, self->entries[dictLen].val);
166 | }
167 | printf("}\n");
168 | }
169 | #endif
170 |
--------------------------------------------------------------------------------
/core/libs/native/c/dict_str.template:
--------------------------------------------------------------------------------
1 | #ifndef __dict_str_!@valType@!
2 | #define __dict_str_!@valType@!
3 | #include "main.h"
4 | #include
5 | #include
6 | #include
7 |
8 | typedef struct dict_str_!@valType@!_entry {
9 | int prehash;
10 | char* key;
11 | !@valNativeType@! val;
12 | } dict_str_!@valType@!_entry;
13 |
14 | typedef struct dict_str_!@valType@! {
15 | int len;
16 | int size;
17 | int* indices;
18 | dict_str_!@valType@!_entry* entries;
19 | } dict_str_!@valType@!;
20 |
21 | int str_prehash(char* value) {
22 | // P and M
23 | const int p = 31;
24 | const int m = 1e9 + 9;
25 | int power_of_p = 1;
26 | int hash_val = 0;
27 |
28 | // Loop to calculate the hash value
29 | // by iterating over the elements of string
30 | int length = strlen(value);
31 | for (int i = 0; i < length; i++) {
32 | // if hash_val overflows, abs turns it into positive again
33 | hash_val = abs((hash_val + (value[i] - 'a' + 1) * power_of_p) % m);
34 | power_of_p = (power_of_p * p) % m;
35 | }
36 |
37 | return hash_val;
38 | }
39 |
40 | !@valNativeType@! dict_str_!@valType@!_get(dict_str_!@valType@!* self, char* key) {
41 | int size = self->size;
42 | int index = str_prehash(key) % size;
43 | if (self->indices[index] != -1) {
44 | while (strcmp(self->entries[self->indices[index]].key, key)) {
45 | index = (index + 1) % size;
46 | if (self->indices[index] == -1) {
47 | printf("KeyError: The key \"%s\" was not found.\n", key);
48 | exit(-1);
49 | }
50 | }
51 | } else {
52 | printf("KeyError: The key \"%s\" was not found.\n", key);
53 | exit(-1);
54 | }
55 | return self->entries[self->indices[index]].val;
56 | }
57 |
58 | void dict_str_!@valType@!_set(dict_str_!@valType@!* self, char* key, !@valNativeType@! value) {
59 | // Check if key already exists
60 | int size = self->size;
61 | int index = str_prehash(key) % size;
62 | while (self->indices[index] != -1) {
63 | if (!strcmp(self->entries[self->indices[index]].key, key)) {
64 | // found, just update its value
65 | self->entries[self->indices[index]].val = value;
66 | return;
67 | }
68 | index = (index + 1) % size;
69 | }
70 | // Insert new key and val
71 | int dictLen = self->len;
72 | self->indices[index] = dictLen;
73 | self->entries[dictLen].prehash = str_prehash(key);
74 | self->entries[dictLen].key = key;
75 | self->entries[dictLen].val = value;
76 | self->len += 1;
77 | dictLen++;
78 | if (dictLen == self->size) {
79 | self->size *= 2;
80 | int size = self->size;
81 | // recompute entries
82 | self->indices = realloc(self->indices, sizeof(int)*size);
83 | self->entries = realloc(self->entries, sizeof(dict_str_!@valType@!_entry)*size);
84 | for (int i=0; iindices[i] = -1; // -1 is None
86 | }
87 | for (int i=0; ientries[i].prehash % size;
89 | while (self->indices[index] != -1) {
90 | index = (index + 1) % size;
91 | }
92 | self->indices[index] = i;
93 | }
94 | }
95 | }
96 |
97 | dict_str_!@valType@!* dict_str_!@valType@!_constructor(int len, int size, ...) {
98 | dict_str_!@valType@!* dict = malloc(sizeof(dict_str_!@valType@!));
99 | dict->len = 0;
100 | dict->size = size;
101 | dict->entries = malloc(sizeof(dict_str_!@valType@!_entry)*size);
102 | dict->indices = malloc(sizeof(int)*size);
103 | for (int i = 0; i < size; i++) {
104 | dict->indices[i] = -1;
105 | }
106 |
107 | va_list ptr;
108 | va_start(ptr, size); // size is the last argument before the ellipsis
109 |
110 | for (int i = 0; i < len; i++) {
111 | char* tempKey = va_arg(ptr, char*);
112 | !@valNativeType@! tempVal = va_arg(ptr, !@valNativeType@!);
113 | dict_str_!@valType@!_set(dict, tempKey, tempVal);
114 | }
115 | va_end(ptr);
116 | return dict;
117 | }
118 |
119 | void dict_str_!@valType@!_del(dict_str_!@valType@!* self, char* key) {
120 | int size = self->size;
121 | int index = str_prehash(key) % size;
122 | while (strcmp(self->entries[self->indices[index]].key, key)) {
123 | index = (index + 1) % size;
124 | if (self->indices[index] == -1) {
125 | printf("KeyError: The key \"%s\" was not found.\n", key);
126 | exit(-1);
127 | }
128 | }
129 | int dictLen = self->len - 1;
130 | int removedPos = self->indices[index];
131 | self->indices[index] = -2; // flag as deleted
132 | // put the last entry in this spot
133 | if (removedPos != dictLen) {
134 | self->entries[removedPos] = self->entries[dictLen];
135 | // update index for this entry
136 | index = self->entries[removedPos].prehash % size;
137 | while (self->indices[index] != dictLen) {
138 | index++;
139 | }
140 | self->indices[index] = removedPos;
141 | }
142 |
143 | if (dictLen > 10 && dictLen < size/4) {
144 | size /= 2;
145 | // Clear indices at the new size
146 | for (int i=0; i < size; i++) {
147 | self->indices[i] = -1;
148 | }
149 | // Recompute entries;
150 | for (int i=0; ientries[i].prehash % size;
152 | while (self->indices[index] != -1) {
153 | index = (index + 1) % size;
154 | }
155 | self->indices[index] = i;
156 | }
157 | // Reallocate indices and entries
158 | self->indices = realloc(self->indices, sizeof(int)*size);
159 | self->entries = realloc(self->entries, sizeof(dict_str_!@valType@!_entry)*size);
160 | self->size = size;
161 | }
162 | self->len--;
163 | }
164 |
165 | char* dict_str_!@valType@!_str(dict_str_!@valType@!* self) {
166 | int dictLen = self->len-1;
167 | char* out = "{";
168 | for (int i=0; ientries[i].key, self->entries[i].val);
170 | }
171 | if (dictLen > -1) {
172 | asprintf(&out, "%s\"%s\": !@formatCode@!}", out, self->entries[dictLen].key, self->entries[dictLen].val);
173 | } else {
174 | asprintf(&out, "%s}", out);
175 | }
176 | return out;
177 | }
178 |
179 | void dict_str_!@valType@!_repr(dict_str_!@valType@!* self) {
180 | int dictLen = self->len-1;
181 | printf("{\n");
182 | for (int i=0; ientries[i].key, self->entries[i].val);
184 | }
185 | if (dictLen > -1) {
186 | printf(" %s: !@formatCode@!\n", self->entries[dictLen].key, self->entries[dictLen].val);
187 | }
188 | printf("}\n");
189 | }
190 | #endif
191 |
--------------------------------------------------------------------------------
/core/libs/native/c/list_float.h:
--------------------------------------------------------------------------------
1 | #ifndef __list_float
2 | #define __list_float
3 |
4 | #include
5 | #include
6 | #include "asprintf.h"
7 |
8 | typedef struct list_float {
9 | int len;
10 | int size;
11 | double* values;
12 | } list_float;
13 |
14 | list_float* list_float_constructor(int len, int size, ...) {
15 | list_float* list = malloc(sizeof(list_float));
16 | list->len = len;
17 | list->size = size;
18 | list->values = malloc(sizeof(double)*size);
19 |
20 | va_list ptr;
21 | va_start(ptr, size); // size is the last argument before the ellipsis
22 |
23 | for (int i = 0; i < len; i++) {
24 | list->values[i] = va_arg(ptr, double);
25 | }
26 | va_end(ptr);
27 | return list;
28 | }
29 |
30 | double list_float_get(list_float* list, int index) {
31 | if (index < 0) {
32 | // -1 is equivalent to the last element
33 | index = list->len + index;
34 | }
35 | if (index < 0 || index > list->len) {
36 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
37 | exit(-1);
38 | }
39 | return list->values[index];
40 | }
41 |
42 | void list_float_set(list_float* list, int index, double value) {
43 | if (index < 0) {
44 | // -1 is equivalent to the last element
45 | index = list->len + index;
46 | }
47 | if (index < 0 || index > list->len) {
48 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
49 | exit(-1);
50 | }
51 | list->values[index] = value;
52 | }
53 |
54 | void list_float_append(list_float* list, double value) {
55 | if (list->len >= list->size) {
56 | list->size = list->size * 2;
57 | list->values = realloc(list->values, sizeof(double) * list->size);
58 | }
59 | list->values[list->len] = value;
60 | list->len += 1;
61 | }
62 |
63 | static inline int float_equals(double v1, double v2) {
64 | double delta = 0.0000000001;
65 | if (v1 >= v2 - delta && v1 <= v2 + delta) {
66 | return 1;
67 | } else {
68 | return 0;
69 | }
70 | }
71 |
72 | void list_float_removeAll(list_float* list, double value) {
73 | int removedItems = 0;
74 | int listLen = list->len;
75 | for (int i=0; ivalues[i], value)) {
77 | removedItems = 1;
78 | for (i=i; ivalues[i], value)) {
80 | removedItems++;
81 | }
82 | list->values[i] = list->values[i+removedItems];
83 | }
84 | break;
85 | }
86 | }
87 | list->len -= removedItems;
88 | if (list->size >= 4*list->len) {
89 | list->size = list->size / 2;
90 | list->values = realloc(list->values, sizeof(long) * list->size);
91 | }
92 | }
93 |
94 | void list_float_del(list_float* list, int index) {
95 | int listLen = list->len;
96 | for (int i=index; ivalues[i] = list->values[i+1];
98 | }
99 | list->len -= 1;
100 | if (list->size >= 4*list->len) {
101 | list->size = list->size / 2;
102 | list->values = realloc(list->values, sizeof(long) * list->size);
103 | }
104 | }
105 | void list_float_inc(list_float* list, int index, double value) {
106 | if (index < 0) {
107 | // -1 is equivalent to the last element
108 | index = list->len + index;
109 | }
110 | if (index < 0 || index > list->len) {
111 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
112 | exit(-1);
113 | }
114 | list->values[index] += value;
115 | }
116 |
117 | void list_float_repr(list_float* list) {
118 | int listLen = list->len;
119 | printf("[");
120 | for (int i=0; ivalues[i]);
122 | }
123 | if (listLen > 0) {
124 | printf("%lg]\n", list->values[listLen-1]);
125 | } else {
126 | printf("]\n");
127 | }
128 | }
129 |
130 | char* list_float_str(list_float* list) {
131 | int listLen = list->len;
132 | char* out = "[";
133 | for (int i=0; ivalues[i]);
135 | }
136 | if (listLen > 0) {
137 | asprintf(&out, "%s%lg]", out, list->values[listLen-1]);
138 | } else {
139 | asprintf(&out, "%s]", out);
140 | }
141 | return out;
142 | }
143 |
144 | void list_float_clear(list_float* list) {
145 | list->len = 0;
146 | }
147 |
148 | #endif
149 |
--------------------------------------------------------------------------------
/core/libs/native/c/list_int.h:
--------------------------------------------------------------------------------
1 | #ifndef __list_int
2 | #define __list_int
3 |
4 | #include
5 | #include
6 | #include
7 | #include "asprintf.h"
8 |
9 | typedef struct list_int {
10 | int len; // number of element stored
11 | int size; // allocated array size
12 | long* values;
13 | } list_int;
14 |
15 | list_int* list_int_constructor(int len, int size, ...) {
16 | list_int* list = malloc(sizeof(list_int));
17 | list->len = len;
18 | list->size = size;
19 | list->values = malloc(sizeof(long)*size);
20 |
21 | va_list ptr;
22 | va_start(ptr, size); // size is the last argument before the ellipsis
23 |
24 | for (int i = 0; i < len; i++) {
25 | list->values[i] = va_arg(ptr, long);
26 | }
27 | va_end(ptr);
28 | return list;
29 | }
30 |
31 | int list_int_get(list_int* list, int index) {
32 | if (index < 0) {
33 | // -1 is equivalent to the last element
34 | index = list->len + index;
35 | }
36 | if (index < 0 || index > list->len) {
37 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
38 | exit(-1);
39 | }
40 | return list->values[index];
41 | }
42 |
43 | void list_int_set(list_int* list, int index, long value) {
44 | if (index < 0) {
45 | // -1 is equivalent to the last element
46 | index = list->len + index;
47 | }
48 | if (index < 0 || index > list->len) {
49 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
50 | exit(-1);
51 | }
52 | list->values[index] = value;
53 | }
54 |
55 | void list_int_append(list_int* list, long value) {
56 | if (list->len >= list->size) {
57 | list->size = list->size * 2;
58 | list->values = realloc(list->values, sizeof(long) * list->size);
59 | }
60 | list->values[list->len] = value;
61 | list->len += 1;
62 | }
63 |
64 | void list_int_removeAll(list_int* list, long value) {
65 | int removedItems = 0;
66 | int listLen = list->len;
67 | for (int i=0; ivalues[i] == value) {
69 | removedItems = 1;
70 | for (i=i; ivalues[i] == value) {
72 | removedItems++;
73 | }
74 | list->values[i] = list->values[i+removedItems];
75 | }
76 | break;
77 | }
78 | }
79 | list->len -= removedItems;
80 | if (list->size >= 4*list->len) {
81 | list->size = list->size / 2;
82 | list->values = realloc(list->values, sizeof(long) * list->size);
83 | }
84 | }
85 |
86 | void list_int_del(list_int* list, int index) {
87 | int listLen = list->len;
88 | for (int i=index; ivalues[i] = list->values[i+1];
90 | }
91 | list->len -= 1;
92 | if (list->size >= 4*list->len) {
93 | list->size = list->size / 2;
94 | list->values = realloc(list->values, sizeof(long) * list->size);
95 | }
96 | }
97 |
98 | void list_int_inc(list_int* list, int index, long value) {
99 | if (index < 0) {
100 | // -1 is equivalent to the last element
101 | index = list->len + index;
102 | }
103 | if (index < 0 || index > list->len) {
104 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
105 | exit(-1);
106 | }
107 | list->values[index] += value;
108 | }
109 |
110 | void list_int_repr(list_int* list) {
111 | int listLen = list->len;
112 | printf("[");
113 | for (int i=0; ivalues[i]);
115 | }
116 | if (listLen > 0) {
117 | printf("%ld]\n", list->values[listLen-1]);
118 | } else {
119 | printf("]\n");
120 | }
121 | }
122 |
123 | char* list_int_str(list_int* list) {
124 | int listLen = list->len;
125 | char* out = "[";
126 | for (int i=0; ivalues[i]);
128 | }
129 | if (listLen > 0) {
130 | asprintf(&out, "%s%ld]", out, list->values[listLen-1]);
131 | } else {
132 | asprintf(&out, "%s]", out);
133 | }
134 | return out;
135 | }
136 |
137 | void list_int_clear(list_int* list) {
138 | list->len = 0;
139 | }
140 |
141 | #endif
142 |
--------------------------------------------------------------------------------
/core/libs/native/c/list_str.h:
--------------------------------------------------------------------------------
1 | #ifndef __list_str
2 | #define __list_str
3 |
4 | #include
5 | #include
6 | #include
7 | #include "asprintf.h"
8 |
9 | typedef struct list_str {
10 | int len; // number of element stored
11 | int size; // allocated array size
12 | char** values;
13 | } list_str;
14 |
15 | list_str* list_str_constructor(int len, int size, ...) {
16 | list_str* list = malloc(sizeof(list_str));
17 | list->len = len;
18 | list->size = size;
19 | list->values = malloc(sizeof(char*)*size);
20 |
21 | va_list ptr;
22 | va_start(ptr, size); // size is the last argument before the ellipsis
23 |
24 | for (int i = 0; i < len; i++) {
25 | list->values[i] = va_arg(ptr, char*);
26 | }
27 | va_end(ptr);
28 | return list;
29 | }
30 |
31 | char* list_str_get(list_str* list, int index) {
32 | if (index < 0) {
33 | // -1 is equivalent to the last element
34 | index = list->len + index;
35 | }
36 | if (index < 0 || index > list->len) {
37 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
38 | exit(-1);
39 | }
40 | return list->values[index];
41 | }
42 |
43 | void list_str_set(list_str* list, int index, char* value) {
44 | if (index < 0) {
45 | // -1 is equivalent to the last element
46 | index = list->len + index;
47 | }
48 | if (index < 0 || index > list->len) {
49 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
50 | exit(-1);
51 | }
52 | list->values[index] = value;
53 | }
54 |
55 | void list_str_append(list_str* list, char* value) {
56 | if (list->len >= list->size) {
57 | list->size = list->size * 2;
58 | list->values = realloc(list->values, sizeof(char*) * list->size);
59 | }
60 | char * copy = malloc(strlen(value) + 1);
61 | strcpy(copy, value);
62 | list->values[list->len] = copy;
63 | list->len += 1;
64 | }
65 |
66 | void list_str_removeAll(list_str* list, char* value) {
67 | int removedItems = 0;
68 | int listLen = list->len;
69 | for (int i=0; ivalues[i], value)) {
71 | removedItems = 1;
72 | for (i=i; ivalues[i], value)) {
74 | removedItems++;
75 | }
76 | list->values[i] = list->values[i+removedItems];
77 | }
78 | break;
79 | }
80 | }
81 | list->len -= removedItems;
82 | if (list->size >= 4*list->len) {
83 | list->size = list->size / 2;
84 | list->values = realloc(list->values, sizeof(long) * list->size);
85 | }
86 | }
87 |
88 | void list_str_del(list_str* list, int index) {
89 | int listLen = list->len;
90 | for (int i=index; ivalues[i] = list->values[i+1];
92 | }
93 | list->len -= 1;
94 | if (list->size >= 4*list->len) {
95 | list->size = list->size / 2;
96 | list->values = realloc(list->values, sizeof(long) * list->size);
97 | }
98 | }
99 |
100 | void list_str_inc(list_str* list, int index, char* value) {
101 | if (index < 0) {
102 | // -1 is equivalent to the last element
103 | index = list->len + index;
104 | }
105 | if (index < 0 || index > list->len) {
106 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
107 | exit(-1);
108 | }
109 | asprintf(&list->values[index], "%s%s", list->values[index], value);
110 | }
111 |
112 | void list_str_repr(list_str* list) {
113 | int listLen = list->len;
114 | printf("[");
115 | for (int i=0; ivalues[i]);
117 | }
118 | if (listLen > 0) {
119 | printf("\"%s\"]\n", list->values[listLen-1]);
120 | } else {
121 | printf("]\n");
122 | }
123 | }
124 |
125 | char* list_str_str(list_str* list) {
126 | int listLen = list->len;
127 | char* out = "[";
128 | for (int i=0; ivalues[i]);
130 | }
131 | if (listLen > 0) {
132 | asprintf(&out, "%s\"%s\"]", out, list->values[listLen-1]);
133 | } else {
134 | asprintf(&out, "%s]", out);
135 | }
136 | return out;
137 | }
138 |
139 | void list_str_clear(list_str* list) {
140 | list->len = 0;
141 | }
142 |
143 | #endif
144 |
--------------------------------------------------------------------------------
/core/libs/native/c/list_template.h:
--------------------------------------------------------------------------------
1 | #ifndef __list_!@valType@!
2 | #define __list_!@valType@!
3 |
4 | #include
5 | #include
6 | #include "asprintf.h"
7 |
8 | typedef struct !@valType@! !@valType@!;
9 |
10 | typedef struct list_!@valType@! {
11 | int len;
12 | int size;
13 | !@valType@!** values;
14 | } list_!@valType@!;
15 |
16 | list_!@valType@!* list_!@valType@!_constructor(int len, int size, ...) {
17 | list_!@valType@!* list = malloc(sizeof(list_!@valType@!));
18 | list->len = len;
19 | list->size = size;
20 | list->values = malloc(sizeof(!@valType@!*)*size);
21 |
22 | va_list ptr;
23 | va_start(ptr, size); // size is the last argument before the ellipsis
24 |
25 | for (int i = 0; i < len; i++) {
26 | list->values[i] = va_arg(ptr, !@valType@!*);
27 | }
28 | va_end(ptr);
29 | return list;
30 | }
31 |
32 | !@valType@!* list_!@valType@!_get(list_!@valType@!* list, int index) {
33 | if (index < 0) {
34 | // -1 is equivalent to the last element
35 | index = list->len + index;
36 | }
37 | if (index < 0 || index > list->len) {
38 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
39 | exit(-1);
40 | }
41 | return list->values[index];
42 | }
43 |
44 | void list_!@valType@!_set(list_!@valType@!* list, int index, !@valType@!* value) {
45 | if (index < 0) {
46 | // -1 is equivalent to the last element
47 | index = list->len + index;
48 | }
49 | if (index < 0 || index > list->len) {
50 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
51 | exit(-1);
52 | }
53 | list->values[index] = value;
54 | }
55 |
56 | void list_!@valType@!_append(list_!@valType@!* list, !@valType@!* value) {
57 | if (list->len >= list->size) {
58 | list->size = list->size * 2;
59 | list->values = realloc(list->values, sizeof(!@valType@!) * list->size);
60 | }
61 | list->values[list->len] = value;
62 | list->len += 1;
63 | }
64 |
65 | void list_!@valType@!_remove(list_!@valType@!* list, !@valType@!* value) {
66 | int removedItems = 0;
67 | int listLen = list->len;
68 | for (int i=0; ivalues[i] == value) {
70 | removedItems = 1;
71 | for (i=i; ivalues[i] = list->values[i+removedItems];
73 | }
74 | break;
75 | }
76 | }
77 | list->len -= removedItems;
78 | if (list->size >= 4*list->len) {
79 | list->size = list->size / 2;
80 | list->values = realloc(list->values, sizeof(!@valType@!) * list->size);
81 | }
82 | }
83 |
84 | void list_!@valType@!_removeAll(list_!@valType@!* list, !@valType@!* value) {
85 | int removedItems = 0;
86 | int listLen = list->len;
87 | for (int i=0; ivalues[i] == value) {
89 | removedItems = 1;
90 | for (i=i; ivalues[i] == value) {
92 | removedItems++;
93 | }
94 | list->values[i] = list->values[i+removedItems];
95 | }
96 | break;
97 | }
98 | }
99 | list->len -= removedItems;
100 | if (list->size >= 4*list->len) {
101 | list->size = list->size / 2;
102 | list->values = realloc(list->values, sizeof(!@valType@!) * list->size);
103 | }
104 | }
105 |
106 | void list_!@valType@!_del(list_!@valType@!* list, int index) {
107 | int listLen = list->len;
108 | for (int i=index; ivalues[i] = list->values[i+1];
110 | }
111 | list->len -= 1;
112 | if (list->size >= 4*list->len) {
113 | list->size = list->size / 2;
114 | list->values = realloc(list->values, sizeof(!@valType@!) * list->size);
115 | }
116 | }
117 |
118 | /* TODO: this makes sense for class?
119 | void list_!@valType@!_inc(list_!@valType@!* list, int index, double value) {
120 | if (index < 0) {
121 | // -1 is equivalent to the last element
122 | index = list->len + index;
123 | }
124 | if (index < 0 || index > list->len) {
125 | printf("IndexError: The array has %d elements, but you required the %d index\n", list->len, index);
126 | exit(-1);
127 | }
128 | list->values[index] += value;
129 | }
130 | */
131 |
132 | void list_!@valType@!_repr(list_!@valType@!* list) {
133 | int listLen = list->len;
134 | printf("[");
135 | for (int i=0; i, ");
137 | }
138 | if (listLen > 0) {
139 | printf("]\n");
140 | } else {
141 | printf("]\n");
142 | }
143 | }
144 |
145 | char* list_!@valType@!_str(list_!@valType@!* list) {
146 | int listLen = list->len;
147 | char* out = "[";
148 | // TODO: change to class_repr
149 | for (int i=0; i, ", out);
151 | }
152 | if (listLen > 0) {
153 | asprintf(&out, "%s]", out);
154 | } else {
155 | asprintf(&out, "%s]", out);
156 | }
157 | return out;
158 | }
159 |
160 | void list_!@valType@!_clear(list_!@valType@!* list) {
161 | list->len = 0;
162 | }
163 |
164 | #endif
165 |
--------------------------------------------------------------------------------
/core/libs/native/c/photonInput.h:
--------------------------------------------------------------------------------
1 | #ifndef __photonInput
2 | #define __photonInput
3 |
4 | #include
5 | #include
6 |
7 | char *photonInput(char* message)
8 | {
9 | printf(message);
10 | int c;
11 | size_t size = 5;
12 | size_t read_size = 0;
13 | char *line = malloc(size);
14 | if (!line)
15 | {
16 | perror("malloc");
17 | return line;
18 | }
19 |
20 | line[0] = '\0';
21 |
22 | c = fgetc(stdin);
23 | while (c != EOF && c!= '\n')
24 | {
25 | line[read_size] = c;
26 | ++read_size;
27 | if (read_size == size)
28 | {
29 | size += 5;
30 | char *test = realloc(line, size);
31 | if (!test)
32 | {
33 | perror("realloc");
34 | return line;
35 | }
36 | line = test;
37 | }
38 | c = fgetc(stdin);
39 | }
40 | line[read_size] = '\0';
41 | return line;
42 | }
43 |
44 | char *photonRead(FILE* file)
45 | {
46 | int c;
47 | size_t size = 5;
48 | size_t read_size = 0;
49 | char *line = malloc(size);
50 | if (!line)
51 | {
52 | perror("malloc");
53 | return line;
54 | }
55 |
56 | line[0] = '\0';
57 |
58 | c = fgetc(file);
59 | while (c != EOF && c!= '\n')
60 | {
61 | line[read_size] = c;
62 | ++read_size;
63 | if (read_size == size)
64 | {
65 | size += 5;
66 | char *test = realloc(line, size);
67 | if (!test)
68 | {
69 | perror("realloc");
70 | return line;
71 | }
72 | line = test;
73 | }
74 | c = fgetc(file);
75 | }
76 | line[read_size] = '\0';
77 | if (!read_size) {
78 | return NULL;
79 | }
80 | return line;
81 | }
82 | #endif
83 |
--------------------------------------------------------------------------------
/core/libs/native/d/dontRemove:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HashLDash/Photon/bfd206db3b91b695139cbde47bc39ba59057d122/core/libs/native/d/dontRemove
--------------------------------------------------------------------------------
/core/libs/native/haxe/dontRemove:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HashLDash/Photon/bfd206db3b91b695139cbde47bc39ba59057d122/core/libs/native/haxe/dontRemove
--------------------------------------------------------------------------------
/core/libs/native/js/dontRemove:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HashLDash/Photon/bfd206db3b91b695139cbde47bc39ba59057d122/core/libs/native/js/dontRemove
--------------------------------------------------------------------------------
/core/libs/native/py/dontRemove:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HashLDash/Photon/bfd206db3b91b695139cbde47bc39ba59057d122/core/libs/native/py/dontRemove
--------------------------------------------------------------------------------
/core/libs/random.w:
--------------------------------------------------------------------------------
1 | for C:
2 | native import time
3 |
4 | time.srand(time.time(null))
5 | def random():
6 | float maxNumber = time.RAND_MAX
7 | float a = time.rand() / maxNumber
8 | return a
9 |
10 | for Python:
11 | native import random
12 |
13 | def random():
14 | float a = random.random()
15 | return a
16 |
17 | for Javascript:
18 | def random():
19 | float a = Math.random()
20 | return a
21 |
22 | def randint(int begin, int end):
23 | int a = random()*(end-begin)+begin
24 | return a
25 |
26 | def randfloat(float begin, float end):
27 | float a = random()*(end-begin)+begin
28 | return a
29 |
--------------------------------------------------------------------------------
/core/libs/requests.w:
--------------------------------------------------------------------------------
1 | import _requests
2 |
3 | def get(str url):
4 | str resp = _requests.get(url)
5 | return resp
6 |
--------------------------------------------------------------------------------
/core/libs/wui.w:
--------------------------------------------------------------------------------
1 | import wuiGraphics
2 | native import raylib
3 |
4 | def pass():
5 | print("Apertou!!")
6 |
7 | class Widget():
8 | def new(.x=0.0, .y=0.0, .width=100.0, .height=100.0):
9 |
10 | def onKeyPress(int a):
11 |
12 | def update():
13 |
14 | def render():
15 |
16 | class Label(Widget):
17 | Font font
18 | str[] lines = []
19 | def new(.text="", .fontSize=40, .align="center", .valign="center", .color=wuiGraphics.Color()):
20 |
21 | def render():
22 | for C:
23 | if .font.baseSize == 0:
24 | .font = raylib.LoadFontEx("assets/Roboto-Italic.ttf", .fontSize, 0, 250)
25 | for Python:
26 | if not .font:
27 | fontName = "assets/Roboto-Italic.ttf"
28 | .font = raylib.LoadFontEx(fontName.encode(), .fontSize, raylib.ffi.new("int *", 0), 250)
29 |
30 | lineBuffer = ''
31 | word = ''
32 | .lines = []
33 | for c in .text:
34 | if c == ' ':
35 | if wuiGraphics.measureText(.font, lineBuffer+' '+word, .fontSize) > .width:
36 | .lines.append(lineBuffer)
37 | lineBuffer = word
38 | else:
39 | if lineBuffer == '':
40 | lineBuffer = word
41 | else:
42 | lineBuffer += ' ' + word
43 | word = ''
44 | elif c == '\n':
45 | if wuiGraphics.measureText(.font, lineBuffer+' '+word, .fontSize) > .width:
46 | .lines.append(lineBuffer)
47 | .lines.append(word)
48 | else:
49 | if lineBuffer == '':
50 | .lines.append(word)
51 | else:
52 | .lines.append(lineBuffer + ' ' + word)
53 | lineBuffer = ''
54 | word = ''
55 | else:
56 | word += c
57 | if wuiGraphics.measureText(.font, lineBuffer+word, .fontSize) > .width:
58 | .lines.append(lineBuffer)
59 | .lines.append(word)
60 | else:
61 | .lines.append(lineBuffer + word)
62 |
63 | dy = .y
64 | if .valign == "center":
65 | dy += (.height - .lines.len * .fontSize)/2
66 | elif .valign == "bottom":
67 | dy += .height - .lines.len * .fontSize
68 |
69 | dx = 0.0
70 | for line in .lines:
71 | textWidth = wuiGraphics.measureText(.font, line, .fontSize)
72 | if .align == "center":
73 | dx = .x + (.width - textWidth)/2
74 | elif .align == "left":
75 | dx = .x
76 | elif .align == "right":
77 | dx = .x + .width - textWidth
78 | wuiGraphics.drawText(.font, line, dx, dy, .fontSize, .color)
79 | dy += .fontSize
80 | for C:
81 | .lines.len = 0
82 | for Python:
83 | .lines = []
84 |
85 | class Button(Label):
86 | def new(func .onPress=pass, func .onRelease=pass, .radius=0.5, .buttonColor=wuiGraphics.Color(b=255)):
87 |
88 | def render():
89 | int posX = raylib.GetMouseX()
90 | int posY = raylib.GetMouseY()
91 | if posX > .x and posX < .x + .width and posY > .y and posY < .y + .height:
92 | if raylib.IsMouseButtonPressed(raylib.MOUSE_LEFT_BUTTON):
93 | .onPress()
94 | elif raylib.IsMouseButtonReleased(raylib.MOUSE_LEFT_BUTTON):
95 | .onRelease()
96 | wuiGraphics.drawRoundedRectangle(.x, .y, .width, .height, .radius, .buttonColor)
97 | super.render()
98 |
99 | class Layout(Widget):
100 | def new(Widget[] .children=[]):
101 |
102 | def update():
103 | for child in .children:
104 | child.update()
105 |
106 | def render():
107 | for child in .children:
108 | child.render()
109 |
110 | def addWidget(Widget widget):
111 | .children.append(widget)
112 |
113 | def removeWidget(Widget widget):
114 | .children.remove(widget)
115 |
116 | class Box(Layout):
117 | def new(.orientation='vertical'):
118 |
119 | def render():
120 | dx = .x
121 | dy = .y
122 | if .children.len > 0:
123 | if .orientation == 'vertical':
124 | wHeight = .height / .children.len
125 | for child in .children:
126 | child.x = dx
127 | child.y = dy
128 | child.width = .width
129 | child.height = wHeight
130 | child.render()
131 | dy += wHeight
132 | else:
133 | wWidth = .width / .children.len
134 | for child in .children:
135 | child.x = dx
136 | child.y = dy
137 | child.width = wWidth
138 | child.height = .height
139 | child.render()
140 | dx += wWidth
141 |
142 | class App():
143 | def new(.background=wuiGraphics.Color(r=255, g=255, b=255), .fps=60, .width=800, .height=600, .title="Photon"):
144 |
145 | def run(Widget widget):
146 | widget.width = .width
147 | widget.height = .height
148 | for C:
149 | raylib.InitWindow(.width, .height, .title)
150 | for Javascript:
151 | raylib.InitWindow(.width, .height, .title)
152 | for Python:
153 | raylib.InitWindow(.width, .height, .title.encode())
154 | raylib.SetTargetFPS(.fps)
155 | while not raylib.WindowShouldClose():
156 | raylib.BeginDrawing()
157 | raylib.ClearBackground(.background.toNative())
158 | widget.update()
159 | widget.render()
160 | raylib.EndDrawing()
161 |
162 |
--------------------------------------------------------------------------------
/core/libs/wui/widgets.w:
--------------------------------------------------------------------------------
1 | print('Imported widgets')
2 |
--------------------------------------------------------------------------------
/core/libs/wui/wuiGraphics.w:
--------------------------------------------------------------------------------
1 | native import raylib
2 | for Python:
3 | native import pyray
4 |
5 | class Color():
6 | def new(.r=0.0, .g=0.0, .b=0.0, .a=255.0):
7 |
8 | def toNative():
9 | for JavaScript:
10 | raylib.Color color = raylib.Color(.r, .g, .b, .a)
11 | for C:
12 | raylib.Color color = raylib.BLACK
13 | color.r = .r
14 | color.g = .g
15 | color.b = .b
16 | color.a = .a
17 | for Python:
18 | pyray.Color color = pyray.Color(int(.r), int(.g), int(.b), int(.a))
19 | return color
20 |
21 | def drawText(Font font, str text, float x, float y, int fontSize, Color color):
22 | for JavaScript:
23 | raylib.DrawTextEx(font, text.encode(), raylib.Vector2(x, y), fontSize, 0.0, color.toNative())
24 | for C:
25 | Vector2 pos
26 | pos.x = x
27 | pos.y = y
28 | raylib.DrawTextEx(font, text, pos, fontSize, 0.0, color.toNative())
29 | for Python:
30 | raylib.DrawTextEx(font, text.encode(), pyray.Vector2(x, y), fontSize, 0.0, color.toNative())
31 |
32 | def measureText(Font font, str text, int fontSize):
33 | for JavaScript:
34 | int width = raylib.MeasureTextEx(font, text, fontSize, 0).x
35 | for C:
36 | int width = raylib.MeasureTextEx(font, text, fontSize, 0).x
37 | for Python:
38 | int width = raylib.MeasureTextEx(font, text.encode(), fontSize, 0).x
39 | return width
40 |
41 | def drawRoundedRectangle(float x, float y, float width, float height, float radius, Color color):
42 | segments = 10
43 | for JavaScript:
44 | rec = raylib.Rectangle(x, y, width, height)
45 | for C:
46 | Rectangle rec
47 | rec.x = x
48 | rec.y = y
49 | rec.width = width
50 | rec.height = height
51 | for Python:
52 | rec = pyray.Rectangle(x, y, width, height)
53 | raylib.DrawRectangleRounded(rec, radius, segments, color.toNative())
54 |
55 | def drawRectangle(float x, float y, float width, float height, Color color):
56 | for JavaScript:
57 | raylib.DrawRectangle(x, y, width, height, color.toNative())
58 | for C:
59 | raylib.DrawRectangle(x, y, width, height, color.toNative())
60 | for Python:
61 | int xi = x
62 | int yi = y
63 | int widthi = width
64 | int heighti = height
65 | raylib.DrawRectangle(xi, yi, widthi, heighti, color.toNative())
66 |
67 | def drawCircle(float x, float y, float radius, Color color):
68 | for JavaScript:
69 | raylib.DrawCircle(x, y, radius, color.toNative())
70 | for C:
71 | raylib.DrawCircle(x, y, radius, color.toNative())
72 | for Python:
73 | raylib.DrawCircle(int(x), int(y), radius, color.toNative())
74 |
--------------------------------------------------------------------------------
/core/libs/wuiGraphics.w:
--------------------------------------------------------------------------------
1 | native import raylib
2 | for Python:
3 | native import pyray
4 |
5 | class Color():
6 | def new(.r=0.0, .g=0.0, .b=0.0, .a=255.0):
7 |
8 | def toNative():
9 | for JavaScript:
10 | raylib.Color color = raylib.Color(.r, .g, .b, .a)
11 | for C:
12 | raylib.Color color = raylib.BLACK
13 | color.r = .r
14 | color.g = .g
15 | color.b = .b
16 | color.a = .a
17 | for Python:
18 | pyray.Color color = pyray.Color(int(.r), int(.g), int(.b), int(.a))
19 | return color
20 |
21 | def drawText(Font font, str text, float x, float y, int fontSize, Color color):
22 | for JavaScript:
23 | raylib.DrawTextEx(font, text.encode(), raylib.Vector2(x, y), fontSize, 0.0, color.toNative())
24 | for C:
25 | Vector2 pos
26 | pos.x = x
27 | pos.y = y
28 | raylib.DrawTextEx(font, text, pos, fontSize, 0.0, color.toNative())
29 | for Python:
30 | raylib.DrawTextEx(font, text.encode(), pyray.Vector2(x, y), fontSize, 0.0, color.toNative())
31 |
32 | def measureText(Font font, str text, int fontSize):
33 | for JavaScript:
34 | int width = raylib.MeasureTextEx(font, text, fontSize, 0).x
35 | for C:
36 | int width = raylib.MeasureTextEx(font, text, fontSize, 0).x
37 | for Python:
38 | int width = raylib.MeasureTextEx(font, text.encode(), fontSize, 0).x
39 | return width
40 |
41 | def drawRoundedRectangle(float x, float y, float width, float height, float radius, Color color):
42 | segments = 10
43 | for JavaScript:
44 | rec = raylib.Rectangle(x, y, width, height)
45 | for C:
46 | Rectangle rec
47 | rec.x = x
48 | rec.y = y
49 | rec.width = width
50 | rec.height = height
51 | for Python:
52 | rec = pyray.Rectangle(x, y, width, height)
53 | raylib.DrawRectangleRounded(rec, radius, segments, color.toNative())
54 |
55 | def drawRectangle(float x, float y, float width, float height, Color color):
56 | for JavaScript:
57 | raylib.DrawRectangle(x, y, width, height, color.toNative())
58 | for C:
59 | raylib.DrawRectangle(x, y, width, height, color.toNative())
60 | for Python:
61 | int xi = x
62 | int yi = y
63 | int widthi = width
64 | int heighti = height
65 | raylib.DrawRectangle(xi, yi, widthi, heighti, color.toNative())
66 |
67 | def drawCircle(float x, float y, float radius, Color color):
68 | for JavaScript:
69 | raylib.DrawCircle(x, y, radius, color.toNative())
70 | for C:
71 | raylib.DrawCircle(x, y, radius, color.toNative())
72 | for Python:
73 | raylib.DrawCircle(int(x), int(y), radius, color.toNative())
74 |
--------------------------------------------------------------------------------
/core/pattern_cli.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import atexit
3 | import os
4 | import builtins
5 | import traceback
6 |
7 | __version__ = '0.0.4'
8 |
9 | terms = sys.argv[1:]
10 |
11 | flags = [flag for flag in terms if flag.startswith('-')]
12 | kwargs = dict([kw.split('=') for kw in terms if '=' in kw])
13 | route = [term for term in terms if not term.startswith('-') and not '=' in term]
14 |
15 | def cli_help(subcommand=None):
16 | print(f'{sys.argv[0]} help')
17 | if subcommand is not None:
18 | print(f'Help for subcommand {subcommand}')
19 | print()
20 | for route in routes:
21 | if subcommand is None or route.startswith(subcommand):
22 | if 'doc' in routes[route]:
23 | print(f' {route} - {routes[route]["doc"].strip()}')
24 |
25 | routes = {
26 | 'help':{'func':cli_help},
27 | '-h':{'func':cli_help},
28 | '--help':{'func':cli_help},
29 | }
30 |
31 | def cli(route, methods=None):
32 | def decorator(f):
33 | def wrapped(*args, **kwargs):
34 | try:
35 | resp = f(*args, **kwargs)
36 | except Exception as e:
37 | tb = traceback.format_exc().replace('"', '\"').replace("'", "\'")
38 | print(tb, file=sys.stderr)
39 | return
40 | routes[route] = {'func':wrapped}
41 | if f.__doc__:
42 | routes[route]['doc'] = f.__doc__
43 | return wrapped
44 | return decorator
45 |
46 | def cast(part, varType):
47 | varType = varType.replace('string', 'str')
48 | if varType in builtins.__dict__:
49 | return getattr(builtins, varType)(part)
50 | raise TypeError
51 |
52 | def isCompatible(pattern, part):
53 | if pattern.startswith('<') and pattern.endswith('>'):
54 | if ':' in pattern:
55 | *varType, var = pattern[1:-1].split(':')
56 | if varType[0] == 'path':
57 | return True, var, part
58 | try:
59 | return True, var, cast(part, varType[0])
60 | except TypeError:
61 | return None
62 | else:
63 | return True
64 | elif pattern == part:
65 | return True
66 | return None
67 |
68 | def checkArgsLen(command, pattern, variables):
69 | if len(command) == len(pattern):
70 | return True
71 | return False
72 |
73 | def parseRoute(pattern, command):
74 | pattern = pattern.split(' ')
75 | path = ''
76 | offset = 0
77 | variables = {}
78 | for n, part in enumerate(pattern):
79 | if '"' in part:
80 | offset = len(command)-len(pattern)
81 | if offset >= 0:
82 | *varType, var = part[1:-1].split(':')
83 | variables[var] = ' '.join(command[n:n+offset+1])
84 | else:
85 | # Route is not compatible
86 | return None, None
87 | else:
88 | result = isCompatible(part, command[n+offset])
89 | if result is None:
90 | # Route is not compatible
91 | return None, None
92 | else:
93 | if result is not True and len(result) > 1:
94 | variables[result[1]] = result[2]
95 | # yep, proceed
96 | continue
97 | if checkArgsLen(command, pattern, variables):
98 | # Route {pattern} is compatible with {command}
99 | return variables, ' '.join(pattern)
100 | return None, None
101 |
102 | def run():
103 | global route
104 | if route and route[-1] == 'help':
105 | cli_help(subcommand=' '.join(route[:-1]))
106 | return
107 | variables = {}
108 | if not ' '.join(route) in routes:
109 | for r in routes:
110 | variables, rule = parseRoute(r, route)
111 | if rule is not None:
112 | route = rule
113 | break
114 | else:
115 | print('Invalid command.')
116 | return
117 | else:
118 | route = ' '.join(route)
119 | try:
120 | if kwargs:
121 | routes[route]['func'](**variables, **kwargs)
122 | else:
123 | routes[route]['func'](**variables)
124 | except SystemExit as e:
125 | atexit.set_exit_code = e
126 |
127 | atexit.register(run)
128 |
--------------------------------------------------------------------------------
/core/photon.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | ''' Photon command-line interface. '''
3 |
4 | import os, sys
5 | from pattern_cli import cli, flags, kwargs, cli_help
6 |
7 | PHOTON_INSTALL_PATH = getattr(sys, '_MEIPASS', os.path.dirname(os.path.realpath(__file__)))
8 | sys.path.insert(0, PHOTON_INSTALL_PATH)
9 |
10 | __version__ = '0.0.10'
11 |
12 | allowed_kwargs = {
13 | 'lang': ['c', 'd', 'js', 'ts', 'dart', 'haxe', 'python'],
14 | 'platform': ['linux', 'windows', 'mac', 'android', 'web'],
15 | 'framework': ['raylib', 'html5', 'flutter', 'opengl', 'canvas'],
16 | }
17 |
18 | def get_home():
19 | import json
20 | import pathlib
21 | return pathlib.Path.home()
22 |
23 | def get_conf():
24 | import json
25 | try:
26 | with open(f'{get_home()}/.photon/photon.conf') as c:
27 | return json.load(c)
28 | except FileNotFoundError:
29 | createConfFolder()
30 | return {'lang':'c'}
31 |
32 | def set_conf(**kwargs):
33 | import json
34 | data = get_conf()
35 | for key, val in kwargs.items():
36 | if key in allowed_kwargs:
37 | if val in allowed_kwargs[key]:
38 | data[key] = val
39 | if key == 'lang':
40 | from dependencies import haveDependencies, resolveDependencies
41 | if not haveDependencies(val, sys.platform):
42 | resolveDependencies(val, sys.platform)
43 | print('Dependencies successfuly installed.')
44 | else:
45 | print(f'Value {val} is not allowed. You can try these: {", ".join(allowed_kwargs[key])}')
46 | else:
47 | print(f'Value {key} or {val} is not allowed. You can try these:')
48 | print(f'{"\n ".join([""] + allowed_kwargs)}')
49 | with open(f'{get_home()}/.photon/photon.conf', 'w') as c:
50 | json.dump(data, c)
51 |
52 | def getParameters():
53 | parameters = get_conf()
54 | parameters.update(kwargs)
55 | return parameters
56 |
57 | def createConfFolder():
58 | home = get_home()
59 | if not '.photon' in os.listdir(home):
60 | os.mkdir(f'{home}/.photon')
61 |
62 | @cli('version')
63 | def version():
64 | 'Show photon version'
65 | print(f'Photon {__version__}')
66 |
67 | @cli('update')
68 | def update():
69 | 'Update photon'
70 | os.system(f'git -C {PHOTON_INSTALL_PATH} pull')
71 |
72 | @cli('set')
73 | def set_config(**kwargs):
74 | 'Set a default parameter in the photon config'
75 | set_conf(**kwargs)
76 |
77 | @cli('')
78 | def run(filename, **kwargs):
79 | 'Run a script'
80 | from interpreter import Interpreter
81 | DEBUG = '-d' in flags or '--debug' in flags
82 | Interpreter(
83 | filename=filename,
84 | standardLibs=os.path.join(
85 | PHOTON_INSTALL_PATH, 'libs'),
86 | debug=DEBUG,
87 | **getParameters()).run()
88 |
89 | @cli('')
90 | def interpreter():
91 | 'Open the interpreter'
92 | if flags:
93 | if '-v' in flags or '--version' in flags:
94 | version()
95 | elif '-h' in flags or '--help' in flags:
96 | cli_help()
97 | else:
98 | print(f'Flag {flags[0]} not valid here')
99 | else:
100 | from interpreter import Interpreter
101 | DEBUG = '-d' in flags or '--debug' in flags
102 | print(f'Photon - {__version__} - pyEngine')
103 | Interpreter(
104 | standardLibs=os.path.join(
105 | PHOTON_INSTALL_PATH, 'libs'),
106 | debug=DEBUG).run()
107 |
--------------------------------------------------------------------------------
/core/photonParser.py:
--------------------------------------------------------------------------------
1 | # Photon parser
2 | # This script converts lines of photon code into tokens
3 | # and also generates the struct of the code.
4 | # This struct is used by the Engine to execute the code.
5 |
6 | import re
7 | from lexer import *
8 |
9 | statements = ['if','else','elif','def','cdef','for','in','as','return','import','class','while','break','continue','try', 'del', 'native', 'from']
10 | operators = ['+','-','%','/','*','**','<','>','not', '!', 'and','or','is', '&']
11 | builtins = ['open','input','sizeof','addr']
12 | types = ['str','cstr','const','struct','char','int','float','double','struct', 'func','uint','ulong','ubyte','file']
13 | symbols = {
14 | '.':'dot',
15 | '=':'equal',
16 | ':':'beginBlock',
17 | '(':'lparen',
18 | ')':'rparen',
19 | ',':'comma',
20 | '[':'lbracket',
21 | ']':'rbracket',
22 | "'":'singleQuote',
23 | '"':'doubleQuote',
24 | '#':'hashtag',
25 | ' ':'space',
26 | '\n':'newLine',
27 | '\t':'tab',
28 | '{':'lbrace',
29 | '}':'rbrace',
30 | '>':'greaterThan',
31 | '<':'lessThan',
32 | '_':'underline'
33 | }
34 |
35 | lineNumber = 0
36 | currentFilename = ''
37 | currentLine = ''
38 | parsePhrase = ''
39 |
40 | DEBUG = False
41 |
42 | def debug(*args, center=False):
43 | if DEBUG:
44 | if center:
45 | consoleWidth = os.get_terminal_size()[0]
46 | print(args[0].center(consoleWidth, '-'))
47 | else:
48 | print(*args)
49 |
50 | def parse(line, filename='', no=-1, debug=False):
51 | global currentLine, lineNumber, currentFilename, DEBUG
52 | ''' Return a list of tokens for the given line '''
53 | DEBUG = debug
54 | lineNumber = no
55 | currentFilename = filename
56 | currentLine = line
57 | tokens = [i for i in re.split(r'(\W)',line) if not i == '' ]
58 | indentation = 0
59 | indentationSet = False
60 | tokenized = []
61 | preserveSpace = False
62 | quote = ''
63 | for n, i in enumerate(tokens):
64 | if not indentationSet and not (i == ' ' or i == '\t'):
65 | indentationSet = True
66 | tokenized.append({'token':'indent','indent':indentation})
67 | if (i == ' ' or i == '\t') and not indentationSet:
68 | indentation += 1
69 | elif i in statements:
70 | tokenized.append({'token':i+'Statement'})
71 | elif i in operators:
72 | tokenized.append({'token':'operator','operator':i})
73 | elif i in types:
74 | tokenized.append({'token':'type','type':i})
75 | elif i in symbols:
76 | if i == ' ' and tokens[n+1] == '.' and tokenized[-1]['token'] in {'var', 'type', 'rbracket'}:
77 | tokenized.append({'token':symbols[i], 'symbol':i})
78 | continue
79 | if i == "'" or i == '"':
80 | if not preserveSpace:
81 | preserveSpace = True
82 | quote = i
83 | elif preserveSpace and i == quote:
84 | tokenized.append({'token':symbols[i],'symbol':i})
85 | preserveSpace = False
86 | quote = ''
87 | if not i in {'"', "'", ' ','\t','\n'} or (i in {'"',"'",' ','\t','\n'} and preserveSpace):
88 | tokenized.append({'token':symbols[i],'symbol':i})
89 | elif i in builtins:
90 | tokenized.append({'token':i})
91 | else:
92 | tokenized.append(inference(i))
93 |
94 | if tokenized == []:
95 | tokenized = [{'token':'indent','indent':0}]
96 | return tokenized
97 |
98 | def token2word(tokens):
99 | phrase = ''
100 | for t in tokens:
101 | if t['token'] == 'indent':
102 | continue
103 | elif 'symbol' in t:
104 | phrase += t['symbol']
105 | elif t['token'] in {'num', 'var', 'expr','print','printFunc',
106 | 'floatNumber', 'type', 'cast', 'special','open','openFunc',
107 | 'assign','operator','group','ifStatement','if','elifStatement',
108 | 'elif','else', 'elseStatement','input','inputFunc', 'args','call',
109 | 'whileStatement','while','forStatement','inStatement','for','range',
110 | 'defStatement','func','returnStatement','return','breakStatement',
111 | 'comment','augAssign','classStatement','class','dotAccess',
112 | 'importStatement','import', 'kwargs','keyVal','keyVals','forTarget',
113 | 'delStatement','delete', 'asStatement', 'nativeStatement', 'fromStatement',
114 | 'fromImport'}:
115 | phrase += t['token']
116 | else:
117 | raise Exception(f'Cannot convert the token {t["token"]} to a word')
118 | phrase += ' '
119 | return phrase[:-1]
120 |
121 | def reduceToken(tokens):
122 | ''' Find patterns that can be reduced to a single token
123 | and return the reduced list of tokens
124 | '''
125 | global parsePhrase
126 | def reduce():
127 | for pattern in patterns:
128 | for i in range(len(tokenList)):
129 | if pattern == tuple(tokenList[i:i+len(pattern)]):
130 | debug(pattern)
131 | result = reduceToken(patterns[pattern](i+1,tokens))
132 | if result == 'continue':
133 | continue
134 | else:
135 | return result
136 |
137 | if tokens == 'continue':
138 | return 'continue'
139 | tokenList = [ token['token'] for token in tokens if not token['token'] == 'indent' ]
140 | parsePhrase = token2word(tokens)
141 | debug(parsePhrase)
142 | reducedTokens = reduce()
143 | if reducedTokens:
144 | tokens = reducedTokens
145 |
146 | # No patterns were found, reduced to maximum
147 | if len(tokens) > 2: #indent reducedToken (beginBlock)
148 | if not 'symbol' in tokens[0]:
149 | if 'indent' in tokens[0] and not 'symbol' in tokens[1]:
150 | showError(f'SyntaxError')
151 | return tokens
152 |
153 | def assembly(tokens, block=None, modifier=None):
154 | ''' Match the given list of tokens with the corresponding '''
155 | ''' grammar and return a struct with its properties '''
156 | if not block == None:
157 | if not 'block' in tokens[1]:
158 | tokens[1]['block'] = block
159 | return tokens
160 | else:
161 | showError('Not expecting an ifBlock here...')
162 | elif not modifier == None:
163 | if modifier[1]['token'] == 'elifStatement':
164 | if not 'elifs' in tokens[1]:
165 | tokens[1]['elifs'] = []
166 | modifier = assembly(modifier)
167 | tokens[1]['elifs'].append({'expr':modifier['expr'], 'elifBlock':modifier['block']})
168 | return tokens
169 | elif modifier[1]['token'] == 'elseStatement':
170 | if not 'else' in tokens[1]:
171 | tokens[1]['else'] = modifier[1]['block']
172 | return tokens
173 | else:
174 | showError('Multiple else statements is not permitted')
175 | else:
176 | showError(f"Not implemented modifier handling for {modifier[1]['token']}")
177 |
178 | else:
179 | reduced = reduceToken(tokens)
180 | if len(reduced) > 1:
181 | struct = reduced[1]
182 | struct['opcode'] = struct['token']
183 | return struct
184 |
185 | def showError(error):
186 | global currentLine, lineNumber, currentFilename
187 | msg = f'''
188 |
189 |
190 | Ops!! This is a syntax error or a parser error.
191 | Common causes: Missing "," ")" "}}"
192 | {error}
193 | This happened in line {currentFilename}:{lineNumber}.
194 | Last parsed line is "\n
195 | {currentLine}\n"
196 | Last Parse attempt was:\n "{parsePhrase}"
197 | '''
198 | raise SyntaxError(msg)
199 |
200 | # Load grammar
201 | import os
202 | with open(f'{os.path.dirname(__file__)}/grammar/generatedGrammar.py') as g:
203 | exec(g.read())
204 |
205 |
--------------------------------------------------------------------------------
/core/toolchains/shared.py:
--------------------------------------------------------------------------------
1 | from toolchains.toolchain import BaseToolchain
2 | from photonParser import debug
3 |
4 | class Toolchain(BaseToolchain):
5 | def transpile(self):
6 | self.interpreter.run()
7 |
8 | def make(self):
9 | from subprocess import call, check_call
10 | debug(f'Compiling shared library...')
11 | links = list(self.interpreter.engine.links)
12 | filename = self.interpreter.engine.filename.split('.')[0] + '.c'
13 | libraryName = self.interpreter.filename.split('.')[0] + '.so'
14 | try:
15 | debug(' '.join(['gcc', '-O2', '-std=c99', f'Sources/c/{filename}'] + links + ['-o', 'Sources/c/main']))
16 | check_call(['gcc', '-O2', '-std=c99', '-fPIC', '-shared', f'Sources/c/{filename}'] + links + ['-o', libraryName])
17 | except Exception as e:
18 | print(e)
19 | print('Compilation error. Check errors above.')
20 |
--------------------------------------------------------------------------------
/core/toolchains/toolchain.py:
--------------------------------------------------------------------------------
1 | from interpreter import Interpreter
2 |
3 | class BaseToolchain():
4 | def __init__(self, platform, filename='main.w', test=False, standardLibs=''):
5 | self.standardLibs = standardLibs
6 | self.platform = platform
7 | self.test = test
8 | self.interpreter = Interpreter(filename, standardLibs=standardLibs, transpileOnly=True)
9 |
10 | def logcat(self):
11 | pass
12 |
13 | def getBuildFiles(self):
14 | pass
15 |
16 | def transpile(self):
17 | pass
18 |
19 | def prepare(self):
20 | pass
21 |
22 | def make(self):
23 | pass
24 |
25 | def runProject(self):
26 | pass
27 |
--------------------------------------------------------------------------------
/core/transpilers/baseType.py:
--------------------------------------------------------------------------------
1 | class BaseType():
2 | nativeTypes = {
3 | 'int':'int',
4 | 'str':'str',
5 | 'float':'float',
6 | 'bool':'bool',
7 | 'unknown':'unknown',
8 | '':'unknown',
9 | 'obj':'obj',
10 | 'file':'file',
11 | }
12 |
13 | def __init__(self, type, elementType=None, keyType=None, valType=None, returnType=None, funcName=None, argsTypes=None, name=None, namespace='', native=False, **kwargs):
14 | if isinstance(type, self.__class__):
15 | self.native = type.native
16 | self.namespace = type.namespace
17 | self.type = type.type
18 | self.elementType = type.elementType
19 | self.keyType = type.keyType
20 | self.valType = type.valType
21 | self.returnType = type.returnType
22 | self.funcName = type.funcName
23 | self.argsTypes = type.argsTypes
24 | self.name = type.name
25 | else:
26 | if type is not None and type.split(' ')[-1] == 'func':
27 | if ' ' in type:
28 | returnType, type = type.split(' ')
29 | else:
30 | type = 'func'
31 | returnType = ''
32 | self.native = native
33 | self.namespace = namespace
34 | self.type = type if type is not None else 'unknown'
35 | self.elementType = self.__class__(elementType) if self.isKnown(self.type) else 'unknown'
36 | self.keyType = self.__class__(keyType) if self.isKnown(self.type) else 'unknown'
37 | self.valType = self.__class__(valType) if self.isKnown(self.type) else 'unknown'
38 | self.returnType = self.__class__(returnType) if self.isKnown(self.type) else 'unknown'
39 | self.funcName = funcName if self.isKnown(self.type) else None
40 | self.argsTypes = argsTypes if self.isKnown(self.type) and isinstance(argsTypes, list) else []
41 | self.name = name
42 |
43 | @property
44 | def known(self):
45 | if self.type == 'array' and self.isKnown(self.elementType):
46 | return True
47 | elif self.type == 'map' and self.isKnown(self.valType) and self.isKnown(self.keyType):
48 | return True
49 | elif self.type == 'func' and self.isKnown(self.returnType):
50 | return True
51 | elif self.type not in ['array', 'map'] and self.isKnown(self.type):
52 | return True
53 | else:
54 | return False
55 |
56 | @property
57 | def isPackage(self):
58 | if self.type == 'package' and self.name is not None:
59 | return True
60 | else:
61 | return False
62 |
63 | @property
64 | def isModule(self):
65 | if self.type == 'module' and self.name is not None:
66 | return True
67 | else:
68 | return False
69 |
70 | @property
71 | def isClass(self):
72 | if self.known and self.type in self.nativeTypes:
73 | return False
74 | elif self.known and not self.native and not self.type in self.nativeTypes and self.type not in ['array', 'map', 'module','package'] and not 'func' in self.type.split(' '):
75 | return True
76 | else:
77 | return False
78 |
79 | def isKnown(self, type):
80 | if isinstance(type, self.__class__):
81 | return type.known
82 | if type not in ['unknown', '']:
83 | return True
84 | return False
85 |
86 | def __str__(self):
87 | return repr(self)
88 |
89 | def __repr__(self):
90 | raise NotImplemented
91 |
92 | def __hash__(self):
93 | return hash((self.type, self.elementType, self.keyType, self.valType))
94 |
95 | def __eq__(self, obj):
96 | return hash(obj) == self.__hash__()
97 |
--------------------------------------------------------------------------------
/core/transpilers/cTranspiler.py:
--------------------------------------------------------------------------------
1 | from transpilers.baseTranspiler import BaseTranspiler
2 | from copy import deepcopy
3 | import os
4 | from string import Formatter
5 |
6 | def debug(*args):
7 | #print(*args)
8 | pass
9 |
10 | class Transpiler(BaseTranspiler):
11 | def __init__(self, filename, **kwargs):
12 | self.lang = 'c'
13 | self.loadTokens(self.lang)
14 | super().__init__(filename, **kwargs)
15 | self.libExtension = 'h'
16 | self.filename = self.filename.replace('.w', '.c')
17 | self.imports = {'#include ', '#include ', '#include ', '#include "main.h"'}
18 | self.links = set()
19 | if self.debug:
20 | # compile with debug symbols for gdb
21 | self.links.add('-g')
22 | self.links.add('-Wall')
23 | self.listTypes = set()
24 | self.dictTypes = set()
25 | self.classes = {}
26 | self.nativeTypes = {
27 | 'float': 'double',
28 | 'int': 'long',
29 | 'str': 'char*',
30 | 'bool': 'int',
31 | 'void': 'void',
32 | 'func': 'void',
33 | 'unknown': 'auto',
34 | 'file': 'FILE*'
35 | }
36 | self.builtins = {
37 | 'open':{'type':'file', 'value':'fopen'},
38 | }
39 |
40 | def renderDictTemplate(self, keyType, valType):
41 | formatCodes = {'int':'%ld', 'str':'\\"%s\\"', 'float':'%lf'}
42 | with open(f'{self.standardLibs}/native/c/dict_{keyType}.template') as template:
43 | dictLib = template.read()
44 | if valType in self.classes:
45 | valNativeType = f"{valType}*"
46 | else:
47 | valNativeType = self.nativeTypes[valType]
48 | #TODO: Call instance repr if it exists instead of the placeholder
49 | dictLib = dictLib.replace('!@valType@!', valType).replace('!@valNativeType@!', valNativeType).replace('!@formatCode@!', formatCodes[valType] if valType in formatCodes else f'')
50 | with open(f'Sources/c/dict_{keyType}_{valType}.h', 'w') as lib:
51 | lib.write(dictLib)
52 |
53 | def renderListTemplate(self, valType):
54 | if not valType in {'str', 'int', 'float'}:
55 | with open(f'{self.standardLibs}/native/c/list_template.h') as template:
56 | listLib = template.read()
57 | listLib = listLib.replace('!@valType@!', valType)
58 | with open(f'Sources/c/list_{valType}.h', 'w') as lib:
59 | lib.write(listLib)
60 |
61 | def write(self):
62 | boilerPlateStart = [
63 | 'int main() {',
64 | 'setlocale(LC_ALL, "");',
65 | ]
66 | boilerPlateEnd = [
67 | 'return 0;',
68 | '}'
69 | ]
70 | if not 'Sources' in os.listdir():
71 | os.mkdir('Sources')
72 | if not 'c' in os.listdir('Sources'):
73 | os.mkdir('Sources/c')
74 | if not self.module:
75 | self.filename = 'main.c'
76 | else:
77 | moduleName = self.filename.split('.')[0]
78 | self.filename = f'{moduleName}.c'
79 | boilerPlateStart = []
80 | boilerPlateEnd = []
81 | with open(f'Sources/c/main.h', 'w') as f:
82 | indent = 0
83 | f.write('#ifndef __main_h\n#define __main_h\n')
84 | if self.listTypes or self.dictTypes:
85 | self.imports.add('#include "asprintf.h"')
86 | listTypeHints = []
87 | dictTypeHints = []
88 | for listType in self.listTypes:
89 | if listType in self.classes:
90 | listTypeHints.append(f'typedef struct list_{listType} list_{listType};')
91 | self.classes[listType].postCode=f'\n#include "list_{listType}.h"\n'
92 | for keyType, valType in self.dictTypes:
93 | if valType in self.classes:
94 | dictTypeHints.append(f'typedef struct dict_{keyType}_{valType} dict_{keyType}_{valType};')
95 | self.classes[valType].postCode+=f'\n#include "dict_{keyType}_{valType}.h"\n'
96 | #TODO: do the same type hint for dicts
97 | for line in listTypeHints + dictTypeHints:
98 | #if '}' in line:
99 | # indent -= 4
100 | f.write(' '*indent + line+'\n')
101 | #if self.isBlock(line) and not ';' in line[-1]:
102 | # indent += 4
103 | f.write('#endif')
104 | with open(f'Sources/c/{self.filename}', 'w') as f:
105 | f.write('#ifndef __main\n#define __main\n')
106 | for imp in sorted(self.imports):
107 | module = imp.split(' ')[-1].replace('.w', '').replace('"', '')
108 | debug(f'Importing {module}')
109 | if module in os.listdir(f'{self.standardLibs}/native/c'):
110 | from shutil import copyfile
111 | copyfile(f'{self.standardLibs}/native/c/{module}', f'Sources/c/{module}')
112 | if not f'{module}.c' in os.listdir('Sources/c'):
113 | # native import
114 | f.write(imp + '\n')
115 | for valType in self.listTypes:
116 | self.renderListTemplate(valType)
117 | for keyType, valType in self.dictTypes:
118 | self.renderDictTemplate(keyType, valType)
119 | for line in [''] + boilerPlateStart + [''] + [self.sequence] + boilerPlateEnd:
120 | f.write(f'{line}\n')
121 | f.write('#endif')
122 | debug('Generated ' + self.filename)
123 |
124 | def run(self):
125 | from subprocess import call, check_call
126 | import sys
127 | self.write()
128 | debug(f'Running {self.filename}')
129 | try:
130 | if self.debug:
131 | optimizationFlags = ['-ggdb']
132 | elif sys.platform == 'darwin':
133 | optimizationFlags = ['-Ofast']
134 | else:
135 | optimizationFlags = ['-Ofast', '-frename-registers', '-funroll-loops']
136 | debug(' '.join(['gcc', '-O2', '-std=c99', f'Sources/c/{self.filename}'] + list(self.links) + ['-o', 'Sources/c/main']))
137 | check_call(['gcc'] + optimizationFlags + ['-std=c99', f'Sources/c/{self.filename}'] + list(self.links) + ['-o', 'Sources/c/main'])
138 | except Exception as e:
139 | print(e)
140 | print('Compilation error. Check errors above.')
141 | exit()
142 | else:
143 | if self.platform in {'linux', 'darwin'}:
144 | # don't call on Sources/c folder because of file paths
145 | call('./Sources/c/main')
146 | #call('./main', cwd='Sources/c')
147 | else:
148 | call('main', cwd='Sources/c', shell=True)
149 |
--------------------------------------------------------------------------------
/core/transpilers/dTranspiler.py:
--------------------------------------------------------------------------------
1 | class Transpiler():
2 | pass
3 |
--------------------------------------------------------------------------------
/core/transpilers/jsTranspiler.py:
--------------------------------------------------------------------------------
1 | from transpilers.baseTranspiler import BaseTranspiler
2 | import os
3 |
4 | def debug(*args):
5 | #print(*args)
6 | pass
7 |
8 | class Transpiler(BaseTranspiler):
9 | def __init__(self, filename, **kwargs):
10 | self.lang = 'javascript'
11 | self.loadTokens('js')
12 | super().__init__(filename, **kwargs)
13 | self.filename = self.filename.replace('.w','.js')
14 | self.libExtension = 'js'
15 | self.imports = set()
16 | self.links = set()
17 | self.listTypes = set()
18 | self.dictTypes = set()
19 | self.classes = {}
20 | self.nativeTypes = {
21 | 'float':'float',
22 | 'int':'int',
23 | 'str':'str',
24 | 'bool':'bool',
25 | 'array':'list',
26 | 'unknown':'any',
27 | 'void':'None',
28 | }
29 | self.builtins = {
30 | 'open':{'type':'file', 'value':'open'},
31 | }
32 |
33 | def write(self):
34 | boilerPlateStart = [
35 | ]
36 | boilerPlateEnd = [
37 | ]
38 | indent = 0
39 | count = 0
40 | if not 'Sources' in os.listdir():
41 | os.mkdir('Sources')
42 | if not 'js' in os.listdir('Sources'):
43 | os.mkdir('Sources/js')
44 | if not self.module:
45 | self.filename = 'main.js'
46 | else:
47 | boilerPlateStart = []
48 | boilerPlateEnd = []
49 | with open(f'Sources/js/{self.filename}', 'w') as f:
50 | for imp in self.imports:
51 | module = imp.split(' ')[-1].replace('.w', '').replace('"', '')
52 | debug(f'Importing {module}')
53 | if f'{module}.js' in os.listdir('Sources/js'):
54 | with open(f'Sources/js/{module}.js', 'r') as m:
55 | for line in m:
56 | f.write(line)
57 | else:
58 | f.write(imp + '\n')
59 | for line in [''] + boilerPlateStart + [self.sequence] + boilerPlateEnd:
60 | f.write(f'{line}\n')
61 | debug('Generated ' + self.filename)
62 |
63 | def run(self):
64 | from subprocess import call, check_call
65 | self.write()
66 | debug(f'Running {self.filename}')
67 | try:
68 | check_call(['node', f'Sources/js/{self.filename}'])
69 | except:
70 | print('Compilation error. Check errors above.')
71 |
--------------------------------------------------------------------------------
/core/transpilers/pyTokens.py:
--------------------------------------------------------------------------------
1 | # Basic Types
2 | from copy import deepcopy
3 | from pprint import pprint
4 | from .baseType import BaseType
5 |
6 | class Type(BaseType):
7 | nativeTypes = {
8 | 'int':'int',
9 | 'str':'str',
10 | 'float':'float',
11 | 'bool':'bool',
12 | 'unknown':'None',
13 | '':'None',
14 | 'obj':'obj',
15 | 'file':'TypeVar("file")',
16 | }
17 |
18 | def __repr__(self):
19 | if self.native:
20 | return f'TypeVar("{self.type}")'
21 | elif self.type == 'array':
22 | return f'list[{self.elementType.type}]'
23 | elif self.type == 'map':
24 | return f'dict[{self.keyType.type}, {self.valType.type}]'
25 | elif self.type == 'func':
26 | return f'Callable[[{", ".join(self.argsTypes)}], {self.returnType}]'
27 | elif self.type in self.nativeTypes:
28 | return self.nativeTypes[self.type]
29 | elif self.isClass:
30 | return f'TypeVar("{self.type}")'
31 | else:
32 | return f'TypeVar("{self.type}")'
33 |
34 | exec(open(__file__.rsplit('/', 1)[0]+"/tokens.py").read())
35 |
36 | class Comment(Comment):
37 | pass
38 |
39 | class Null(Null):
40 | def __repr__(self):
41 | return 'None'
42 |
43 | class Module(Module):
44 | def __init__(self, expr, name, namespace, native=False, scope=None, filepath=''):
45 | super().__init__(expr, name, namespace, native=native, scope=scope, filepath='')
46 | if self.native:
47 | self.imports = [f'import {self.name}']
48 |
49 | def __repr__(self):
50 | return f'#module {self.name}'
51 |
52 | class Group(Group):
53 | pass
54 |
55 | class Scope(Scope):
56 | beginSymbol = ':'
57 | endSymbol = ''
58 | def __repr__(self):
59 | if repr(self.sequence).strip():
60 | return super().__repr__()
61 | else:
62 | return f':\n{self.indent}pass\n'
63 |
64 | class NativeCode(NativeCode):
65 | pass
66 |
67 | class Bool(Bool):
68 | def format(self):
69 | return f'"true" if {self.expression()} else "false"'
70 |
71 | def expression(self):
72 | return '1' if self.value == 'true' else '0'
73 |
74 | class Num(Num):
75 | pass
76 |
77 | class String(String):
78 | imports = []
79 | def __repr__(self):
80 | if self.expressions:
81 | return f'{self.value}.format({", ".join([repr(expr) for expr in self.expressions])})'
82 | return self.value
83 |
84 | class Var(Var):
85 | imports = []
86 | def prepare(self):
87 | if self.namespace:
88 | self.name = f'{self.namespace}__{self.value}'
89 | else:
90 | self.name = self.value
91 |
92 | def declaration(self):
93 | return f'{self.value}:{self.type}'
94 |
95 | def format(self):
96 | if self.type.type in ['map', 'array']:
97 | if not self.indexAccess:
98 | return f'str({self.name})'
99 | return self.expression()
100 | if self.type.type == 'bool':
101 | return f'"true" if {self.name} else "false"'
102 | if self.type.type not in ['str','int','float', 'bool']:
103 | if self.type.isClass:
104 | return f'""'
105 | return f'str({self.name})'
106 | return self.name
107 |
108 | def method(self):
109 | return f'{self.name}'
110 |
111 | def expression(self):
112 | if self.indexAccess:
113 | if self.type.type == 'array':
114 | return f'{self.name}[{self.indexAccess}]'
115 | if self.type.type == 'map':
116 | return f'{self.name}[{self.indexAccess}]'
117 | else:
118 | return f'{self.name}[{self.indexAccess}]'
119 | return self.name
120 |
121 | class Expr(Expr):
122 | operatorOrder = [
123 | 'not','**','*','%','/','-','+','==','!=','>','<','>=','<=',
124 | 'is','in','andnot','and','or','&', '<<', '>>'
125 | ]
126 | opConversions = {
127 | 'and': 'and',
128 | 'or': 'or',
129 | 'not': 'not',
130 | }
131 | def concatenate(self, arg1, arg2, t):
132 | return Expr(value=f'{arg1} + {arg2}', type=t)
133 |
134 | class Delete(Delete):
135 | def __repr__(self):
136 | self.expr.mode = 'method'
137 | if self.expr.type.type in ['array', 'map']:
138 | return f'del {self.expr}[{self.expr.value.indexAccess}]'
139 | if isinstance(self.expr.value, DotAccess):
140 | return f'del {self.expr}[{self.expr.value.indexAccess}]'
141 | raise SyntaxError(f'Delete not supported for type {type(self.expr.value)}')
142 |
143 | class DotAccess(DotAccess):
144 | imports = []
145 | def format(self):
146 | if self.type.isClass or self.type.type in ['array', 'map']:
147 | return f'str({self.value})'
148 | return self.value
149 |
150 | def expression(self):
151 | if self.chain[0].type.isModule:
152 | self.chain[0].namespace = ''
153 | chain = [repr(self.chain[0])]
154 | currentType = self.chain[0].type
155 | for n, c in enumerate(self.chain[1:]):
156 | if currentType.native:
157 | chain.append('.')
158 | chain.append(repr(c))
159 | elif currentType.type == 'file':
160 | if isinstance(c, Call):
161 | if repr(c.name) in ['write', 'close', 'read']:
162 | if repr(c.name) == 'read' and not c.args:
163 | c.name.value = 'readline'
164 | chain.append('.')
165 | chain.append(repr(c))
166 | else:
167 | raise SyntaxError(f'File object has no method {c.name}')
168 | else:
169 | raise SyntaxError(f'File object has no attribute {c}')
170 | elif currentType.type == 'array' and isinstance(c, Call):
171 | chain.append('.')
172 | chain.append(repr(c))
173 | elif currentType.type == 'array' and isinstance(c, Var):
174 | if repr(c) == 'len':
175 | varName = ''.join(chain)
176 | chain = [f'len({varName})']
177 | else:
178 | chain.append('.')
179 | chain.append(c.name)
180 | elif c.type.type == 'array' and getattr(c, 'indexAccess', None):
181 | chain.append('.')
182 | chain.append(repr(c))
183 | c.type = c.type.elementType
184 | elif currentType.isClass and isinstance(c, Call):
185 | instanceName = ''.join(chain)
186 | #TODO this fails sometimes but a method
187 | # always should have the self...
188 | if c.signature:
189 | del c.signature[0]
190 | if c.args.args:
191 | del c.args.args[0]
192 | if instanceName == 'super':
193 | chain.append('().')
194 | chain.append(repr(c))
195 | else:
196 | chain.append('.')
197 | chain.append(repr(c))
198 | elif currentType.isModule:
199 | if currentType.native:
200 | input(f'Is native {c}')
201 | else:
202 | chain = [repr(c)]
203 | else:
204 | chain.append('.')
205 | chain.append(repr(c))
206 | currentType = c.type
207 | if self.mode == 'method':
208 | self.chain[-1].mode = 'method'
209 | chain[-1] = repr(self.chain[-1])
210 | self.chain[-1].mode = 'expr'
211 | self.processed = True
212 | return ''.join(chain)
213 |
214 | class Return(Return):
215 | def __repr__(self):
216 | return f'return {self.expr}'
217 |
218 | class Array(Array):
219 | imports = []
220 | def prepare(self):
221 | self.len = len(self.elements)
222 | self.size = 8 if self.len < 8 else self.len
223 |
224 | def expression(self):
225 | return '[' + ','.join([repr(e) for e in self.elements]) + ']'
226 |
227 | def __repr__(self):
228 | self.prepare()
229 | value = self.expression()
230 | if self.mode == 'format':
231 | return f'str({value})'
232 | return value
233 |
234 | class KeyVal(KeyVal):
235 | def __repr__(self):
236 | return f'{self.key}:{self.val}'
237 |
238 | class Map(Map):
239 | def __repr__(self):
240 | return '{' + ', '.join([repr(kv) for kv in self.keyVals])+ '}'
241 |
242 | class Open(Open):
243 | def __repr__(self):
244 | return f'open({self.args})'
245 |
246 | class Input(Input):
247 | imports = []
248 | def __repr__(self):
249 | return f'input({self.expr})'
250 |
251 | class Break(Break):
252 | def __repr__(self):
253 | return f'break'
254 |
255 | # Representation Types
256 |
257 | class Sequence(Sequence):
258 | def __init__(self, objs=None, terminator='', apply=None):
259 | super().__init__(objs=objs, terminator=terminator, apply=apply)
260 |
261 | class Cast(Cast):
262 | conversion = {
263 | 'int':{
264 | 'str': 'int({self.expr})',
265 | 'float': 'int({self.expr})',
266 | },
267 | 'float':{
268 | 'str': 'float({self.expr})',
269 | 'int': 'float({self.expr})',
270 | },
271 | 'str':{
272 | 'int': 'str({self.expr})',
273 | 'float': 'str({self.expr})',
274 | },
275 | }
276 |
277 | def __repr__(self):
278 | self.expr.namespace = self.namespace
279 | castFrom = self.expr.type.type
280 | castTo = self.castTo.type
281 | if castTo == 'map':
282 | castTo = self.castTo.valType.type
283 | elif castTo == 'array' and castFrom == 'array':
284 | return f'{self.expr}'
285 | elif castTo == 'array':
286 | castTo = self.castTo.elementType.type
287 | if castFrom == 'map' and self.expr.indexAccess is not None:
288 | castFrom = self.expr.type.valType
289 | elif castFrom == 'array' and self.expr.indexAccess is not None:
290 | castFrom = self.expr.type.elementType
291 | try:
292 | if self.castTo.isClass:
293 | return f'{self.expr}'
294 | elif castTo != castFrom and castTo in self.conversion:
295 | return self.conversion[castTo][castFrom].format(self=self)
296 | return repr(self.expr)
297 | except KeyError as e:
298 | raise SyntaxError(f'Cast not implemented for type {castTo} from {castFrom} {e}')
299 |
300 | class Assign(Assign):
301 | def declaration(self):
302 | return f'{self.target}:{self.target.type}'
303 |
304 | def expression(self):
305 | if self.inMemory or isinstance(self.target, DotAccess):
306 | if self.target.indexAccess:
307 | if self.target.type.type == 'array':
308 | return f'{self.target.name}[{self.target.indexAccess}] = {self.value}'
309 | if self.target.type.type == 'map':
310 | return f'{self.target.name}[{self.target.indexAccess}] = {self.value}'
311 | else:
312 | # indexAccess already processed in self.target
313 | return f'{self.target} = {self.value}'
314 | return f'{self.target} = {self.value}'
315 | else:
316 | return f'{self.target}:{self.target.type} = {self.value}'
317 |
318 | class Args(Args):
319 | pass
320 |
321 | class Kwargs(Kwargs):
322 | def __repr__(self):
323 | self.prepare()
324 | if self.mode == 'value':
325 | return ', '.join([repr(kwarg.value) for kwarg in self.kwargs])
326 | return ', '.join([repr(kwarg) for kwarg in self.kwargs])
327 |
328 | class Call(Call):
329 | def __repr__(self):
330 | if self.mode == 'format' and self.type.isClass:
331 | return f'""'
332 | if self.signature:
333 | kwargs = []
334 | args = []
335 | # allocate args then sort kwargs
336 | for s in self.signature[len(self.args.args):]:
337 | for kwarg in self.kwargs.kwargs:
338 | if isinstance(s, Assign):
339 | kwarg.target.namespace = ''
340 | if s.target.index == kwarg.target.index:
341 | if kwarg.type != s.type:
342 | kwarg = Cast(Expr(kwarg.value), s.type)
343 | kwargs.append(kwarg)
344 | break
345 | else:
346 | kwargs.append(s)
347 | kwargs = Kwargs(kwargs, mode='value')
348 | for arg, sig in zip(self.args, self.signature):
349 | if arg.type != sig.type:
350 | args.append(Cast(arg, sig.type))
351 | else:
352 | args.append(arg)
353 | args = Args(args, mode='expr')
354 | else:
355 | kwargs = []
356 | for kwarg in self.kwargs.kwargs:
357 | kwarg.namespace = ''
358 | kwargs.append(kwarg)
359 | kwargs = Kwargs(kwargs, mode='value')
360 | args = self.args
361 | separator = ', ' if args and kwargs else ''
362 | if self.type.isClass:
363 | return f'{self.name}({args}{separator}{kwargs})'
364 | else:
365 | return f'{self.name}({args}{separator}{kwargs})'
366 |
367 | class Print(Print):
368 | def __repr__(self):
369 | return f'print({self.args})'
370 |
371 | class Function(Function):
372 | def expression(self):
373 | return f'def {self.name}({self.args}{self.separator}{self.kwargs}) -> {self.name.type} {self.code}'
374 |
375 | class Class(Class):
376 | def formatNewMethod(self):
377 | paramsInit = []
378 | for p in self.parameters.values():
379 | if isinstance(p, Assign):
380 | if not p.target.attribute:
381 | paramsInit.append(
382 | NativeCode(f'self.{p.target} = {p.value}'))
383 | else:
384 | paramsInit.append(
385 | NativeCode(f'self.{p.target} = {p.target}'))
386 | elif isinstance(p, Expr):
387 | paramsInit.append(
388 | NativeCode(f'self.{p} = None'))
389 | code = paramsInit + self.new.code.sequence.sequence
390 | self.new.code = Scope(code)
391 |
392 | def __repr__(self):
393 | value = f'class {self.name}({self.args}):\n'
394 | self.writeMode()
395 | for method in self.methods.values():
396 | if method.name.value == 'new':
397 | method = deepcopy(method)
398 | method.name.value = '__init__'
399 | method.name.type = Type('unknown')
400 | if not method.args.args or not repr(method.args.args[0].name) != "self":
401 | method.args.args.insert(0, Var('self', repr(self.name)))
402 | method.namespace = ''
403 | method.code.indent = ' '*8
404 | value += f' {method}\n'
405 | return value+self.postCode
406 |
407 | class Elif(Elif):
408 | def __repr__(self):
409 | return f'elif {self.expr} {self.block}'
410 |
411 | class Else(Else):
412 | def __repr__(self):
413 | return f'else {self.block}'
414 |
415 | class If(If):
416 | def __repr__(self):
417 | return f'if {self.expr} {self.ifBlock}{"".join(repr(e) for e in self.elifs)}{self.elseBlock}'
418 |
419 | class While(While):
420 | def __repr__(self):
421 | return f'while {self.expr} {self.block}'
422 |
423 | class For(For):
424 | def __repr__(self):
425 | if isinstance(self.iterable, Range):
426 | if len(self.args.args) == 1:
427 | return f'for {self.args[0]} in range({self.iterable.initial}, {self.iterable.final}, {self.iterable.step}) {self.code}'
428 | if len(self.args.args) == 2:
429 | return f'for {self.args[0]}, {self.args[1]} in enumerate(range({self.iterable.initial}, {self.iterable.final}, {self.iterable.step})) {self.code}'
430 | elif isinstance(self.iterable, Expr):
431 | if self.iterable.type.type == 'array':
432 | if len(self.args.args) == 1:
433 | return f'for {self.args[0]} in {self.iterable} {self.code}'
434 | if len(self.args.args) == 2:
435 | return f'for {self.args[0]}, {self.args[1]} in enumerate({self.iterable}) {self.code}'
436 | if self.iterable.type.type == 'map':
437 | if len(self.args.args) == 1:
438 | return f'for {self.args[0]} in {self.iterable} {self.code}'
439 | if len(self.args.args) == 2:
440 | return f'for {self.args[0]}, {self.args[1]} in {self.iterable}.items() {self.code}'
441 | if self.iterable.type.type == 'str':
442 | if len(self.args.args) == 1:
443 | return f'for {self.args[0]} in {self.iterable} {self.code}'
444 | if len(self.args.args) == 2:
445 | return f'for {self.args[0]}, {self.args[1]} in enumerate({self.iterable}) {self.code}'
446 | else:
447 | raise TypeError('Iterable type is unknown')
448 | else:
449 | raise ValueError(f'Iterable of type {type(self.iterable)} no supported in for.')
450 |
451 | class Range(Range):
452 | pass
453 |
454 | class AugAssign(AugAssign):
455 | pass
456 |
--------------------------------------------------------------------------------
/core/transpilers/pyTranspiler.py:
--------------------------------------------------------------------------------
1 | from transpilers.baseTranspiler import BaseTranspiler
2 | import os
3 |
4 | def debug(*args):
5 | #print(*args)
6 | pass
7 |
8 | class Transpiler(BaseTranspiler):
9 | def __init__(self, filename, **kwargs):
10 | self.lang = 'python'
11 | self.loadTokens('py')
12 | super().__init__(filename, **kwargs)
13 | self.filename = self.filename.replace('.w','.py')
14 | self.libExtension = 'py'
15 | self.imports = {"from collections.abc import Callable","from typing import TypeVar"}
16 | self.links = set()
17 | self.listTypes = set()
18 | self.dictTypes = set()
19 | self.classes = {}
20 | self.nativeTypes = {
21 | 'float':'float',
22 | 'int':'int',
23 | 'str':'str',
24 | 'bool':'bool',
25 | 'array':'list',
26 | 'unknown':'any',
27 | 'void':'None',
28 | }
29 | self.builtins = {
30 | 'open':{'type':'file', 'value':'open'},
31 | }
32 |
33 | def write(self):
34 | boilerPlateStart = [
35 | ]
36 | boilerPlateEnd = [
37 | ]
38 | indent = 0
39 | count = 0
40 | if not 'Sources' in os.listdir():
41 | os.mkdir('Sources')
42 | if not 'py' in os.listdir('Sources'):
43 | os.mkdir('Sources/py')
44 | if not self.module:
45 | self.filename = 'main.py'
46 | else:
47 | #self.filename = f'{moduleName}.py'
48 | boilerPlateStart = []
49 | boilerPlateEnd = []
50 | with open(f'Sources/py/{self.filename}', 'w') as f:
51 | for imp in self.imports:
52 | module = imp.split(' ')[-1].replace('.w', '').replace('"', '')
53 | debug(f'Importing {module}')
54 | if f'{module}.py' in os.listdir('Sources/py'):
55 | with open(f'Sources/py/{module}.py', 'r') as m:
56 | for line in m:
57 | f.write(line)
58 | else:
59 | f.write(imp + '\n')
60 | for line in [''] + boilerPlateStart + [self.sequence] + boilerPlateEnd:
61 | f.write(f'{line}\n')
62 | debug('Generated ' + self.filename)
63 |
64 | def run(self):
65 | from subprocess import call, check_call
66 | self.write()
67 | debug(f'Running {self.filename}')
68 | try:
69 | check_call(['python', f'Sources/py/{self.filename}'])
70 | except:
71 | print('Compilation error. Check errors above.')
72 |
--------------------------------------------------------------------------------
/core/transpilers/tsTranspiler.py:
--------------------------------------------------------------------------------
1 | from transpilers.jsTranspiler import Transpiler as JSTranspiler
2 | import os
3 |
4 | def debug(*args):
5 | #print(*args)
6 | pass
7 |
8 | class Transpiler(JSTranspiler):
9 | def __init__(self, filename, **kwargs):
10 | super().__init__(filename, **kwargs)
11 | self.filename = self.filename.replace('.w','.ts')
12 | self.lang = 'ts'
13 |
14 | def formatInput(self, expr):
15 | message = expr['value']
16 | message = message[:-2] + '"'
17 | return f'prompt({message})'
18 |
19 | def formatFor(self, variables, iterable):
20 | if iterable['type'] in {'array', 'str'}:
21 | jsFormatFor = super().formatFor(variables, iterable)
22 | # now self.iterVar is updated, we can use it
23 | return f'var {self.iterVar[-1][0]}; ' + jsFormatFor
24 | return super().formatFor(variables, iterable)
25 |
26 | def formatPrint(self, value, terminator='\\n'):
27 | if value['value']:
28 | return f'Deno.writeAll(Deno.stdout, new TextEncoder().encode(JSON.stringify({value["value"]})+"{terminator}"))'
29 | return f'Deno.writeAll(Deno.stdout, new TextEncoder().encode("{terminator}"))'
30 |
31 | def write(self):
32 | boilerPlateStart = [
33 | ]
34 | boilerPlateEnd = [
35 | ]
36 | indent = 0
37 | count = 0
38 | if not 'Sources' in os.listdir():
39 | os.mkdir('Sources')
40 | if not 'ts' in os.listdir('Sources'):
41 | os.mkdir('Sources/ts')
42 | if not self.module:
43 | self.filename = 'main.js'
44 | else:
45 | self.filename = f'{moduleName}.js'
46 | boilerPlateStart = []
47 | boilerPlateEnd = []
48 | del self.imports[0]
49 | del self.imports[0]
50 | del self.imports[0]
51 | # Force utf8 on windows
52 | with open(f'Sources/ts/{self.filename}', 'w', encoding='utf8') as f:
53 | for imp in self.imports:
54 | module = imp.split(' ')[-1].replace('.w', '').replace('"', '')
55 | debug(f'Importing {module}')
56 | if f'{module}.ts' in os.listdir('Sources/ts'):
57 | with open(f'Sources/ts/{module}.js', 'r') as m:
58 | for line in m:
59 | f.write(line)
60 | else:
61 | f.write(imp + '\n')
62 | for line in [''] + self.outOfMain + [''] + boilerPlateStart + self.source + boilerPlateEnd:
63 | if line:
64 | if line.startswith('}'):
65 | indent -= 4
66 | f.write(' ' * indent + line.replace('/*def*/', '') + '\n')
67 | if self.isBlock(line):
68 | indent += 4
69 | debug('Generated ' + self.filename)
70 |
71 | def run(self):
72 | from subprocess import call, check_call
73 | self.write()
74 | debug(f'Running {self.filename}')
75 | try:
76 | check_call(['deno', 'run', f'Sources/ts/{self.filename}'])
77 | except Exception as e:
78 | print(f'Compilation error {e}. Check errors above.')
79 |
--------------------------------------------------------------------------------
/examples/callback_ex.w:
--------------------------------------------------------------------------------
1 |
2 | def xyz(int a, float b, str c, int d = [], float e = [], str f = []):
3 | print("{a} | {b} | {c} | {d} | {e} | {f}")
4 |
5 | def test(func callback):
6 | callback(1, 2.0, "Matheus", [1, 2], [1.0, 2.0], ["PHO", "TON"])
7 |
8 | test(xyz)
9 |
--------------------------------------------------------------------------------
/examples/class_ex.w:
--------------------------------------------------------------------------------
1 |
2 | class Person():
3 |
4 | def new(.name = "Matheus", .age = 23, .gen = "1"):
5 |
6 | def print_name():
7 | print("My name is {.name}")
8 |
9 | def print_age():
10 | print("My age is {.age} years old")
11 |
12 | def print_gen():
13 | if .gen == "1" or .gen == "Man":
14 | .gen = "Man"
15 | elif .gen == "0" or .gen == "Woman":
16 | .gen = "Woman"
17 | else:
18 | .gen = "Undefined"
19 | print("I am a {.gen}")
20 |
21 | person = Person()
22 | person.print_name()
23 | person.print_age()
24 | person.print_gen()
25 |
26 | print()
27 |
28 | person = Person(age=30)
29 | person.name = "William"
30 | person.print_name()
31 | person.print_age()
32 |
--------------------------------------------------------------------------------
/examples/conditionals_ex.w:
--------------------------------------------------------------------------------
1 |
2 | # Variable that is used in the conditional logic test below
3 | int num = 3
4 |
5 | # If the value stored in the variable `num` is equal to 3 do:
6 | if num == 3:
7 | print("The number entered in the variable `num` is 3")
8 |
9 | # Otherwise, if the value stored in the variable `num` is equal to 4, do:
10 | elif num == 4:
11 | print("The number entered in the variable `num` is 4")
12 |
13 | # If the value is neither 3 nor 4 do:
14 | else:
15 | print("The number entered in the variable `num` is neither 3 nor 4")
16 |
--------------------------------------------------------------------------------
/examples/dict_ex.w:
--------------------------------------------------------------------------------
1 |
2 | # The dictionary structure is a way of relating a key to a value.
3 | # Where the pair (key:value) must have their respective types.
4 |
5 | # Type examples for (key:value dictionary_name):
6 | # int:int `dictionary_name`
7 | # int:float `dictionary_name`
8 | # int:str `dictionary_name`
9 |
10 | # Example of creating and assigning keys and values to the dictionary
11 | #int:int my_dict = { 1:1, 2:4, 3:9, 4:16 }
12 |
13 | int:int dict_int = {}
14 | dict_int[1] = 1
15 | dict_int[2] = 4
16 | dict_int[3] = 9
17 | dict_int[4] = 16
18 |
19 | print("# Iterating by index")
20 | # This structure only works if the key is a sequence of integers.
21 | for i in 1..dict_int.len + 1:
22 | print("The key {i} contains the value {dict_int[i]}")
23 |
24 | # Deletes an element from the dictionary using the entered key
25 | del dict_int[2]
26 |
27 | # Line break
28 | print()
29 |
30 | print("# Gets the key and value in each dictionary iteration")
31 | for key, value in dict_int:
32 | print("The key {key} contains the value {value}")
33 |
34 | # Line break
35 | print()
36 |
37 | int:str dict_str = {}
38 | dict_str[1] = "P"
39 | dict_str[2] = "H"
40 | dict_str[3] = "O"
41 | dict_str[4] = "T"
42 | dict_str[5] = "O"
43 | dict_str[6] = "N"
44 |
45 | print(dict_str)
46 |
--------------------------------------------------------------------------------
/examples/ffi/ffi_photon.py:
--------------------------------------------------------------------------------
1 |
2 | # pip install photon-lang
3 | # python ffi_photon.py
4 | import photon_lang
5 |
6 | # Name of `main.so`
7 | import main
8 |
9 | # Calling function implemented through photon
10 | main.compute()
11 |
--------------------------------------------------------------------------------
/examples/ffi/main.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HashLDash/Photon/bfd206db3b91b695139cbde47bc39ba59057d122/examples/ffi/main.so
--------------------------------------------------------------------------------
/examples/ffi/main.w:
--------------------------------------------------------------------------------
1 |
2 | # To generate the shared constructor file (`main.so` or `main.dll`) you need to use the command:
3 | # photon --build shared
4 |
5 | def compute():
6 | for i in 0..10:
7 | print("Ok {i}")
8 |
--------------------------------------------------------------------------------
/examples/for_target_ex.w:
--------------------------------------------------------------------------------
1 |
2 | # On the `C` target, do:
3 | for C:
4 | print("Target C")
5 |
6 | # On the `D` target, do:
7 | for D:
8 | print("Target D")
9 |
10 | # On the `JS` target, do:
11 | for JS:
12 | print("Target JavaScript")
13 |
14 | # On the `TS` target, do:
15 | for TS:
16 | print("Target TypeScript")
17 |
18 | # On the `DART` target, do:
19 | for DART:
20 | print("Target Dart")
21 |
22 | # On the `HAXE` target, do:
23 | for HAXE:
24 | print("Target Haxe")
25 |
26 | # On the `PY` target, do:
27 | for PY:
28 | print("Target Python")
29 |
--------------------------------------------------------------------------------
/examples/functions_ex.w:
--------------------------------------------------------------------------------
1 |
2 | # Functions are made up of parameters and a return value type.
3 | # Data types that can be used to define parameters/return: int, float, str...
4 | # Every function has def `return type` `function name` (`parameter type and name, next parameter`)
5 |
6 | def int add(int x, int y):
7 | return x + y
8 |
9 | def float sub(float x, float y):
10 | return x - y
11 |
12 | def example(int a = 0, int b = 0):
13 | print("A = {a} | B = {b}")
14 |
15 | def add_list(int list = []):
16 | int sum = 0
17 | for num in list:
18 | sum += num
19 | return sum
20 |
21 | print("Add 3 + 1 = {add(3, 1)}")
22 |
23 | # Line break
24 | print()
25 |
26 | print("Sub 5 - 2.1 = {sub(5, 2.1)}")
27 |
28 | # Line break
29 | print()
30 |
31 | # Line break
32 | example()
33 | # You must specify the name of each argument that has a default value,
34 | # otherwise the entered value will be ignored and the default value applied.
35 | example(1, 2) # Don't do like that
36 | example(a = 1, b = 2) # Do like this
37 | example(b = 1, a = 2) # Do like this
38 |
39 | # Line break
40 | print()
41 |
42 | int list = [1, 2, 3, 4]
43 |
44 | print("Add {list} = {add_list(list=list)}")
45 |
46 | # Line break
47 | #print()
48 |
49 | #def test(func callback):
50 | # print(callback(1, 2))
51 |
52 | #test(add)
53 |
--------------------------------------------------------------------------------
/examples/list_ex.w:
--------------------------------------------------------------------------------
1 |
2 | # The list starts with index 0
3 | list = [1, 2, 3, 4]
4 | print("List: {list}")
5 |
6 | # Removing the second element from the list
7 | del list[2]
8 | print("The element in index 2 has been removed.")
9 |
10 | print("List: {list}")
11 |
12 | # Line break
13 | print()
14 |
15 | # A list of strings
16 | str list_of_str = []
17 |
18 | # Adding elements to the list
19 | # At each call of `+=` a new element will be assigned to a new index
20 | list_of_str += "P"
21 | list_of_str += "h"
22 | list_of_str += "o"
23 | list_of_str += "t"
24 | list_of_str += "o"
25 | list_of_str += "n"
26 |
27 | # Iterating a list through variable i
28 | for i in 0..list_of_str.len:
29 | print("The key {i} contains the value {list_of_str[i]}")
30 |
31 | # Line break
32 | print()
33 |
34 | # The foreach cycles through the list and returns a key-value pair
35 | for key, value in list_of_str:
36 | print("The key {key} contains the value {value}")
37 |
38 | # Line break
39 | print()
40 |
41 | # The foreach is also capable of traversing a string (list of characters)
42 | for index, caracter in "Photon":
43 | print('The {index + 1}st character of the string is: {caracter}')
44 |
45 |
--------------------------------------------------------------------------------
/examples/loops_ex.w:
--------------------------------------------------------------------------------
1 |
2 | # FOR iteration structure
3 | # This loop will go from 0 to 4, and at each iteration the variable `i` will be incremented from 1 in 1.
4 | for i in 0..5:
5 | print("For: {i}")
6 |
7 | # Separate output with a new line
8 | print()
9 |
10 | i = 5
11 | # WHILE iteration structure
12 |
13 | while i >= 0:
14 | print("While: {i}")
15 | i = i - 1
16 |
--------------------------------------------------------------------------------
/examples/print_and_input_ex.w:
--------------------------------------------------------------------------------
1 |
2 | # The `print` function allows displaying in the command line interface (CLI) a certain value
3 | # informed in the argument.
4 | print("Hi.")
5 |
6 | # The `input` function allows to obtain a textual value informed in the command line
7 | # interface (CLI), the function's return will always be a string.
8 | name = input("What is your name? ")
9 |
10 | # Displaying the string with the value 'Hello, ' along with the name given above.
11 | # In the example below, the string interpolation technique is used to include the name value.
12 | print("Hello, {name}")
13 |
14 | # Displays a line break.
15 | print()
16 |
17 | # In this case, the input function's return is cast from string to integer
18 | int a = input("Enter an integer: ")
19 | # or float in this case
20 | float b = input("Enter a number with decimal places: ")
21 |
22 | # Displaying the sum result.
23 | print("The sum of {a} + {b} = {a + b}")
24 |
--------------------------------------------------------------------------------
/examples/random_ex.w:
--------------------------------------------------------------------------------
1 |
2 | for C:
3 |
4 | import time
5 |
6 | srand(time(NULL))
7 |
8 | def float random_example(float begin = 0.0, float end = 0.0):
9 | float gen = rand() / RAND_MAX
10 | if begin != 0.0 or end != 0.0:
11 | gen = gen * (end - begin) + begin
12 | return gen
13 |
14 | def test_random_example(float begin, float end, int max_iteration = 100000):
15 | x = 0
16 | y = 0
17 | z = 0
18 | float k = []
19 | for i in 0..max_iteration:
20 | gen = random_example(begin = begin, end = end)
21 | if gen == begin:
22 | x += 1
23 | elif gen == end:
24 | y += 1
25 | else:
26 | z += 1
27 | k += gen
28 | print("max_iteration: {max_iteration == (x + y + z)}")
29 | print("x: {x} | Begin: {begin}")
30 | print("y: {y} | End: {end}")
31 | print("z: {z} | Interval: {begin}..{end}")
32 | #print("k: ", end='')
33 | #print(k)
34 | print()
35 |
36 | test_random_example(-5, 5)
37 |
--------------------------------------------------------------------------------
/examples/run_all_ex.w:
--------------------------------------------------------------------------------
1 | # File import example
2 |
3 | print("---------------------------------------------")
4 | print("# import callback_ex")
5 | import callback_ex
6 |
7 | print("---------------------------------------------")
8 | print("# import class_ex")
9 | import class_ex
10 |
11 | print("---------------------------------------------")
12 | print("# import conditionals_ex")
13 | import conditionals_ex
14 |
15 | #print("---------------------------------------------")
16 | #print("# import dict_ex")
17 | #import dict_ex
18 |
19 | print("---------------------------------------------")
20 | print("# import for_target_ex")
21 | import for_target_ex
22 |
23 | print("---------------------------------------------")
24 | print("# import functions_ex")
25 | import functions_ex
26 |
27 | #print("---------------------------------------------")
28 | #print("# import list_ex")
29 | #import list_ex
30 |
31 | print("---------------------------------------------")
32 | print("# import loops_ex")
33 | import loops_ex
34 |
35 | print("---------------------------------------------")
36 | print("# import variables_ex")
37 | import variables_ex
38 |
39 | print("---------------------------------------------")
40 | print("# import random_ex")
41 | import random_ex
42 |
43 | print("---------------------------------------------")
44 | print("# import print_and_input_ex")
45 | import print_and_input_ex
46 |
--------------------------------------------------------------------------------
/examples/test_ex.w:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/variables_ex.w:
--------------------------------------------------------------------------------
1 |
2 | # Variables in the photon language can be inferred or explicitly typed.
3 | #-----------------------------------------------------------------------------------------
4 | # Every variable contains three elements. Type, Name and Value. By default, Photon
5 | # tries to infer the type of the variable based on the assigned value.
6 |
7 | #-----------------------------------------------------------------------------------------
8 | # Type inference in action
9 | my_int = 1
10 | my_float = 3.1415
11 | my_string = "The name of this programming language is called Photon"
12 | my_int_array = [1, 2, 3]
13 | my_float_array = [1.1, 2.1, 3.1]
14 | my_str_array = ["My name", "is Johann"]
15 |
16 | print("Variables typed by inference:")
17 | print(my_int)
18 | print(my_float)
19 | print(my_string)
20 | print(my_int_array)
21 | print(my_float_array)
22 | print(my_str_array)
23 | print()
24 |
25 | #-----------------------------------------------------------------------------------------
26 | # Explicitly typed variables
27 |
28 | # Integer number
29 | int number_int = 1
30 |
31 | # Floating point number
32 | float number_real = 3.1415
33 |
34 | # String of characters
35 | str text = "The name of this programming language is called Photon"
36 |
37 | # Array of integers
38 | int array_int = []
39 | # Append elements on array of integers
40 | array_int += 1
41 | array_int += 2
42 | array_int += 3
43 |
44 | # Array of floats
45 | float array_float = []
46 | # Append elements on array of floats
47 | array_float += 1.1
48 | array_float += 2.1
49 | array_float += 3.1
50 |
51 | # Array of strings
52 | str array_str = []
53 | array_str += "My name"
54 | array_str += "is Johann"
55 |
56 | print("Variables explicitly typed:")
57 | print(number_int)
58 | print(number_real)
59 | print(text)
60 | print(array_int)
61 | print(array_float)
62 | print(array_str)
63 |
--------------------------------------------------------------------------------
/install.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | ''' Photon installer script. '''
4 |
5 | import os
6 | import sys
7 | from core.dependencies import haveDependencies, resolveDependencies
8 |
9 | PHOTON_PATH = os.path.join(os.path.dirname(__file__), 'core', 'photon.py')
10 |
11 | try:
12 | if sys.platform in {'linux', 'linux2', 'darwin'}:
13 | p_path = '/usr/local/bin/photon'
14 | try:
15 | os.remove(p_path)
16 | except FileNotFoundError:
17 | pass # Ensure the path does not exists.
18 | else:
19 | print('Removing and creating new symlink')
20 | os.symlink(PHOTON_PATH, p_path)
21 | os.chmod(PHOTON_PATH, 0o777)
22 | print(f'Photon Command Path: {p_path}')
23 | elif sys.platform in {'win32', 'cygwin', 'msys'} or os.name == "nt" or os.environ.get('OS', '') == 'Windows_NT':
24 | p_dir = os.path.expandvars('%ProgramFiles%\\Photon')
25 | if not os.path.exists(p_dir):
26 | os.mkdir(p_dir)
27 | with open(os.path.join(p_dir, 'photon.bat'), 'w', encoding='utf-8') as w:
28 | w.write(f'@echo off\npython "{PHOTON_PATH}" %*')
29 | if p_dir in os.environ.get("PATH"):
30 | print('Photon already on PATH, skipping')
31 | else:
32 | os.system(f'setx /M PATH "%PATH%;{p_dir}"')
33 | print(f'Photon Command Path: {os.path.join(p_dir, "photon")}')
34 | else:
35 | print('Automatic installation in this system is not supported yet.')
36 | sys.exit(1)
37 | except PermissionError:
38 | print('The installation failed due to lack of permissions.',
39 | 'Run the proper script for your operational system or try to execute this as super user/administrator',
40 | sep='\n')
41 | sys.exit(1)
42 |
43 | if not haveDependencies('c', sys.platform):
44 | resolveDependencies('c', sys.platform)
45 |
46 | print("Successfully installed! Now you can use the photon command!")
47 |
--------------------------------------------------------------------------------
/linuxInstaller.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | red='\033[0;31m'
3 | green='\033[0;32m'
4 | normal='\033[0m'
5 |
6 | printf "${green}Linux Installer - Photon${normal}\n"
7 |
8 | printf "Checking Photon dependencies...\n"
9 |
10 | installDeps="false";
11 |
12 | if ! command -v git &> /dev/null
13 | then
14 | echo "git could not be found"
15 | installDeps="true";
16 | else
17 | echo "You already have git installed."
18 | fi
19 | if ! command -v gcc &> /dev/null
20 | then
21 | echo "gcc could not be found"
22 | installDeps="true";
23 | else
24 | echo "You already have gcc installed."
25 | fi
26 | if ! command -v python3 &> /dev/null
27 | then
28 | echo "python3 could not be found"
29 | installDeps="true";
30 | else
31 | echo "You already have python3 installed."
32 | fi
33 |
34 | SUDO=''
35 | if [ $(id -u) -ne 0 ] ; then
36 | SUDO='sudo'
37 | fi
38 | if [ "$installDeps" == "true" ]; then
39 | echo "Preparing to install dependencies..."
40 |
41 |
42 | if [ -f '/etc/debian_version' ]; then
43 | $SUDO apt update && $SUDO apt install python3 build-essential git
44 | elif [ -f '/etc/arch-release' ]; then
45 | $SUDO pacman -Syy python gcc git glibc
46 | elif [ -f '/etc/gentoo-release' ]; then
47 | $SUDO emerge --sync && $SUDO emerge dev-lang/python sys-devel/gcc dev-vcs/git
48 | elif [ -f '/etc/SuSE-release' ]; then
49 | $SUDO zypper refresh && $SUDO zypper install python3 gcc git
50 | elif [ -f '/etc/redhat-release' ]; then
51 | ($SUDO dnf check-update && $SUDO dnf install python3 gcc git) ||
52 | ($SUDO yum check-update && $SUDO yum install python3 gcc git)
53 | elif [ "$(uname)" == "Darwin" ]; then
54 | if ! command -v brew &> /dev/null
55 | then
56 | echo "brew could not be found. Installing it..."
57 | $SUDO /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
58 | fi
59 | $SUDO brew install gcc git python3
60 | else
61 | printf "${red}Automatic installation in this system is not supported yet.\n${normal}"
62 | printf "Photon needs Python>=3.6, gcc and git on your PATH to work properly."
63 | exit 1
64 | fi
65 | fi
66 | echo "Dependencies installed. Installing Photon command-line interface..."
67 |
68 | SCRIPT=$(readlink -f "$0")
69 | SCRIPTPATH=$(dirname "$SCRIPT")
70 |
71 | if command -v python3; then
72 | $SUDO python3 "$SCRIPTPATH/install.py"
73 | elif command -v python; then
74 | $SUDO python "$SCRIPTPATH/install.py"
75 | else
76 | printf "${red}Was not possible to install Python >= 3.6, please do it manually\n${normal}"
77 | exit 1
78 | fi
79 |
80 |
--------------------------------------------------------------------------------
/tests/parserTest.py:
--------------------------------------------------------------------------------
1 | import sys, os
2 | sys.path.insert(1, os.path.pardir+'/core')
3 | from photonParser import parse
4 | from interpreter import Interpreter
5 | import unittest
6 |
7 | class ParserTest(unittest.TestCase):
8 | def runFile(self, file):
9 | i = Interpreter(os.path.pardir+'/tests/testFiles/'+file)
10 |
11 | nextLine = False
12 | while True:
13 | if not nextLine or i.line == '':
14 | i.line = i.input('>>> ')
15 | i.processing = True
16 | if i.line == 'exit' or not i.line:
17 | break
18 | tokenized = parse(i.line, filename=i.filename, no=i.lineNumber)
19 | struct, nextLine = i.handleTokenized(tokenized)
20 | return struct
21 |
22 | def test_printStr(self):
23 | struct = self.runFile('printFunc/printStr.w')
24 | self.assertEqual(struct['token'], 'printFunc')
25 | self.assertEqual(struct['expr']['args'][0], {'token':'str',
26 | 'type':'str', 'value':'"Hello World"', 'expressions':[]})
27 |
28 | def test_printInt(self):
29 | struct = self.runFile('printFunc/printInt.w')
30 | self.assertEqual(struct['token'], 'printFunc')
31 | self.assertEqual(struct['expr']['args'][0], {'token':'num', 'type':'int', 'value':'26'})
32 |
33 | def test_printFloat(self):
34 | struct = self.runFile('printFunc/printFloat.w')
35 | self.assertEqual(struct['token'], 'printFunc')
36 | self.assertEqual(struct['expr']['args'][0], {'token':'floatNumber','type':'float', 'value':'4.7'})
37 |
38 | def test_printFloatDot(self):
39 | struct = self.runFile('printFunc/printFloatDot.w')
40 | self.assertEqual(struct['token'], 'printFunc')
41 | self.assertEqual(struct['expr']['args'][0], {'token':'floatNumber','type':'float', 'value':'2.'})
42 |
43 | def test_printVar(self):
44 | struct = self.runFile('printFunc/printVar.w')
45 | self.assertEqual(struct['token'], 'printFunc')
46 | self.assertEqual(struct['expr']['args'][0]['name'], 'var')
47 |
48 | def test_varInitInt(self):
49 | struct = self.runFile('varInit/initInt.w')
50 | self.assertEqual(struct['token'], 'expr')
51 | self.assertEqual(struct['args'][0]['name'], 'a')
52 | self.assertEqual(struct['args'][0]['type'], 'int')
53 |
54 | def test_varInitFloat(self):
55 | struct = self.runFile('varInit/initFloat.w')
56 | self.assertEqual(struct['token'], 'expr')
57 | self.assertEqual(struct['args'][0]['name'], 'a')
58 | self.assertEqual(struct['args'][0]['type'], 'float')
59 |
60 | def test_varInitStr(self):
61 | struct = self.runFile('varInit/initStr.w')
62 | self.assertEqual(struct['token'], 'expr')
63 | self.assertEqual(struct['args'][0]['name'], 'a')
64 | self.assertEqual(struct['args'][0]['type'], 'str')
65 |
66 | def test_varInitClass(self):
67 | struct = self.runFile('varInit/initClass.w')
68 | self.assertEqual(struct['token'], 'expr')
69 | self.assertEqual(struct['args'][0]['name'], 'a')
70 | self.assertEqual(struct['args'][0]['type'], 'SomeClass')
71 |
72 | def test_varInitStrArray(self):
73 | struct = self.runFile('varInit/initStrArray.w')
74 | self.assertEqual(struct['token'], 'expr')
75 | self.assertEqual(struct['args'][0]['name'], 'array')
76 | self.assertEqual(struct['args'][0]['elementType'], 'str')
77 | self.assertEqual(struct['args'][0]['size'], '10')
78 |
79 | def test_varInitClassArray(self):
80 | struct = self.runFile('varInit/initClassArray.w')
81 | self.assertEqual(struct['token'], 'expr')
82 | self.assertEqual(struct['args'][0]['name'], 'array')
83 | self.assertEqual(struct['args'][0]['type'], 'array')
84 | self.assertEqual(struct['args'][0]['elementType'], 'SomeClass')
85 | self.assertEqual(struct['args'][0]['size'], '10')
86 |
87 | def test_varInitStrStrMap(self):
88 | struct = self.runFile('varInit/initStrStrMap.w')
89 | self.assertEqual(struct['token'], 'expr')
90 | self.assertEqual(struct['args'][0]['name'], 'var')
91 | self.assertEqual(struct['args'][0]['type'], 'map')
92 | self.assertEqual(struct['args'][0]['keyType'], 'str')
93 | self.assertEqual(struct['args'][0]['valType'], 'str')
94 |
95 | def test_varInitClassStrMap(self):
96 | struct = self.runFile('varInit/initClassStrMap.w')
97 | self.assertEqual(struct['token'], 'expr')
98 | self.assertEqual(struct['args'][0]['name'], 'var')
99 | self.assertEqual(struct['args'][0]['type'], 'map')
100 | self.assertEqual(struct['args'][0]['keyType'], 'SomeClass')
101 | self.assertEqual(struct['args'][0]['valType'], 'str')
102 |
103 | def test_varInitStrClassMap(self):
104 | struct = self.runFile('varInit/initStrClassMap.w')
105 | self.assertEqual(struct['token'], 'expr')
106 | self.assertEqual(struct['args'][0]['name'], 'var')
107 | self.assertEqual(struct['args'][0]['type'], 'map')
108 | self.assertEqual(struct['args'][0]['keyType'], 'str')
109 | self.assertEqual(struct['args'][0]['valType'], 'SomeClass')
110 |
111 | def test_assignImplicitInt(self):
112 | struct = self.runFile('assign/varEqualInt.w')
113 | self.assertEqual(struct['token'], 'assign')
114 | self.assertEqual(struct['target']['token'], 'var')
115 | self.assertEqual(struct['expr']['args'][0]['value'], '1')
116 | self.assertEqual(struct['expr']['args'][0]['type'], 'int')
117 |
118 | def test_assignExplicitInt(self):
119 | struct = self.runFile('assign/varEqualInt.w')
120 | self.assertEqual(struct['token'], 'assign')
121 | self.assertEqual(struct['target']['token'], 'var')
122 | self.assertEqual(struct['expr']['args'][0]['value'], '1')
123 | self.assertEqual(struct['expr']['args'][0]['type'], 'int')
124 |
125 | def test_assignExplicitFloatVarInt(self):
126 | struct = self.runFile('assign/floatVarEqualInt.w')
127 | self.assertEqual(struct['token'], 'assign')
128 | self.assertEqual(struct['target']['token'], 'var')
129 | self.assertEqual(struct['target']['type'], 'float')
130 | self.assertEqual(struct['expr']['args'][0]['value'], '4')
131 |
132 | def test_assignVarEqualExpr(self):
133 | struct = self.runFile('assign/varEqualExpr.w')
134 | self.assertEqual(struct['token'], 'assign')
135 | self.assertEqual(struct['target']['token'], 'var')
136 | self.assertEqual(struct['target']['type'], 'unknown')
137 | self.assertEqual(struct['expr']['args'][0]['value'], '1')
138 | self.assertEqual(struct['expr']['args'][1]['value'], '2')
139 | self.assertEqual(struct['expr']['ops'], ['+'])
140 |
141 | def test_assignVarEqualModifierExpr(self):
142 | struct = self.runFile('assign/varEqualModifierExpr.w')
143 | self.assertEqual(struct['token'], 'assign')
144 | self.assertEqual(struct['target']['token'], 'var')
145 | self.assertEqual(struct['target']['type'], 'unknown')
146 | self.assertEqual(struct['expr']['args'][0]['value'], '1')
147 | self.assertEqual(struct['expr']['args'][0]['modifier'], '-')
148 | self.assertEqual(struct['expr']['args'][1]['value'], '2')
149 | self.assertEqual(struct['expr']['args'][2]['value'], '6')
150 | self.assertEqual(struct['expr']['ops'], ['+','-'])
151 |
152 | def test_assignVarEqualExprGroup(self):
153 | struct = self.runFile('assign/varEqualExprGroup.w')
154 | self.assertEqual(struct['token'], 'assign')
155 | self.assertEqual(struct['target']['token'], 'var')
156 | self.assertEqual(struct['target']['type'], 'unknown')
157 | self.assertEqual(struct['expr']['ops'], ['+'])
158 | self.assertEqual(struct['expr']['args'][0]['expr']['args'][0]['value'], '1')
159 | self.assertEqual(struct['expr']['args'][0]['expr']['args'][1]['value'], '2')
160 | self.assertEqual(struct['expr']['args'][0]['expr']['ops'], ['+'])
161 | self.assertEqual(struct['expr']['args'][1]['value'], '5')
162 |
163 | def test_assignModifierWithVar(self):
164 | struct = self.runFile('assign/modifierWithVar.w')
165 | self.assertEqual(struct['token'], 'assign')
166 | self.assertEqual(struct['target']['token'], 'var')
167 | self.assertEqual(struct['target']['type'], 'unknown')
168 | self.assertEqual(struct['expr']['args'][0]['name'], 'b')
169 | self.assertEqual(struct['expr']['args'][0]['modifier'], '-')
170 | self.assertEqual(struct['expr']['args'][1]['value'], '1')
171 | self.assertEqual(struct['expr']['ops'], ['+'])
172 |
173 | def test_assignGroup(self):
174 | struct = self.runFile('assign/varEqualGroup.w')
175 | self.assertEqual(struct['token'], 'assign')
176 | self.assertEqual(struct['target']['token'], 'var')
177 | self.assertEqual(struct['target']['type'], 'unknown')
178 | self.assertEqual(struct['expr']['args'][0]['token'], 'group')
179 | self.assertEqual(struct['expr']['args'][0]['expr']['args'][0]['value'], '1')
180 | self.assertEqual(struct['expr']['args'][0]['expr']['args'][1]['value'], '2')
181 | self.assertEqual(struct['expr']['args'][0]['expr']['ops'], ['+'])
182 |
183 | def test_assignModifierGroup(self):
184 | struct = self.runFile('assign/varEqualModifierGroup.w')
185 | self.assertEqual(struct['token'], 'assign')
186 | self.assertEqual(struct['target']['token'], 'var')
187 | self.assertEqual(struct['target']['type'], 'unknown')
188 | self.assertEqual(struct['expr']['args'][0]['token'], 'group')
189 | self.assertEqual(struct['expr']['args'][0]['expr']['args'][0]['value'], '1')
190 | self.assertEqual(struct['expr']['args'][0]['expr']['args'][1]['value'], '2')
191 | self.assertEqual(struct['expr']['args'][0]['expr']['ops'], ['+'])
192 | self.assertEqual(struct['expr']['args'][0]['modifier'], '-')
193 |
194 | if __name__ == "__main__":
195 | unittest.main()
196 |
--------------------------------------------------------------------------------
/tests/testFiles/assign/floatVarEqualInt.w:
--------------------------------------------------------------------------------
1 | float var = 4
2 |
--------------------------------------------------------------------------------
/tests/testFiles/assign/intVarEqualInt.w:
--------------------------------------------------------------------------------
1 | int var = 1
2 |
--------------------------------------------------------------------------------
/tests/testFiles/assign/modifierWithVar.w:
--------------------------------------------------------------------------------
1 | a = -b + 1
2 |
--------------------------------------------------------------------------------
/tests/testFiles/assign/varEqualExpr.w:
--------------------------------------------------------------------------------
1 | a = 1 + 2
2 |
--------------------------------------------------------------------------------
/tests/testFiles/assign/varEqualExprGroup.w:
--------------------------------------------------------------------------------
1 | a = (1+2) + 5
2 |
--------------------------------------------------------------------------------
/tests/testFiles/assign/varEqualGroup.w:
--------------------------------------------------------------------------------
1 | a = (1+2)
2 |
--------------------------------------------------------------------------------
/tests/testFiles/assign/varEqualInt.w:
--------------------------------------------------------------------------------
1 | var = 1
2 |
--------------------------------------------------------------------------------
/tests/testFiles/assign/varEqualModifierExpr.w:
--------------------------------------------------------------------------------
1 | a = -1 + 2 - 6
2 |
--------------------------------------------------------------------------------
/tests/testFiles/assign/varEqualModifierGroup.w:
--------------------------------------------------------------------------------
1 | a = -(1+2)
2 |
--------------------------------------------------------------------------------
/tests/testFiles/printFunc/printFloat.w:
--------------------------------------------------------------------------------
1 | print(4.7)
2 |
--------------------------------------------------------------------------------
/tests/testFiles/printFunc/printFloatDot.w:
--------------------------------------------------------------------------------
1 | print(2.)
2 |
--------------------------------------------------------------------------------
/tests/testFiles/printFunc/printInt.w:
--------------------------------------------------------------------------------
1 | print(26)
2 |
--------------------------------------------------------------------------------
/tests/testFiles/printFunc/printStr.w:
--------------------------------------------------------------------------------
1 | print("Hello World")
2 |
--------------------------------------------------------------------------------
/tests/testFiles/printFunc/printVar.w:
--------------------------------------------------------------------------------
1 | var = 2
2 | print(var)
3 |
--------------------------------------------------------------------------------
/tests/testFiles/varInit/initClass.w:
--------------------------------------------------------------------------------
1 | SomeClass a
2 |
--------------------------------------------------------------------------------
/tests/testFiles/varInit/initClassArray.w:
--------------------------------------------------------------------------------
1 | SomeClass:10 array
2 |
--------------------------------------------------------------------------------
/tests/testFiles/varInit/initClassStrMap.w:
--------------------------------------------------------------------------------
1 | SomeClass:str var
2 |
--------------------------------------------------------------------------------
/tests/testFiles/varInit/initFloat.w:
--------------------------------------------------------------------------------
1 | float a
2 |
--------------------------------------------------------------------------------
/tests/testFiles/varInit/initInt.w:
--------------------------------------------------------------------------------
1 | int a
2 |
--------------------------------------------------------------------------------
/tests/testFiles/varInit/initStr.w:
--------------------------------------------------------------------------------
1 | str a
2 |
--------------------------------------------------------------------------------
/tests/testFiles/varInit/initStrArray.w:
--------------------------------------------------------------------------------
1 | str:10 array
2 |
--------------------------------------------------------------------------------
/tests/testFiles/varInit/initStrClassMap.w:
--------------------------------------------------------------------------------
1 | str:SomeClass var
2 |
--------------------------------------------------------------------------------
/tests/testFiles/varInit/initStrStrMap.w:
--------------------------------------------------------------------------------
1 | str:str var
2 |
--------------------------------------------------------------------------------
/tests/transpilersTest.py:
--------------------------------------------------------------------------------
1 | import sys, os
2 | sys.path.insert(1, os.path.pardir+'/core')
3 | from photonParser import parse
4 | from interpreter import Interpreter
5 | import unittest
6 | from subprocess import Popen, PIPE
7 |
8 | class TranspilersTest(unittest.TestCase):
9 | langs = ['c', 'py', 'js']
10 |
11 | def runFile(self, file, lang='c'):
12 | out = ''
13 | result = Popen(f'photon testFiles/{file} lang={lang}', shell=True, stdout=PIPE)
14 | for line in result.stdout:
15 | out += str(line, encoding='utf8').strip()
16 | sys.stdout.buffer.write(line)
17 | sys.stdout.buffer.flush()
18 | break
19 | result.stdout.close()
20 | result.wait()
21 | return out
22 |
23 | def checkFile(self, filename, result=None):
24 | for lang in self.langs:
25 | out = self.runFile(filename, lang=lang)
26 | if isinstance(result, int):
27 | self.assertEqual(int(out), result)
28 | elif isinstance(result, str):
29 | self.assertEqual(str(out), result)
30 | elif isinstance(result, float):
31 | self.assertAlmostEqual(float(out), result)
32 | else:
33 | raise NotImplemented
34 |
35 | def test_printInt(self):
36 | out = self.checkFile('printFunc/printInt.w', 26)
37 |
38 | def test_printFloat(self):
39 | self.checkFile('printFunc/printFloat.w', 4.7)
40 |
41 | def test_printFloatDot(self):
42 | self.checkFile('printFunc/printFloatDot.w', 2.0)
43 |
44 | def test_printStr(self):
45 | self.checkFile('printFunc/printStr.w', 'Hello World')
46 |
47 | def test_printVar(self):
48 | self.runFile('printFunc/printVar.w', 2)
49 |
50 | if __name__ == "__main__":
51 | unittest.main()
52 |
--------------------------------------------------------------------------------
/uninstall.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | local = '/usr/local/bin/photon'
4 |
5 | try:
6 | if os.path.isfile(local):
7 | print(f'Removing the file {local}.')
8 | os.remove(local)
9 | print('Successfully removed!')
10 |
11 | else:
12 | print("It has nothing to be removed!")
13 | except PermissionError:
14 | print(
15 | " Please run this script with the 'sudo' command\n",
16 | "Example:\n 'sudo python3 uninstall.py'")
17 |
--------------------------------------------------------------------------------
/windowsInstaller.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | title Windows Installer - Photon
3 | set mydir=%~dp0
4 | powershell -command "Start-Process powershell -Verb RunAs -PassThru -ArgumentList '-ExecutionPolicy RemoteSigned -NoProfile -File \"%mydir%\windowsInstaller.ps1\"'"
5 | timeout /t 3
6 | exit
7 |
--------------------------------------------------------------------------------
/windowsInstaller.ps1:
--------------------------------------------------------------------------------
1 | # $ErrorActionPreference = "Stop"
2 |
3 | $host.UI.RawUI.WindowTitle = "Windows Installer - Photon"
4 |
5 | if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator"))
6 | {
7 | echo "To install Photon, you need administrator privileges!"
8 | timeout /t 3
9 | exit
10 | }
11 |
12 | while ((Get-Command "choco.exe" -ErrorAction SilentlyContinue) -eq $null)
13 | {
14 | echo "Chocolatey was not found! Do you want to install it?"
15 | pause
16 | Set-ExecutionPolicy Bypass -Scope Process -Force
17 | [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
18 | iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
19 | $env:Path = "$env:Path;$env:AllUsersProfile\chocolatey\bin"
20 | }
21 |
22 | $dependencies = ""
23 | $show_dependencies = ""
24 |
25 | if (((Get-Command "python.exe" -ErrorAction SilentlyContinue) -eq $null) -or ((Get-Item (Get-Command "python.exe").Path).length -eq 0))
26 | {
27 | $dependencies = "python;"
28 | $show_dependencies = "python "
29 | }
30 |
31 | if ((Get-Command "gcc.exe" -ErrorAction SilentlyContinue) -eq $null)
32 | {
33 | $dependencies = "${dependencies}mingw;"
34 | $show_dependencies = "${show_dependencies}mingw "
35 | }
36 |
37 | if ((Get-Command "git.exe" -ErrorAction SilentlyContinue) -eq $null)
38 | {
39 | $dependencies = "${dependencies}git;"
40 | $show_dependencies = "${show_dependencies}git "
41 | }
42 |
43 | if ($dependencies -ne "")
44 | {
45 | echo "To use Photon, you need to install the following programs: ${show_dependencies}"
46 | pause
47 | choco install -y "$dependencies"
48 | }
49 | else
50 | {
51 | echo "The programs Photon needs are already installed!"
52 | }
53 |
54 | if ((Get-Command "python.exe" -ErrorAction SilentlyContinue) -ne $null)
55 | {
56 | cmd /c "refreshenv; python -m pip install pyreadline"
57 | $scriptPath = -join('"', (split-path -parent $MyInvocation.MyCommand.Definition), '"')
58 | echo "Installing Photon . . ."
59 | cmd /c "python ${scriptPath}\install.py"
60 | }
61 | else
62 | {
63 | echo "Python was not found!"
64 | }
65 |
66 | pause
67 |
--------------------------------------------------------------------------------