Skip to content

Commit

Permalink
Update tutorial_content.md
Browse files Browse the repository at this point in the history
  • Loading branch information
SatinWukerORIG authored Aug 19, 2023
1 parent e0f3205 commit 1a957f0
Showing 1 changed file with 29 additions and 5 deletions.
34 changes: 29 additions & 5 deletions tutorial_content.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,67 @@ You can think of a Turing machine as a device just like your computer. It is a m
Try this website: https://turingmachinesimulator.com/
<br>
Therefore, HTML (markup language), CSS (style sheet language), and Markdown (similar to HTML) are not programming languages as they only specify instructions, but cannot emulate a Turing machine. In another approach, a language with valid if and looping statements can simulate a Turing machine. Notice: Although the [BF langauge](https://wikipedia.org/wiki/Brainfuck) does not have any regular statements like regular languages such as Java and C++, BF itself is a simulation of a Turing machine, therefore it is also a programming language!

<br>
<br>
<br>
# Ways to Implement a Programming Language
There are mainly three ways of implementing a programming language:
1. making a compiler
2. making an interpreter
3. making a transpiler (source-to-source compiler)
4. making a just-in-time compiler (JIT)
<br>

## Compiler
A compiler is a program that converts a higher-level code into a machine or low-level code, allowing code execution at runtime to be extremely fast and efficient.
Some languages that are built as compilers are C, C++, and Rust.
Some languages that are built as compilers are C, C++, Rust, and Swift.
C++ compilers, such as G++ or Clang++, convert C++ source code into [intermediate representation](https://en.wikipedia.org/wiki/Intermediate_representation#:~:text=An%20intermediate%20representation%20(IR)%20is,such%20as%20optimization%20and%20translation.)(IR), and then to machine code. Translating to IR is to optimize the source code, such as [dead code elimination](https://en.wikipedia.org/wiki/Dead-code_elimination) and [code motion or frequency reduction](https://www.geeksforgeeks.org/frequency-reduction-in-code-optimization).
<br>

## Interpreter
An interpreter analyzes and executes a high-level code line by line, usually with a virtual machine. Some examples are Python, Ruby, PHP, Java, Kotlin, and Lisp. Python and Ruby first convert their source code into abstract syntax trees, and then the byte code gets executed by [virtual machines](https://medium.com/@principledminds/virtual-machines-explained-5578371195f#:~:text=Summary-,Virtual%20machines%20are%20programs%20that%20compile%20an%20intermediate%20language%20down,compilers%20for%20each%20individual%20language.). Interpreted languages are way slower compared to compiled languages because the virtual machines are way less efficient and slower than the real processor. However, interpreted languages are usually more flexible than compiled languages. For example, Ruby and Python are dynamically typed, meaning that a variable's type can be changed during the runtime, while compiled languages like C and C++ are statically typed. One example is that in Python, variable `a` can be defined without a type at first, and then be changed into a string: `a = "3.1415926"`, and then be converted to a float: `float(a)`. However, these operations are not allowed in C, C++, and Rust.
<br>

## Transpiler
A transpiler converts a piece of code to another code in another language, and these 2 pieces have the same level (complexity). For example, there is a transpiler that converts C++ to C. The most famous transpiler must be [Babel](https://babeljs.io/), a tool for developers to write modern JS code at once and transpile to older version code for compatibility!
<br>

## JIT
JIT is a special interpreter that improves code performance by compiling bytecodes to native machine code at run time.

In This tutorial, we are going through the [Rickroll Programming Language](https://github.com/Rick-Lang/rickroll-lang), a compiling, interpreting, and transpiling language!


<br>
<br>
<br>
# Making a Transpiler
Transpiler is the easiest to make among all other implementations. Our task is to convert the Rickroll source code into Python.
<br>

## Lexer
We have the source file ended in `.rickroll`, but we need to break the string down to meaningful keywords and values, which we call tokens. Click the interactive example - Lexer:

You can look into the Rickroll source code, [src-py/Lexer.py](https://github.com/Rick-Lang/rickroll-lang/blob/main/src-py/Lexer.py)
<br>

## Translator
Since we have the tokens, we can map them to the corresponding keywords in Python! E.g. `i just wanna tell u how im feeling` is equivalent to `print()` in Python. Click the interactive example - Transpiler:

You can look into the Rickroll source code, [src-py/pyrickroll.py](https://github.com/Rick-Lang/rickroll-lang/blob/main/src-py/pyrickroll.py), class TranslateToPython()
<br>

## Executor
After storing our translated python code into `py_code`, we can execute it: `exec(transpiler.py_code, globals(), globals())`

<br>
<br>
<br>
# Making an Interpreter
Different from a transpiler, an interpreter requires a virtual machine and the usage of [abstract syntax tree](https://medium.com/basecs/leveling-up-ones-parsing-game-with-asts-d7a6fc2400ff), or AST. This tree structure stores pieces of tokens to represent the order of code execution.
<br>

## Lexer
We use the same lexer with transpiler, breaking them down into the same tokens
<br>

## Parser
The tokens cannot represent the structure and order of execution of the code alone, and AST is the solution. For example, in the if control flow, the tokens are
```python
Expand All @@ -64,5 +87,6 @@ In which the interpreter knows that `['a', '==', '1']` is the condition, and `['
Click the interactive example:

Look into [src-py/Parser.py](https://github.com/Rick-Lang/rickroll-lang/blob/main/src-py/Parser.py) to see how it is implemented.
<br>

## Interpreter

0 comments on commit 1a957f0

Please sign in to comment.