This repository was archived by the owner on Aug 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathinterpreter.py
More file actions
161 lines (143 loc) · 7.13 KB
/
interpreter.py
File metadata and controls
161 lines (143 loc) · 7.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# Simple Interpreter
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# میخواهیم یک مفسر ساده برای یک زبان برنامه نویسی فرضی بسازیم
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# منطق این برنامه ساده نیست؛ پس برای همه پیشنهاد نمیشود؛ اما
# اگر علاقه به یادگیری بیشتر دارید این فایل را بررسی کنید
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# یک زبان برنامه نویسی فرضی ساختیم که 4 دستور بیشتر ندارد
# let, add, sub, ech
# اولین دستور یک مقدار را در یک متغیر قرار میدهد
# دومین دستور یک عدد را با مقدار پیشفرض داخل متغیر جمع میکند
# سومین دستور یک عدد را با مقدار پیشفرض داخل متغیر تفریق میکند
# و اخرین دستور، متغیر ما را به تعدادی که میخواهیم نمایش میدهد
# فقط یک نوع داده ای داریم و آن هم عدد صحیح است
# فقط دو متغیر داریم و آن هم
# ax, bx
# هستند؛ حالا میخواهیم یک تفسیر کننده بسازیم که بتواند این زبان
# برنامه نویسی فرضی را بخواهد
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# خط زیر یک برنامه فرضی است که با زبان فرضی ما نوشته شده است
# آیا میتوانید با این منطقی که توضیح داده شد یک برنامه فرضی
# مشابه بنویسید و آن را تست کنید؟
# منظور این است که 6 خط کد زیر را کمی تغییر دهید و برنامه را
# اجرا کنید
code = """
let ax,8 # it means ax =8
let bx,4 # it means bx =4
add ax,5 # it means ax+=5
ech ax,1 # it means print(ax) 1 time
sub ax,2 # it means ax-=2
ech ax,3 # it means print(ax) 3 time
"""
print(code)
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# کد برنامه را بر اساس خط ها جدا میکنیم
# ما نیاز داریم خط به خط برنامه را تفسیر و اجرا کنیم پس لازم
# است خطوط برنامه را از هم جدا کرده و آنها را بررسی کنیم
lines = code.splitlines()
for line in lines:
print(line)
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# خطهای برنامه را جدا کردیم اما این خطوط تمیز نیستند
# کامنت و فاصله اضافی وجود دارد
# و این موارد ممکن است در پردازش نهایی ما اختلال ایجاد کند
# پس در این مرحله خطوط کد را پاکسازی می کنیم
for i in range(len(lines)):
lines[i] = lines[i].strip()
lines[i] = lines[i].replace(" ", " ")
if "#" in lines[i]:
lines[i] = lines[i].split("#")[0].strip()
print(lines[i])
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# خروجی برنامه تا این لحظه به صورت زیر خواهد بود
# هر خط از برنامه پاکسازی شده و زمان بررسی و تفسیر آن است
"""
let ax,8
add ax,5
ech ax,1
sub ax,2
ech ax,3
"""
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# نیاز داریم مقدار متغیر های زبان برنامه نویسی فرضی خود را در
# جایی ذخیره کنیم
# از یک دیکشنری برای ذخیره متغیر های خود استفاده میکنیم
# برنامه را اجرا کنید
# اگر در کد زبان برنامه نویسی فرضی خود بجای دو متغیر
# ax یا bx
# یک متغیر با نام دیگر، برای نمونه
# dx
# قرار دهیم چه اتفاقی در خروجی برنامه رخ میدهد؟
variables = {"ax": None, "bx": None}
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# در مرحله بعد اجزای کد را از هم جدا کرده و انها را خط به خط
# اجرا میکنیم
# از یک حلفه فور برای این منظور کمک میگیریم
print()
for i in range(len(lines)):
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# خطوط کد تمیز شده را دوباره از ابتدا و بصورت خط به خط می خوانیم
if lines[i].strip() == "":
continue
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# هر خط از برنامه را میخوانیم و اجزای آن را بصورت جداگانه از هم
# تفکیک میکنیم و در خروجی نمایش میدهیم
print("-" * 50)
command = lines[i].split(" ")
operand = command[1].split(",")
opr = command[0]
op1 = operand[0]
op2 = operand[1]
print(f"Line {i}: [{lines[i]}] -> [{opr} | {op1} | {op2}] -> {variables}")
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# محاسبه دستورات زبان برنامه نویسی فرضی ما
# هر یک از 4 دستور زبان برنامه نویسی جدید فرضی ما در این قسمت
# محاسبه میشوند
if opr == "ech":
for i in range(int(op2)):
print(variables[op1])
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
elif opr == "let":
variables[op1] = int(op2)
print(f"{op1} assigned")
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
elif opr == "add":
variables[op1] += int(op2)
print(f"{op1} changed")
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
elif opr == "sub":
variables[op1] -= int(op2)
print(f"{op1} changed")
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# خروجی برنامه
"""
--------------------------------------------------
Line 1: [let ax,8] -> [let | ax | 8] -> {'ax': None, 'bx': None}
ax assigned
--------------------------------------------------
Line 2: [let bx,4] -> [let | bx | 4] -> {'ax': 8, 'bx': None}
bx assigned
--------------------------------------------------
Line 3: [add ax,5] -> [add | ax | 5] -> {'ax': 8, 'bx': 4}
ax changed
--------------------------------------------------
Line 4: [ech ax,1] -> [ech | ax | 1] -> {'ax': 13, 'bx': 4}
13
--------------------------------------------------
Line 5: [sub ax,2] -> [sub | ax | 2] -> {'ax': 13, 'bx': 4}
ax changed
--------------------------------------------------
Line 6: [ech ax,3] -> [ech | ax | 3] -> {'ax': 11, 'bx': 4}
11
11
11
"""
###~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# سوال
# آیا میتوانید یک عملیات دیگر مثلا عملیات ضرب یا تقسیم به این
# برنامه اضافه کنید؟
# آیا میتوانید کد ابتدای برنامه
# "code"
# را به صورتی تغییر دهید که در اجرای برنامه خطا ایجاد شود؟
# کاری کنید که مفسری که نوشتیم به نقطه ای برسد که خطا دهد