├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── BLOGS.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── images
├── components.png
├── issues-1.PNG
├── issues-2.PNG
├── logo.png
└── simc-pipeline.png
├── ins.sh
├── readme-lang
├── README-French.md
├── README-GER.md
├── README-ITA.md
├── README-RU.md
├── README-eng.md
└── README-pt.md
├── setup.py
├── simc-codes
├── .gitkeep
├── array-declaration.simc
├── char-input-test.simc
├── q1.simc
├── q10.simc
├── q100.simc
├── q102.simc
├── q103.simc
├── q104.simc
├── q105.simc
├── q106.simc
├── q107.simc
├── q108.simc
├── q109.simc
├── q110.simc
├── q112.simc
├── q113.simc
├── q114.simc
├── q12.simc
├── q13.simc
├── q14.simc
├── q15.simc
├── q17.simc
├── q18.simc
├── q19.simc
├── q2.simc
├── q20.simc
├── q201.simc
├── q22.simc
├── q23.simc
├── q24.simc
├── q25.simc
├── q26.simc
├── q27.simc
├── q28.simc
├── q29.simc
├── q3.simc
├── q30.simc
├── q31.simc
├── q32.simc
├── q33.simc
├── q34.simc
├── q35.simc
├── q36.simc
├── q37.simc
├── q38.simc
├── q39.simc
├── q4.simc
├── q40.simc
├── q41.simc
├── q42.simc
├── q43.simc
├── q44.simc
├── q45.simc
├── q46.simc
├── q47.simc
├── q48.simc
├── q49.simc
├── q5.simc
├── q51.simc
├── q52.simc
├── q53.simc
├── q54.simc
├── q55.simc
├── q56.simc
├── q57.simc
├── q58.simc
├── q59.simc
├── q6.simc
├── q60.simc
├── q61.simc
├── q64.simc
├── q65.simc
├── q66.simc
├── q67.simc
├── q68.simc
├── q69.simc
├── q7.simc
├── q70.simc
├── q71.simc
├── q72.simc
├── q73.simc
├── q74.simc
├── q75.simc
├── q76.simc
├── q77.simc
├── q78.simc
├── q79.simc
├── q80.simc
├── q81.simc
├── q82.simc
├── q83.simc
├── q84.simc
├── q85.simc
├── q86.simc
├── q87.simc
├── q88.simc
├── q9.simc
├── q90.simc
├── q92.simc
├── q93.simc
├── q94.simc
├── q95.simc
├── q96.simc
├── q97.simc
├── q98.simc
└── q99.simc
└── simc
├── __init__.py
├── compiler.py
├── global_helpers.py
├── lexical_analyzer.py
├── op_code.py
├── package-index
├── parser
├── __init__.py
├── array_parser.py
├── conditional_parser.py
├── function_parser.py
├── loop_parser.py
├── parser_constants.py
├── simc_parser.py
├── struct_parser.py
└── variable_parser.py
├── scope_resolve.py
├── simc.py
├── simpack.py
├── symbol_table.py
└── token_class.py
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | open_collective: sim-c
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG]"
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 |
12 | **Steps to Reproduce**
13 |
14 | **Expected behavior**
15 |
16 | **Screenshots (if any)**
17 |
18 | **Additional context (if any)**
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[FEATURE]"
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the feature and the solution**
11 |
12 | **Example code (if any**
13 |
14 | **Screenshots (if any)**
15 |
16 |
17 | **Note**: You can only start working on this issue if a maintainer approves of the feature.
18 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Closes #{Issue Number}
2 |
3 | **Implementation details**
4 |
5 | **Test Case 1**
6 |
7 | **simC Code**
8 |
9 | **C Code (If generated)**
10 |
11 | **Error message (If any)**
12 |
13 |
14 | NOTE:- You can add more test cases if you want
15 |
16 | Number of unit tests passing: [{Passing Unit Tests} / {Total Unit Tests}]
17 | Number of code tests passing: [{Passing Code Tests} / {Total Code Tests}]
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | .DS_Store
3 | *.pyc
4 | a.out
5 | a.exe
6 | build/*
7 | dist/*
8 | simc.spec
9 | .vscode
10 | simc.egg-info/*
11 | simc/modules/
--------------------------------------------------------------------------------
/BLOGS.md:
--------------------------------------------------------------------------------
1 | # KWoC 2020
2 |
3 | - Aryaman Kolhe - KWoC Project Report
4 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at cimplec.simc@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to simC
2 |
3 | ### Please star (⭐) the repository to show your support to the project.
4 |
5 | ## Pull Requests (PRs)
6 |
7 | - PR will be reviewed within a maximum of 72 hours of submitting the request.
8 | - The following rules are to be followed while submitting a PR:-
9 | - Branch Name: The name of the branch should start with 'in' followed by hyphen (-) and the issue number. Eg:- If you are working on issue number 57 then your branch name should be in-57. You need to make sure that in your fork you create a branch following this pattern.
10 | - Commit Message: Commit message should make sense, anyone should be able to get an idea of what changes were made in that particular commit. Irrelevant or inapporpriate commit messages are highly discouraged.
11 | - Docstrings: Docstrings are special comments in python which helps one to understand what a function or class does, the parameters passed, and the data returned from that function. We expect everyone to adhere to the format in your code. To get a better idea of the format of docstrings, please refer to the codebase.
12 | - Comments: The comments should be meaningful and one should be able to understand what the line(s) of code mean from the comments. Do not add unecessary comments in each line, leave out comments from code which is self-explanatory.
13 | - Variables: Variable names used in your code should explain what the variable is. Some unacceptable variable names are:- a, b, hello, world, etc. While creating variable name with multiple words in it, the words should be separated by underscore (_) e.g:- player_initial_energy and should not be written in camel case e.g- playerInitialEnergy.
14 | - Run tests: Run the tests using simC's test-suite and report the number of tests passing, if this is missing then the PR will be closed immediately.
15 | - Follow PR template: Fill all the details in PR template as it helps us understand the PR better, the PR will be closed if any mandatory field is found empty.
16 | - After successful submission of PR, it will be subjected to testing and if the code fails any of the tests you will be given a time period of 3 days to fix the issue, else your PR will be closed.
17 |
18 | ## New Issue (New feature or bug)
19 |
20 | - The time period for reviewing of a new issue is a maximum of 36 hours, you can expect to hear from a maintainer within this time frame.
21 | - The implementation of the new feature or fixing of the bug should only be started after a maintainer approves the feature or bug report in the discussion.
22 | - Once approved start implementing the feature or fix the bug and submit a pull request.
23 |
24 | Note:- The bug and feature issue rules mentioned above are for issues opened by an outside collaborator and not a core dev.
25 |
26 | ## Start Contributing
27 |
28 |
Go through simC's Wiki to get an in-depth understanding of simC.
29 |
30 | Three files are important for you when you start contributing to this project, you should have a rough idea of these files, the order is:-
31 |
32 | - [lexical_analyzer.py](https://github.com/cimplec/sim-c/blob/master/simc/lexical_analyzer.py)
33 | - [simc_parser.py](https://github.com/cimplec/sim-c/blob/master/simc/parser/simc_parser.py)
34 | - [compiler.py](https://github.com/cimplec/sim-c/blob/master/simc/compiler.py)
35 |
36 |
37 | ## Contributing
38 |
39 | To get started with simC follow the official documentation:- https://cimplec.github.io/docs/
40 |
41 | The following resources are a good place to get to know more about simC:-
42 |
43 | 1) Writing code in C? Simplify your life with sim-C Dev.to, Medium.
44 | 2) Getting Started with sim-C Dev.to, Medium.
45 |
46 | ## Unit Testing
47 |
48 | - Make sure you test your code using the test suite before you make a PR.
49 | - To test your code, the steps are as follows:-
50 | 1) Install sim-C test suite:-
51 | ```bash
52 | user@programmer~:$ pip install git+https://github.com/cimplec/test-suite
53 | ```
54 | 2) Run the tests
55 | ```bash
56 | user@programmer~:$ simc-test
57 | ```
58 | - If any test fails make sure to fix your code so that the error goes away.
59 |
60 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # sim-C
2 |
3 |
4 |
5 |
6 |
7 | [](https://github.com/cimplec/sim-c/blob/master/LICENSE)       
8 |
9 | ## What is sim-C?
10 |
11 | Often people have trouble programming in C (especially beginners) due to its low level syntax and unavailability of stable third party libraries. We present sim-C a high-level front end for C which creates a dynamically typed syntax for C. Users can write code in this high level syntax and then compile it to optimized C code. sim-C does not process the code and simply translates it to C thus, there is no possibility of the code running slowly. So, with sim-C users can write code faster using the high level syntax and at the same time be able to harness the power and speed of a C program.
12 |
13 | ## Pipeline
14 |
15 |
16 |
17 |
18 |
19 | ## Important links
20 |
21 | 1. Official documentation
22 | 2. simC Wiki
23 |
24 | ## New Developers
25 |
26 | New developers can join simC New Devs slack channel where they can get help from core developers on their issues, link to the slack channel - simC New Devs Slack
27 |
28 | ## OSS Programs
29 |
30 | 1) Hacktoberfest 2020
31 | 2) KWoC (Kharagpur Winter of Code) 2020
32 | 3) SWoC (Script Winter of Code) 2021
33 |
34 | ## Contributor blogs
35 |
36 | Follow this [link](https://github.com/cimplec/sim-c/blob/master/BLOGS.md) to read blogs written by contributors after completing various OSS programs.
37 |
38 | ## License
39 |
40 | sim-C is licensed under GNU General Public License (GPL) v3.0. [LICENSE](https://github.com/cimplec/sim-c/blob/master/LICENSE)
41 |
--------------------------------------------------------------------------------
/images/components.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cimplec/sim-c/64f96d92c5a58abeb7656160ab38c8386c0d3bc9/images/components.png
--------------------------------------------------------------------------------
/images/issues-1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cimplec/sim-c/64f96d92c5a58abeb7656160ab38c8386c0d3bc9/images/issues-1.PNG
--------------------------------------------------------------------------------
/images/issues-2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cimplec/sim-c/64f96d92c5a58abeb7656160ab38c8386c0d3bc9/images/issues-2.PNG
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cimplec/sim-c/64f96d92c5a58abeb7656160ab38c8386c0d3bc9/images/logo.png
--------------------------------------------------------------------------------
/images/simc-pipeline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cimplec/sim-c/64f96d92c5a58abeb7656160ab38c8386c0d3bc9/images/simc-pipeline.png
--------------------------------------------------------------------------------
/ins.sh:
--------------------------------------------------------------------------------
1 | pip uninstall simc -y
2 | python setup.py install
3 |
--------------------------------------------------------------------------------
/readme-lang/README-French.md:
--------------------------------------------------------------------------------
1 |
2 | # sim-C
3 |
4 |
5 |
6 |
7 |
8 | [](https://github.com/cimplec/sim-c/blob/master/LICENSE)    
9 |
10 | ## Qu'est-ce que sim-C?
11 |
12 | Souvent, les gens ont du mal à programmer en C (en particulier les débutants) en raison de sa syntaxe de bas niveau et de l'indisponibilité de bibliothèques tierces stables. Nous présentons sim-C un frontal de haut niveau pour C qui crée une syntaxe typée dynamiquement pour C. L'utilisateur peut écrire du code dans cette syntaxe de haut niveau, puis le compiler en code C optimisé. sim-C ne traite pas le code et le traduit simplement en C, il n'y a donc aucune possibilité que le code s'exécute lentement. Ainsi, avec sim-C, les utilisateurs peuvent écrire du code plus rapidement en utilisant la syntaxe de haut niveau et en même temps être en mesure d'exploiter la puissance et la vitesse d'un programme C. Faisons à nouveau C cool.
13 |
14 | ## Pipeline
15 |
16 |
17 |
18 |
19 |
20 | ## Commencer à contribuer
21 |
22 | sim-C qui a une base de code très intuitive, vous serez prêt à contribuer en un rien de temps! Lors de l'ajout de fonctionnalités à sim-C, vous devez uniquement apporter des modifications aux fichiers suivants:
23 |
24 | 1. lexical_analyzer.py
25 | L'analyse lexicale est la première phase d'un compilateur. Il prend le code source modifié des préprocesseurs de langage qui sont écrits sous forme de phrases. L'analyseur lexical décompose ces syntaxes en une série de jetons, en supprimant tout espace ou commentaire dans le code source. Selon le type de fonctionnalité, ajoutez-le à la fonction respective: is_keyword, numeric_val, string_val, keyword_identifier et / ou lexical_analyze.
26 |
27 | 2. op_code.py
28 | Il est responsable de la création des opcodes. Si besoin est, vous devez modifier uniquement la fonction opcode2dig qui renvoie la représentation entière du type opcode.
29 |
30 | 3. simc_parser.py
31 | Parser est un composant interpréteur utilisé pour diviser les données en éléments plus petits provenant de la phase d'analyse lexicale. Un analyseur prend l'entrée sous la forme d'une séquence de jetons et produit une sortie. Ici, vous devrez peut-être créer une fonction distincte qui définit la grammaire et vérifie la syntaxe. La fonction doit renvoyer l'OpCode. De plus, si nécessaire, vous devez ajouter la fonctionnalité à la fonction d'analyse qui analyse les jetons, appelle la fonction particulière et renvoie les opcodes.
32 |
33 | 4. compiler.py
34 | Enfin, vous devez définir le type d'opcode dans le compilateur et écrire la syntaxe C attendue pour la fonctionnalité.
35 |
36 | Vous pouvez écrire un test dans test.simc et vérifier s'il produit des résultats dans le fichier test.c.
37 |
38 |
39 | ## Commencer
40 |
41 | Pour démarrer avec simC suivez la documentation officielle: - https://cimplec.github.io/docs/
42 |
43 | Les ressources suivantes sont un bon endroit pour en savoir plus sur simC: -
44 |
45 | 1) Écrire du code en C? Simplifiez-vous la vie avec sim-C Dev.to, Medium.
46 | 2) Premiers pas avec sim-C Dev.to, Medium.
47 |
48 | En dehors de ces articles de blog, vous pouvez également consulter le documents officiels.
49 |
50 | Avant d'aller plus loin, veuillez parcourir les règles dans [CONTRIBUTING.md](../CONTRIBUTING.md)
51 |
52 | ## Licence
53 |
54 | sim-C est sous licence GNU General Public License (GPL) v3.0. [LICENCE](../LICENSE)
55 |
56 | ## L'équipe
57 |
58 | - [Siddhartha Dhar Choudhury](https://github.com/frankhart2018)
59 | - [Dhairya Jain](https://github.com/dhairyaj)
60 | - [Mathias Fernandes Duarte Coelho](https://github.com/Math-O5)
61 |
--------------------------------------------------------------------------------
/readme-lang/README-GER.md:
--------------------------------------------------------------------------------
1 | # sim-C
2 |
3 |
4 |
5 |
6 |
7 | [](https://github.com/cimplec/sim-c/blob/master/LICENSE)    
8 |
9 | ## Was ist sim-C?
10 |
11 | Häufig haben Menschen (insbesondere Anfänger) Probleme beim Programmieren in C aufgrund der Syntax auf niedriger Ebene und der Nichtverfügbarkeit von stabilen Bibliotheken von Drittanbietern. Wir stellen sim-C ein High-Level-Frontend für C vor, das eine dynamisch typisierte Syntax für C erzeugt. Der Benutzer kann Code in dieser High-Level-Syntax schreiben und ihn dann zu optimiertem C-Code kompilieren. sim-C verarbeitet den Code nicht und übersetzt ihn einfach in C, so dass es keine Möglichkeit gibt, dass der Code langsam läuft. Mit sim-C können Benutzer also unter Verwendung der High-Level-Syntax schneller Code schreiben und gleichzeitig die Leistung und Geschwindigkeit eines C-Programms nutzen. Lassen Sie uns C wieder kühl machen.
12 |
13 | ## Die Pipeline
14 |
15 |
16 |
17 |
18 |
19 | ## Mit dem Beitragen beginnen
20 |
21 | sim-C, das über eine sehr intuitive Codebasis verfügt, werden Sie im Handumdrehen bereit sein, einen Beitrag zu leisten!
22 | Beim Hinzufügen jeglicher Funktionalität zu sim-C müssen Sie nur in den folgenden Dateien Änderungen vornehmen:
23 |
24 | 1. lexical_analyzer.py
25 | Die lexikalische Analyse ist die erste Phase eines Compilers. Sie übernimmt den modifizierten Quellcode von Sprachpräprozessoren, die in Form von Sätzen geschrieben werden. Der lexikalische Analysator zerlegt diese Syntaxen in eine Reihe von Token, indem er alle Leerzeichen oder Kommentare im Quellcode entfernt. Je nach Art der Funktionalität fügen Sie diese der jeweiligen Funktion hinzu: is_Schlüsselwort, numeric_val, string_val, keyword_identifier und/oder lexical_analyze.
26 |
27 | 2. op_code.py
28 | Sie ist für die Erstellung von Opcodes zuständig. Gegebenenfalls müssen Sie nur die Funktion opcode2dig ändern, die die ganzzahlige Darstellung des Opcode-Typs zurückgibt.
29 |
30 | 3. simc_parser.py
31 | Der Parser ist eine Interpreterkomponente, die verwendet wird, um die Daten in kleinere Elemente zu zerlegen, die aus der lexikalischen Analysephase stammen. Ein Parser nimmt Eingaben in Form einer Folge von Token entgegen und erzeugt Ausgaben. Hier kann es erforderlich sein, eine separate Funktion zu erstellen, die die Grammatik definiert und auf die Syntax prüft. Die Funktion sollte den OpCode zurückgeben. Gegebenenfalls müssen Sie auch die Funktionalität an die Parser-Funktion anhängen, die die Token parst, die jeweilige Funktion aufruft und den OpCode zurückgibt.
32 |
33 | 4. compiler.py
34 | Schließlich müssen Sie den Opcode-Typ im Compiler definieren und die erwartete C-Syntax für die Funktionalität schreiben.
35 |
36 | Sie können einen Test in test.simc schreiben und in der Datei test.c überprüfen, ob er Ergebnisse liefert.
37 |
38 |
39 | ## Beginnen Sie
40 |
41 | Um mit simC zu beginnen, folgen Sie der offiziellen Dokumentation:- https://cimplec.github.io/docs/
42 |
43 | Die folgenden Ressourcen sind ein guter Ort, um mehr über simC zu erfahren:-
44 |
45 | 1) Schreiben von Code in C? Vereinfachen Sie Ihr Leben mit sim-C Dev.to, Medium.
46 | 2) Erste Schritte mit sim-C Dev.to, Medium.
47 |
48 | Abgesehen von diesen Blog-Einträgen können Sie auch die offizielle Dokumente.
49 |
50 | Bevor Sie weitergehen, gehen Sie bitte die Regeln in [CONTRIBUTING.md](../CONTRIBUTING.md)
51 |
52 | ## Lizenz
53 |
54 | sim-C ist unter der GNU General Public License (GPL) v3.0 lizenziert. [LIZENZ](../LICENSE)
55 |
56 | ## Das Team
57 |
58 | - [Siddhartha Dhar Choudhury](https://github.com/frankhart2018)
59 | - [Dhairya Jain](https://github.com/dhairyaj)
60 | - [Mathias Fernandes Duarte Coelho](https://github.com/Math-O5)
61 |
--------------------------------------------------------------------------------
/readme-lang/README-ITA.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # sim-C
4 |
5 |
6 |
7 |
8 |
9 | [](https://github.com/cimplec/sim-c/blob/master/LICENSE)    
10 |
11 | ## Cos'è simC?
12 |
13 | Spesso le persone hanno problemi a programmare in C (specialmente i principianti) a causa della sua sintassi di basso livello e dell'indisponibilità di librerie di terze parti stabili. Presentiamo sim-C un front-end di alto livello per C che crea una sintassi tipizzata dinamicamente per C. L'utente può scrivere codice in questa sintassi di alto livello e quindi compilarlo in codice C ottimizzato. sim-C non elabora il codice e lo traduce semplicemente in C, quindi non c'è possibilità che il codice funzioni lentamente. Quindi, con sim-C gli utenti possono scrivere codice più velocemente utilizzando la sintassi di alto livello e allo stesso tempo essere in grado di sfruttare la potenza e la velocità di un programma C. Facciamo raffreddare di nuovo C.
14 |
15 | ## Tubatura
16 |
17 |
18 |
19 |
20 |
21 | ## Inizia a contribuire
22 | sim-C che ha una base di codice molto intuitiva, sarai pronto a contribuire in pochissimo tempo!
23 | Durante l'aggiunta di qualsiasi funzionalità a sim-C è necessario apportare modifiche solo ai seguenti file:
24 |
25 | 1. lexical_analyzer.py
26 | L'analisi lessicale è la prima fase di un compilatore. Prende il codice sorgente modificato dai preprocessori del linguaggio scritti sotto forma di frasi. L'analizzatore lessicale suddivide queste sintassi in una serie di token, rimuovendo eventuali spazi o commenti nel codice sorgente. A seconda del tipo di funzionalità aggiungilo alla rispettiva funzione: is_keyword, numeric_val, string_val, keyword_identifier e / o lexical_analyze.
27 |
28 | 2. op_code.py
29 | È responsabile della creazione di codici operativi. Se necessario, è necessario modificare solo la funzione opcode2dig che restituisce la rappresentazione intera del tipo di codice operativo.
30 |
31 | 3. simc_parser.py
32 | Parser è un componente interprete che viene utilizzato per suddividere i dati in elementi più piccoli provenienti dalla fase di analisi lessicale.Un parser prende l'input sotto forma di sequenza di token e produce output. Qui potrebbe essere necessario creare una funzione separata che definisce la grammatica e controlla la sintassi. La funzione dovrebbe restituire l'OpCode. Inoltre, se necessario, devi aggiungere la funzionalità alla funzione di analisi che analizza i token, chiama la particolare funzione e restituisce gli opcode.
33 |
34 | 4. compiler.py
35 | Infine è necessario definire il tipo di codice operativo nel compilatore e scrivere la sintassi C prevista per la funzionalità.
36 |
37 | Puoi scrivere un test in test.simc e verificare se sta producendo risultati nel file test.c.
38 |
39 |
40 | ## Iniziare
41 |
42 | Per iniziare con simC segui la documentazione ufficiale:-
43 | https://cimplec.github.io/docs/
44 |
45 | Le seguenti risorse sono un buon posto per conoscere meglio simC: -
46 |
47 | 1) Scrivi codice in C? Semplifica la tua vita con sim-C Dev.to, Medium.
48 | 2) Iniziare con sim-C Dev.to, Medium.
49 |
50 | Oltre a questi post del blog, puoi anche consultare i documenti ufficiali .
51 |
52 | Prima di procedere oltre, leggi le regole in [CONTRIBUTING.md](../CONTRIBUTING.md)
53 |
54 | ## Licenza
55 |
56 | sim-C è concesso in licenza con GNU General Public License (GPL) v3.0. [LICENSE](../LICENSE)
57 |
58 | ## Il gruppo
59 |
60 | - [Siddhartha Dhar Choudhury](https://github.com/frankhart2018)
61 | - [Dhairya Jain](https://github.com/dhairyaj)
62 | - [Mathias Fernandes Duarte Coelho](https://github.com/Math-O5)
63 |
--------------------------------------------------------------------------------
/readme-lang/README-RU.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # sim-C
4 |
5 |
6 |
7 |
8 |
9 | [](https://github.com/cimplec/sim-c/blob/master/LICENSE)    
10 |
11 | ## Что такое sim-C?
12 |
13 | Часто люди (особенно новички) испытывают проблемы с программированием на C из-за его синтаксиса низкого уровня и недоступности стабильных сторонних библиотек. Мы представляем sim-C как высокоуровневый интерфейс для C, который создает динамически типизированный синтаксис для C. Пользователь может писать код в этом синтаксисе высокого уровня, а затем компилировать его в оптимизированный код C. sim-C не обрабатывает код, а просто переводит его на C, поэтому нет возможности, что код будет работать медленно. Таким образом, с помощью sim-C пользователи могут писать код быстрее, используя синтаксис высокого уровня, и в то же время иметь возможность использовать мощность и скорость программы C. Давайте снова заставим C остыть.
14 |
15 | ## Трубопровод
16 |
17 |
18 |
19 |
20 |
21 | ## Начать участие
22 |
23 | sim-C с интуитивно понятной кодовой базой, вы будете готовы внести свой вклад в кратчайшие сроки!
24 | При добавлении каких-либо функций в sim-C вам необходимо внести изменения только в следующие файлы:
25 |
26 | 1. lexical_analyzer.py
27 | Лексический анализ - это первая фаза компилятора. Он берет модифицированный исходный код из языковых препроцессоров, которые записываются в форме предложений. Лексический анализатор разбивает эти синтаксисы на серию токенов, удаляя любые пробелы или комментарии в исходном коде. В зависимости от типа функциональности добавьте его к соответствующей функции: is_keyword, numeric_val, string_val, keyword_identifier и / или lexical_analyze.
28 |
29 | 2. op_code.py
30 | Он отвечает за создание кодов операций. При необходимости вам нужно изменить только функцию opcode2dig, которая возвращает целочисленное представление типа кода операции.
31 |
32 | 3. simc_parser.py
33 | Синтаксический анализатор - это компонент интерпретатора, который используется для разбиения данных на более мелкие элементы, поступающие на этапе лексического анализа. Парсер принимает входные данные в виде последовательности токенов и производит выходные данные. Здесь вам может потребоваться создать отдельную функцию, которая определяет грамматику и проверяет синтаксис. Функция должна вернуть OpCode. Кроме того, при необходимости вы должны добавить функциональность к функции синтаксического анализа, которая анализирует токены, вызывает конкретную функцию и возвращает коды операций.
34 |
35 | 4. compiler.py
36 | Наконец, вам нужно определить тип кода операции в компиляторе и написать ожидаемый синтаксис C для функциональности.
37 |
38 | Вы можете написать тест в test.simc и проверить, дает ли он результаты в файле test.c.
39 |
40 |
41 | ## Начать
42 |
43 | Чтобы начать работу с simC, следуйте официальной документации: - https://cimplec.github.io/docs/
44 |
45 | Следующие ресурсы - хорошее место, чтобы узнать больше о simC: -
46 |
47 | 1) Написание кода на C? Упростите свою жизнь с помощью sim-C Dev.to , Средний .
48 | 2) Начало работы с sim-C Dev.to , Средний.
49 |
50 | Помимо этих сообщений в блоге, вы также можете ознакомиться с официальными документами .
51 |
52 | Прежде чем двигаться дальше, ознакомьтесь с правилами на [CONTRIBUTING.md](../CONTRIBUTING.md)
53 |
54 | ## Лицензия
55 |
56 | sim-C находится под лицензией GNU General Public License (GPL) v3.0. [ЛИЦЕНЗИЯ](../LICENSE)
57 |
58 | ## Команда
59 |
60 | - [Siddhartha Dhar Choudhury](https://github.com/frankhart2018)
61 | - [Dhairya Jain](https://github.com/dhairyaj)
62 | - [Mathias Fernandes Duarte Coelho](https://github.com/Math-O5)
63 |
--------------------------------------------------------------------------------
/readme-lang/README-eng.md:
--------------------------------------------------------------------------------
1 |
2 | # sim-C
3 |
4 |
5 |
6 |
7 |
8 | [](https://github.com/cimplec/sim-c/blob/master/LICENSE)    
9 |
10 | ## What is sim-C?
11 |
12 | Often people have trouble programming in C (especially beginners) due to its low level syntax and unavailability of stable third party libraries. We present sim-C a high-level front end for C which creates a dynamically typed syntax for C. User can write code in this high level syntax and then compile it to optimized C code. sim-C does not process the code and simply translates it to C thus, there is no possibility of the code running slowly. So, with sim-C users can write code faster using the high level syntax and at the same time be able to harness the power and speed of a C program. Let us make C cool again.
13 |
14 | ## Pipeline
15 |
16 |
17 |
18 |
19 |
20 | ## Start Contributing
21 |
22 | sim-C which has a highly intuitive codebase, you'll be ready to contribute in no time!
23 | While adding any functionality to sim-C you need to make changes in the following files only:
24 |
25 | 1. lexical_analyzer.py
26 | Lexical analysis is the first phase of a compiler. It takes the modified source code from language preprocessors that are written in the form of sentences. The lexical analyzer breaks these syntaxes into a series of tokens, by removing any whitespace or comments in the source code. Depending on the type of functionality add it to the respective function: is_keyword, numeric_val, string_val, keyword_identifier and/or lexical_analyze.
27 |
28 | 2. op_code.py
29 | It is responsible for creating opcodes. If need be you need to change the opcode2dig function only which returns the integer representation of opcode type.
30 |
31 | 3. simc_parser.py
32 | Parser is an interpreter component that is used to break the data into smaller elements coming from lexical analysis phase. A parser takes input in the form of sequence of tokens and produces output. Here you may need to create a separate function which defines the grammar and checks for the syntax. The function should return the OpCode. Also, if need be you have to append the functionality to the parse function which parses the tokens, calls the particular function and returns opcodes.
33 |
34 | 4. compiler.py
35 | Finally you need to define the opcode type in the compiler and write the expected C syntax for the functonality.
36 |
37 | You can write a test in test.simc and verify whether it's producing results in the test.c file.
38 |
39 |
40 | ## Get started
41 |
42 | To get started with simC follow the official documentation:- https://cimplec.github.io/docs/
43 |
44 | The following resources are a good place to get to know more about simC:-
45 |
46 | 1) Writing code in C? Simplify your life with sim-C Dev.to, Medium.
47 | 2) Getting Started with sim-C Dev.to, Medium.
48 |
49 | Apart from these blog posts, you can also checkout the official docs.
50 |
51 | Before moving further please go through the rules in [CONTRIBUTING.md](../CONTRIBUTING.md)
52 |
53 | ## License
54 |
55 | sim-C is licensed under GNU General Public License (GPL) v3.0. [LICENSE](../LICENSE)
56 |
57 | ## The Team
58 |
59 | - [Siddhartha Dhar Choudhury](https://github.com/frankhart2018)
60 | - [Dhairya Jain](https://github.com/dhairyaj)
61 | - [Mathias Fernandes Duarte Coelho](https://github.com/Math-O5)
62 |
--------------------------------------------------------------------------------
/readme-lang/README-pt.md:
--------------------------------------------------------------------------------
1 |
2 | # sim-C
3 |
4 |
5 |
6 |
7 |
8 | [](https://github.com/cimplec/sim-c/blob/master/LICENSE)    
9 |
10 | ## O que é sim-C?
11 |
12 | Muitas vezes as pessoas têm problemas para programar em C (especialmente iniciantes) devido à sua sintaxe de baixo nível e indisponibilidade de bibliotecas externas. Nós apresentamos sim-C, um *front end* de alto nível para C que cria uma sintaxe *dynamically typed* para C. O utlizador pode escrever código nesta sintaxe de alto nível e depois compliar para código C otimizado. sim-C não processa o código e o simplesmente traduz para C portanto, não é possível que o código seja lento. Por isso, com sim-C os utilizadores podem escrever código rapidamente usando a sintaxe de alto nível e ao mesmo tempo ser capazes de aproveitar a potência e velocidade de um programa de C. Deixa-nos fazer C fixe outra vez.
13 |
14 | ## Pipeline
15 |
16 |
17 |
18 |
19 |
20 | ## Começa a Contribuir
21 |
22 | sim-C tem uma base de código muito intuitiva, estarás pronto a contribuir num instante!
23 | Enquanto adicionas funcionalidades ao sim-C precisas de fazer alterações apenas nos seguintes ficheiros:
24 |
25 | 1. lexical_analyzer.py
26 | Análise lexical é a primeira fase do compilador. Pega no código fonte modificado dos processadores de linguagem que estão escritos na forma de frases. O analisador lexical separa estas sintaxes em séries de *tokens*, removendo espaços ou comentários no código fonte. Dependendo do tipo de funcionalidade adiciona-a à respetiva função: is_keyword, numeric_val, string_val, keyword_identifier e/ou lexical_analyze.
27 |
28 | 2. op_code.py
29 | É responsável por criar *opcodes*. Se necessário, precisas de alterar apenas a função opcode2dig, que retorna a representação inteira do topo de *opcode*
30 |
31 | 3. simc_parser.py
32 | O analisador é uma componente do interpretador que é usado para separar informação em elementos mais pequenos vindos da fase da análise lexical. Um analisador recebe *input* na forma de uma sequência de *tokens* e produz um resultado. Aqui pode ser preciso criar uma função separada que defina a gramática e que verifique a sintaxe. A função deve retornar o *opcode*. Além disto, se necessário, deves anexar a funcionalidade à função parse que analisa os *tokens*, chama a função pretendida e returna os *opcodes*.
33 |
34 | 4. compiler.py
35 | Finalmente, tens de definir o tipo de *opcode* no compilador e escrever a sintaxe experada em C para a funcionalidade.
36 |
37 | Você pode escrever testes em test.simc e verificar se está a produzir resultados no ficheiro test.c
38 |
39 |
40 | ## Começar
41 |
42 | Para começar com simC segue a documentação oficial:- https://cimplec.github.io/docs/
43 |
44 | Os seguintes recursos são um bom sítio para conhecer melhor simC:-
45 |
46 | 1) Escreves código em C? Simplifica a tua vida com sim-C Dev.to, Medium.
47 | 2) Começar com sim-C Dev.to, Medium.
48 |
49 | Além destas publicações em blogs, podes verificar os documentos oficiais.
50 |
51 | Antes de continuares, por favor lê as regras em [CONTRIBUTING.md](../CONTRIBUTING.md)
52 |
53 | ## Licença
54 |
55 | sim-C tem uma lincença GNU General Public License (GPL) v3.0. [LICENSE](../LICENSE)
56 |
57 | ## A Equipa
58 |
59 | - [Siddhartha Dhar Choudhury](https://github.com/frankhart2018)
60 | - [Dhairya Jain](https://github.com/dhairyaj)
61 | - [Mathias Fernandes Duarte Coelho](https://github.com/Math-O5)
62 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import os
2 | import codecs
3 | import pathlib
4 | from setuptools import setup, find_packages
5 |
6 | # The directory containing this file
7 | HERE = pathlib.Path(__file__).parent
8 |
9 | # The text of the README file
10 | README = (HERE / "README.md").read_text()
11 |
12 |
13 | def read(rel_path):
14 | here = os.path.abspath(os.path.dirname(__file__))
15 | with codecs.open(os.path.join(here, rel_path), "r") as fp:
16 | return fp.read()
17 |
18 |
19 | def get_version(rel_path):
20 | for line in read(rel_path).splitlines():
21 | if line.startswith("__version__"):
22 | delim = '"' if '"' in line else "'"
23 | return line.split(delim)[1]
24 | else:
25 | raise RuntimeError("Unable to find version string.")
26 |
27 |
28 | # This call to setup() does all the work
29 | setup(
30 | name="simc",
31 | version=get_version("simc/__init__.py"),
32 | description="A dynamically typed high-level front end for C",
33 | long_description=README,
34 | long_description_content_type="text/markdown",
35 | url="https://github.com/cimplec/simc",
36 | author="Siddhartha Dhar Choudhury",
37 | author_email="sdharchou@gmail.com",
38 | license="GNU General Public License v3",
39 | packages=find_packages(),
40 | entry_points={
41 | "console_scripts": [
42 | "simc = simc.simc:run",
43 | "simpack = simc.simpack:get_package",
44 | ]
45 | },
46 | package_data={"simc": ["package-index"]},
47 | install_requires=["requests"],
48 | classifiers=[
49 | "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
50 | "Programming Language :: Python :: 3",
51 | "Programming Language :: Python :: 3.9",
52 | "Programming Language :: Python :: 3.8",
53 | "Programming Language :: Python :: 3.7",
54 | "Programming Language :: Python :: 3.6",
55 | ],
56 | )
57 |
--------------------------------------------------------------------------------
/simc-codes/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cimplec/sim-c/64f96d92c5a58abeb7656160ab38c8386c0d3bc9/simc-codes/.gitkeep
--------------------------------------------------------------------------------
/simc-codes/array-declaration.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var name[3] = {1,2,3}
3 | END_MAIN
4 |
--------------------------------------------------------------------------------
/simc-codes/char-input-test.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var c = input("Enter a character: ","c")
3 | print(c)
4 | END_MAIN
5 |
--------------------------------------------------------------------------------
/simc-codes/q1.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var my_string = "Hello SimC!"
3 | print("My cool string is : {my_string}")
4 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q10.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | //right upper triangle pattern
3 |
4 | var rows = 5
5 | var i = 0
6 | var j = 0
7 | while(i<=rows)
8 | {
9 | j = 0
10 |
11 | //printing empty space
12 | while(j=ctr)
10 | {
11 | x = ctr*ctr
12 | sum = sum + x
13 | print (x)
14 | print (" ")
15 | ctr = ctr + 1
16 | }
17 | print("The sum is : {sum}")
18 |
19 | END_MAIN
20 |
--------------------------------------------------------------------------------
/simc-codes/q110.simc:
--------------------------------------------------------------------------------
1 | // Print sum of numbers divisible by 9 from 100 to 200
2 |
3 | MAIN
4 |
5 | var sum=0
6 | var num=0
7 | var x=100
8 |
9 | while(x<=200)
10 | {
11 | if(x%9==0)
12 | {
13 | sum = sum + x
14 | num = num + 1
15 | }
16 | x = x + 1
17 | }
18 | print("The sum is : {sum} \n")
19 | print("The number of such numbers is : {num}")
20 |
21 | END_MAIN
22 |
--------------------------------------------------------------------------------
/simc-codes/q112.simc:
--------------------------------------------------------------------------------
1 | fun area_circumcircle_square( side ) {
2 | return 3.14159 * side * side / 2
3 | }
4 | MAIN
5 | var sideLength = input( "Enter side length: ", "f" )
6 | var answer = area_circumcircle_square( sideLength )
7 | print( "Area of the given Square's Circumcircle: {answer}" )
8 |
9 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q113.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var rad = 0.06
3 | var h = 0.21
4 | var vol = PI*rad*rad*h
5 | print("The volume of the cylinder with radius 6cm and height 21cm is : {vol} cubic metres")
6 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q114.simc:
--------------------------------------------------------------------------------
1 | //If a metal cube of side 3m is melted to make small balls, find the number of balls formed if each ball has a radius of 1.5cm
2 | MAIN
3 | var vol1 = 3*3*3
4 | var vol2 = 4/3 * PI * ((1.5/100)*(1.5/100)*(1.5/100))
5 | var number_of_balls = vol1/vol2
6 | print("The number of balls formed are: {number_of_balls}")
7 | END_MAIN
8 |
--------------------------------------------------------------------------------
/simc-codes/q12.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var n = 3
3 | var i = 0
4 | var j = 0
5 | while(i0){
5 | sum = sum + n % 10
6 | n= n/10
7 | }
8 | print("{sum} is the Sum of the digits.")
9 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q14.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var side = 4
3 | var perimeter = 4 * side
4 | print("The perimeter of square of length {side} = {perimeter}")
5 | END_MAIN
6 |
--------------------------------------------------------------------------------
/simc-codes/q15.simc:
--------------------------------------------------------------------------------
1 | //Compute perimeter of a rectangle
2 | MAIN
3 | var width = 5
4 | var length = 7
5 | var perimeter = 2*(length + width)
6 | print("Perimeter = {perimeter}")
7 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q17.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Multiply the digits of a number together
3 | var num = input("Enter a number: ", "i")
4 | var result = 1
5 | var temp = num
6 | if (num == 0) { // Manage the special case if the user enters 0
7 | result = 0
8 | }
9 | while (temp > 0) {
10 | result = result * (temp % 10)
11 | temp = temp / 10
12 | }
13 | print("If you multiply all of the digits in ")
14 | print(num)
15 | print(", you get ")
16 | print(result)
17 | print("\n")
18 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q18.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Check if the number is a palindrome
3 | var num = input("Enter a number: ", "i")
4 | var temp1 = num
5 | var temp2 = 0
6 | while (num > 0) {
7 | temp2 = temp2 * 10 + (num % 10)
8 | num = num / 10
9 | }
10 |
11 | if(temp1 == temp2) {
12 | print("Number is palindrome ")
13 | }
14 | else {
15 | print("Number is not a palindrome")
16 | }
17 | END_MAIN
18 |
--------------------------------------------------------------------------------
/simc-codes/q19.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Convert a binary number to a decimal number
3 |
4 | // Read in the binary number and count its digits
5 | var num = input("Enter a binary number: ", "i")
6 | var digs = 0
7 | var tmp = num
8 | while (tmp > 0) {
9 | digs = digs+1
10 | tmp = tmp/10
11 | }
12 |
13 | // Generate the binary result
14 | var val = 1
15 | var result = 0
16 | tmp = num
17 | while (tmp > 0) {
18 | if (tmp % 10 > 0) {
19 | result = result + val
20 | }
21 | val = val * 2
22 | tmp = tmp / 10
23 | }
24 |
25 | // Print the result
26 | print(num)
27 | print(" in binary is ")
28 | print(result)
29 | print(" in decimal\n")
30 |
31 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q2.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // taking input from the user
3 | var number1 = input("Enter first number : ", "f")
4 | var number2 = input("Enter second number : ", "f")
5 | var sum=0
6 |
7 |
8 | // A logic to print sum of two numbers
9 | sum=number1+number2
10 | print("The value of Sum is = {sum}")
11 | END_MAIN
12 |
--------------------------------------------------------------------------------
/simc-codes/q20.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // User input takes a binary number as input
3 | var dec_num = input("Enter a Number: ", "i")
4 | var bin_num = 0
5 | var lsb = 0
6 | var counter = 0
7 | var temp_dec = dec_num // for presentation purpose in print statement
8 |
9 |
10 | // working
11 | // the decimal number is converted in a single single bit and is then worked upon (starting from lsb [Least significant bit (rightmost)])
12 | // the bit is first isolated, converted into decimal by multiplying 8 ^ position of the bit and added to the decimal number
13 | // the binary number is then divided so that the lsb is shifted to right by one position
14 |
15 | while(dec_num > 0) {
16 | lsb = dec_num % 2
17 | bin_num = bin_num + lsb * 10 ^ counter
18 | dec_num = dec_num / 2
19 | counter = counter + 1
20 | }
21 | print("{temp_dec} in Binary format is {bin_num}")
22 |
23 | END_MAIN
24 |
--------------------------------------------------------------------------------
/simc-codes/q201.simc:
--------------------------------------------------------------------------------
1 | // Calculate modulo of two numbers without using the inbuilt modulo operator (%), second method.
2 | // A == (A/B)*B + (A%B)
3 | MAIN
4 | var numerator = input("Numerator: ", "i")
5 | var divisor = input("Divisor: ", "i")
6 | var rest = numerator
7 | var abs_divisor = divisor
8 |
9 | // Load the abs value for divisor
10 | if(divisor < 0) {
11 | abs_divisor = -divisor
12 | }
13 |
14 | // The zero is not defined for division
15 | if(divisor == 0) {
16 | print("Divisor is not defined in zero.\n")
17 | return 0
18 | }
19 |
20 | // Calculate the division A/B
21 | var divided = rest/divisor
22 |
23 | // The division of A/B is equivalent to subtract B from A until A is greater or equal to B.
24 | rest = rest - (divided*divisor)
25 |
26 | //
27 | if(rest < 0) {
28 | rest = rest + abs_divisor
29 | }
30 |
31 | print("The remain of {numerator} MOD({divisor}) = {rest}\n")
32 | END_MAIN
33 |
--------------------------------------------------------------------------------
/simc-codes/q22.simc:
--------------------------------------------------------------------------------
1 | // to find maximum and minimum digit of a number.
2 | MAIN
3 | var n = input("Input number : ", "i")
4 | var small = 9
5 | var large = 0
6 | var digit
7 | if(n==0){
8 | small = 0
9 | large = 0
10 | }
11 | else if(n>0){
12 | while(n>0)
13 | {
14 | digit=n%10
15 |
16 | if(digit>large){
17 | large=digit;
18 | }
19 | if(digit<=small){
20 | small=digit;
21 | }
22 | n=n/10
23 | }
24 | }
25 | else{
26 | print("Enter a non-negative integer")
27 | exit(0)
28 | }
29 | print("Maximum digit of the number is : {large}\n")
30 | print("Minimum digit of the number is : {small}")
31 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q23.simc:
--------------------------------------------------------------------------------
1 | // to find greatest of three numbers
2 |
3 | MAIN
4 |
5 | //Take input of the three numbers
6 | var n1 = input("Input first number : ", "i")
7 | var n2 = input("Input second number : ", "i")
8 | var n3 = input("Input third number : ", "i")
9 |
10 | //Compare the three numbers pairwise and print the maximum among them
11 | if(n1>=n2 && n1>=n3){
12 | print("Maximum of the three numbers is: {n1}")
13 | }
14 | else if(n2>=n1 && n2>=n3){
15 | print("Maximum of the three numbers is: {n2}")
16 | }
17 | else{
18 | print("Maximum of the three numbers is: {n3}")
19 | }
20 |
21 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q24.simc:
--------------------------------------------------------------------------------
1 | //To find least of three numbers
2 |
3 | MAIN
4 |
5 | //Take input of the three numbers
6 | var n1 = input("Input the first number : ", "i")
7 | var n2 = input("Input the second number : ", "i")
8 | var n3 = input("Input the third number : ", "i")
9 |
10 | //Compare the three numbers pairwise and print the least among them
11 | if(n1<=n2 && n1<=n3){
12 | print("Least of the three numbers is: {n1}")
13 | }
14 | else if(n2<=n1 && n2<=n3){
15 | print("Least of the three numbers is: {n2}")
16 | }
17 | else{
18 | print("Least of the three numbers is: {n3}")
19 | }
20 |
21 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q25.simc:
--------------------------------------------------------------------------------
1 | // Print reverse of a number.
2 | MAIN
3 | var n = input("Input number : ", "i")
4 | var reverse = 0
5 | var digit
6 | if(n<0){
7 | print("Enter non-negative integer")
8 | }
9 | else{
10 | while(n>0)
11 | {
12 | digit=n%10
13 | reverse = reverse*10 + digit
14 | n=n/10
15 | }
16 | print("Reverse of the number is : {reverse}")
17 | }
18 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q26.simc:
--------------------------------------------------------------------------------
1 | // to find factorial of a number without recursion
2 |
3 | MAIN
4 |
5 | //Take input of the number whose factorial is to be calculated
6 | var n = input("Input number : ", "i")
7 | var i = 1
8 | var factorialofn = 1
9 | while(i<=n){
10 | factorialofn = factorialofn*i;
11 | i++
12 | }
13 | print("Factorial of n is: {factorialofn}")
14 |
15 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q27.simc:
--------------------------------------------------------------------------------
1 | // Sum of factorial of digits of a number.
2 | MAIN
3 | var n = input("Input number : ", "i")
4 | var digit
5 | var sum = 0
6 | if(n==0){
7 | sum = 1
8 | }
9 | else{
10 | while(n>0)
11 | {
12 | digit=n%10
13 | var f = 1
14 | var k = digit+1
15 | var i = 1
16 | while(i < k) {
17 | f = f*i
18 | i=i+1
19 | }
20 | sum = sum + f
21 | n=n/10
22 | }
23 |
24 | }
25 | print("Sum of factorial of digits of the number is : {sum}")
26 | END_MAIN
27 |
28 |
--------------------------------------------------------------------------------
/simc-codes/q28.simc:
--------------------------------------------------------------------------------
1 | //Calculate value of nPx
2 |
3 | MAIN
4 |
5 | //Take input of the n and x to calculate nPx
6 | var n = input("Input value of n in nPx : ", "i")
7 | var x = input("Input value of x in nPx : ", "i")
8 |
9 | var i = 1
10 | var nfact = 1
11 | while(i<=n){
12 | nfact = nfact*i
13 | i++
14 | }
15 |
16 | var nminusx = n-x
17 | var nminusxfact = 1
18 | var j = 1
19 | while(j<=nminusx){
20 | nminusxfact = nminusxfact*j
21 | j++
22 | }
23 |
24 | var npx = nfact/nminusxfact
25 |
26 | print("Value of nPx is: {npx}")
27 |
28 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q29.simc:
--------------------------------------------------------------------------------
1 | //Calculate value of nCx
2 |
3 | MAIN
4 |
5 | //Take input of the n and x to calculate nCx
6 | var n = input("Input value of n in nCx : ", "i")
7 | var x = input("Input value of x in nCx : ", "i")
8 |
9 | var i = 1
10 | var nfact = 1
11 | while(i<=n){
12 | nfact = nfact*i
13 | i++
14 | }
15 |
16 | var nminusx = n-x
17 | var nminusxfact = 1
18 | var j = 1
19 | while(j<=nminusx){
20 | nminusxfact = nminusxfact*j
21 | j++
22 | }
23 |
24 | var k = 1
25 | var xfact = 1
26 | while(k<=x){
27 | xfact = xfact*k
28 | k++
29 | }
30 |
31 | var ncx = nfact/(nminusxfact*xfact)
32 |
33 | print("Value of nCx is: {ncx}")
34 |
35 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q3.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var n = input("Enter a num: ","i")
3 |
4 | var a = 1
5 | if(n==1){
6 | a = 0
7 | }
8 | else{
9 | var root = n^0.5
10 | var i = 2
11 | while(i <= root) {
12 | if(n%i == 0){
13 | a = 0
14 | break
15 | }
16 | i = i+1
17 | }
18 | }
19 |
20 | if(a == 0){
21 | print("{n} is not prime")
22 | }
23 | else{
24 | print("{n} is prime")
25 | }
26 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q30.simc:
--------------------------------------------------------------------------------
1 |
2 | MAIN
3 | // Calculate the sum of series: x^1/1 - x^2/2 + x^3/3 ..
4 | var x = input("Enter the variable x : ", "i")
5 | var num = input("Enter the limit of the series: ", "i")
6 | var sum = 0
7 | var calc = 1
8 | for i in 0 to num by +1 {
9 | calc = calc*x
10 | if(i%2==0) {
11 | sum = sum + calc/(i+1)
12 | }
13 | else{
14 | sum = sum - calc/(i+1)
15 | }
16 | }
17 | print("Sum of the series is : ")
18 | print(sum)
19 | END_MAIN
20 |
--------------------------------------------------------------------------------
/simc-codes/q31.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var year = input("Input the year : " , "i")
3 |
4 | if(year%4==0 && year%100 !=0){
5 | print("Yes , It is a leap year!")
6 | }
7 | else if(year%400 ==0){
8 | print("Yes , It is a leap year!")
9 | }
10 | else{
11 | print("No , It is not a leap year!")
12 | }
13 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q32.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 |
3 | var x = input("Enter value of the base : ", "f" )
4 | var n = input("Enter value of the range : ", "f" )
5 |
6 | var i=1
7 | var total= x
8 | var multi = x
9 | n= n+1
10 | var multi_temp=1.0
11 |
12 | for i in 1 to n by +1{
13 | multi_temp=multi/i
14 | total = total + multi_temp
15 | multi = multi* x;
16 | }
17 |
18 | print("The final value is {total}")
19 |
20 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q33.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var n
3 | var i=1
4 | var s = 0.0
5 | n=input("Enter Range of Number: ","i")
6 | while(i<=n){
7 | s = s + 1/i
8 | i++
9 | }
10 | print("Sum is %f")
11 | print(s)
12 | END_MAIN
13 |
--------------------------------------------------------------------------------
/simc-codes/q34.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var string1 = input()
3 | var string2 = input()
4 | print("First String is : {string1}")
5 | print("Second String is : {string2}")
6 | BEGIN_C
7 | int len1 = 0;
8 | int len2 = 0;
9 | while(string1[len1]!='\0') len1++;
10 | while(string2[len2]!='\0') len2++;
11 | char result[len1+len2];
12 | for(int i=0;i
9 | END_C
10 |
11 | // sqrt wrapper function
12 | fun square_root(value) {
13 | var result = 0.0
14 |
15 | BEGIN_C
16 | result = sqrt(value);
17 | END_C
18 |
19 | return result
20 | }
21 |
22 | MAIN
23 | // User input
24 | print("Enter sides of the ABC triangle")
25 | var side_a = input("Enter side A : ", "d")
26 | var side_b = input("Enter side B : ", "d")
27 | var side_c = input("Enter side C : ", "d")
28 |
29 | // Heron's formula
30 | // area = sqrt(s * (s - a) * (s - b) * (s - c))
31 | var semi_perimeter = side_a + side_b + side_c
32 | semi_perimeter /= 2
33 |
34 | var squared_area = semi_perimeter
35 | squared_area *= semi_perimeter - side_a
36 | squared_area *= semi_perimeter - side_b
37 | squared_area *= semi_perimeter - side_c
38 |
39 | var tri_area = square_root(squared_area)
40 |
41 | print("The area is {tri_area}")
42 | END_MAIN
43 |
--------------------------------------------------------------------------------
/simc-codes/q37.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 |
3 | var num1 = input("Enter the first number : ", "i")
4 | var num2 = input("Enter the second number : ", "i")
5 |
6 | var count1 = 0
7 | var count2 = 0
8 |
9 | var i =1
10 |
11 | while(i<=num1) {
12 | if(num1 % i == 0){
13 | count1++;
14 | }
15 | i++
16 | }
17 | i=1
18 | while(i<=num2){
19 | if(num2 % i == 0){
20 | count2++;
21 | }
22 | i++
23 | }
24 |
25 | var d
26 |
27 | if(num1 > num2){
28 | d=num1 - num2
29 | }
30 | else{
31 | d= num2-num1
32 | }
33 |
34 | if(d == 2 && count1 == 2 && count2 == 2){
35 | print("The Two Numbers are Twin Prime");
36 | }
37 | else{
38 | print("The two Numbers are Not Twin Prime");
39 | }
40 | END_MAIN
41 |
42 |
--------------------------------------------------------------------------------
/simc-codes/q38.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Finding hypotenuse of a triangle using Pythagoras Theorem
3 | var perp = input("Enter the length of the perpendicular of the triangle:\t","f")
4 | var base = input("Enter the length of the base of the triangle:\t","f")
5 | var num1=perp^2
6 | var num2=base^2
7 | var num3=num1+num2
8 | // Finding the square root of the sum of squares of the perpendicular and base
9 | var sqrt=num3/2
10 | var temp=0
11 | var v1
12 |
13 | while(sqrt!=temp ) {
14 | temp=sqrt
15 |
16 | v1=(num3/temp + temp)
17 | sqrt=v1/2
18 | }
19 | print("The length of the hypotenuse of the triangle is = {sqrt}")
20 | END_MAIN
21 |
22 |
--------------------------------------------------------------------------------
/simc-codes/q39.simc:
--------------------------------------------------------------------------------
1 |
2 | MAIN
3 | var p = input("Input principle : ", "i")
4 | var r = input("Input Rate of interest : ", "i")
5 | var t = input("Input Time : ", "i")
6 | var amount= p*r*t/100
7 | print("Simple interest =")
8 | print(amount)
9 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q4.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Taking input from user
3 | var input_number = input("Enter a number : ", "i")
4 |
5 | // Checking Odd or Even by using Modulo Operator
6 | if (input_number % 2 == 0) {
7 | print("{input_number} is Even!")
8 | } else {
9 | print("{input_number} is Odd!")
10 | }
11 |
12 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q40.simc:
--------------------------------------------------------------------------------
1 | //Compute compound interest
2 | MAIN
3 | var p = input("Input principle amount : ", "f")
4 | var t = input("Input time : ", "f")
5 | var r = input("Input rate : ", "f")
6 | r = r/100
7 | var interest = 1+r
8 | interest = interest^t
9 | var ci= p*interest
10 | print("Compound interest is : {ci}")
11 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q41.simc:
--------------------------------------------------------------------------------
1 | //Question
2 |
3 | //Check if a number is special or not.
4 | //A number is special when sum of factorial of digits of number is equal to that number.
5 | //Example 145 = 1! + 4! + 5! = 145.
6 |
7 |
8 |
9 | MAIN
10 | //Taking input nunmber from user in p(int)
11 | var p = input("enter a nunmber : ", "i")
12 |
13 | // Initializations
14 | //temperory variable : temp
15 | //variable to store sum of factorials : facto
16 |
17 | var temp=p
18 | var facto=0
19 |
20 |
21 | // This is where the real magic happens !!
22 | // The main while loop
23 |
24 | while (temp!=0){
25 | var facto_cal=1
26 |
27 | var digit=temp%10
28 |
29 | while (digit != 1)
30 | {
31 | facto_cal = facto_cal*digit
32 | digit=digit-1
33 | }
34 |
35 | facto = facto+facto_cal
36 | temp = temp/10
37 |
38 |
39 | }
40 |
41 | //Conditionals to check if the number is special or not
42 |
43 | if ( facto == p){
44 | print('Special')
45 | }
46 | else{
47 | print('Not special')
48 | }
49 |
50 | END_MAIN
51 |
--------------------------------------------------------------------------------
/simc-codes/q42.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var num = input("Enter a number:\t","i")
3 | var sqr = num * num
4 | var temp = num;
5 | var n = 0;
6 | while(temp>0){
7 | n = n + 1
8 | temp = temp/10
9 | }
10 | var power = 10 ^n
11 | var split = sqr % power
12 | if(split == num){
13 | print("Automorphic number\n")
14 | }
15 | else{
16 | print("Not a Automorphic number\n")
17 | }
18 | END_MAIN
19 |
--------------------------------------------------------------------------------
/simc-codes/q43.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var num = input("Enter a number:\t","i")
3 | var count =0
4 | var i =1
5 | var flag =0
6 | while(i<=num){
7 | if(num % i == 0){
8 | count = count + 1
9 | }
10 | i = i+1
11 | }
12 | if(count>2){
13 | flag =1
14 | }
15 | if(flag==1){
16 | var sumofdigits =0
17 | i = num
18 | while(i!=0){
19 | sumofdigits = sumofdigits + (i%10)
20 | i = i/10
21 | }
22 | var sumofprime = 0
23 | var prime = 2
24 | i = num
25 | var tempsum = 0
26 | var j
27 | while(i != 1){
28 | while(i % prime == 0 && prime <= i){
29 | tempsum = 0
30 | j = prime
31 | while(j!=0){
32 | tempsum = tempsum + (j%10)
33 | j = j/10
34 | }
35 | sumofprime = sumofprime + tempsum;
36 | i /= prime;
37 | }
38 | prime++;
39 | }
40 | if(sumofdigits==sumofprime){
41 | print("Smith Number")
42 | }
43 | else{
44 | print("Not a Smith Number")
45 | }
46 | }
47 | else{
48 | print("Not a Smith Number")
49 | }
50 | END_MAIN
51 |
--------------------------------------------------------------------------------
/simc-codes/q44.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Determines if a number is a Kaprekar number
3 | // A list of Kaprekar numbers can be found here: https://oeis.org/A006886
4 | // First get all of the parameters from the user
5 | print("Kaprekar Number Test\n")
6 | var power = input("Power: ", "i")
7 | var n = input("Number you want to test: ", "i")
8 |
9 | // Next, find the values for the Kaprekar function
10 | var beta_1 = n^2
11 | var beta_2 = (10^power)
12 | var beta = beta_1 % beta_2
13 | var alpha_1 = n^2 - beta
14 | var alpha_2 = 10^power
15 | var alpha = alpha_1/alpha_2
16 |
17 | // Finally, calculate and compare the result
18 | if (alpha+beta == n) {
19 | print(n)
20 | print(" is a ")
21 | print(power)
22 | print("-Kaprekar number\n")
23 | } else {
24 | print(n)
25 | print(" is not a ")
26 | print(power)
27 | print("-Kaprekar number\n")
28 | }
29 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q45.simc:
--------------------------------------------------------------------------------
1 | //To find composite factors of a number
2 | MAIN
3 | //Take input of the number whose factors are to be calculated
4 | var n = input("Input number : ", "i")
5 | print("Composite Factors of {n} are:")
6 | var i = 1
7 | var p = 1
8 | while(i <= n){
9 | if (n % i == 0){
10 | var j = 2
11 | while (j < i) {
12 | if (i%j == 0){
13 | p=0
14 | }
15 | j++
16 | }
17 | if(p == 0){
18 | print(" {i}")
19 | }
20 | }
21 | i++
22 | }
23 | END_MAIN
24 |
--------------------------------------------------------------------------------
/simc-codes/q46.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var n1 = input("Enter first number : ", "i")
3 | var n2 = input("Enter second number : ", "i")
4 | var max
5 | if (n1 > n2){
6 | max = n1
7 | }
8 | else {
9 | max = n2
10 | }
11 | while(1){
12 | if(max % n1 == 0 && max % n2 ==0){
13 | print("LCM is : {max}")
14 | break
15 | }
16 | max++
17 | }
18 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q47.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var a = input("Enter first number : ", "i")
3 | var b = input("Enter second number : ", "i")
4 | var c
5 | var max
6 | var min
7 |
8 | // Handle special cases
9 | if (a == 0 && b == 0){
10 | print("Numbers must not be all zero!")
11 | exit(0)
12 | }
13 | if (a == 0 || b == 0){
14 | c = a + b
15 | print("GCD = {c}")
16 | exit(0)
17 | }
18 | if (a == b){
19 | print("GCD = {a}")
20 | exit(0)
21 | }
22 |
23 | //Sort numbers
24 | if (a > b){
25 | max = a
26 | min = b
27 | }
28 | else{
29 | max = a
30 | min = b
31 | }
32 |
33 | // Euklidian Algorithm
34 | do {
35 | c = max % min
36 | max = min
37 | min = c
38 | } while (c != 0)
39 |
40 | print("GCD = {max}")
41 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q48.simc:
--------------------------------------------------------------------------------
1 | //To check if a phone number is valid
2 | MAIN
3 | //Take input of the number whose factors are to be calculated
4 | var n = input("Input number : ", "d")
5 | if (n >= 1000000000 && n <= 9999999999) {
6 | print("Valid Phone Number")
7 | } else {
8 | print("Invalid Phone Number")
9 | }
10 | END_MAIN
11 |
--------------------------------------------------------------------------------
/simc-codes/q49.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var pi = 3.14
3 | var radius = 4
4 | var height = 2
5 | var volume = pi * radius * radius * height
6 | print("Result = {volume}")
7 | END_MAIN
8 |
--------------------------------------------------------------------------------
/simc-codes/q5.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var num = input("Enter a number : ", "i")
3 |
4 | var sum = 0
5 |
6 | var x = num
7 | while(x != 0)
8 | {
9 | var digit = x % 10
10 | sum = sum + digit ^ 3
11 | x = x/10
12 | }
13 |
14 | if(num == sum){
15 | print("{num} is an Armstrong number")
16 | }
17 | else {
18 | print("{num} is not an Armstrong number")
19 | }
20 | END_MAIN
21 |
--------------------------------------------------------------------------------
/simc-codes/q51.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var x1 = input("Enter x coordinate of center of circle 1 ", "i")
3 | var y1 = input("Enter y coordinate of center of circle 1 ", "i")
4 | var r1 = input("Enter radius of circle 1 ","i")
5 | var x2 = input("Enter x coordinate of center of circle 2 ","i")
6 | var y2 = input("Enter y coordinate of center of circle 2 ","i")
7 | var r2 = input("Enter radius of circle 2 ","i")
8 | var diffx = (x1-x2)
9 | var diffy = (y1-y2)
10 | diffx = diffx*diffx
11 | diffy = diffy*diffy
12 | var diff = diffx + diffy
13 | var rad1 = r1*r1
14 | var rad2 = r2*r2
15 | var sum = rad1 + rad2
16 | if(sum==diff){
17 | print("The circles are orthogonal")
18 | }
19 | else{
20 | print("The circles are not orthogonal")
21 | }
22 | END_MAIN
23 |
--------------------------------------------------------------------------------
/simc-codes/q52.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Get the number and figure out how many digits it has
3 | print("Magic Number Checker\n")
4 | var num = input("Enter a number: ", "i")
5 | var digs = 0
6 | var ismagic = 1
7 | var tmp = num
8 | while (tmp > 0) {
9 | tmp = tmp/10
10 | digs = digs + 1
11 | }
12 |
13 | // Check each digit to see if duplicates exist
14 | var loc1 = 0 // The location of the digit being checked for
15 | var loc2 = 0 // The current digit location
16 | while (loc1 < digs) {
17 | var digit1 = num / (10^loc1) // The digit being checked for
18 | digit1 = digit1 % 10
19 | var digit2
20 |
21 | // Check each location to see if we can find a duplicate of the number
22 | loc2 = 0
23 | while (loc2 < digs) {
24 | digit2 = num / (10^loc2) // The digit we're currently checking digit1 against
25 | digit2 = digit2 % 10
26 | if (digit1==digit2 && loc1!=loc2) { // Notice that we exclude the number from counting itself as a duplicate
27 | ismagic = 0
28 | }
29 | loc2 = loc2 + 1
30 | }
31 | loc1 = loc1 + 1
32 | }
33 |
34 | // Print the result
35 | if (ismagic==1) {
36 | print("This is a magic number!\n")
37 | } else {
38 | print("This is not a magic number!\n")
39 | }
40 |
41 | END_MAIN
42 |
--------------------------------------------------------------------------------
/simc-codes/q53.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Compute the area of a rhombus, given its diagonals
3 | // The diagonals are float inputs
4 |
5 | // Get the two diagonals
6 | var p = input("First diagonal : ", "f")
7 | var q = input("Second diagonal : ", "f")
8 |
9 | // Verify that the diagonals are positive
10 | if(p>=0 && q>=0) {
11 | var area = p*q/2
12 |
13 | print("Area of the rhombus ({p}, {q}) is {area}")
14 | } else {
15 | print("Diagonals cannot be negative")
16 | }
17 | END_MAIN
18 |
--------------------------------------------------------------------------------
/simc-codes/q54.simc:
--------------------------------------------------------------------------------
1 | //Print Area of Trapezium.
2 |
3 | MAIN
4 | var a = input("Input shorter parallel side length: ", "i")
5 | var b = input("Input larger parallel side length: ", "i")
6 | var h = input("Input perpendicular distance between parallel sides: ", "i")
7 | var area
8 | var num1
9 |
10 | if(h<=0){
11 | print("Height cannot be 0 or negative")
12 | }
13 | else{
14 | num1 = (a+b)
15 | area = num1*h/2
16 | print("Area of trapezium is : {area}")
17 | }
18 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q55.simc:
--------------------------------------------------------------------------------
1 | // Check if two numbers are coprime or not.
2 |
3 | MAIN
4 | var num1 = input("Input first number: ", "i")
5 | var num2 = input("Input second number: ", "i")
6 | var hcf = 0
7 | var i = 1
8 | if(num1 <= num2){
9 | while(i <= num1){
10 | if(num1%i == 0 && num2%i ==0){
11 | hcf = i
12 | }
13 | i++
14 | }
15 | }
16 | else{
17 | while(i <= num2){
18 | if(num1%i == 0 && num2%i ==0){
19 | hcf = i
20 | }
21 | i++
22 | }
23 | }
24 | if(hcf == 1){
25 | print("The numbers are Coprime")
26 | }
27 | else{
28 | print("The numbers are not Coprime")
29 | }
30 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q56.simc:
--------------------------------------------------------------------------------
1 | // Calculate Cost Price when loss percentage and selling price are given
2 |
3 | MAIN
4 | var loss = input("Enter the percentage loss incurred: ", "i")
5 | var sell_price = input("Enter the selling price: ", "i")
6 | var cost_price
7 | var deno
8 |
9 | if(loss >= 100){
10 | print("Percentage loss cannot be greater than or equal to 100")
11 | }
12 | else{
13 | deno = 100 - loss
14 | cost_price = 100*sell_price/deno
15 | print("The Cost Price is: {cost_price}")
16 | }
17 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q57.simc:
--------------------------------------------------------------------------------
1 | //Divide two numbers
2 |
3 | MAIN
4 | var num = input("Input numerator: ", "i")
5 | var denom = input("Input denominator: ", "i")
6 | var res
7 |
8 | if(denom != 0) {
9 | res = num / denom
10 | print("The division output is: {res}")
11 | } else {
12 | print("Denominator cannot be zero")
13 | }
14 |
15 |
16 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q58.simc:
--------------------------------------------------------------------------------
1 | // task of this problem to find average of 7 numbers when
2 | // sum of six numbers and seventh number is provided to us
3 |
4 | MAIN
5 |
6 | var avg_of_six_numbers = 45
7 | var seventh_number = 21
8 |
9 | var sum_of_six_numbers = avg_of_six_numbers * 6 // since average of 6 numbers are given ((ie a1+a2+a3+a4+a5+a6) / 6 = 45) therefore sum of 6 numbers is 45 * 6
10 | var sum_of_seven_numbers = sum_of_six_numbers + seventh_number // we can add seventh number to the sum ie(sum of 7 numbers), dividing it with 7 will give us the needed average
11 | var result = sum_of_seven_numbers / 7
12 | print("Area of 7 numbers is {result} ")
13 |
14 | END_MAIN
15 |
--------------------------------------------------------------------------------
/simc-codes/q59.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // User input [taking radius as input, declaring pi in the code itself, would be directly imported from math helper class]
3 | var radius = input("Enter a Radius: ", "i")
4 | var pi = 3.14159
5 |
6 | var area = radius * radius * pi // area = (pi * (r ^ 2))
7 |
8 | print("Area of circle with Radius {radius} is {area} ")
9 |
10 | END_MAIN
11 |
--------------------------------------------------------------------------------
/simc-codes/q6.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var i = 0
3 | var n = 10
4 | var prev = 0
5 | var next = 1
6 | while(i=0; j--)
35 | printf("%c",hexaDeciNum[j]);
36 |
37 | END_C
38 |
39 |
40 | END_MAIN
41 |
--------------------------------------------------------------------------------
/simc-codes/q65.simc:
--------------------------------------------------------------------------------
1 | //Convert Hexadecimal to Decimal
2 |
3 | MAIN
4 |
5 | var decnum=0
6 | var i=0
7 | var len=0
8 | var rem=0
9 |
10 | //C used to declare and use array for hexadecimal to decimal conversion.
11 | BEGIN_C
12 | char hexnum[20];
13 | printf("Enter any Hexadecimal Number: ");
14 | scanf("%s", hexnum);
15 | while(hexnum[i]!='\0')
16 | {
17 | len++;
18 | i++;
19 | }
20 | len--;
21 | i=0;
22 | while(len>=0)
23 | {
24 | rem = hexnum[len];
25 | if(rem>=48 && rem<=57)
26 | rem = rem-48;
27 | else if(rem>=65 && rem<=90)
28 | rem = rem-55;
29 |
30 | decnum = decnum + (rem*pow(16, i));
31 | len--;
32 | i++;
33 | }
34 | END_C
35 | print("Decimal Value is {decnum}")
36 |
37 | END_MAIN
38 |
--------------------------------------------------------------------------------
/simc-codes/q66.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // User input takes a binary number as input
3 | var oct_num = input("Enter a Number in its octal representation: ", "i")
4 | var dec_num = 0
5 | var lsb = 0
6 | var counter = 0
7 | var temp_oct = oct_num // for presentation purpose in print statement
8 |
9 |
10 | // working
11 | // the octal number is converted in a single single bit and is then worked upon (starting from lsb [Least significant bit (rightmost)])
12 | // the bit is first isolated, converted into decimal by multiplying 8 ^ position of the bit and added to the decimal number
13 | // the binary number is then divided so that the lsb is shifted to right by one position
14 |
15 | while(oct_num > 0) {
16 | lsb = oct_num % 10
17 | if (lsb > 7) {
18 | print("Not a valid Octal Number")
19 | break
20 | }
21 | dec_num = dec_num + lsb * 8 ^ counter
22 | oct_num = oct_num / 10
23 | counter = counter + 1
24 | }
25 | if(lsb < 8 && temp_oct != 0){
26 | print("{temp_oct} in Octal format is {dec_num}")
27 | }
28 | END_MAIN
29 |
--------------------------------------------------------------------------------
/simc-codes/q67.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var decimal_no = input("Enter a number :", "i")
3 | var initial_val = decimal_no //saving initial value for output
4 | var octal_no = 0
5 | var place = 1
6 | while(decimal_no != 0){
7 |
8 | octal_no += decimal_no % 8*place //digit for consecutive places added
9 | place *= 10 // move to next place
10 | decimal_no /= 8
11 |
12 | }
13 | print("{initial_val} in octal = {octal_no}\n")
14 | END_MAIN
15 |
--------------------------------------------------------------------------------
/simc-codes/q68.simc:
--------------------------------------------------------------------------------
1 | //Convert binary number to hexadecimal
2 | MAIN
3 | //Take input as the binary number as a double
4 | var binaryval = input("Input number : ", "i")
5 | var hexadecimalval = 0
6 | var i = 1
7 | var remainder = 0
8 | while (binaryval != 0) {
9 | remainder = binaryval % 10
10 | hexadecimalval = hexadecimalval + remainder * i
11 | i = i * 2
12 | binaryval = binaryval / 10
13 | }
14 | BEGIN_C
15 | printf("Equivalent hexadecimal value: %lX\n", hexadecimalval);
16 | END_C
17 |
18 | END_MAIN
19 |
--------------------------------------------------------------------------------
/simc-codes/q69.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // User input takes a binary number as input
3 | var bin_num = input("Enter a Binary Number: ", "i")
4 | var dec_num = 0
5 | var lsb = 0
6 | var counter = 0
7 | var temp_bin = bin_num // for presentation purpose in print statement
8 |
9 |
10 | // working
11 | // the binary number is converted in a single single bit and is then worked upon (starting from lsb [Least significant bit (rightmost)])
12 | // the bit is first isolated, converted into decimal by multiplying 2 ^ position of the bit and added to the decimal number
13 | // the binary number is then divided so that the lsb is shifted to right by one position
14 |
15 | while(bin_num > 0) {
16 | lsb = bin_num % 10
17 | dec_num = dec_num + lsb * 2 ^ counter
18 | bin_num = bin_num / 10
19 | counter = counter + 1
20 | }
21 |
22 | // working
23 | // this while loop works similar to the above one
24 | // only difference here is the base is changed from 10 to 8 [for octal format]
25 | // and the result is filled from right most position
26 |
27 | var result = 0
28 | counter = 0
29 | while(dec_num > 0) {
30 | result = result + dec_num % 8 * 10 ^ counter
31 | dec_num = dec_num / 8
32 | counter = counter + 1
33 | }
34 |
35 | print("{temp_bin} in Octal format is {result}")
36 | END_MAIN
37 |
--------------------------------------------------------------------------------
/simc-codes/q7.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | //Lower left triangle pattern
3 | var rows = 5
4 | var i = 0
5 | var j = 0
6 | while(i<=rows)
7 | {
8 | j = 0
9 | //printing the pattern
10 | while(j number2) {
17 | print("{number1} is greater than {number2}")
18 | }
19 | //Checking that Number1 is less than Number2
20 | else{
21 | print("{number1} is less than {number2}")
22 | }
23 | END_MAIN
24 |
--------------------------------------------------------------------------------
/simc-codes/q71.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // User input taking a valid month input
3 | // uses switch case to check the input and ouputs the month
4 |
5 | var month = input("Enter a number to find the corresponding month: ", "i")
6 |
7 | switch (month) {
8 | case 1 :
9 | print("{month}st Month of the Year is January")
10 | break
11 | case 2 :
12 | print("{month}nd Month of the Year is February")
13 | break
14 | case 3:
15 | print("{month}rd Month of the Year is March")
16 | break
17 | case 4 :
18 | print("{month}th Month of the Year is April")
19 | break
20 | case 5 :
21 | print("{month}th Month of the Year is May")
22 | break
23 | case 6 :
24 | print("{month}th Month of the Year is June")
25 | break
26 | case 7 :
27 | print("{month}th Month of the Year is July")
28 | break
29 | case 8 :
30 | print("{month}th Month of the Year is August")
31 | break
32 | case 9 :
33 | print("{month}th Month of the Year is September")
34 | break
35 | case 10 :
36 | print("{month}th Month of the Year is October")
37 | break
38 | case 11 :
39 | print("{month}th Month of the Year is November")
40 | break
41 | case 12 :
42 | print("{month}th Month of the Year is December")
43 | break
44 | default :
45 | print("{month} is not a valid Month")
46 | break
47 | }
48 | END_MAIN
49 |
--------------------------------------------------------------------------------
/simc-codes/q72.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var sides = input("Enter number of sides: ", "i")
3 |
4 | if (sides < 3) {
5 | print("Invalid number of sides.\n")
6 | } else {
7 | var temp = sides - 2.0
8 | var internal_angle = temp * 180 / sides
9 | print("Internal angle is {internal_angle} degrees.\n")
10 | }
11 | END_MAIN
12 |
--------------------------------------------------------------------------------
/simc-codes/q73.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 |
3 | // Ask for input for radius
4 | var radius = input("Enter the radius of the sphere: ", "f")
5 |
6 | // Using the formula (4/3)(PI)(r^3) compute the area
7 | var volume = 4.0/3 * PI * radius^3
8 |
9 | // Print Output and add units cubed to the end
10 | print("{volume} units cubed")
11 | END_MAIN
12 |
--------------------------------------------------------------------------------
/simc-codes/q74.simc:
--------------------------------------------------------------------------------
1 | // Question :
2 | // Calculate and print the Volume of Cone given height and base radius
3 | // The area of the triangle with sides A = 4, B = 13, C = 15 is 24
4 | MAIN
5 | var pi = 3.1415
6 | var height = input("Enter the height of the cone ","i")
7 | var base_radius = input("Enter the radius of the base of the cone ","i")
8 | var volume = 1/3 * pi * base_radius * base_radius * height
9 | print("Volume of the cone is = {volume} units")
10 | END_MAIN
11 |
--------------------------------------------------------------------------------
/simc-codes/q75.simc:
--------------------------------------------------------------------------------
1 | // *
2 | // sim-C
3 | //
4 | // Question:
5 | //
6 | // In a class there are 50% students study English,
7 | // 30% study Hindi,
8 | // 25% study foreign language,
9 | // 10% study english with foreign language,
10 | // find the percentage of students who study hindi with foreign language,
11 | // if no one studies all the three subjects at a time
12 | //
13 | // Resolution:
14 | //
15 | // en: only English
16 | // hi: only Hindi
17 | // fl: only foreign language
18 | // no: no language(disjoint from others)
19 | //
20 | // en_hi : English and Hindi
21 | // en_fl : English and foreign
22 | // hi_fl : Hindi and foreign
23 | //
24 | // en_hi_fl : en + hi + fl = 0%
25 | // en_fl : 10%
26 | //
27 | // From the statment:
28 | //
29 | // (1) 100% = en + hi + fl + en_hi + en_fl + hi_fl + no
30 | // (2) 40% = en_hi + en
31 | // (3) 30% = en_hi + hi + hi_fl + hi
32 | // (4) 15% = hi_fl + fl
33 | //
34 | // Put (2) and (4) into (1)
35 | // 100% = (en_hi + en) + (hi_fl + fl) + (en_fl) + hi + no = 40% + 15% + 10% + hi + no
36 | //
37 | // (5) 35% = hi + no
38 | //
39 | // Next follow a trick to discover which students is not studyng any langueges(no)
40 | //
41 | // Suppose n = 100 is an arbitary number of students. Then it is possible distribute the students such that
42 | // the restrictions are satified and conclude then the total students must be 85%.
43 | //
44 | // Note, it does not matter thaat the numbers is correct distributed yet. You can note that this arrange satifies
45 | // the initial restriction and with that we infer quantity of no.
46 | //
47 | // en: 30
48 | // hi: 15
49 | // fl: 20
50 | // no: no language(disjoint from others)
51 | //
52 | // en_hi : 10
53 | // en_fl : 10
54 | // hi_fl : 0
55 | //
56 | // en_hi_fl : 0
57 | // total : 85
58 | //
59 | // no = (n - all students of langues) / n
60 | //
61 | // This says that the total number of students who does not study language is 15%!
62 | // no = (100 - 85) / 100 = 15%
63 | //
64 | // From (5) => hi = 20%
65 | //
66 | // Now, the equations can solve all the unknow variables.
67 | //
68 | // From (3) with (no) => (6) en_hi + fl_hi = 10%
69 | //
70 | // The sum of en + en_fl + en_hi + en_fl + hi + fl + fl_hi= 85
71 | //
72 | // We add en_hi in both sides:
73 | //
74 | // en + en_fl + (2*en_hi + en_fl + hi) + fl + fl_hi = 85 + en_hi
75 | //
76 | // As (6) and (3) fl + 2*en_hi + fl_hi = 25%
77 | //
78 | // So en + en_fl + hi - en_hi = 60
79 | //
80 | // hi and en_fl are know as 20% and 10%
81 | //
82 | // Finally, en - en_hi = 30%
83 | //
84 | // With that, we conclude that
85 | // en + en_hi = 40%
86 | // +
87 | // en - en_hi = 30%
88 | // -----------------
89 | // en = 35% => en_hi = 5%
90 | //
91 | // en_hi + fl_hi = 10% => fl_hi = 5%
92 | //
93 | // Answer: fl_hi = 5%
94 | //
95 |
96 | MAIN
97 | var n_students = input("Enter number of students : ","i")
98 | var fl_hi = 0.05*n_students
99 | print("The number of students learning Foreign Language and Hindi is {fl_hi}\n")
100 | END_MAIN
101 |
102 |
103 |
--------------------------------------------------------------------------------
/simc-codes/q76.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | /*
3 | Given a user input positive integer n between 0 and 9,
4 | print n + nn + nnn
5 | Example:
6 | n = 5
7 | n + nn + nnn = 5 + 55 + 555 = 615
8 | */
9 | var n1 = input("Enter a positive integer between 0 and 9: ", "i")
10 | var n2 = n1*11
11 | var n3 = n1*111
12 | var ans = n1 + n2 + n3
13 | print("{n1} + {n2} + {n3} = {ans}")
14 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q77.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 |
3 | var min = 1
4 | var max = 99
5 |
6 | print("Odd numbers from {min} to {max}:\n")
7 |
8 | var num = min
9 | do {
10 | if (num % 2 != 0) {
11 | print("{num} ")
12 | }
13 |
14 | num += 1
15 |
16 | // Optional: break line every 5 numbers for nicer formatting
17 | if (num % 10 == 0) {
18 | print("\n")
19 | }
20 |
21 | } while(num <= max)
22 |
23 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q78.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | /*
3 | Print numbers in a user provide range that are divisible
4 | by either 3 or 7 but not by both
5 | */
6 | var left = input("Enter an integer to represent start of range: ", "i")
7 | var right = input("Enter an integer to represent end of range: ", "i")
8 |
9 | for i in left to right by +1 {
10 | if(i%3==0 || i%7==0) {
11 | if(i%21!=0){
12 | print("{i}\n")
13 | }
14 | }
15 | }
16 | END_MAIN
17 |
--------------------------------------------------------------------------------
/simc-codes/q79.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var n = 100
3 | n++;
4 | for i in 1 to n by +1{
5 | if(i%3==0 || i%5==0){
6 | print("{i}\n")
7 | }
8 | }
9 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q80.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var x = input("Enter first number: ","i")
3 | var y = input("Enter second number: ","i")
4 | var z = input("Enter third number: ","i")
5 |
6 |
7 | if(x+y==z){
8 | print("{z} is equal to {x} + {y}")
9 | }
10 | else{
11 | print("{z} is not equal to {x} + {y}")
12 | }
13 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q81.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Initialize our variables
3 | var first_variable = 10
4 | var second_variable = 15
5 |
6 | // Make the first variable equal the sum of the two
7 | first_variable += second_variable
8 |
9 | // Make the second variable equal the first, by subtracting it from the sum
10 | second_variable = first_variable - second_variable
11 |
12 | // Make the first variable be the second, by subtracting the original first which is now second_variable, from itself, the sum
13 | first_variable -= second_variable
14 |
15 | // Print output
16 | print("After the switch the first variable is {first_variable} and the second is {second_variable}")
17 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q82.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var x = input("Enter the number: ","i")
3 | var cnt=0
4 | var i=1
5 | var sqN=(x^0.5)
6 | sqN=sqN+1
7 | for i in 1 to sqN by +1{
8 | if(x % i == 0){
9 | if(x / i == i){
10 | cnt=cnt+1
11 | }
12 | else{
13 | cnt=cnt+2
14 | }
15 | }
16 | }
17 | print("The total factors of {x} is/ are {cnt}")
18 | END_MAIN
19 |
20 |
--------------------------------------------------------------------------------
/simc-codes/q83.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | // Declare and initialize the dividend and divisor, note here I use floats to show that it works with them, but it will work with integers aswell
3 | var dividend = 15.3
4 | var divisor = 3.2
5 |
6 | // Declare and initialize what will be the whole part of the division, in other words the integer quotient
7 | var integer_quotient = 1
8 |
9 | // Since sim-c is dynamically typed, adding the following line would convert integer_quotient to a float, and since sim-c does not have any type casting we must use the built in c type casting.
10 | BEGIN_C
11 | integer_quotient = dividend / divisor;
12 | END_C
13 |
14 | // Now since we have the truncated answer, we simply multiply that by the divisor, and subtract from the dividend
15 | var remainder = dividend - divisor*integer_quotient
16 |
17 | // Print the remainder out
18 | print("{dividend} modulo {divisor} is {remainder}")
19 | END_MAIN
20 |
--------------------------------------------------------------------------------
/simc-codes/q84.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var num1 = input("Enter value of first number : ", "i" )
3 | var num2 = input("Enter value of second number : ", "i" )
4 | var temp
5 |
6 | //swapping the numbers using a temp varianble
7 | temp = num1
8 | num1 = num2
9 | num2 = temp
10 |
11 | print("After swapping first number is = {num1}")
12 |
13 | print("\nAfter swapping second number is = {num2}")
14 |
15 | END_MAIN
16 |
--------------------------------------------------------------------------------
/simc-codes/q85.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var n = input("Enter the number : ", "i" )
3 | var i=1
4 | var j=1
5 | var check=0
6 | for i in 1 to n by +1 {
7 | for j in 1 to n by +1 {
8 | if(i * i + j * j == n){
9 | check=check+1
10 | }
11 | }
12 | }
13 |
14 | if(check==0){
15 | print("{n} is scarcely a sum of two whole squares")
16 | }
17 | else{
18 | print("{n} is a sum of two whole squares")
19 | }
20 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q86.simc:
--------------------------------------------------------------------------------
1 | //to print Fibonacci Series numbers at even places
2 | MAIN
3 | var term1 = 0
4 | var term2 = 1
5 | var nextTerm = 0
6 | var max_term = input("Enter number of terms : ","i") //number of terms to be calculated
7 | print("Fibonacci series :{term2}")
8 | nextTerm = term1+term2
9 | var term_position = 3
10 | while(term_position <= max_term){
11 | if(term_position % 2 == 0){
12 | print(", {nextTerm}")
13 | }
14 | term1 = term2
15 | term2 = nextTerm
16 | nextTerm = term1 + term2
17 | term_position += 1
18 | }
19 | print("\n");
20 | END_MAIN
21 |
--------------------------------------------------------------------------------
/simc-codes/q87.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var N = input("Enter the number: ","i")
3 | var i=0
4 | var count=0
5 | while(count 18 && age < 65) {
12 | result = "Yes"
13 | }
14 | print("Age: {age}, Eligible to vote: {result}")
15 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q9.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | var n = 3
3 | var i = 0
4 | var j = 0
5 | while(i,<) and logical(&&) operator to judge the value */
13 | /* and printing the strings */
14 | if (n>0 && n<1){
15 | print("Lies in between 0 and 1")
16 | }else{
17 | print("Does not lies in between 0 and 1")
18 | }
19 | END_MAIN
20 |
--------------------------------------------------------------------------------
/simc-codes/q96.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | /*
3 | Convert given weight in KGs to pounds.
4 | The conversion factor is 2.2046.
5 | Ex.
6 | 1 Kg = 2.2046 pounds
7 | */
8 |
9 | var value = 2.2046;
10 | var n = input("Enter the weight in Kg:","f");
11 |
12 | var ans = n * value;
13 |
14 | print("The weight in pounds is {ans} pounds")
15 |
16 | END_MAIN
17 |
--------------------------------------------------------------------------------
/simc-codes/q97.simc:
--------------------------------------------------------------------------------
1 | /*
2 | sim-c
3 |
4 | The Aritmetic Progressing is a sequence that start at a1( and each following term is increase by d
5 |
6 | the Sum of an Aritmetic Progressing is given by:
7 |
8 | Sn = n/2(2*a1 + (n-1)*d)
9 | */
10 | MAIN
11 |
12 | print("Welcome to sim-C, give a range to sum up!\n")
13 |
14 | var init = input("Enter first term of the progression : ","i") // a1
15 | var step = input("Enter step of the progression : ", "i") // d
16 | var n = input("Enter the number of the term: ", "i") // n
17 | var result = 0;
18 |
19 | var prog = step*(n-1)
20 | var range = 0.0
21 |
22 | // the division made in C to cast to double
23 | BEGIN_C
24 | range = n / (double)2;
25 | END_C
26 |
27 | var first = 2*init
28 |
29 | // AP (Aritmetic Progressing)
30 | result = range*(first + prog)
31 | print("The sum of all terms until n = {result}\n")
32 |
33 | END_MAIN
--------------------------------------------------------------------------------
/simc-codes/q98.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 |
3 | var a = input("Enter value of the first term : ", "f" )
4 | var r = input("Enter value of the common ratio : ", "f" )
5 | var n = input("Enter value of total number of terms : ", "f" )
6 |
7 | var sum=0.0
8 | var power = r^n
9 | r=r-1
10 | sum= power -1
11 | sum = sum* a
12 | sum= sum/r
13 |
14 | print("The final value is {sum}")
15 |
16 | END_MAIN
17 |
18 |
--------------------------------------------------------------------------------
/simc-codes/q99.simc:
--------------------------------------------------------------------------------
1 | MAIN
2 | //harmonic mean of two numbers num1 and num2
3 | var num1 = input("Enter the first value: ", "f")
4 | var num2 = input("Enter the second value: ", "f")
5 |
6 | var product = num1*num2
7 | var sum = num1 + num2
8 |
9 | /*
10 | harmonic mean is 2*num1*num2/(num1+num2)
11 | */
12 | product = 2*product
13 | var ans = product/sum
14 |
15 | print("Harmonic mean of {num1} and {num2} is {ans}")
16 | END_MAIN
17 |
--------------------------------------------------------------------------------
/simc/__init__.py:
--------------------------------------------------------------------------------
1 | import simc
2 |
3 | __version__ = "0.1-alpha-4"
4 |
--------------------------------------------------------------------------------
/simc/compiler.py:
--------------------------------------------------------------------------------
1 | # Module to import OpCode class
2 | from .op_code import OpCode
3 |
4 |
5 | def check_include(opcodes):
6 | """
7 | Checks if any opcode requires standard libraries to be included
8 |
9 | Params
10 | ======
11 | opcodes (list) = List of opcodes
12 |
13 | Returns
14 | =======
15 | string: The string representation of unique include files
16 | """
17 |
18 | # List of includes
19 | includes = []
20 |
21 | # List of math constants
22 | math_func_const = ["M_PI", "M_E", "pow(", "INFINITY", "NAN"]
23 |
24 | # Loop through all opcodes
25 | for opcode in opcodes:
26 | # If opcode is of type print, then it requires stdio.h to be included
27 | if opcode.type == "print":
28 | includes.append("#include ")
29 |
30 | # If there is any boolean assignment opcode then include stdbool.h
31 | if opcode.dtype == "bool":
32 | includes.append("#include ")
33 |
34 | # If the opcode is a statement of type input, then it requires stdio.h to be included
35 | if len(opcode.val.split("---")) >= 3 and len(opcode.val.split('---')[-1]) == 1:
36 | includes.append("#include ")
37 |
38 | if any(math in opcode.val for math in math_func_const):
39 | includes.append("#include ")
40 |
41 | # Return string representation of unique elements of includes list separated by newline characters
42 | return "\n".join(list(set(includes)))
43 |
44 |
45 | def compile_func_main_code(outside_code, ccode, outside_main, code):
46 | """
47 | Check which code should go in main and which outside of main
48 |
49 | Params
50 | ======
51 | outside_code (string) = Code to be put outside main function
52 | ccode (string) = Code to be put inside main function
53 | outside_main (bool) = Decides where the code should go (true - outside, false - inside)
54 | code (string) = Compiled code
55 |
56 | Returns
57 | =======
58 | string, string: The outside and main C code strings
59 | """
60 |
61 | # If outside_main is true then code goes outside main
62 | if outside_main:
63 | outside_code += code
64 | else:
65 | if code == "}\n":
66 | code = "\t" + code
67 | ccode += code
68 |
69 | # Return code strings
70 | return outside_code, ccode
71 |
72 |
73 | def compile(opcodes, c_filename, table):
74 | """
75 | Compiles opcodes produced by parser into C code
76 |
77 | Params
78 | ======
79 | opcodes (list) = List of opcodes
80 | c_filename (string) = Name of C file to write C code into
81 | table (SymbolTable) = Symbol table constructed during lexical analysis and parsing
82 | """
83 |
84 | # Check for includes
85 | compiled_code = check_include(opcodes) + "\n"
86 |
87 | # Put the code in main function
88 | ccode = ""
89 |
90 | # Function code is compiled into separate list
91 | outside_code = ""
92 |
93 | # Check if function body has started or not
94 | outside_main = True
95 |
96 | # Check if the function has returned or not
97 | has_returned = False
98 |
99 | # Loop through all opcodes
100 | for opcode in opcodes:
101 | code = ""
102 | # If opcode is of type print then generate a printf statement
103 | if opcode.type == "print":
104 |
105 | if (
106 | opcode.val == '"%s", i'
107 | ): # Temporary solution to the printf( ) statement being used on strings
108 | opcode.val = '"%s", &i'
109 | # Generation of opcode is flawed as it fails to add the reference addess of the string being printed
110 |
111 | code = "\tprintf(%s);\n" % opcode.val
112 |
113 | # If opcode is of type import then generate include statement
114 | if opcode.type == "import":
115 | code = '#include "' + opcode.val + '.h"\n'
116 |
117 | # If opcode is of type var_assign then generate a declaration [/initialization] statement
118 | elif opcode.type == "var_assign":
119 | code = ""
120 |
121 | # val contains - ---, split that into a list
122 | val = opcode.val.split("---")
123 |
124 | # Get the datatye of the variable
125 | dtype = opcode.dtype
126 | if dtype == "declared":
127 | _, dtype, _, _, _ = table.get_by_id(table.get_by_symbol(val[0]))
128 |
129 | # Helper Dictionaries
130 | get_data_type = {
131 | "i": "int",
132 | "s": "char*",
133 | "f": "float",
134 | "d": "double",
135 | "c": "char",
136 | }
137 | get_placeholder = {"i": "d", "s": "s", "f": "f", "d": "lf", "c": "c"}
138 |
139 | # If it is of string type then change it to char []
140 | if dtype == "string":
141 | dtype = "char*"
142 | # Check if the statement is of type input or not
143 | if len(val) < 3:
144 | code += "\t" + dtype + " " + str(val[0]) + " = " + str(val[1]) + ";\n"
145 | else:
146 | # If the statement is of type input -
147 | dtype = get_data_type[val[2]]
148 | placeholder = get_placeholder[val[2]]
149 | code += "\t" + dtype + " " + str(val[0]) + ";\n"
150 | if val[1] != "":
151 | code += "\t" + 'printf("' + str(val[1]) + '");\n'
152 | code += "\t" + 'scanf("%' + placeholder
153 |
154 | if dtype == "char*":
155 | # If the datatype is character array, we need to pass in the reference address into scanf( )
156 | code += '", &' + str(val[0]) + ");\n"
157 | elif "*" in dtype:
158 | code += '", ' + str(val[0]) + ");\n"
159 | else:
160 | code += '", &' + str(val[0]) + ");\n"
161 | # If opcode is of type ptr_assign then generate a declarative statement
162 | elif opcode.type == "ptr_assign":
163 | code = ""
164 |
165 | # val contains - ------, split that into a list
166 | val = opcode.val.split("---")
167 |
168 | # Get the datatye of the variable
169 | _, dtype, _, _, _ = table.get_by_id(table.get_by_symbol(val[0]))
170 |
171 | # Helper Dictionaries
172 | get_data_type = {
173 | "i": "int",
174 | "s": "char*",
175 | "f": "float",
176 | "d": "double",
177 | "c": "char",
178 | }
179 | get_placeholder = {"i": "d", "s": "s", "f": "f", "d": "lf", "c": "c"}
180 |
181 | # If it is of string type then change it to char []
182 | if dtype == "string":
183 | dtype = "char*"
184 | code += (
185 | "\t"
186 | + dtype
187 | + " "
188 | + "*" * int(val[2])
189 | + str(val[0])
190 | + " = "
191 | + str(val[1])
192 | + ";\n"
193 | )
194 |
195 | # If opcode is of type var_no_assign then generate a declaration statement
196 | elif opcode.type == "var_no_assign":
197 | # val contains - ---, split that into a list
198 | val = opcode.val.split("---")
199 |
200 | # Get the datatye of the variable
201 | _, dtype, _, _, _ = table.get_by_id(table.get_by_symbol(val[0]))
202 | # Check if dtype could be inferred or not
203 | opcode.dtype = str(dtype) if dtype is not None else "not_known"
204 | code += "\t" + opcode.dtype + " " + str(opcode.val) + ";\n"
205 | elif opcode.type == "array_no_assign":
206 | # val contains - ---, split that into a list
207 | val = opcode.val.split("---")
208 | # Get the datatye of the variable
209 | _, dtype, _, _, _ = table.get_by_id(table.get_by_symbol(val[0]))
210 | # Check if dtype could be inferred or not
211 | opcode.dtype = str(dtype) if dtype is not None else "not_known"
212 | code += "\t" + opcode.dtype + " *" + str(val[0]) + ";\n"
213 | elif opcode.type == "array_assign":
214 | # val contains - ---, split that into a list
215 | val = opcode.val.split("---")
216 | # Get the datatye of the variable
217 | _, dtype, _, _, _ = table.get_by_id(table.get_by_symbol(val[0]))
218 | # Check if dtype could be inferred or not
219 | opcode.dtype = str(dtype) if dtype is not None else "not_known"
220 | code += (
221 | "\t"
222 | + opcode.dtype
223 | + " "
224 | + str(val[0])
225 | + "["
226 | + (val[1])
227 | + "]"
228 | + " = "
229 | + val[2]
230 | + ";\n"
231 | )
232 | elif opcode.type == "array_only_assign":
233 | # val contains - ---=( []), split that into a list
234 | val = opcode.val.split("---")
235 |
236 | # val[0] contains identifier and val[1] contains =( [])
237 | code += "\t" + val[0] + val[1] + ";\n"
238 | # If opcode is of type ptr_no_assign then generate declaration statement
239 | elif opcode.type == "ptr_no_assign":
240 | val = opcode.val.split("---")
241 | # Get the datatye of the variable
242 | _, dtype, _, _, _ = table.get_by_id(table.get_by_symbol(val[0]))
243 | # Check if dtype could be inferred or not
244 | opcode.dtype = str(dtype) if dtype is not None else "not_known"
245 | if opcode.dtype == "string":
246 | opcode.dtype = "char"
247 | code += "\t" + opcode.dtype + " *" + str(opcode.val) + ";\n"
248 |
249 | # If opcode is of type assign then generate an assignment statement
250 | elif opcode.type == "assign":
251 | # val contains - ---, split that into a list
252 | val = opcode.val.split("---")
253 | # Helper Dictionaries
254 | get_data_type = {
255 | "i": "int",
256 | "s": "char *",
257 | "f": "float",
258 | "d": "double",
259 | "c": "char",
260 | }
261 | get_placeholder = {"i": "d", "s": "s", "f": "f", "d": "lf", "c": "c"}
262 | # Check if the statement is of type input or not
263 | if len(val) == 3:
264 | code += "\t" + val[0] + " " + val[1] + " " + val[2] + ";\n"
265 | else:
266 | # If the statement is of type input
267 | dtype = get_data_type[val[3]]
268 | placeholder = get_placeholder[val[3]]
269 | if val[2] != "":
270 | code += "\t" + 'printf("' + str(val[2]) + '");\n'
271 | code += "\t" + 'scanf("%' + placeholder + '", &' + str(val[0]) + ");\n"
272 |
273 | # If opcode is of type ptr_only_assign then generate an assignment statement
274 | elif opcode.type == "ptr_only_assign":
275 | # val contains - ------, split that into a list
276 | val = opcode.val.split("---")
277 | code += "\t" + int(val[3]) * "*" + val[0] + " = " + val[2] + ";\n"
278 |
279 | # If opcode is of type unary then generate an uanry statement
280 | elif opcode.type == "unary":
281 | # val contains - ---, split that into a list
282 | val = opcode.val.split("---")
283 | print_val = ""
284 | for i in val:
285 | i = i.replace(" ", "")
286 | print_val += str(i)
287 | code += "\t" + print_val + ";\n"
288 | # If opcode is of type func_decl then generate function declaration statement
289 | elif opcode.type == "func_decl":
290 | # val contains - ---, split that into list
291 | val = opcode.val.split("---")
292 |
293 | # Check if function has params
294 | params = val[1].split("&&&") if len(val[1]) > 0 else []
295 |
296 | # Get the return type of the function
297 | _, dtype, _, _, _ = table.get_by_id(table.get_by_symbol(val[0]))
298 | dtype = dtype if dtype != "var" else "void"
299 |
300 | # Append the function return type and name to code
301 | code += "\n" + dtype + " " + val[0] + "("
302 |
303 | # Compile the formal params
304 | has_param = False
305 | for i in range(len(params)):
306 | if len(params[i]) > 0:
307 | has_param = True
308 | _, dtype, _, _, _ = table.get_by_id(table.get_by_symbol(params[i]))
309 | dtype = dtype if dtype != "var" else "not_known"
310 | dtype = "char*" if dtype == "string" else dtype
311 | code += dtype + " " + params[i] + ", "
312 | if has_param:
313 | code = code[:-2]
314 | else:
315 | code += "void"
316 |
317 | # Finally add opening brace to start the function body
318 | code += ") "
319 | # If the opcode is of type func_call then generate function calling statement
320 | elif opcode.type == "func_call":
321 | # val contains - ---, split that into list
322 | val = opcode.val.split("---")
323 |
324 | # Check if function has params
325 | params = val[1].split("&&&") if len(val[1]) > 0 else []
326 |
327 | # Compile function name
328 | code = "\t" + val[0] + "("
329 |
330 | # Compile the actual params
331 | has_param = False
332 | for param in params:
333 | if len(params) > 0:
334 | has_param = True
335 | code += param + ", "
336 | if has_param:
337 | code = code[:-2]
338 |
339 | # Finally add opening brace to start the function body
340 | code += ");\n"
341 | # If opcode is of type struct_decl then generate structure declaration statement
342 | elif opcode.type == "struct_decl":
343 | # extracting struct name from val
344 | struct_name = opcode.val
345 |
346 | # append the struct keyword and structure nameto the code
347 | code += "\n" + "struct" + " " + struct_name + " "
348 | # If opcode is of type struct_instantiate then generate structure instantiation statement
349 | elif opcode.type == "struct_instantiate":
350 | # Extract the identifier name of instance variable
351 | struct_name, instance_var_name = opcode.val.split("---")
352 |
353 | code += (
354 | "\t"
355 | + "struct "
356 | + struct_name.strip()
357 | + " "
358 | + instance_var_name.strip()
359 | + ";\n"
360 | )
361 | # If opcode is of type scope_begin then generate open brace statement
362 | elif opcode.type == "scope_begin":
363 | code += "\t{\n"
364 | # If opcode is of type scope_over then generate closing brace statement
365 | elif opcode.type == "scope_over":
366 | code += "}\n"
367 | # If opcode is of type struct_scope_over then generate closing brace, name of struct instance (if any) and add a semi-colon
368 | elif opcode.type == "struct_scope_over":
369 | code += "} " + opcode.val + ";\n"
370 | # If opcode is of type scope_over then generate closing brace statement
371 | elif opcode.type == "MAIN":
372 | code += "\nint main() {\n"
373 | outside_main = False
374 | has_returned = False
375 | # If opcode is of type scope_over then generate closing brace statement
376 | elif opcode.type == "END_MAIN":
377 | if not has_returned:
378 | code += "\n\treturn 0;"
379 | code += "\n}\n"
380 | outside_code, ccode = compile_func_main_code(
381 | outside_code, ccode, outside_main, code
382 | )
383 | outside_main = True
384 | continue
385 | # If opcode is of type for
386 | elif opcode.type == "for":
387 | val = opcode.val.split("&&&")
388 | code += (
389 | "\tfor(int "
390 | + val[0]
391 | + " = "
392 | + val[1]
393 | + "; "
394 | + val[0]
395 | + " "
396 | + val[4]
397 | + " "
398 | + val[2]
399 | + "; "
400 | + val[0]
401 | + val[3]
402 | + "="
403 | + val[5]
404 | + ") "
405 | )
406 | # If opcode is of type while then generate while loop statement
407 | elif opcode.type == "while":
408 | code = "\twhile(%s) " % opcode.val
409 | # If opcode is of type do then generate do statement
410 | elif opcode.type == "do":
411 | code = "\tdo "
412 | # If opcode is of type while_do then generate while for do-while statement
413 | elif opcode.type == "while_do":
414 | code = "\twhile(%s);" % opcode.val
415 | # If opcode is of type if then generate if statement
416 | elif opcode.type == "if":
417 | code = "\tif(%s) " % opcode.val
418 | # If opcode is of type exit then generate exit statement
419 | elif opcode.type == "exit":
420 | code = "\texit(%s);\n" % opcode.val
421 | # If opcode is of type else_if then generate else if statement
422 | elif opcode.type == "else_if":
423 | code = "\telse if(%s) " % opcode.val
424 | # If opcode is of type else then generate else statement
425 | elif opcode.type == "else":
426 | code = "\telse "
427 | # If opcode is of type return then generate return statement
428 | elif opcode.type == "return":
429 | code += "\n\treturn " + opcode.val + ";\n"
430 | has_returned = True
431 | # If opcode is of type break then generate break statement
432 | elif opcode.type == "break":
433 | code += "\tbreak;\n"
434 | # If opcode is of type continue then generate continue statement
435 | elif opcode.type == "continue":
436 | code += "\tcontinue;\n"
437 | # If opcode is of type single_line_comment the generate single comment line
438 | elif opcode.type == "single_line_comment":
439 | code += "\t// %s \n" % opcode.val
440 | # If opcode is of type multi_line_comment the generate single comment line
441 | elif opcode.type == "multi_line_comment":
442 | code += "/* %s*/\n" % opcode.val
443 | # If opcode is of type switch then generate switch statement
444 | elif opcode.type == "switch":
445 | code += "\tswitch(" + opcode.val + ") "
446 | # If opcode is of type case then generate case statement
447 | elif opcode.type == "case":
448 | code += "\tcase " + opcode.val + ":\n"
449 | # If opcode is of type default then generate default statement
450 | elif opcode.type == "default":
451 | code += "\tdefault:\n"
452 | # If opcode is of type RAW_c, simpaly copy the value
453 | elif opcode.type == "raw":
454 | code += opcode.val + "\n"
455 |
456 | outside_code, ccode = compile_func_main_code(
457 | outside_code, ccode, outside_main, code
458 | )
459 |
460 | # Add return 0 to the end of code
461 | compiled_code += outside_code + ccode
462 |
463 | # Write generated code into C file
464 | with open(c_filename, "w") as file:
465 | file.write(compiled_code)
466 |
--------------------------------------------------------------------------------
/simc/global_helpers.py:
--------------------------------------------------------------------------------
1 | # Library to exit code when error occurs
2 | import sys
3 |
4 |
5 | def check_if(got_type, should_be_types, error_msg, line_num):
6 | """
7 | Check if type matches what it should be otherwise throw an error and exit
8 |
9 | Params
10 | ======
11 | given_type (string) = Type of token to be checked
12 | should_be_types (string/list) = Type(s) to be compared with
13 | msg (string) = Error message to print in case some case fails
14 | line_num (int) = Line number
15 | """
16 |
17 | # Convert to list if type is string
18 | if type(should_be_types) == str:
19 | should_be_types = [should_be_types]
20 |
21 | # If the given_type is not part of should_be_types then throw error and exit
22 | if got_type not in should_be_types:
23 | error(error_msg, line_num)
24 |
25 |
26 | def error(msg, line_num):
27 | """
28 | Shows error message in red color and exits the current process
29 |
30 | Params
31 | ======
32 | msg (string) = The message to be shown as error message
33 | line_num (int) = Line number
34 | """
35 |
36 | # Prints the error to screen in red color and then exits tokenizer
37 | print("\033[91m[Line %d] Error: %s" % (line_num, msg), end=" ")
38 | print(" \033[m")
39 | sys.exit()
40 |
41 |
42 | def is_digit(char):
43 | """
44 | Checks if character is digit or not, includes 0-9 and .
45 |
46 | Params
47 | ======
48 | char (string) = Single character mostly part of a longer string
49 |
50 | Returns
51 | =======
52 | bool: Checks whether the character is number or not
53 | """
54 |
55 | return char in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."]
56 |
57 |
58 | def is_alpha(char):
59 | """
60 | Checks if character is alphabet or not, includes a-z and _
61 |
62 | Params
63 | ======
64 | char (string) = Single character mostly part of a longer string
65 |
66 | Returns
67 | =======
68 | bool: Checks whether the character is alphabet or not
69 | """
70 |
71 | return char.isalpha() or char == "_"
72 |
73 |
74 | def is_alnum(char):
75 | """
76 | Checks if character is alphabet or digit or none, checks if character is in a-z, 0-9, _, and . for alphanumeric character
77 |
78 | Params
79 | ======
80 | char (string) = Single character mostly part of a longer string
81 |
82 | Returns
83 | =======
84 | bool: Checks whether the character is alphabet/digit not
85 | """
86 |
87 | return (
88 | char.isalpha()
89 | or char == "_"
90 | or char in ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."]
91 | )
92 |
--------------------------------------------------------------------------------
/simc/op_code.py:
--------------------------------------------------------------------------------
1 | class OpCode:
2 | """
3 | OpCode class is responsible for creating opcodes
4 | """
5 |
6 | def __init__(self, opcode, val, dtype=None):
7 | """
8 | Initializer of OpCode class
9 |
10 | Params
11 | ======
12 | opcode (string) = Type of opcode as string
13 | val (string) = Value stored at opcode
14 | dtype (string) = Datatype of opcode
15 | """
16 |
17 | self.type = opcode
18 | self.val = val
19 | self.dtype = dtype
20 |
21 | def __str__(self):
22 | """
23 | Returns string representation of OpCode
24 |
25 | Returns
26 | =======
27 | string: The string representation of OpCode object, which can be used to print the opcodes
28 | """
29 |
30 | return "OpCode('%s', '%s', '%s')" % (self.type, self.val, self.dtype)
31 |
32 | def __eq__(self, other):
33 | """
34 | Check for equality of opcodes
35 |
36 | Returns
37 | =======
38 | bool: Whether a token object is equal to another or not
39 | """
40 |
41 | if (
42 | self.type == other.type
43 | and self.val == other.val
44 | and self.dtype == other.dtype
45 | ):
46 | return True
47 |
48 | return False
49 |
--------------------------------------------------------------------------------
/simc/package-index:
--------------------------------------------------------------------------------
1 | geometry - https://raw.githubusercontent.com/frankhart2018/geometry/master/geometry.simc
--------------------------------------------------------------------------------
/simc/parser/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/cimplec/sim-c/64f96d92c5a58abeb7656160ab38c8386c0d3bc9/simc/parser/__init__.py
--------------------------------------------------------------------------------
/simc/parser/array_parser.py:
--------------------------------------------------------------------------------
1 | from ..global_helpers import error, check_if
2 |
3 | from ..op_code import OpCode
4 |
5 |
6 | def array_initializer(tokens, i, table, size_of_array, msg, func_ret_type):
7 | """
8 | Parse array initializer list
9 |
10 | Params
11 | ======
12 | tokens (list) = List of tokens
13 | i (string/list) = Current index in list of tokens
14 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
15 | size_of_array (number) = Number of fileds expected to fill
16 | msg (string) = Error message to print in case some case fails
17 |
18 | Returns
19 | =======
20 | string, string, int: The expression, datatype of the expression and the current index in source
21 | code after parsing
22 | """
23 | from .simc_parser import expression
24 | from .function_parser import function_call_statement
25 |
26 | # Initial values
27 | op_value = ""
28 | op_type = -1
29 |
30 | # Mapping for precedence checking (double > float > int)
31 | type_to_prec = {"int": 3, "float": 4, "double": 5}
32 |
33 | # Mapping simc constant name to c constant name
34 | math_constants = {"PI": "M_PI", "E": "M_E", "inf": "INFINITY", "NaN": "NAN"}
35 |
36 | # Number of values initialized
37 | initialized_value_counts = 0
38 |
39 | # Predicted type of variable
40 | type_of_id = ""
41 |
42 | # Mark if comma if need
43 | expected_comma = False
44 |
45 | # Check if left brace follows assignment operator
46 | check_if(
47 | got_type=tokens[i].type,
48 | should_be_types="left_brace",
49 | error_msg="Expected {",
50 | line_num=tokens[i].line_num,
51 | )
52 |
53 | # Begin array initializer
54 | op_value += "{"
55 |
56 | # Maximum possible length of array
57 | max_length_array = 2 ** 32
58 |
59 | # If size is not empty then update max_length_array to that size
60 | if size_of_array != "":
61 | max_length_array = int(size_of_array)
62 |
63 | # Loop until right brace
64 | while i < len(tokens) - 1:
65 |
66 | # Check end of expression, stop loop
67 | if tokens[i].type == "right_brace":
68 | op_value += "}"
69 | break
70 |
71 | # The values overflow size of declared array
72 | if initialized_value_counts > max_length_array:
73 | error("Too many initializers ", tokens[i].line_num)
74 |
75 | # If is a new line, go to next
76 | if tokens[i].type == "newline":
77 | op_value += "\n"
78 | i += 1
79 | continue
80 |
81 | # Check for comma before next element
82 | if expected_comma and tokens[i].type == "comma":
83 | expected_comma = False
84 | op_value += ","
85 | i += 1
86 | continue
87 | elif expected_comma or (expected_comma is False and tokens[i].type == "comma"):
88 | error(
89 | "Expected values to be separated by comma in initializer list",
90 | tokens[i].line_num,
91 | )
92 |
93 | # If token is identifier or constant
94 | if tokens[i].type in ["number", "string", "id"]:
95 | # Fetch information from symbol table
96 | value, type_, typedata, _, _ = table.get_by_id(tokens[i].val)
97 |
98 | if type_ == "var":
99 | error("Variable %s used before declaration" % value, tokens[i].line_num)
100 |
101 | # Check if there is more than one type in initializers
102 | if initialized_value_counts > 1 and type_ != type_of_id:
103 | error("Too many unique types in initializers", tokens[i].line_num)
104 | else:
105 | type_of_id = type_
106 |
107 | error_message = "Array Initializer parsed incorrectly"
108 | op_value_temp, op_type, i_temp, func_ret_type = expression(
109 | tokens,
110 | i,
111 | table,
112 | error_message,
113 | block_type_promotion=True,
114 | func_ret_type=func_ret_type,
115 | )
116 | op_value += op_value_temp
117 |
118 | # If after splitting by comma there are more than one empty field then throw error
119 | # One is allowed since there can be one comma at the end like - {1, 2, }
120 | split_by_comma = op_value_temp.split(",")
121 | if split_by_comma.count('') > 1:
122 | error("Too many commas at the end of initializer list", line_num=tokens[i].line_num)
123 |
124 | # If the size of the array is defined, and if the number of tokens parsed is not equal to
125 | # what it should be, then display error
126 | if (
127 | size_of_array != ""
128 | and (i_temp - i != int(size_of_array) * 2 - 1)
129 | and tokens[i_temp - 1].type != "comma"
130 | ):
131 |
132 | # Number of elements in parsed array is equal to the
133 | # number of tokens parsed in expression minus the number of commas
134 | number_of_elements = (i_temp - i) - int((i_temp - i - 1) / 2)
135 | error_message = (
136 | f"Expected {size_of_array} entries, got {number_of_elements}"
137 | " entries instead."
138 | )
139 |
140 | error(error_message, tokens[i].line_num)
141 |
142 | # We need to update the total number of tokens parsed (i) according to the number of tokens
143 | # parsed in expression( ), which depends on if the second last token is a comma or not.
144 | if size_of_array == "":
145 | # If the size of the array is not mentioned, number of tokens parsed = i_temp - 1
146 | i = i_temp - 1
147 |
148 | elif tokens[i_temp - 1].type == "comma":
149 | # If the token following the last element inserted is a comma, then we will skip the following tokens.
150 | # For example, int arr[2] = { 1,2, }
151 | # 3 Skipped Tokens after the first element (We need to account for 2 commas and 1 element)
152 | i += int(size_of_array) * 2 - 1
153 | else:
154 | # Same logic as before, but in this case, the last element inserted has no
155 | # comma at the end, which means that we will have to skip 1 less token from before. For example,
156 | # int arr[2] = { 1,2 }
157 | # 2 Skipped Tokens after the first element (We need to account for 1 comma and 1 element)
158 | i += int(size_of_array) * 2 - 2
159 |
160 | # Expected comma
161 | expected_comma = True
162 |
163 | initialized_value_counts += 1
164 | i += 1
165 |
166 | # one comma after expression is allowed
167 | if tokens[i].type == "comma":
168 | i += 1
169 |
170 | # Check if ending right brace is present or not
171 | check_if(
172 | got_type=tokens[i].type,
173 | should_be_types="right_brace",
174 | error_msg="Expected }",
175 | line_num=tokens[i].line_num,
176 | )
177 |
178 | return op_value, op_type, i + 1
179 |
--------------------------------------------------------------------------------
/simc/parser/conditional_parser.py:
--------------------------------------------------------------------------------
1 | from ..global_helpers import error, check_if
2 |
3 | from ..op_code import OpCode
4 |
5 |
6 | def if_statement(tokens, i, table, func_ret_type):
7 | """
8 | Parse if statement
9 |
10 | Params
11 | ======
12 | tokens (list) = List of tokens
13 | i (int) = Current index in token
14 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
15 | func_ret_type (dict) = Dict of functions whose return type could not be resolved immediately
16 |
17 | Returns
18 | =======
19 | OpCode, int: The opcode for the assign code and the index after parsing if statement
20 | """
21 |
22 | from .simc_parser import expression, skip_all_nextlines
23 |
24 | # Check if ( follows if statement
25 | check_if(
26 | got_type=tokens[i].type,
27 | should_be_types="left_paren",
28 | error_msg="Expected ( after if statement",
29 | line_num=tokens[i].line_num,
30 | )
31 |
32 | # check if expression follows ( in if statement
33 | op_value, op_type, i, func_ret_type = expression(
34 | tokens,
35 | i,
36 | table,
37 | "Expected expression inside if statement",
38 | func_ret_type=func_ret_type,
39 | )
40 |
41 | # check if ) follows expression in if statement
42 | check_if(
43 | got_type=tokens[i - 1].type,
44 | should_be_types="right_paren",
45 | error_msg="Expected ) after expression in if statement",
46 | line_num=tokens[i - 1].line_num,
47 | )
48 |
49 | # If \n follows ) then skip all the \n characters
50 | if tokens[i + 1].type == "newline":
51 | i = skip_all_nextlines(tokens, i)
52 | i -= 1
53 |
54 | # Token index to be returned
55 | ret_idx = i
56 |
57 | if tokens[i].type == "newline":
58 | ret_idx = i + 1
59 |
60 | if tokens[i + 1].type == "left_brace":
61 | # Loop until } is reached
62 | i += 1
63 | ret_idx = i
64 | found_right_brace = False
65 | while i < len(tokens) and tokens[i].type != "right_brace":
66 | i += 1
67 |
68 | # If right brace found at end
69 | if i != len(tokens) and tokens[i].type == "right_brace":
70 | found_right_brace = True
71 |
72 | return OpCode("if", op_value[1:-1]), ret_idx - 1, func_ret_type
73 |
74 |
75 | def switch_statement(tokens, i, table, func_ret_type):
76 | """
77 | Parse switch statement
78 |
79 | Params
80 | ======
81 | tokens (list) = List of tokens
82 | i (int) = Current index in token
83 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
84 | func_ret_type (dict) = Dict of functions whose return type could not be resolved immediately
85 |
86 | Returns
87 | =======
88 | OpCode, int: The opcode for the assign code and the index after parsing switch statement
89 | """
90 |
91 | from .simc_parser import expression, skip_all_nextlines
92 |
93 | # Check if ( is present after switch keyword
94 | check_if(
95 | got_type=tokens[i].type,
96 | should_be_types="left_paren",
97 | error_msg="Expected ( after switch",
98 | line_num=tokens[i].line_num,
99 | )
100 |
101 | # Expected expression after ( in switch
102 | op_value, _, i, func_ret_type = expression(
103 | tokens,
104 | i,
105 | table,
106 | "Expected expression inside switch statement",
107 | func_ret_type=func_ret_type,
108 | )
109 |
110 | # Check if ) is present after expression in switch
111 | check_if(
112 | got_type=tokens[i - 1].type,
113 | should_be_types="right_paren",
114 | error_msg="Expected ) after expression in switch",
115 | line_num=tokens[i - 1].line_num,
116 | )
117 |
118 | # Skip all next lines before {
119 | if tokens[i + 1].type == "newline":
120 | i = skip_all_nextlines(tokens, i)
121 | i -= 1
122 |
123 | # Check if opening { is present, as switch cannot be single line
124 | check_if(
125 | got_type=tokens[i + 1].type,
126 | should_be_types="left_brace",
127 | error_msg="Expected { after switch statement",
128 | line_num=tokens[i + 1].line_num,
129 | )
130 |
131 | return OpCode("switch", op_value[1:-1], ""), i, func_ret_type
132 |
133 |
134 | def case_statement(tokens, i, table, func_ret_type):
135 | """
136 | Parse case statement
137 |
138 | Params
139 | ======
140 | tokens (list) = List of tokens
141 | i (int) = Current index in token
142 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
143 | func_ret_type (dict) = Dict of functions whose return type could not be resolved immediately
144 |
145 | Returns
146 | =======
147 | OpCode, int: The opcode for the assign code and the index after parsing case statement
148 | """
149 |
150 | from .simc_parser import expression
151 |
152 | # Expected expression after case keyword
153 | op_value, _, i, func_ret_type = expression(
154 | tokens,
155 | i,
156 | table,
157 | "Expected expected expression after case",
158 | expect_paren=False,
159 | func_ret_type=func_ret_type,
160 | )
161 |
162 | # Check if expression is followed by : (colon) in case statement
163 | check_if(
164 | got_type=tokens[i].type,
165 | should_be_types="colon",
166 | error_msg="Expected : after case in switch statement",
167 | line_num=tokens[i].line_num,
168 | )
169 |
170 | return OpCode("case", op_value, ""), i + 1, func_ret_type
171 |
--------------------------------------------------------------------------------
/simc/parser/function_parser.py:
--------------------------------------------------------------------------------
1 | from ..global_helpers import error, check_if
2 |
3 | from ..op_code import OpCode
4 |
5 |
6 | def function_call_statement(tokens, i, table, func_ret_type):
7 | """
8 | Parse function calling statement
9 |
10 | Params
11 | ======
12 | tokens (list) = List of tokens
13 | i (int) = Current index in token
14 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
15 | func_ret_type (dict) = If return type of function is not figured yet
16 |
17 | Returns
18 | =======
19 | OpCode, int, dict: The opcode for the assign code, index after parsing function calling statement and function return type
20 | """
21 |
22 | from .simc_parser import expression
23 |
24 | # Store the beginning index for function call from imported libraries
25 | beg_idx = i
26 |
27 | # Get information about the function from symbol table
28 | func_info = table.get_by_id(tokens[i].val)
29 | func_id = tokens[i].val
30 | func_name = func_info[0]
31 | metadata = func_info[2]
32 |
33 | if metadata == "variable":
34 | error(f"No definition found for function {func_name}", tokens[i].line_num)
35 |
36 | # Get all parameter ids (default and non-default) and the default values (if any)
37 | params, default_values = extract_func_typedata(metadata, table)
38 | num_formal_params = len(params)
39 | num_required_args = num_formal_params - len(default_values)
40 |
41 | params_start_idx = i + 1
42 |
43 | # Parse the arguments
44 | op_value, op_type, i, func_ret_type = expression(
45 | tokens,
46 | i + 1,
47 | table,
48 | "",
49 | accept_empty_expression=True,
50 | expect_paren=True,
51 | func_ret_type=func_ret_type,
52 | )
53 |
54 | params_end_idx = i
55 | actual_param_tokens = []
56 |
57 | for i in range(params_start_idx, params_end_idx):
58 | if tokens[i].type == "id":
59 | actual_param_tokens.append(tokens[i])
60 |
61 | # op_value start in 1 because it should start with "params)" not "(params)"
62 | op_value = op_value[1:]
63 | op_value_list = op_value.replace(" ", "").split(",")
64 | op_value_list = (
65 | op_value_list if len(op_value_list) > 0 and len(op_value_list[0]) > 0 else []
66 | )
67 | num_actual_params = len(op_value_list) if op_value_list != [")"] else 0
68 |
69 | # Check if number of actual and formal parameters match
70 | if num_actual_params != num_required_args:
71 | error(
72 | "Expected {} arguments but got {} in function {}".format(
73 | num_required_args, num_actual_params, func_name
74 | ),
75 | tokens[i].line_num,
76 | )
77 |
78 | # Fill the missing values in function call with default values
79 | op_value_list = fill_missing_args_with_defaults(
80 | op_value_list, default_values, num_actual_params, num_formal_params
81 | )
82 |
83 | # Assign datatype to formal parameters
84 | for j in range(len(params)):
85 | # If parameter list is empty
86 | if params[j] == ")":
87 | continue
88 |
89 | # Fetch the datatype of corresponding actual parameter from symbol table
90 | _, dtype, _, _, _ = table.get_by_id(
91 | actual_param_tokens[j].val
92 | if (len(actual_param_tokens) > 0 and j < len(actual_param_tokens))
93 | else table.get_by_symbol(op_value_list[j].replace(")", ""))
94 | )
95 |
96 | # The id of the formal parameter will always be greater than the function's identifier in symbol table
97 | param_id = table.get_by_symbol(params[j], id_greater_than=func_id)
98 |
99 | # Set the datatype of the formal parameter
100 | table.symbol_table[param_id][1] = dtype
101 |
102 | # Resolve pendenting infer types
103 | table.resolve_dependency(tokens, i, param_id)
104 |
105 | use_module_tokens = False
106 |
107 | # If it an imported function the type of the function will be a list containing tokens from module's lexing results
108 | # Push all the function names and the corresponding position from where to parse
109 | if func_info != -1 and type(func_info[1][2]) == list:
110 | func_ret_type[func_name] = func_info[1][1]
111 | use_module_tokens = True
112 |
113 | # Handles delayed inference of return types, this can occur in two situations
114 | # 1 - When the function is part of third party module, 2 - When the function's parameter are contained in return expression
115 | if func_name in func_ret_type.keys():
116 | # Case 1
117 | if use_module_tokens:
118 | # Parse the tokens which will help in deciding on the return type
119 | _, op_type, _, _ = expression(
120 | func_info[1][2],
121 | func_ret_type[func_name],
122 | table,
123 | "",
124 | func_ret_type=func_ret_type,
125 | )
126 |
127 | # Case 2
128 | else:
129 | _, op_type, _, _ = expression(
130 | tokens, func_ret_type[func_name], table, "", func_ret_type=func_ret_type
131 | )
132 |
133 | # Map datatype to appropriate datatype in C
134 | prec_to_type = {
135 | -1: "declared",
136 | 0: "char*",
137 | 1: "char*",
138 | 2: "char",
139 | 3: "int",
140 | 4: "float",
141 | 5: "double",
142 | 6: "bool",
143 | }
144 |
145 | table.symbol_table[table.get_by_symbol(func_name)][1] = prec_to_type[op_type]
146 | del func_ret_type[func_name]
147 |
148 | return (
149 | OpCode("func_call", func_name + "---" + "&&&".join(op_value_list)[:-1], ""),
150 | i + 1,
151 | func_ret_type,
152 | )
153 |
154 |
155 | def extract_func_typedata(typedata, table):
156 | """
157 | Extract typedata of function
158 |
159 | Params
160 | ======
161 | typedata (string) = Typedata of function in format "function---param1---param2---...&&&default_val1&&&...
162 | table (SymbolTable) = Symbol table
163 |
164 | Returns
165 | =======
166 | parameters (list) = Parameter names
167 | default_values (list) = Default values
168 | """
169 |
170 | func_typedata_split = typedata.split("&&&")
171 |
172 | param_segment = func_typedata_split[0]
173 |
174 | # Ignore the first index as it contains function's name
175 | parameters = param_segment.split("---")[1:]
176 |
177 | default_values = []
178 | for seg in func_typedata_split[1:]:
179 | default_value, _, _, _, _ = table.get_by_id(int(seg))
180 | default_values.append(default_value)
181 |
182 | return parameters, default_values
183 |
184 |
185 | def fill_missing_args_with_defaults(
186 | op_value_list, default_values, num_actual_params, num_formal_params
187 | ):
188 |
189 | # Compute the offset of default values according to the missing values count
190 | offset = len(default_values) - num_formal_params + num_actual_params
191 | default_values = default_values[offset:]
192 |
193 | # If there are not default values to be filled
194 | if not default_values:
195 | return op_value_list
196 |
197 | args = []
198 | for op_value in op_value_list:
199 | arg = op_value.replace(")", "")
200 | if arg:
201 | args.append(arg)
202 | args += default_values
203 | args[-1] = args[-1] + ")"
204 |
205 | return args
206 |
207 |
208 | def function_definition_statement(tokens, i, table, func_ret_type):
209 | """
210 | Parse function definition statement
211 | Params
212 | ======
213 | tokens (list) = List of tokens
214 | i (int) = Current index in token
215 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
216 | func_ret_type (string) = Function return type
217 | Returns
218 | =======
219 | OpCodes, int, string: The opcodes for the assign code, the index, and the name of the function after
220 | parsing function calling statement
221 | Grammar
222 | =======
223 | function_definition_statement -> fun id([formal_param,]*) { body }
224 | formal_params -> id ('=' default_value)
225 | default_value -> number || string
226 | body -> statement
227 | id -> [a-zA-Z_]?[a-zA-Z0-9_]*
228 | """
229 |
230 | from .simc_parser import skip_all_nextlines
231 |
232 | # Check if identifier follows fun
233 | check_if(
234 | got_type=tokens[i].type,
235 | should_be_types="id",
236 | error_msg="Expected function name",
237 | line_num=tokens[i].line_num,
238 | )
239 |
240 | # Store the id of function name in symbol table
241 | func_idx = tokens[i].val
242 |
243 | # Get function name
244 | func_name, _, _, _, _ = table.get_by_id(func_idx)
245 |
246 | # Check if ( follows id in function
247 | check_if(
248 | got_type=tokens[i + 1].type,
249 | should_be_types="left_paren",
250 | error_msg="Expected ( after function name",
251 | line_num=tokens[i + 1].line_num,
252 | )
253 |
254 | # Get the function parameter [and default value] tuples
255 | parameters, i = function_parameters(tokens, i + 2, table)
256 |
257 | # Check if ) follows expression in function
258 | check_if(
259 | got_type=tokens[i - 1].type,
260 | should_be_types="right_paren",
261 | error_msg="Expected ) after function params list",
262 | line_num=tokens[i - 1].line_num,
263 | )
264 |
265 | # If \n follows ) then skip all the \n characters
266 | if tokens[i + 1].type == "newline":
267 | i = skip_all_nextlines(tokens, i)
268 | i -= 1
269 |
270 | op_codes = []
271 |
272 | # Index to be returned to main parsing loop
273 | ret_idx = i
274 |
275 | if tokens[i].type == "newline":
276 | ret_idx = i + 1
277 |
278 | if tokens[i + 1].type == "left_brace":
279 | # Loop until } is reached
280 | i += 1
281 | ret_idx = i
282 | found_right_brace = False
283 |
284 | while i < len(tokens) and tokens[i].type != "right_brace":
285 | i += 1
286 |
287 | # If right brace found at end
288 | if i != len(tokens) and tokens[i].type == "right_brace":
289 | found_right_brace = True
290 |
291 | # If right brace is not found then produce error
292 | if not found_right_brace:
293 | error("Expected } after function body", tokens[i].line_num)
294 |
295 | else:
296 | op_codes.append(OpCode("scope_begin", "", ""))
297 |
298 | # Add the identifier types to function's typedata
299 | parameter_names = [parameter[0] for parameter in parameters]
300 | default_values = [
301 | str(parameter[1]) for parameter in parameters if parameter[1] is not None
302 | ]
303 |
304 | func_typedata = "function"
305 | if parameter_names:
306 | func_typedata += "---" + "---".join(parameter_names)
307 | if default_values:
308 | func_typedata += "&&&" + "&&&".join(default_values)
309 |
310 | table.symbol_table[func_idx][2] = func_typedata
311 |
312 | op_codes.append(
313 | OpCode("func_decl", func_name + "---" + "&&&".join(parameter_names), "")
314 | )
315 |
316 | # The order now is scope_begin followed by func_decl, but the compiler expects the opposite order
317 | op_codes.reverse()
318 |
319 | return (
320 | op_codes,
321 | ret_idx - 1,
322 | func_name,
323 | func_ret_type,
324 | )
325 |
326 |
327 | def function_parameters(tokens, i, table):
328 | """
329 | Parse function parameters
330 | Params
331 | ======
332 | tokens (list) = List of tokens
333 | i (int) = Current index in list of tokens
334 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
335 | Returns
336 | =======
337 | parameters (list) = List of parameters (= list of (ids, default))
338 | i (int) = Current index in list of tokens
339 | """
340 | if tokens[i].type == "right_paren":
341 |
342 | i += 1
343 |
344 | return [], i
345 |
346 | parameters = []
347 | default_val_required = False
348 |
349 | # Get the first parameter [and default value]
350 | param_info, i = function_parameter(tokens, i, table, default_val_required)
351 |
352 | # If there are parameters
353 | if param_info is not None:
354 |
355 | parameters.append(param_info)
356 | _, default_val = param_info
357 | default_val_required = default_val is not None
358 |
359 | # Continue parsing until comma tokens are encountered
360 | while tokens[i].type == "comma":
361 | # Skip comma token
362 | i += 1
363 |
364 | # Get parameter [and default value]
365 | param_info, i = function_parameter(tokens, i, table, default_val_required)
366 |
367 | if param_info is not None:
368 | parameters.append(param_info)
369 | if not default_val_required:
370 | _, default_val = param_info
371 | default_val_required = default_val is not None
372 | else:
373 | error("Parameter expected after comma", tokens[i].line_num)
374 |
375 | check_if(
376 | got_type=tokens[i].type,
377 | should_be_types="right_paren",
378 | error_msg="Right parentheses expected",
379 | line_num=tokens[i].line_num,
380 | )
381 |
382 | # Skip right parantheses
383 | i += 1
384 |
385 | else:
386 | error("Function parameters must be identifiers", tokens[i].line_num)
387 |
388 | return parameters, i
389 |
390 |
391 | def function_parameter(tokens, i, table, default_val_required):
392 | """
393 | Parse function parameter
394 | Params
395 | ======
396 | tokens (list) = List of tokens
397 | i (int) = Current index in list of tokens
398 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
399 | default_val_required (bool) = Default value is required
400 | Returns
401 | =======
402 | (parameter, default_val_id?) (tuple?) = Parameter and optional default value id or none
403 | i (int) = Current index in list of tokens
404 | """
405 | if tokens[i].type != "id":
406 | return None, i
407 |
408 | # Get the parameter from symbol table id stored in token
409 | parameter, _, _, _, _ = table.get_by_id(tokens[i].val)
410 | i += 1
411 |
412 | default_val = None
413 |
414 | # To handle the case when a parameter on left has default value and the current one does not
415 | if default_val_required:
416 | check_if(
417 | got_type=tokens[i].type,
418 | should_be_types="assignment",
419 | error_msg="Default value expected for parameter {}".format(parameter),
420 | line_num=tokens[i].line_num,
421 | )
422 |
423 | # Skip the assignment operator
424 | i += 1
425 |
426 | # Default parameter values can be number or string only as of now
427 | if tokens[i].type in ["number", "string"]:
428 | default_val = tokens[i].val
429 | i += 1
430 | else:
431 | error(
432 | "Only numbers and strings are allowed as default arguments",
433 | tokens[i].line_num,
434 | )
435 | elif tokens[i].type == "assignment":
436 | i += 1
437 | if tokens[i].type in ["number", "string"]:
438 | default_val = tokens[i].val
439 | i += 1
440 | else:
441 | error(
442 | "Only numbers and strings are allowed as default arguments",
443 | tokens[i].line_num,
444 | )
445 |
446 | return (parameter, default_val), i
447 |
--------------------------------------------------------------------------------
/simc/parser/loop_parser.py:
--------------------------------------------------------------------------------
1 | from ..global_helpers import error, check_if
2 |
3 | from ..op_code import OpCode
4 |
5 |
6 | def for_statement(tokens, i, table, func_ret_type):
7 | """
8 | Parse for for_loop
9 | Params
10 | ======
11 | tokens (list) = List of tokens
12 | i (int) = Current index in token
13 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
14 | Returns
15 | =======
16 | OpCode, int: The opcode for the for loop code and the index after parsing for loop
17 | Grammar
18 | =======
19 | for_loop -> for id in number to number by operator number
20 | number -> [0-9]+
21 | id -> [a-zA-Z_]?[a-zA-Z0-9_]*
22 | operator -> + | - | * | /
23 | """
24 | from .simc_parser import expression
25 |
26 | # Check if identifier follows for keyword
27 | check_if(
28 | got_type=tokens[i].type,
29 | should_be_types="id",
30 | error_msg="Expected variable name",
31 | line_num=tokens[i].line_num,
32 | )
33 |
34 | # Check if in follows identifier
35 | check_if(
36 | got_type=tokens[i + 1].type,
37 | should_be_types="in",
38 | error_msg="Expected in keyword",
39 | line_num=tokens[i + 1].line_num,
40 | )
41 |
42 | # Check if number follows in keyword
43 | expression(tokens, i + 2, table, "Expected starting value", expect_paren=False)
44 |
45 | # Check if to keyword follows number
46 | check_if(
47 | got_type=tokens[i + 3].type,
48 | should_be_types="to",
49 | error_msg="Expected to keyword",
50 | line_num=tokens[i + 3].line_num,
51 | )
52 |
53 | # Check if number follows in keyword
54 | expression(tokens, i + 4, table, "Expected ending value", expect_paren=False)
55 |
56 | # Check if by keyword follows number
57 | check_if(
58 | got_type=tokens[i + 5].type,
59 | should_be_types="by",
60 | error_msg="Expected by keyword",
61 | line_num=tokens[i + 5].line_num,
62 | )
63 |
64 | word_to_op = {"plus": "+", "minus": "-", "multiply": "*", "divide": "/"}
65 |
66 | # Check if number follows operator
67 | expression(tokens, i + 7, table, "Expected value for change", expect_paren=False)
68 |
69 | # Get required values
70 | var_name, _, _, _, _ = table.get_by_id(tokens[i].val)
71 |
72 | # Set the value
73 | table.symbol_table[tokens[i].val][1] = "int"
74 |
75 | starting_val, _, _, _, _ = table.get_by_id(tokens[i + 2].val)
76 | ending_val, _, _, _, _ = table.get_by_id(tokens[i + 4].val)
77 | operator_type = word_to_op[tokens[i + 6].type]
78 | change_val, _, _, _, _ = table.get_by_id(tokens[i + 7].val)
79 |
80 | # To determine the > or < sign
81 | if starting_val > ending_val:
82 | sign_needed = ">"
83 | else:
84 | sign_needed = "<"
85 |
86 | # Return the opcode and i+1 (the token after for loop statement)
87 | return (
88 | OpCode(
89 | "for",
90 | str(var_name)
91 | + "&&&"
92 | + str(starting_val)
93 | + "&&&"
94 | + str(ending_val)
95 | + "&&&"
96 | + str(operator_type)
97 | + "&&&"
98 | + sign_needed
99 | + "&&&"
100 | + str(change_val),
101 | ),
102 | i + 1,
103 | func_ret_type,
104 | )
105 |
106 |
107 | def while_statement(tokens, i, table, in_do, func_ret_type):
108 | """
109 | Parse while statement
110 | Params
111 | ======
112 | tokens (list) = List of tokens
113 | i (int) = Current index in token
114 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
115 | in_do (bool) = While is part of do-while or is a separate while
116 | Returns
117 | =======
118 | OpCode, int: The opcode for the assign code and the index after parsing while statement
119 | Grammar
120 | =======
121 | while_statement -> while(condition) { body }
122 | condition -> expr
123 | expr -> string | number | id | operator
124 | string -> quote [a-zA-Z0-9`~!@#$%^&*()_-+={[]}:;,.?/|\]+ quote
125 | quote -> "
126 | number -> [0-9]+
127 | id -> [a-zA-Z_]?[a-zA-Z0-9_]*
128 | operator -> + | - | * | /
129 | """
130 | from .simc_parser import expression, skip_all_nextlines
131 |
132 | # Check if ( follows while statement
133 | check_if(
134 | got_type=tokens[i].type,
135 | should_be_types="left_paren",
136 | error_msg="Expected ( after while statement",
137 | line_num=tokens[i].line_num,
138 | )
139 |
140 | # check if expression follows ( in while statement
141 | op_value, _, i, func_ret_type = expression(
142 | tokens,
143 | i,
144 | table,
145 | "Expected expression inside while statement",
146 | func_ret_type=func_ret_type,
147 | )
148 |
149 | # check if ) follows expression in while statement
150 | check_if(
151 | got_type=tokens[i - 1].type,
152 | should_be_types="right_paren",
153 | error_msg="Expected ) after expression in while statement",
154 | line_num=tokens[i - 1].line_num,
155 | )
156 |
157 | # If while is not part of do-while
158 | if not in_do:
159 | # If \n follows ) then skip all the \n characters
160 | if tokens[i + 1].type == "newline":
161 | i = skip_all_nextlines(tokens, i)
162 | i -= 1
163 |
164 | ret_idx = i
165 | if tokens[i].type == "newline":
166 | ret_idx = i + 1
167 | if tokens[i + 1].type == "left_brace":
168 | # Loop until } is reached
169 | i += 1
170 | ret_idx = i
171 | found_right_brace = False
172 |
173 | while i < len(tokens) and tokens[i].type != "right_brace":
174 | i += 1
175 |
176 | # If right brace found at end
177 | if i != len(tokens) and tokens[i].type == "right_brace":
178 | found_right_brace = True
179 |
180 | # If right brace is not found then produce error
181 | if not found_right_brace:
182 | error("Expected } after while loop body", tokens[i].line_num)
183 |
184 | return OpCode("while", op_value[1:-1]), ret_idx - 1, func_ret_type
185 | else:
186 | return OpCode("while_do", op_value[1:-1]), i + 1, func_ret_type
187 |
--------------------------------------------------------------------------------
/simc/parser/parser_constants.py:
--------------------------------------------------------------------------------
1 | OP_TOKENS = [
2 | "number",
3 | "input",
4 | "string",
5 | "id",
6 | "plus",
7 | "minus",
8 | "multiply",
9 | "power",
10 | "divide",
11 | "bitwise_and",
12 | "bitwise_xor",
13 | "bitwise_or",
14 | "bitwise_and_equal",
15 | "bitwise_xor_equal",
16 | "bitwise_or_equal",
17 | "comma",
18 | "equal",
19 | "not_equal",
20 | "greater_than",
21 | "less_than",
22 | "greater_than_equal",
23 | "less_than_equal",
24 | "modulus",
25 | "increment",
26 | "decrement",
27 | "plus_equal",
28 | "minus_equal",
29 | "multiply_equal",
30 | "divide_equal",
31 | "modulus_equal",
32 | "power_equal",
33 | "and",
34 | "or",
35 | "left_paren",
36 | "left_bracket",
37 | "exit",
38 | "right_paren",
39 | "right_bracket",
40 | "newline",
41 | "call_end",
42 | "address_of",
43 | "right_shift",
44 | "left_shift",
45 | "bool",
46 | "type_cast",
47 | "size",
48 | "type",
49 | ]
50 |
51 | WORD_TO_OP = {
52 | "plus": " + ",
53 | "minus": " - ",
54 | "multiply": " * ",
55 | "divide": " / ",
56 | " comma ": ", ",
57 | "equal": " == ",
58 | "not_equal": " != ",
59 | "greater_than": " > ",
60 | "less_than": " < ",
61 | "greater_than_equal": " >= ",
62 | "less_than_equal": " <= ",
63 | "input": " scanf ",
64 | "modulus": " % ",
65 | "increment": " ++ ",
66 | "decrement": " -- ",
67 | "plus_equal": " += ",
68 | "minus_equal": " -= ",
69 | "multiply_equal": " *= ",
70 | "divide_equal": " /= ",
71 | "modulus_equal": " %= ",
72 | "and": " && ",
73 | "or": " || ",
74 | "bitwise_and": " & ",
75 | "bitwise_or": " | ",
76 | "bitwise_xor": " ^ ",
77 | "bitwise_and_equal": " &= ",
78 | "bitwise_or_equal": " |= ",
79 | "bitwise_xor_equal": " ^= ",
80 | "comma": ",",
81 | "left_bracket": "[",
82 | "right_bracket": "]",
83 | "left_paren": "(",
84 | "right_paren": ")",
85 | "address_of": "&",
86 | "left_shift": " << ",
87 | "right_shift": " >> ",
88 | "power": "",
89 | }
90 |
--------------------------------------------------------------------------------
/simc/parser/struct_parser.py:
--------------------------------------------------------------------------------
1 | from ..global_helpers import error, check_if
2 |
3 | from ..op_code import OpCode
4 |
5 |
6 | def initializate_struct(tokens, i, table, instance_var_name, var_list):
7 | """
8 | Initialization of a struction when the variable instantiate is type of a declared struct
9 | Params
10 | ======
11 | tokens (list) = List of tokens
12 | i (int) = Current index in token
13 | table (SymbolTable) = Symbol Table constructed holding information about identifiers and constans
14 | instance_var_name (String) = Name of the instance of the struct
15 | var_list (String) = List of if variable declared inside struct
16 | """
17 | # Initializate the child variable of struct
18 | var_ids = var_list.split("-")[1:]
19 |
20 | # Load var and copy to struct initilization
21 | for var_id in var_ids:
22 |
23 | # Find the child variable of struct
24 | var_name, type_, metatype_, _, _ = table.get_by_id(int(var_id))
25 | new_var_name = instance_var_name + "." + var_name
26 |
27 | # Check if variable already exist
28 | new_var_id = table.get_by_symbol(new_var_name)
29 | # If it not exist, then create a new
30 | if new_var_id is -1:
31 | table.entry(instance_var_name + "." + var_name, type_, metatype_, "")
32 | # Otherwise, Modify datatype of the identifier
33 | else:
34 | table.symbol_table[new_var_id][1] = type_
35 | table.symbol_table[new_var_id][3] += "-" + var_id
36 |
37 |
38 | def struct_declaration_statement(tokens, i, table):
39 | """
40 | Parse structure declaration statement
41 | Params
42 | ======
43 | tokens (list) = List of tokens
44 | i (int) = Current index in token
45 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
46 | Returns
47 | =======
48 | OpCode, int, string: The opcode for the assign code, the index, and the name of the function after
49 | parsing function calling statement
50 | """
51 |
52 | from .simc_parser import skip_all_nextlines
53 |
54 | # Check if identifier follows struct
55 | check_if(
56 | got_type=tokens[i].type,
57 | should_be_types="id",
58 | error_msg="Expected structure name",
59 | line_num=tokens[i].line_num,
60 | )
61 |
62 | # Store the id of strcuture name in symbol table
63 | struct_idx = tokens[i].val
64 |
65 | # Update type to hold struct_var instead of var
66 | table.symbol_table[struct_idx][1] = "struct_var"
67 |
68 | # Get struct name
69 | struct_name, _, _, _, _ = table.get_by_id(struct_idx)
70 |
71 | # If \n follows struct name then skip all the \n characters
72 | if tokens[i + 1].type == "newline":
73 | i = skip_all_nextlines()
74 | i -= 1
75 |
76 | # Check if { follows the structure name
77 | check_if(
78 | got_type=tokens[i + 1].type,
79 | should_be_types="left_brace",
80 | error_msg="Expected { after structure name body",
81 | line_num=tokens[i + 1].line_num,
82 | )
83 |
84 | # Loop until } is reached
85 | i += 2
86 | ret_idx = i
87 | found_right_brace = False
88 | while i < len(tokens) and tokens[i].type != "right_brace":
89 | i += 1
90 |
91 | # If right brace found at end
92 | if i != len(tokens) and tokens[i].type == "right_brace":
93 | found_right_brace = True
94 |
95 | # If right brace is not found then produce error
96 | if not found_right_brace:
97 | error("Expected } after structure body", tokens[i].line_num)
98 |
99 | return (OpCode("struct_decl", struct_name, ""), ret_idx - 1, struct_name)
100 |
--------------------------------------------------------------------------------
/simc/parser/variable_parser.py:
--------------------------------------------------------------------------------
1 | from ..global_helpers import error, check_if
2 |
3 | from ..op_code import OpCode
4 |
5 |
6 | def check_ptr(tokens, i):
7 | # Check if a pointer is being declared
8 | is_ptr = False
9 |
10 | # Count the depth of pointer
11 | count_ast = 0
12 |
13 | if tokens[i].type == "multiply":
14 | asterisk_count = 0
15 |
16 | # Accumulate count of * in j
17 | while tokens[i + asterisk_count].type == "multiply":
18 | asterisk_count += 1
19 |
20 | # Add asterisk count to token index to get index of token after all asterisks
21 | i += asterisk_count
22 |
23 | is_ptr = True
24 | return is_ptr, asterisk_count, i
25 | else:
26 | return False, 0, i
27 |
28 |
29 | def var_statement(tokens, i, table, func_ret_type):
30 | """
31 | Parse variable and array declaration [/initialization] statement
32 | Params
33 | ======
34 | tokens (list) = List of tokens
35 | i (int) = Current index in token
36 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
37 | func_ret_type (string) = Function return type
38 | Returns
39 | =======
40 | OpCode, int: The opcode for the var_assign/var_no_assign code and the index after parsing var statement
41 | Grammar
42 | =======
43 | var_statement -> var id [= expr]?
44 | expr -> string | number | id | operator
45 | string -> quote [a-zA-Z0-9`~!@#$%^&*()_-+={[]}:;,.?/|\]+ quote
46 | quote -> "
47 | number -> [0-9]+
48 | id -> [a-zA-Z_]?[a-zA-Z0-9_]*
49 | operator -> + | - | * | /
50 | """
51 | from .array_parser import array_initializer
52 | from .simc_parser import expression
53 |
54 | # Check if the variable is a pointer, and if it is then get the depth of pointer
55 | is_ptr, asterisk_count, i = check_ptr(tokens, i)
56 |
57 | # Check if identifier is present after var
58 | check_if(
59 | got_type=tokens[i].type,
60 | should_be_types="id",
61 | error_msg="Expected id after var keyword",
62 | line_num=tokens[i].line_num,
63 | )
64 |
65 | # Tokens that are not accepted after declaration of a variable
66 | invalid_tokens = [
67 | # Shortcut arithmetic assignments
68 | "plus_equal",
69 | "minus_equal",
70 | "multiply_equal",
71 | "divide_equal",
72 | "modulus_equal",
73 | # Arithmetic operators
74 | "plus",
75 | "minus",
76 | "multiply",
77 | "divide",
78 | "modulus",
79 | # Bitwise operators
80 | "bitwise_and",
81 | "bitwise_or",
82 | "bitwise_xor",
83 | # Shortcut bitwise assignments
84 | "bitwise_and_equal",
85 | "bitwise_or_equal",
86 | "bitwise_xor_equal",
87 | # Relational operators
88 | "equal",
89 | "not_equal",
90 | ]
91 |
92 | # Map datatype to appropriate datatype in C
93 | prec_to_type = {
94 | -1: "declared",
95 | 0: "string",
96 | 1: "char*",
97 | 2: "char",
98 | 3: "int",
99 | 4: "float",
100 | 5: "double",
101 | 6: "bool",
102 | }
103 |
104 | # Check if it is an array declaration (+ initializer list)
105 | if tokens[i + 1].type == "left_bracket":
106 |
107 | # Size of array
108 | size_of_array = ""
109 |
110 | # Store the index of identifier
111 | id_idx = i
112 |
113 | # If the next token after [ is a number
114 | if tokens[i + 2].type == "number":
115 | # Fetch information from symbol table
116 | value, type_, _, _, _ = table.get_by_id(tokens[i + 2].val)
117 |
118 | if type_ == "int":
119 | size_of_array = value
120 | else:
121 | error(
122 | f"Expected integer size of array but got {type_}",
123 | tokens[i + 2].line_num,
124 | )
125 |
126 | # Check if array statement has closing ] (right_bracket)
127 | check_if(
128 | got_type=tokens[i + 3].type,
129 | should_be_types="right_bracket",
130 | error_msg="Expected ] after expression in array statement",
131 | line_num=tokens[i + 3].line_num,
132 | )
133 |
134 | # Move token index to end of array declaration (right bracket)
135 | i += 3
136 | elif tokens[i + 2].type == "right_bracket":
137 | # Size of array is not known
138 | size_of_array = ""
139 |
140 | # Move token index to end of array declaration (right bracket)
141 | i += 2
142 |
143 | # Check if array is initialized as var [] = {1, 2, ...}
144 | if i + 1 < len(tokens) and tokens[i + 1].type == "assignment":
145 | # Check if expression follows = in array statement
146 | op_value, op_type, i = array_initializer(
147 | tokens,
148 | i + 2,
149 | table,
150 | size_of_array,
151 | "Required expression after assignment operator",
152 | func_ret_type=func_ret_type,
153 | )
154 | i += 1
155 |
156 | # Modify datatype of the identifier
157 | table.symbol_table[tokens[id_idx].val][1] = prec_to_type[op_type]
158 |
159 | # Add the size of array to metadata (typedata) in symbol table
160 | table.symbol_table[tokens[id_idx].val][2] = (
161 | size_of_array if size_of_array != "" else -1
162 | )
163 |
164 | # Return the opcode and i (the token after var statement)
165 | return (
166 | OpCode(
167 | "array_assign",
168 | table.symbol_table[tokens[id_idx].val][0]
169 | + "---"
170 | + str(size_of_array)
171 | + "---"
172 | + op_value,
173 | prec_to_type[op_type],
174 | ),
175 | i,
176 | func_ret_type,
177 | )
178 | elif i + 1 < len(tokens) and tokens[i + 1].type in invalid_tokens:
179 | error("Invalid Syntax for declaration", tokens[i].line_num)
180 | else:
181 | # Get the value from symbol table by id
182 | value, type_, _, _, _ = table.get_by_id(tokens[id_idx].val)
183 |
184 | # If already declared then throw error
185 | if type_ in [
186 | "declared",
187 | "int",
188 | "char",
189 | "float",
190 | "double",
191 | "string",
192 | "char *",
193 | "char*",
194 | ]:
195 | error("Variable %s already declared" % value, tokens[i].line_num)
196 |
197 | # Set type to declared
198 | table.symbol_table[tokens[id_idx].val][1] = "arr_declared"
199 |
200 | # Check if size of array has been determined or not, it isn't then throw error
201 | # Since for later assignment size needs to be known
202 | if size_of_array == "":
203 | error(
204 | "Size of array needs to be known if assignment is not done while"
205 | " declaration",
206 | tokens[i].line_num,
207 | )
208 | else:
209 | table.symbol_table[tokens[id_idx].val][2] = size_of_array
210 | return (
211 | OpCode("array_no_assign", value + "---" + str(size_of_array)),
212 | i,
213 | func_ret_type,
214 | )
215 |
216 | # Check if variable is assigned with declaration
217 | elif i + 1 < len(tokens) and tokens[i + 1].type == "assignment":
218 | # Store the index of identifier
219 | id_idx = i
220 |
221 | # Check if expression follows = in var statement
222 | op_value, op_type, i, func_ret_type = expression(
223 | tokens,
224 | i + 2,
225 | table,
226 | "Required expression after assignment operator",
227 | expect_paren=False,
228 | func_ret_type=func_ret_type,
229 | )
230 |
231 | # Modify datatype of the identifier
232 | table.symbol_table[tokens[id_idx].val][1] = prec_to_type[op_type]
233 |
234 | if is_ptr:
235 | return (
236 | OpCode(
237 | "ptr_assign",
238 | table.symbol_table[tokens[id_idx].val][0]
239 | + "---"
240 | + op_value
241 | + "---"
242 | + str(asterisk_count),
243 | prec_to_type[op_type],
244 | ),
245 | i,
246 | func_ret_type,
247 | )
248 | else:
249 | # Return the opcode and i (the token after var statement)
250 | return (
251 | OpCode(
252 | "var_assign",
253 | table.symbol_table[tokens[id_idx].val][0] + "---" + op_value,
254 | prec_to_type[op_type],
255 | ),
256 | i,
257 | func_ret_type,
258 | )
259 | elif i + 1 < len(tokens) and tokens[i + 1].type in invalid_tokens:
260 | error("Invalid Syntax for declaration", tokens[i].line_num)
261 |
262 | # If it is of pointer or variable type but has no value yet
263 | else:
264 | # Get the value from symbol table by id
265 | value, type, _, _, _ = table.get_by_id(tokens[i].val)
266 |
267 | # If already declared then throw error
268 | if type in [
269 | "declared",
270 | "int",
271 | "char",
272 | "float",
273 | "double",
274 | "string",
275 | "char *",
276 | "char*",
277 | "bool",
278 | ]:
279 | error("Variable %s already declared" % value, tokens[i].line_num)
280 |
281 | # Set declared
282 | table.symbol_table[tokens[i].val][1] = "declared"
283 |
284 | # Return the opcode and i+1 (the token after var statement)
285 | if is_ptr:
286 | return OpCode("ptr_no_assign", value), i + 1, func_ret_type
287 |
288 | return OpCode("var_no_assign", value), i + 1, func_ret_type
289 |
290 |
291 | def assign_statement(tokens, i, table, func_ret_type):
292 | """
293 | Parse assignment statement
294 | Params
295 | ======
296 | tokens (list) = List of tokens
297 | i (int) = Current index in token
298 | table (SymbolTable) = Symbol table constructed holding information about identifiers and constants
299 | Returns
300 | =======
301 | OpCode, int: The opcode for the assign code and the index after parsing assign statement
302 | Grammar
303 | =======
304 | var_statement -> var id [= expr]?
305 | expr -> string | number | id | operator
306 | string -> quote [a-zA-Z0-9`~!@#$%^&*()_-+={[]}:;,.?/|\]+ quote
307 | quote -> "
308 | number -> [0-9]+
309 | id -> [a-zA-Z_]?[a-zA-Z0-9_]*
310 | operator -> + | - | * | /
311 | """
312 | from .simc_parser import expression
313 | from .array_parser import array_initializer
314 |
315 | # Map datatype to appropriate datatype in C
316 | prec_to_type = {
317 | -1: "declared",
318 | 0: "string",
319 | 1: "char*",
320 | 2: "char",
321 | 3: "int",
322 | 4: "float",
323 | 5: "double",
324 | 6: "bool",
325 | }
326 |
327 | # Check if the identifier is a pointer
328 | is_ptr = False
329 | # count depth of pointer
330 | count_ast = 0
331 |
332 | if tokens[i - 2].type == "multiply":
333 | j = -2
334 | while tokens[j + i].type == "multiply":
335 | j -= 1
336 | count_ast = -1 * j - 2
337 | is_ptr = True
338 |
339 | # Check if variable is declared or not
340 | var_name, type_, _, _, scope = table.get_by_id(tokens[i - 1].val)
341 |
342 | # If - is not in scope then it wasn't declared, otherwise its scope would have been resolved by now
343 | # and it would have the form -- as the scope
344 | if type_ == "var" and "-" not in scope:
345 | error("Variable %s used before declaration" % var_name, tokens[i - 1].line_num)
346 |
347 | # Index of assignment in array
348 | op_value_idx = ""
349 |
350 | # Store the index of identifier
351 | id_idx = i - 1
352 |
353 | # Store the id of variable in Symbol Table
354 | var_id = tokens[id_idx].val
355 |
356 | # Check if is a array indexing case
357 | if tokens[i].type == "left_bracket":
358 | if tokens[i + 1].type == "number":
359 | # Fetch information from symbol table
360 | value, type_, _, _, _ = table.get_by_id(tokens[i + 1].val)
361 |
362 | if type_ == "int":
363 | if int(value) >= int(table.symbol_table[tokens[id_idx].val][2]):
364 | error(
365 | f"Index {value} out of bounds for array {var_name}",
366 | tokens[i].line_num,
367 | )
368 | else:
369 | error(
370 | "Expected integer value or expression in array idexing",
371 | tokens[i].line_num,
372 | )
373 |
374 | op_value_idx, op_type_idx, i, func_ret_type = expression(
375 | tokens,
376 | i,
377 | table,
378 | "Expected integer an index for array",
379 | block_type_promotion=True,
380 | expect_paren=False,
381 | func_ret_type=func_ret_type,
382 | )
383 |
384 | # Type 3 is for integer expressions
385 | if op_type_idx != 3:
386 | error(
387 | "Expected integer value or expression in array idexing",
388 | tokens[i].line_num,
389 | )
390 |
391 | # Dictionary to convert tokens to their corresponding assignment types
392 | assignment_type = {
393 | "assignment": "=",
394 | "plus_equal": "+=",
395 | "minus_equal": "-=",
396 | "multiply_equal": "*=",
397 | "divide_equal": "/=",
398 | "modulus_equal": "%=",
399 | "bitwise_and_equal": "&=",
400 | "bitwise_xor_equal": "^=",
401 | "bitwise_or_equal": "|=",
402 | }
403 |
404 | check_if(
405 | got_type=tokens[i].type,
406 | should_be_types=[
407 | "assignment",
408 | "plus_equal",
409 | "minus_equal",
410 | "multiply_equal",
411 | "divide_equal",
412 | "modulus_equal",
413 | "bitwise_and_equal",
414 | "bitwise_xor_equal",
415 | "bitwise_or_equal",
416 | ],
417 | error_msg="Expected assignment operator after identifier",
418 | line_num=tokens[i].line_num,
419 | )
420 |
421 | # Convert the token to respective symbol
422 | converted_type = assignment_type[tokens[i].type]
423 |
424 | # Get the symbol table entry for the identifier
425 | id_table_entry = table.symbol_table[tokens[id_idx].val]
426 | type_ = id_table_entry[1]
427 |
428 | # Flag to check array assignment
429 | is_arr = False
430 |
431 | # Check if assignment is an array initializer or a simple expression type
432 | if tokens[i + 1].type == "left_brace":
433 | is_arr = True
434 | if type_ != "arr_declared":
435 | error("Cannot assign an initializer list to a variable", tokens[i].line_num)
436 |
437 | size_of_array = id_table_entry[2]
438 |
439 | op_value, op_type, i = array_initializer(
440 | tokens,
441 | i + 1,
442 | table,
443 | size_of_array,
444 | "Required expression after assignment operator",
445 | func_ret_type=func_ret_type,
446 | )
447 |
448 | # Modify datatype of the identifier
449 | table.symbol_table[var_id][1] = prec_to_type[op_type]
450 |
451 | else:
452 | if type_ == "arr_declared" and tokens[id_idx + 1].type != "left_bracket":
453 | error(
454 | "Array assignment requires initializer list, cannot assign expression",
455 | tokens[i].line_num,
456 | )
457 |
458 | # Check if expression follows = in assign statement
459 | op_value, op_type, i, func_ret_type = expression(
460 | tokens,
461 | i + 1,
462 | table,
463 | "Required expression after assignment operator",
464 | expect_paren=False,
465 | func_ret_type=func_ret_type,
466 | )
467 |
468 | op_value = converted_type + "---" + op_value
469 |
470 | if table.symbol_table[var_id][1] in ["var", "declared"]:
471 | # Modify datatype of the identifier
472 | table.symbol_table[var_id][1] = prec_to_type[op_type]
473 |
474 | # Check if a pointer is being assigned
475 | if is_ptr:
476 | return (
477 | OpCode(
478 | "ptr_only_assign",
479 | table.symbol_table[var_id][0]
480 | + op_value_idx
481 | + "---"
482 | + op_value
483 | + "---"
484 | + str(count_ast),
485 | "",
486 | ),
487 | i,
488 | func_ret_type,
489 | )
490 |
491 | # Resolve pendenting infer types
492 | table.resolve_dependency(tokens, i, var_id)
493 |
494 | # If it is an array then generate array_only_assign
495 | if is_arr:
496 | # Add ( []) to op_value
497 | op_value = (
498 | " "
499 | + op_value.split("---")[0]
500 | + " ("
501 | + prec_to_type[op_type]
502 | + " ["
503 | + size_of_array
504 | + "])"
505 | + op_value.split("---")[1]
506 | )
507 | return (
508 | OpCode(
509 | "array_only_assign",
510 | table.symbol_table[var_id][0] + "---" + op_value,
511 | "",
512 | ),
513 | i,
514 | func_ret_type,
515 | )
516 |
517 | # Return the opcode and i (the token after assign statement)
518 | return (
519 | OpCode("assign", var_name + op_value_idx + "---" + op_value, ""),
520 | i,
521 | func_ret_type,
522 | )
523 |
--------------------------------------------------------------------------------
/simc/scope_resolve.py:
--------------------------------------------------------------------------------
1 | from .token_class import Token
2 |
3 |
4 | class ScopeResolver:
5 | def __init__(self, tokens_list, symbol_table):
6 | self.__tokens_list = tokens_list
7 | self.__symbol_table = symbol_table
8 | self.__scope_stack = []
9 |
10 | def __push_to_scope_stack(self, val):
11 | self.__scope_stack.append(val)
12 |
13 | def __pop_from_scope_stack(self):
14 | return self.__scope_stack.pop()
15 |
16 | def resolve_scope(self, module_name):
17 | final_line = 0
18 | id_usage_to_resolve = []
19 | function_started = False
20 |
21 | for i, token in enumerate(self.__tokens_list):
22 | if i > 0 and self.__tokens_list[i - 1].type == "fun" and token.type == "id":
23 | self.__push_to_scope_stack(Token("left_brace", "", token.line_num))
24 | function_started = True
25 | elif (
26 | i > 0 and self.__tokens_list[i - 1].type == "var" and token.type == "id"
27 | ):
28 | self.__push_to_scope_stack(token)
29 | elif token.type == "id" and function_started:
30 | self.__push_to_scope_stack(token)
31 | elif token.type == "call_end" and function_started:
32 | function_started = False
33 | elif token.type == "id":
34 | id_usage_to_resolve.append(i)
35 | elif (
36 | i > 0
37 | and token.type == "left_brace"
38 | and self.__tokens_list[i - 1].type != "call_end"
39 | ):
40 | self.__push_to_scope_stack(token)
41 | elif token.type == "right_brace":
42 | while len(self.__scope_stack) != 0:
43 | top_token = self.__pop_from_scope_stack()
44 |
45 | if top_token.type == "id":
46 | top_token_id = top_token.val
47 | self.__symbol_table.symbol_table[top_token_id][-1] += (
48 | "-" + str(token.line_num) + "-" + module_name
49 | )
50 | elif top_token.type == "left_brace":
51 | break
52 |
53 | final_line = token.line_num
54 |
55 | while len(self.__scope_stack) != 0:
56 | top_token = self.__pop_from_scope_stack()
57 |
58 | if top_token.type == "id":
59 | top_token_id = top_token.val
60 | self.__symbol_table.symbol_table[top_token_id][-1] += (
61 | "-" + str(final_line) + "-" + module_name
62 | )
63 |
64 | for id_ in id_usage_to_resolve:
65 | resolved_id = self.__symbol_table.resolve_scope_for_id(
66 | token=self.__tokens_list[id_], module_name=module_name
67 | )
68 | self.__tokens_list[id_].val = (
69 | resolved_id if resolved_id != None else self.__tokens_list[id_].val
70 | )
71 |
72 | return self.__tokens_list, self.__symbol_table
73 |
74 | def swap_tokens_and_table(self, tokens_list, table):
75 | self.__tokens_list = tokens_list
76 | self.__symbol_table = table
77 |
--------------------------------------------------------------------------------
/simc/simc.py:
--------------------------------------------------------------------------------
1 | # Import sys, os and pprint module
2 | import sys
3 | import os
4 | import pprint
5 |
6 | # Module to import global helpers
7 | from .global_helpers import error
8 |
9 | # Module to import Symbol Table class
10 | from .symbol_table import SymbolTable
11 |
12 | # Module for using lexical analyzer
13 | from .lexical_analyzer import LexicalAnalyzer
14 |
15 | # Module for using parser
16 | from .parser.simc_parser import parse
17 |
18 | # Module for using compiler
19 | from .compiler import compile
20 |
21 | from .scope_resolve import ScopeResolver
22 |
23 |
24 | def run():
25 | filename = ""
26 |
27 | pretty_printer = pprint.PrettyPrinter(indent=4)
28 |
29 | # Check if filepath is provided or not
30 | if len(sys.argv) >= 2:
31 | filename = sys.argv[1]
32 |
33 | # Check if extension of file is correct or not
34 | if "." not in filename or filename.split(".")[-1] != "simc":
35 | error("Incorrect file extension", -1)
36 | else:
37 | error("Please provide simc file path", -1)
38 |
39 | # Get the filename of c file to be generated
40 | c_filename = "".join(filename.split(".")[:-1]) + ".c"
41 |
42 | # Create symbol table
43 | table = SymbolTable()
44 |
45 | # Get tokens and list of modules from source code
46 | lexical_analyzer = LexicalAnalyzer(filename, table)
47 | tokens, module_source_paths = lexical_analyzer.lexical_analyze()
48 |
49 | scope_resolver = ScopeResolver(tokens_list=tokens, symbol_table=table)
50 | tokens, table = scope_resolver.resolve_scope(module_name="main")
51 |
52 | # Get tokens for modules
53 | all_module_tokens = {}
54 | if len(module_source_paths) > 0:
55 | for module_source_path in module_source_paths:
56 | module_name = os.path.basename(module_source_path).split(".")[0]
57 |
58 | lexical_analyzer.update_filename(module_source_path)
59 | all_module_tokens[module_name], _ = lexical_analyzer.lexical_analyze()
60 |
61 | scope_resolver.swap_tokens_and_table(
62 | tokens_list=all_module_tokens[module_name], table=table
63 | )
64 | all_module_tokens[module_name], table = scope_resolver.resolve_scope(
65 | module_name=module_name
66 | )
67 |
68 | # Option to check out tokens
69 | if len(sys.argv) > 2 and sys.argv[2] == "token":
70 | # Print source code tokens
71 | for token in tokens:
72 | print(token)
73 |
74 | # Print module tokens
75 | for module_name, module_tokens in all_module_tokens.items():
76 | print("\n---Tokens for module " + module_name + "---")
77 | for token in module_tokens:
78 | print(token)
79 |
80 | # Option to check symbol table after lexical analysis
81 | if len(sys.argv) > 2 and sys.argv[2] == "table_after_lexing":
82 | # print(table)
83 | pretty_printer.pprint(table.symbol_table)
84 |
85 | # Parse the modules first as these function definitions will be important during source parsing
86 | all_module_opcodes = {}
87 |
88 | for module_name, module_tokens in all_module_tokens.items():
89 | all_module_opcodes[module_name] = parse(module_tokens, table)
90 |
91 | # Get opcodes for source code from parser
92 | op_codes = parse(tokens, table)
93 |
94 | # Remove opcodes of unused functions from modules
95 | all_module_opcodes_pruned = {}
96 | for module_name, module_opcodes in all_module_opcodes.items():
97 | all_module_opcodes_pruned[module_name] = []
98 | i = 0
99 |
100 | # Loops through all the opcodes of specific module and checks for functions which weren't called from source code
101 | while i < len(module_opcodes):
102 | if module_opcodes[i].type == "func_decl":
103 | func_name = module_opcodes[i].val.split("---")[0].strip()
104 | func_symbol_table_val = table.symbol_table.get(
105 | table.get_by_symbol(func_name)
106 | )
107 | func_ret_type = func_symbol_table_val[1]
108 |
109 | # Skip all functions whose return type is not_known meaning they weren't called
110 | if func_ret_type == "not_known" or type(func_ret_type) == list:
111 | beg_idx = i
112 | while module_opcodes[i].type != "scope_over":
113 | i += 1
114 | else:
115 | all_module_opcodes_pruned[module_name].append(module_opcodes[i])
116 | else:
117 | all_module_opcodes_pruned[module_name].append(module_opcodes[i])
118 | i += 1
119 |
120 | # Option to check out opcodes
121 | if len(sys.argv) > 2 and sys.argv[2] == "opcode":
122 | # Print source code opcodes
123 | for op_code in op_codes:
124 | print(op_code)
125 |
126 | # Print module opcodes
127 | for module_name, module_opcodes in all_module_opcodes_pruned.items():
128 | print("\n---OpCodes for module " + module_name + "---")
129 | for op_code in module_opcodes:
130 | print(op_code)
131 |
132 | # Option to check symbol table after parsing
133 | if len(sys.argv) > 2 and sys.argv[2] == "table_after_parsing":
134 | # print(table)
135 | pretty_printer.pprint(table.symbol_table)
136 |
137 | # Compile to C code
138 | compile(op_codes, c_filename, table)
139 |
140 | # Compile the module functions, this can be done in any order
141 | for module_name, module_opcodes in all_module_opcodes_pruned.items():
142 | module_c_filename = module_name + ".h"
143 |
144 | compile(module_opcodes, module_c_filename, table)
145 |
146 | print("\033[92mC code generated at %s!" % c_filename, end="")
147 | print(" \033[m")
148 |
--------------------------------------------------------------------------------
/simc/simpack.py:
--------------------------------------------------------------------------------
1 | # simpack (short for simC Packages) is the official package manager for simC
2 |
3 | # Import libraries
4 | import requests
5 | import argparse
6 | import os
7 |
8 | # Import error from global helpers
9 | from .global_helpers import error
10 |
11 |
12 | def get_package():
13 | # Get path to local simc installation
14 | simc_path = os.path.dirname(__file__)
15 |
16 | # Get path for package-index which has link to download simc modules
17 | index_path = os.path.join(simc_path, "package-index")
18 |
19 | # Open the path and read all the package names with corresponding links
20 | with open(index_path, "r") as file:
21 | index = file.read().split("\n")
22 | package_index = {}
23 | for i in range(len(index)):
24 | name_link = index[i].split("-")
25 | package_index[name_link[0].strip()] = name_link[1].strip()
26 |
27 | # Command line argument parser
28 | parser = argparse.ArgumentParser(description="simC Packages")
29 | parser.add_argument("--name", help="Enter name of package")
30 |
31 | args = parser.parse_args()
32 |
33 | # Find the link for the package name
34 | requested_name = args.name
35 | requested_link = package_index.get(requested_name, "Unknown")
36 |
37 | # If the package is not listed in package-index then throw an error
38 | if requested_link == "Unknown":
39 | error("Unable to find package with name " + requested_name, -1)
40 |
41 | # All modules go inside modules directory in local simc installation
42 | module_dir = os.path.join(simc_path, "modules")
43 | module_path = os.path.join(module_dir, requested_name + ".simc")
44 |
45 | # If module directory does not exist (user did not install anything yet) then create the directory
46 | if not os.path.exists(module_dir):
47 | os.mkdir(module_dir)
48 |
49 | # If the simc file is already present in modules directory then the package is already installed
50 | if os.path.exists(module_path):
51 | print(requested_name + " is already installed!")
52 |
53 | # Otherwise fetch the simc module from the corresponding link
54 | else:
55 | print("Fetching package " + requested_name + " from " + requested_link)
56 | r = requests.get(requested_link)
57 |
58 | # Dump module code into modules/.simc
59 | open(module_path, "wb").write(r.content)
60 | print(requested_name + " is now available for use!")
61 |
--------------------------------------------------------------------------------
/simc/symbol_table.py:
--------------------------------------------------------------------------------
1 | class SymbolTable:
2 | """
3 | SymbolTable class is responsible for storing information about identifiers and constants
4 | """
5 |
6 | def __init__(self):
7 | """
8 | Initializer of SymbolTable class
9 | """
10 |
11 | self.id = 1
12 | self.symbol_table = {}
13 |
14 | def __str__(self):
15 | """
16 | String representation of SymbolTable
17 |
18 | Returns
19 | =======
20 | string: The string representation of SymbolTable object - used for pretty printing the table
21 | """
22 |
23 | table_dict = self.symbol_table
24 |
25 | # Maximum length when all strings in the lists are compared
26 | max_length = max(
27 | [len(i) for dict_list in table_dict.values() for i in dict_list]
28 | )
29 |
30 | table_string = ""
31 |
32 | # To solve spacing issue for when lines exceed some power of 10 (like from line 9 to 10, 99 to 100 etc. )
33 | spaces_after_integer = len(str(len(table_dict)))
34 |
35 | # Keeps track of the lengths of each line (To account for alignment, when structures are involved)
36 | line_lengths = []
37 |
38 | for i in range(1, len(table_dict) + 1):
39 |
40 | line = "| " + str(i) + " "
41 |
42 | # Without this line, as the number of elements in symbol table exceeds some power of 10,
43 | # there will be some distortion in table rows. For example, between row 99 and 100.
44 | line += " " * (spaces_after_integer - len(str(i)))
45 |
46 | dict_list = table_dict[i] # Dictionary to be printed in tabular form
47 |
48 | for j in range(len(dict_list)):
49 |
50 | line += dict_list[j]
51 | if j < len(dict_list) - 2: # To add space between columns
52 | line += " " * (max_length - len(dict_list[j]) + 2)
53 |
54 | line_lengths.append(len(line))
55 | table_string += line + "\n"
56 |
57 | symbol_table_string = "" # Final string which will be displayed
58 | max_line_len = max(line_lengths)
59 | line_len = 0
60 |
61 | for character in table_string:
62 |
63 | if character == "\n": # If a newline is detected, add necessary spaces
64 | symbol_table_string += " " * (max_line_len - line_len) + " |\n"
65 | line_len = 0
66 | else:
67 | symbol_table_string += character
68 | line_len += 1
69 |
70 | horizontal_bar = "|" + "-" * (max_line_len) + "|\n"
71 | symbol_table_string = horizontal_bar + symbol_table_string + horizontal_bar
72 |
73 | return symbol_table_string
74 |
75 | def entry(self, value, type, typedata, dependency="", scope=""):
76 | """
77 | Returns id in symbol table after making an entry
78 |
79 | Params
80 | ======
81 | value (string) = Value to be stored in symbol table (identifier/constant)
82 | type (string) = Datatype of symbol
83 | typedata (string) = Type of data (constant/variable)
84 | dependency (string) = List of token ids of dependent variables
85 | scope (string) = Scope of entry
86 |
87 | Returns
88 | =======
89 | int: The id of the current entry in symbol table
90 | """
91 |
92 | self.symbol_table[self.id] = [value, type, typedata, dependency, scope]
93 | self.id += 1
94 | return self.id - 1
95 |
96 | def get_by_id(self, id):
97 | """
98 | Returns symbol table entry by integer unique id
99 |
100 | Params
101 | ======
102 | id (id) = Integer unique id of a symbol in the table
103 |
104 | Returns
105 | =======
106 | list: Table entry
107 | """
108 |
109 | return self.symbol_table.get(id, [None, None, None, None, None])
110 |
111 | def get_by_symbol(self, value, id_greater_than=None):
112 | """
113 | Returns unique id of a given value
114 |
115 | Params
116 | ======
117 | value (string) = Value to be searched in the symbol table
118 | consider_scope (bool) = Should consider scope or not while getting by symbol
119 | current_scope (string) = If scope is to be considered then which scope is to be searched for
120 |
121 | Returns
122 | =======
123 | int: The unique id of the entry in symbol table
124 | """
125 |
126 | id = -1
127 | for ids, value_list in self.symbol_table.items():
128 | if value_list[0] == value:
129 | if id_greater_than == None:
130 | return ids
131 | else:
132 | if ids < id_greater_than:
133 | continue
134 | else:
135 | return ids
136 |
137 | return id
138 |
139 | def resolve_scope_for_id(self, token, module_name):
140 | min_distance = None
141 | min_id = None
142 |
143 | token_line_num = token.line_num
144 | token_symbol = self.get_by_id(token.val)[0]
145 |
146 | for id_, value_list in self.symbol_table.items():
147 | if value_list[0] == token_symbol and "-" in value_list[-1]:
148 | (
149 | scope_start_line_num,
150 | scope_end_line_num,
151 | scope_module_name,
152 | ) = value_list[-1].split("-")
153 |
154 | if scope_module_name != module_name:
155 | continue
156 |
157 | distance_line_num = token_line_num - int(scope_start_line_num)
158 | if distance_line_num < 0:
159 | continue
160 |
161 | if min_distance == None or (
162 | distance_line_num < min_distance
163 | and token_line_num < int(scope_end_line_num)
164 | ):
165 | min_distance = distance_line_num
166 | min_id = id_
167 |
168 | return min_id
169 |
170 | def add_dependency(self, var_father_id, var_child_id):
171 | """
172 | Adds a relation of dependecy beetween two variables
173 |
174 | It is used when the variable is assigned to other varible before it is type had been defined
175 | When the type of the varible is discovered, use the function resolve_dependency to update the child variables
176 |
177 | Params
178 | ======
179 | var_father_id (int) = ID of parent identifier in SymbolTable
180 | var_child_id (int) = ID of child identifier in SymbolTable
181 | """
182 |
183 | # Add the variable to list in the expression:: "<-ID>"
184 | self.symbol_table[var_father_id][3] += "-" + str(var_child_id)
185 |
186 | def resolve_dependency(self, tokens, i, var_id):
187 | """
188 | Resolves the dependency relation between variables
189 |
190 | This is a recursive function, it is used when the parser discovers the type of a varible which has been
191 | assign to another one, then the type of the assigned one dependes on this
192 |
193 | Params
194 | ======
195 | tokens (list) = List of tokens
196 | i (int) = Current index in token
197 | var_id (int) = ID in Symbol table where the function will look at for child dependencies
198 |
199 | Returns
200 | =======
201 | bool: Whether it is possible to resolve the dependency or not
202 | """
203 | # Extract the type of variable and the list of variable which dependies on it
204 | _, type_, _, list_dependency, _ = self.symbol_table[var_id]
205 |
206 | # Nothing to do
207 | if type_ == "var":
208 | return
209 |
210 | # Clear the dependencies
211 | self.symbol_table[var_id][3] = ""
212 |
213 | # Split the list "ID-ID-...-ID" => ['ID', 'ID', ..., 'ID']
214 | list_dependency = [
215 | int(child_var_id)
216 | for child_var_id in list_dependency.split("-")
217 | if child_var_id != ""
218 | ]
219 |
220 | is_allowed = True
221 |
222 | # For each child variable assign the new type and check up for its dependencies.
223 | for var_child_id in list_dependency:
224 |
225 | if is_allowed is False:
226 | break
227 |
228 | # Extract the current type of child variable
229 | child_type = self.symbol_table[var_child_id][1]
230 |
231 | # If the type is not defined
232 | if child_type == "declared":
233 | if type_ == "string":
234 | type_ = "char*"
235 | self.symbol_table[var_child_id][1] = type_
236 | is_allowed = self.resolve_dependency(tokens, i, var_child_id)
237 |
238 | # If the type is defined, it cannot downgrade
239 | elif child_type > type_:
240 | self.symbol_table[var_child_id][1] = type_
241 |
242 | # If the type is defined and the type of child is greater or equal than the father
243 | elif child_type < type_:
244 | is_allowed = False
245 |
246 | return is_allowed
247 |
--------------------------------------------------------------------------------
/simc/token_class.py:
--------------------------------------------------------------------------------
1 | class Token:
2 | """
3 | Token class is responsible for creating tokens
4 | """
5 |
6 | def __init__(self, type, val, line_num, scope=None):
7 | """
8 | Class initializer
9 |
10 | Params
11 | ======
12 | type (string) = Type of token as string
13 | val (string) = Value stored at token
14 | line_num (int) = Line number
15 | scope (string) = Scope of token
16 | """
17 |
18 | self.type = type
19 | self.val = val
20 | self.line_num = line_num
21 |
22 | def __str__(self):
23 | """
24 | String representation of a Token
25 |
26 | Returns
27 | =======
28 | string: The string representation of Token object, which can be used to print the tokens
29 | """
30 |
31 | return "Token(%s, %s, %s)" % (self.type, self.val, self.line_num)
32 |
33 | def __eq__(self, other):
34 | """
35 | Check for equality of tokens
36 |
37 | Returns
38 | =======
39 | bool: Whether a token object is equal to another or not
40 | """
41 |
42 | if (
43 | self.type == other.type
44 | and self.val == other.val
45 | and self.line_num == other.line_num
46 | ):
47 | return True
48 |
49 | return False
50 |
--------------------------------------------------------------------------------