diff --git a/tutorial_content.md b/tutorial_content.md index 33e4f14..9f572ad 100644 --- a/tutorial_content.md +++ b/tutorial_content.md @@ -3,15 +3,15 @@ Then, what is a programming language? You can think that it is a language that humans (programmers) talk to machines. We the programmers are precision-pursuing. A language, or a list of words, is a programming language if and only if it: 1. specifies a set of instructions for a machine to perform. (if this is satisfied, then it is a language at least!) -2. is Turing complete (meaning that this language is able to emulate a [Turing machine](https://wikipedia.org/wiki/Turing_machine)). +2. is Turing complete (meaning that this language can emulate a [Turing machine](https://wikipedia.org/wiki/Turing_machine)) ![](turingmachine.png) -You can think of a Turing machine as a device just like your computer. It is a machine that has infinite tape divided in cells, and has a set of instructions/rules that can power the machine. Try this website: https://turingmachinesimulator.com/ -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, if a language has valid if and looping statements, it can simulate a Turing machine. Notice: Although the [BF langauge](https://wikipedia.org/wiki/Brainfuck) does not have any regular statements like regular langauges such as Java and C++, BF itself is a simulation of a Turing machine, therefore it is also a programming language! +You can think of a Turing machine as a device just like your computer. It is a machine that has infinite tape divided into cells and has a set of instructions/rules that can power the machine. Try this website: https://turingmachinesimulator.com/ +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! # Ways to Implement a Programming Language -There are mainly three ways of implementng 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) @@ -21,7 +21,7 @@ A compiler is a program that converts a higher-level code into a machine or low- Some languages that are built as compilers are C, C++, and Rust. 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). ## Interpreter -An interpreter analyzes and executes a high-level code line by line, usually with a virtual machine. Some examples are Python, Ruby, and PHP. Python and Ruby first converts 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 exaple is that in Python, variable `a` can be defined without a type at first, and then be changed into string: `a = "3.1415926"`, and then be converted to integer: `int(a)`. However, these operations are not allowed in C, C++, and Rust. +An interpreter analyzes and executes a high-level code line by line, usually with a virtual machine. Some examples are Python, Ruby, and PHP. 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 integer: `int(a)`. However, these operations are not allowed in C, C++, and Rust. ## 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! ## JIT @@ -33,7 +33,7 @@ In This tutorial, we are going through the [Rickroll Programming Language](https # Making a Transpiler Transpiler is the easiest to make among all other implementations. Our task is to convert the Rickroll source code into Python. ## Lexer -We have the source file ended in `.rickroll`, but we need to break the string down to meaningful keywords and values, and we call them, tokens. Click the interactive example - 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) ## Translator @@ -48,7 +48,7 @@ Different from a transpiler, an interpreter requires a virtual machine and the u ## Lexer We use the same lexer with transpiler, breaking them down into the same tokens ## 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 +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 ['if', 'a', '==', '1', ':', 'print', '(', '"', '"Hello World!"', '"', ')'] ```