|
| 1 | +#+title: WHILE-Programme |
| 2 | +#+author: Felix Drees |
| 3 | +#+STARTUP: latexpreview |
| 4 | +#+OPTIONS: toc:nil tex:t # tex:verbatim num:nil |
| 5 | +#+keywords: while programs, turing complete, turing machines |
| 6 | + |
1 | 7 | * while |
2 | 8 |
|
3 | | -Parser and interpreter for the While programming language |
| 9 | +Parser and interpreter for the *while* programming language |
| 10 | + |
| 11 | +The *while* programming language is a verry simplified language, which is turing complete! |
4 | 12 |
|
5 | 13 | [[https://github.com/felixbd/while/actions/workflows/ci-test.yml/badge.svg?branch=main]] |
6 | 14 |
|
7 | 15 |
|
| 16 | +** syntax specification via context-free type-2 grammar |
| 17 | + |
| 18 | +The set of *WHILE* programs is the language generated by the following grammar |
| 19 | + |
| 20 | +$$ G = (N, \sum, P, S) $$ |
| 21 | + |
| 22 | +where |
| 23 | + |
| 24 | +$N = \{ Prog, Var, Const, Expr \}$ |
| 25 | + |
| 26 | +(the set of non terminal Symbols) |
| 27 | + |
| 28 | +$\sum = \{ loop, while, do, end, +, -, ;, :=, != \} \cup \mathbb{N}_0 \cup VariableNames$ |
| 29 | + |
| 30 | +(the set of terminal symbols) |
| 31 | + |
| 32 | +$S = Prog$ |
| 33 | + |
| 34 | +(the start non terminal) |
| 35 | + |
| 36 | +$P = \{$ |
| 37 | + |
| 38 | +$Prog \to Prog; Prog$ |
| 39 | + |
| 40 | +$Prog \to Var := Expr$ |
| 41 | + |
| 42 | +$Expr \to Var \mid Const \mid Expr + Expr \mid Expr - Expr$ |
| 43 | + |
| 44 | +$Prog \to \textrm{loop Expr do Prog end}$ |
| 45 | + |
| 46 | +$Prog \to \textrm{while Expr != Expr do Prog end}$ |
| 47 | + |
| 48 | +$Var \to VariableName$ (that has to start with ascii letter and can contain digits or underscore) |
| 49 | + |
| 50 | +$Const \to \mathbb{N}_0$ |
| 51 | + |
| 52 | +$\}$ |
| 53 | + |
| 54 | +(the set of production rules) |
| 55 | + |
| 56 | + |
| 57 | +** semantic |
| 58 | + |
| 59 | +as expected, i guess ... lol |
| 60 | + |
| 61 | +NOTE: the subtraction is only defined in $\mathbb{N}_0$ |
| 62 | +therefore $5 - 8$ will result in $0$ |
| 63 | + |
| 64 | +also i added a max recursion depth like python3 to prevent users to write non terminating code ... |
| 65 | +(the max rec depth for a *while* loop is *1500* iterations) |
| 66 | + |
| 67 | + |
8 | 68 | ** usage |
9 | 69 |
|
10 | 70 | *** example |
11 | 71 |
|
| 72 | +lets say you have a function $\psi$ for calculating a simple multiplication $a \cdot b$ |
| 73 | + |
| 74 | +$$\psi \colon \mathbb{N}^2_0 \longrightarrow \mathbb{N}_0$$ |
| 75 | + |
| 76 | +$$(x_1, x_2) \mapsto x_1 \cdot x_2$$ |
| 77 | + |
| 78 | +lets calculate $420 \cdot 69$ via $\psi(v)$ where $v := (420, 69)$, the result should be $28980$. |
| 79 | + |
| 80 | +#+begin_src shell :exports both :results output |
| 81 | +cat ./examples/multiplication-func.while |
| 82 | +#+end_src |
| 83 | + |
| 84 | +#+RESULTS: |
| 85 | +#+begin_example |
| 86 | +rv := 0; |
| 87 | +a := 420; |
| 88 | +b := 69; |
| 89 | + |
| 90 | +while b != 0 do |
| 91 | + temp := rv; |
| 92 | + loop a do temp := temp + 1 end; |
| 93 | + rv := temp; |
| 94 | + |
| 95 | + b := b - 1 |
| 96 | +end |
| 97 | +#+end_example |
| 98 | + |
| 99 | +since this is a bit tidies i allowed users to use expressions in the context |
| 100 | + |
| 101 | +- conditions |
| 102 | +- additions |
| 103 | +- and subtractions |
| 104 | + |
| 105 | +(refer to the grammar defined above) |
| 106 | + |
| 107 | +shortened (not completely while-language correct ...) version |
| 108 | + |
| 109 | +#+begin_src |
| 110 | +x0 := 0; |
| 111 | +x1 := 420; |
| 112 | +x2 := 69; |
| 113 | + |
| 114 | +loop x2 do x0 := x0 + x1 end |
| 115 | +#+end_src |
| 116 | + |
| 117 | + |
12 | 118 | #+begin_src shell |
13 | | -felix in ~/git-repos/hub/while on main ● λ stack build |
14 | | -felix in ~/git-repos/hub/while on main ● λ stack run |
| 119 | +felix in ~/git-repos/hub/while on dev ● λ stack build |
| 120 | +felix in ~/git-repos/hub/while on dev ● λ stack run |
15 | 121 |
|
16 | 122 | = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = |
17 | 123 |
|
18 | 124 | Enter the file name: |
19 | | -./examples/simple.while |
20 | | -[READING .WHILE FILE] "./examples/simple.while" |
| 125 | +./examples/multiplication-func.while |
| 126 | +[READING .WHILE FILE] "./examples/multiplication-func.while" |
21 | 127 |
|
22 | 128 | [DONE TOKENIZE]: |
23 | | -[MetaToken {getLineNumber = 1, getToken = VarToken {getVarName = "x_1"}}, |
| 129 | +[MetaToken {getLineNumber = 1, getToken = VarToken {getVarName = "rv"}}, |
24 | 130 | MetaToken {getLineNumber = 1, getToken = AssignToken}, |
25 | | -MetaToken {getLineNumber = 1, getToken = ConstToken {getConstInt = 10}}, |
| 131 | +MetaToken {getLineNumber = 1, getToken = ConstToken {getConstInt = 0}}, |
26 | 132 | MetaToken {getLineNumber = 1, getToken = SemicolonToken}, |
27 | | -MetaToken {getLineNumber = 2, getToken = VarToken {getVarName = "x_2"}}, |
| 133 | +MetaToken {getLineNumber = 2, getToken = VarToken {getVarName = "a"}}, |
28 | 134 | MetaToken {getLineNumber = 2, getToken = AssignToken}, |
29 | | -MetaToken {getLineNumber = 2, getToken = ConstToken {getConstInt = 0}}, |
| 135 | +MetaToken {getLineNumber = 2, getToken = ConstToken {getConstInt = 420}}, |
30 | 136 | MetaToken {getLineNumber = 2, getToken = SemicolonToken}, |
31 | | -MetaToken {getLineNumber = 4, getToken = WhileToken}, |
32 | | -MetaToken {getLineNumber = 4, getToken = VarToken {getVarName = "x_1"}}, |
33 | | -MetaToken {getLineNumber = 4, getToken = NotEqualToken}, |
34 | | -MetaToken {getLineNumber = 4, getToken = ConstToken {getConstInt = 0}}, |
35 | | -MetaToken {getLineNumber = 4, getToken = DoToken}, |
36 | | -MetaToken {getLineNumber = 5, getToken = VarToken {getVarName = "x_1"}}, |
37 | | -MetaToken {getLineNumber = 5, getToken = AssignToken}, |
38 | | -MetaToken {getLineNumber = 5, getToken = VarToken {getVarName = "x_1"}}, |
39 | | -MetaToken {getLineNumber = 5, getToken = MinusToken}, |
40 | | -MetaToken {getLineNumber = 5, getToken = ConstToken {getConstInt = 1}}, |
41 | | -MetaToken {getLineNumber = 5, getToken = SemicolonToken}, |
42 | | -MetaToken {getLineNumber = 6, getToken = LoopToken}, |
43 | | -MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_1"}}, |
44 | | -MetaToken {getLineNumber = 6, getToken = DoToken}, |
45 | | -MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_2"}}, |
| 137 | +MetaToken {getLineNumber = 3, getToken = VarToken {getVarName = "b"}}, |
| 138 | +MetaToken {getLineNumber = 3, getToken = AssignToken}, |
| 139 | +MetaToken {getLineNumber = 3, getToken = ConstToken {getConstInt = 69}}, |
| 140 | +MetaToken {getLineNumber = 3, getToken = SemicolonToken}, |
| 141 | +MetaToken {getLineNumber = 5, getToken = WhileToken}, |
| 142 | +MetaToken {getLineNumber = 5, getToken = VarToken {getVarName = "b"}}, |
| 143 | +MetaToken {getLineNumber = 5, getToken = NotEqualToken}, |
| 144 | +MetaToken {getLineNumber = 5, getToken = ConstToken {getConstInt = 0}}, |
| 145 | +MetaToken {getLineNumber = 5, getToken = DoToken}, |
| 146 | +MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "temp"}}, |
46 | 147 | MetaToken {getLineNumber = 6, getToken = AssignToken}, |
47 | | -MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_2"}}, |
48 | | -MetaToken {getLineNumber = 6, getToken = PlusToken}, |
49 | | -MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "x_1"}}, |
50 | | -MetaToken {getLineNumber = 6, getToken = EndToken}, |
51 | | -MetaToken {getLineNumber = 7, getToken = EndToken}] |
| 148 | +MetaToken {getLineNumber = 6, getToken = VarToken {getVarName = "rv"}}, |
| 149 | +MetaToken {getLineNumber = 6, getToken = SemicolonToken}, |
| 150 | +MetaToken {getLineNumber = 7, getToken = LoopToken}, |
| 151 | +MetaToken {getLineNumber = 7, getToken = VarToken {getVarName = "a"}}, |
| 152 | +MetaToken {getLineNumber = 7, getToken = DoToken}, |
| 153 | +MetaToken {getLineNumber = 7, getToken = VarToken {getVarName = "temp"}}, |
| 154 | +MetaToken {getLineNumber = 7, getToken = AssignToken}, |
| 155 | +MetaToken {getLineNumber = 7, getToken = VarToken {getVarName = "temp"}}, |
| 156 | +MetaToken {getLineNumber = 7, getToken = PlusToken}, |
| 157 | +MetaToken {getLineNumber = 7, getToken = ConstToken {getConstInt = 1}}, |
| 158 | +MetaToken {getLineNumber = 7, getToken = EndToken}, |
| 159 | +MetaToken {getLineNumber = 7, getToken = SemicolonToken}, |
| 160 | +MetaToken {getLineNumber = 8, getToken = VarToken {getVarName = "rv"}}, |
| 161 | +MetaToken {getLineNumber = 8, getToken = AssignToken}, |
| 162 | +MetaToken {getLineNumber = 8, getToken = VarToken {getVarName = "temp"}}, |
| 163 | +MetaToken {getLineNumber = 8, getToken = SemicolonToken}, |
| 164 | +MetaToken {getLineNumber = 10, getToken = VarToken {getVarName = "b"}}, |
| 165 | +MetaToken {getLineNumber = 10, getToken = AssignToken}, |
| 166 | +MetaToken {getLineNumber = 10, getToken = VarToken {getVarName = "b"}}, |
| 167 | +MetaToken {getLineNumber = 10, getToken = MinusToken}, |
| 168 | +MetaToken {getLineNumber = 10, getToken = ConstToken {getConstInt = 1}}, |
| 169 | +MetaToken {getLineNumber = 11, getToken = EndToken}] |
52 | 170 |
|
53 | 171 | [DONE PARSING AST]: |
54 | 172 | Sequential |
55 | | - (Assignment "x_1" (Constant {getConst = 10})) |
56 | | - (Sequential |
57 | | - (Assignment "x_2" (Constant {getConst = 0})) |
58 | | - (While |
59 | | - (Neq (Variable {getVar = "x_1"}) (Constant {getConst = 0})) |
60 | | - (Sequential |
61 | | - (Assignment "x_1" (Subtract (Variable {getVar = "x_1"}) (Constant {getConst = 1}))) |
62 | | - (Loop |
63 | | - (Variable {getVar = "x_1"}) |
64 | | - (Assignment "x_2" (Add (Variable {getVar = "x_2"}) (Variable {getVar = "x_1"}))))))) |
| 173 | + (Assignment "rv" (Constant {getConst = 0})) |
| 174 | + (Sequential |
| 175 | + (Assignment "a" (Constant {getConst = 420})) |
| 176 | + (Sequential |
| 177 | + (Assignment "b" (Constant {getConst = 69})) |
| 178 | + (While |
| 179 | + (Neq (Variable {getVar = "b"}) (Constant {getConst = 0})) |
| 180 | + (Sequential |
| 181 | + (Assignment "temp" (Variable {getVar = "rv"})) |
| 182 | + (Sequential |
| 183 | + (Loop |
| 184 | + (Variable {getVar = "a"}) |
| 185 | + (Assignment "temp" (Add (Variable {getVar = "temp"}) (Constant {getConst = 1})))) |
| 186 | + (Sequential |
| 187 | + (Assignment "rv" (Variable {getVar = "temp"})) |
| 188 | + (Assignment "b" (Subtract (Variable {getVar = "b"}) (Constant {getConst = 1}))))))))) |
65 | 189 |
|
66 | 190 | [OUTPUT OF EVALUATION]: |
67 | | -[("x_2",285),("x_1",0)] |
| 191 | +[("temp",28980),("b",0),("a",420),("rv",28980)] |
68 | 192 |
|
69 | 193 | = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = |
70 | 194 |
|
71 | | -felix in ~/git-repos/hub/while on main ● λ |
| 195 | +felix in ~/git-repos/hub/while on dev ● λ |
72 | 196 | #+end_src |
73 | 197 |
|
74 | 198 | *** compile |
|
0 commit comments