WARAJA commited on
Commit
e5fb3aa
·
verified ·
1 Parent(s): f8ad25b

Upload Tzefa Space (full pipeline: OCR + language + execution)

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ demo.png filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,12 +1,69 @@
1
- ---
2
- title: Tzefa
3
- emoji: 🌍
4
- colorFrom: gray
5
- colorTo: indigo
6
- sdk: gradio
7
- sdk_version: 6.8.0
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Tzefa
3
+ emoji: "\U0001F40D"
4
+ colorFrom: green
5
+ colorTo: blue
6
+ sdk: gradio
7
+ sdk_version: "5.8.0"
8
+ app_file: app.py
9
+ pinned: true
10
+ license: cc-by-nc-3.0
11
+ pipeline_tag: image-to-text
12
+ tags:
13
+ - vision
14
+ - ocr
15
+ - document-processing
16
+ - binarization
17
+ - yolo
18
+ - trocr
19
+ - handwriting-recognition
20
+ - programming-language
21
+ - compiler
22
+ thumbnail: >-
23
+ https://cdn-uploads.huggingface.co/production/uploads/6645e2ce9c6ed6c615e56bf0/eTdBX9sR1-qzBuEPVWwZA.jpeg
24
+ ---
25
+
26
+ # Tzefa - Handwritten Code to Execution
27
+
28
+ **Tzefa** is an end-to-end system that photographs handwritten code on a whiteboard,
29
+ recognizes it via a custom OCR pipeline, compiles it through a custom programming language,
30
+ and executes it -- all from a single image upload.
31
+
32
+ ## Pipeline
33
+ ```
34
+ Image Upload
35
+ |-- Stage 1: Binarization -- HighResMAnet (mit_b5), tiled 640x640
36
+ |-- Stage 2: Line Segmentation -- YOLO11x-OBB, oriented bounding boxes
37
+ |-- Stage 3: Word Segmentation -- Morphological dilation (exactly 3 words/line)
38
+ |-- Stage 4: Word OCR -- Fine-tuned TrOCR
39
+ |-- Stage 5: Error Correction -- Edit-distance matching against Tzefa vocabulary
40
+ |-- Stage 6: Compilation -- Tzefa instructions -> Python code
41
+ '-- Stage 7: Execution -- Subprocess with 15s timeout
42
+ ```
43
+
44
+ ## Modular Design
45
+ All models load from their own HuggingFace repos. Push new weights to any repo
46
+ and this Space picks them up on next run.
47
+
48
+ | Component | Model Repo |
49
+ |-----------|-----------|
50
+ | Binarization (b3) | [WARAJA/Model](https://huggingface.co/spaces/WARAJA/Model) |
51
+ | Binarization (b5) | [WARAJA/b5_model](https://huggingface.co/WARAJA/b5_model) |
52
+ | Line Segmentation | [WARAJA/Tzefa-Line-Segmentation-YOLO](https://huggingface.co/WARAJA/Tzefa-Line-Segmentation-YOLO) |
53
+ | Word OCR | [WARAJA/Tzefa-Word-OCR-TrOCR](https://huggingface.co/WARAJA/Tzefa-Word-OCR-TrOCR) |
54
+
55
+ ## Tzefa Language
56
+ Every instruction is exactly 3 tokens: `COMMAND ARG1 ARG2`
57
+
58
+ ```
59
+ MAKEINTEGER NUMY FIVE -- create integer NUMY = 5
60
+ MULTIPLY RESULT BIGLY -- RESULT = RESULT * BIGLY
61
+ PRINTINTEGER TEMPORARY BREAK -- print TEMPORARY with newline
62
+ ```
63
+
64
+ Numbers are written as words (ZERO through ONEHUNDRED) to maximize OCR error correction.
65
+
66
+ ## Related Spaces
67
+ - [Binarization Demo](https://huggingface.co/spaces/WARAJA/Tzefa-Binarization)
68
+ - [OCR-Only Demo](https://huggingface.co/spaces/WARAJA/Tzefa-OCR)
69
+
app.py ADDED
@@ -0,0 +1,479 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Tzefa - Complete Pipeline Demo Space
3
+ Image -> Binarization -> Line Segmentation -> Word Segmentation -> OCR ->
4
+ Error Correction -> Compilation -> Execution
5
+
6
+ All models loaded from their HF repos. Modular: swap weights and this updates.
7
+ Language files (ErrorCorrection, topy, createdpython, Number2Name) are bundled in language/
8
+ """
9
+ import os
10
+ import gc
11
+ import sys
12
+ import subprocess
13
+ import importlib
14
+ import traceback
15
+ import cv2
16
+ import torch
17
+ import numpy as np
18
+ from PIL import Image
19
+ import gradio as gr
20
+ from huggingface_hub import hf_hub_download
21
+ import segmentation_models_pytorch as smp
22
+ import torch.nn as nn
23
+ import torch.nn.functional as F
24
+ from transformers import TrOCRProcessor, VisionEncoderDecoderModel
25
+ from ultralytics import YOLO
26
+
27
+ # Add language/ to path so ErrorCorrection can import Number2Name etc.
28
+ SPACE_DIR = os.path.dirname(os.path.abspath(__file__))
29
+ sys.path.insert(0, SPACE_DIR)
30
+
31
+ from language import ErrorCorrection, topy
32
+
33
+ # ══════════════════════════════════════════════════════════════
34
+ # CONFIG
35
+ # ══════════════════════════════════════════════════════════════
36
+ HF_TOKEN = os.environ.get("HF_TOKEN")
37
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
38
+
39
+ BIN_B3_REPO = "WARAJA/Model"
40
+ BIN_B3_FILE = "b3_model.pth"
41
+ BIN_B5_REPO = "WARAJA/b5_model"
42
+ BIN_B5_FILE = "b5_model.pth"
43
+ YOLO_REPO = "WARAJA/Tzefa-Line-Segmentation-YOLO"
44
+ YOLO_FILE = "best.pt"
45
+ TROCR_REPO = "WARAJA/Tzefa-Word-OCR-TrOCR"
46
+ TROCR_BASE_PROC = "microsoft/trocr-small-stage1"
47
+
48
+ TILE_SIZE = 640
49
+ YOLO_IMGSZ = 640
50
+ TARGET_WORDS = 3
51
+ MAX_DILATE_ITERS = 200
52
+
53
+
54
+ # ══════════════════════════════════════════════════════════════
55
+ # 1. BINARIZATION
56
+ # ══════════════════════════════════════════════════════════════
57
+ class HighResMAnet(nn.Module):
58
+ def __init__(self, encoder_name="mit_b5", classes=1):
59
+ super().__init__()
60
+ self.base_model = smp.MAnet(
61
+ encoder_name=encoder_name, encoder_weights=None,
62
+ in_channels=3, classes=classes, encoder_depth=5,
63
+ decoder_channels=(256, 128, 64, 32, 16),
64
+ )
65
+ self.high_res_stem = nn.Sequential(
66
+ nn.Conv2d(3, 16, 3, padding=1), nn.BatchNorm2d(16), nn.ReLU(True),
67
+ nn.Conv2d(16, 32, 3, padding=1), nn.BatchNorm2d(32), nn.ReLU(True),
68
+ )
69
+ self.final_fusion = nn.Sequential(
70
+ nn.Conv2d(48, 16, 3, padding=1), nn.ReLU(True),
71
+ nn.Conv2d(16, classes, 1),
72
+ )
73
+
74
+ def forward(self, x):
75
+ hr = self.high_res_stem(x)
76
+ feat = self.base_model.encoder(x)
77
+ dec = self.base_model.decoder(feat)
78
+ return self.final_fusion(torch.cat([dec, hr], dim=1))
79
+
80
+
81
+ def _load_bin_models():
82
+ models = {}
83
+ b3_path = hf_hub_download(BIN_B3_REPO, BIN_B3_FILE, token=HF_TOKEN, repo_type="space")
84
+ m3 = smp.Unet(encoder_name="mit_b3", encoder_weights=None, in_channels=3, classes=1)
85
+ ckpt3 = torch.load(b3_path, map_location=DEVICE)
86
+ m3.load_state_dict(ckpt3.get("model_state_dict", ckpt3))
87
+ models["mit_b3 (Standard)"] = m3.to(DEVICE).eval()
88
+ b5_path = hf_hub_download(BIN_B5_REPO, BIN_B5_FILE, token=HF_TOKEN, repo_type="model")
89
+ m5 = HighResMAnet(encoder_name="mit_b5")
90
+ ckpt5 = torch.load(b5_path, map_location=DEVICE)
91
+ m5.load_state_dict(ckpt5.get("model_state_dict", ckpt5))
92
+ models["mit_b5 (HighRes)"] = m5.to(DEVICE).eval()
93
+ return models
94
+
95
+
96
+ def _preprocess_tile(pil_img):
97
+ arr = np.array(pil_img).astype(np.float32) / 255.0
98
+ mean, std = np.array([0.485, 0.456, 0.406]), np.array([0.229, 0.224, 0.225])
99
+ return torch.from_numpy(((arr - mean) / std).transpose(2, 0, 1))
100
+
101
+
102
+ def binarize(pil_img, model):
103
+ orig_w, orig_h = pil_img.size
104
+ pad_w = (TILE_SIZE - orig_w % TILE_SIZE) % TILE_SIZE
105
+ pad_h = (TILE_SIZE - orig_h % TILE_SIZE) % TILE_SIZE
106
+ padded = Image.new("RGB", (orig_w + pad_w, orig_h + pad_h), (255, 255, 255))
107
+ padded.paste(pil_img, (0, 0))
108
+ nw, nh = padded.size
109
+ canvas = Image.new("L", (nw, nh), 255)
110
+ for y in range(0, nh, TILE_SIZE):
111
+ for x in range(0, nw, TILE_SIZE):
112
+ tile = padded.crop((x, y, x + TILE_SIZE, y + TILE_SIZE))
113
+ t = _preprocess_tile(tile).unsqueeze(0).to(DEVICE).float()
114
+ with torch.no_grad():
115
+ logits = model(t)
116
+ if logits.shape[-2:] != (TILE_SIZE, TILE_SIZE):
117
+ logits = F.interpolate(logits, (TILE_SIZE, TILE_SIZE), mode="bilinear")
118
+ mask = (torch.sigmoid(logits) > 0.5).float().cpu().numpy()[0, 0]
119
+ canvas.paste(Image.fromarray(((1.0 - mask) * 255).astype(np.uint8)), (x, y))
120
+ return canvas.crop((0, 0, orig_w, orig_h))
121
+
122
+
123
+ # ══════════════════════════════════════════════════════════════
124
+ # 2. LINE SEGMENTATION
125
+ # ══════════════════════════════════════════════════════════════
126
+ def _load_yolo():
127
+ path = hf_hub_download(YOLO_REPO, YOLO_FILE, token=HF_TOKEN, repo_type="model")
128
+ return YOLO(path)
129
+
130
+
131
+ def segment_lines(bin_arr, yolo_model):
132
+ img_rgb = cv2.cvtColor(bin_arr, cv2.COLOR_GRAY2RGB) if len(bin_arr.shape) == 2 else bin_arr
133
+ orig_h, orig_w = img_rgb.shape[:2]
134
+ results = yolo_model.predict(img_rgb, imgsz=YOLO_IMGSZ, conf=0.2, iou=0.2, verbose=False)
135
+ truelines = []
136
+ if len(results) > 0 and results[0].obb is not None:
137
+ obbs = sorted(results[0].obb.xyxyxyxy.cpu().numpy(), key=lambda p: np.min(p[:, 1]))
138
+ for pts in obbs:
139
+ rx0, rx1 = np.min(pts[:, 0]), np.max(pts[:, 0])
140
+ ry0, ry1 = np.min(pts[:, 1]), np.max(pts[:, 1])
141
+ pad = (rx1 - rx0) * 0.12
142
+ x0 = int(np.clip(rx0 - pad, 0, orig_w))
143
+ x1 = int(np.clip(rx1 + pad, 0, orig_w))
144
+ y0, y1 = int(np.clip(ry0, 0, orig_h)), int(np.clip(ry1, 0, orig_h))
145
+ if x1 - x0 > 0 and y1 - y0 > 0:
146
+ truelines.append((x0, y0, x1 - x0, y1 - y0))
147
+ return truelines
148
+
149
+
150
+ # ══════════════════════════════════════════════════════════════
151
+ # 3. WORD SEGMENTATION
152
+ # ══════════════════════════════════════════════════════════════
153
+ def _get_word_boxes(dilated, min_w, min_h):
154
+ contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
155
+ boxes = sorted([b for b in [cv2.boundingRect(c) for c in contours] if b[2] >= min_w and b[3] >= min_h],
156
+ key=lambda b: b[0])
157
+ return boxes
158
+
159
+
160
+ def segment_words(bin_arr, lines):
161
+ words_dict = {}
162
+ for i, (lx, ly, lw, lh) in enumerate(lines):
163
+ ih, iw = bin_arr.shape[:2]
164
+ ly, lx = max(0, ly), max(0, lx)
165
+ lh, lw = min(lh, ih - ly), min(lw, iw - lx)
166
+ if lw <= 0 or lh <= 0:
167
+ continue
168
+ crop = bin_arr[ly:ly+lh, lx:lx+lw]
169
+ inv = cv2.bitwise_not(crop)
170
+ min_ww, min_wh = max(5, int(lw * 0.02)), max(5, int(lh * 0.25))
171
+ kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 3))
172
+ dilated, prev, found = inv.copy(), None, False
173
+ for _ in range(MAX_DILATE_ITERS):
174
+ dilated = cv2.dilate(dilated, kernel, iterations=1)
175
+ boxes = _get_word_boxes(dilated, min_ww, min_wh)
176
+ if len(boxes) == TARGET_WORDS:
177
+ prev = boxes; found = True; break
178
+ elif len(boxes) < TARGET_WORDS:
179
+ break
180
+ else:
181
+ prev = boxes
182
+ if not found and prev and len(prev) > TARGET_WORDS:
183
+ while len(prev) > TARGET_WORDS:
184
+ gaps = [(prev[j+1][0] - (prev[j][0]+prev[j][2]), j) for j in range(len(prev)-1)]
185
+ _, mi = min(gaps)
186
+ b1, b2 = prev[mi], prev[mi+1]
187
+ merged = (min(b1[0],b2[0]), min(b1[1],b2[1]),
188
+ max(b1[0]+b1[2],b2[0]+b2[2])-min(b1[0],b2[0]),
189
+ max(b1[1]+b1[3],b2[1]+b2[3])-min(b1[1],b2[1]))
190
+ prev = list(prev); prev[mi] = merged; prev.pop(mi+1)
191
+ found = True
192
+ if not found or not prev or len(prev) != TARGET_WORDS:
193
+ continue
194
+ line_words = {}
195
+ for wi, (wx, wy, ww, wh) in enumerate(prev):
196
+ line_words[wi+1] = (wx, wx+ww)
197
+ words_dict[i+1] = line_words
198
+ return words_dict
199
+
200
+
201
+ # ══════════════════════════════════════════════════════════════
202
+ # 4. OCR
203
+ # ══════════════════════════════════════════════════════════════
204
+ def _load_trocr():
205
+ proc = TrOCRProcessor.from_pretrained(TROCR_BASE_PROC, use_fast=False)
206
+ model = VisionEncoderDecoderModel.from_pretrained(TROCR_REPO, token=HF_TOKEN).to(DEVICE).eval()
207
+ return proc, model
208
+
209
+
210
+ def _pad_aspect(img, max_ratio=4.0):
211
+ w, h = img.size
212
+ if w <= max_ratio * h:
213
+ return img
214
+ th = int(w / max_ratio)
215
+ pad = th - h
216
+ from PIL import ImageOps
217
+ return ImageOps.expand(img, (0, pad//2, 0, pad - pad//2), fill=(255,255,255))
218
+
219
+
220
+ def ocr_word(img_pil, proc, model):
221
+ if img_pil.mode != "RGB":
222
+ img_pil = img_pil.convert("RGB")
223
+ img_pil = _pad_aspect(img_pil)
224
+ pv = proc(img_pil, return_tensors="pt").pixel_values.to(DEVICE)
225
+ with torch.no_grad():
226
+ ids = model.generate(pv)
227
+ txt = proc.batch_decode(ids, skip_special_tokens=True)[0]
228
+ parts = txt.split()
229
+ return max(parts, key=len) if parts else txt
230
+
231
+
232
+ # ══════════════════════════════════════════════════════════════
233
+ # 5. VISUALIZATION
234
+ # ══════════════════════════════════════════════════════════════
235
+ def draw_line_bboxes(img_arr, bboxes):
236
+ vis = cv2.cvtColor(img_arr, cv2.COLOR_GRAY2RGB) if len(img_arr.shape) == 2 else img_arr.copy()
237
+ for i, (x, y, w, h) in enumerate(bboxes):
238
+ cv2.rectangle(vis, (x, y), (x+w, y+h), (255, 50, 50), 2)
239
+ cv2.putText(vis, str(i+1), (x, max(y-5, 0)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
240
+ return vis
241
+
242
+
243
+ def draw_word_bboxes(img_arr, word_tuples):
244
+ vis = cv2.cvtColor(img_arr, cv2.COLOR_GRAY2RGB) if len(img_arr.shape) == 2 else img_arr.copy()
245
+ colors = [(50, 220, 50), (50, 180, 255), (255, 180, 50)]
246
+ for lt in word_tuples:
247
+ for wi, (text, (x1, y1, x2, y2)) in enumerate(lt):
248
+ c = colors[wi % len(colors)]
249
+ cv2.rectangle(vis, (x1, y1), (x2, y2), c, 2)
250
+ cv2.putText(vis, text, (x1, max(y1-4, 0)), cv2.FONT_HERSHEY_SIMPLEX, 0.45, c, 1)
251
+ return vis
252
+
253
+
254
+ # ══════════════════════════════════════════════════════════════
255
+ # 6. CLEAR VRAM
256
+ # ══════════════════════════════════════════════════════════════
257
+ def clear_vram():
258
+ gc.collect()
259
+ if torch.cuda.is_available():
260
+ torch.cuda.empty_cache()
261
+
262
+
263
+ # ══════════════════════════════════════════════════════════════
264
+ # 7. CODE EXECUTION
265
+ # ══════════════════════════════════════════════════════════════
266
+ def execute_code(compiled_code):
267
+ try:
268
+ result = subprocess.run(
269
+ [sys.executable, "-c", compiled_code],
270
+ capture_output=True, text=True, timeout=15,
271
+ cwd=SPACE_DIR,
272
+ )
273
+ output = result.stdout
274
+ if result.stderr:
275
+ output += "\n--- STDERR ---\n" + result.stderr
276
+ if result.returncode != 0:
277
+ output += f"\n[Process exited with code {result.returncode}]"
278
+ return output.strip() if output.strip() else "(no output)"
279
+ except subprocess.TimeoutExpired:
280
+ return "[Execution timed out after 15 seconds]"
281
+ except Exception as e:
282
+ return f"[Execution error: {e}]"
283
+
284
+
285
+ # ══════════════════════════════════════════════════════════════
286
+ # 8. FULL PIPELINE
287
+ # ══════════════════════════════════════════════════════════════
288
+ def run_full_pipeline(input_image, bin_model_choice):
289
+ """Returns: binarized, line_vis, word_vis, raw_ocr, corrected, compiled, execution, status"""
290
+ if input_image is None:
291
+ return None, None, None, "", "", "", "", "No image provided."
292
+
293
+ if isinstance(input_image, np.ndarray):
294
+ pil_img = Image.fromarray(input_image).convert("RGB")
295
+ else:
296
+ pil_img = input_image.convert("RGB")
297
+
298
+ status = []
299
+
300
+ # Reset language global state between runs
301
+ importlib.reload(ErrorCorrection)
302
+ importlib.reload(topy)
303
+
304
+ # ── Stage 1: Binarization ──
305
+ try:
306
+ status.append("[1/6] Binarization...")
307
+ bin_models = _load_bin_models()
308
+ model = bin_models[bin_model_choice]
309
+ bin_pil = binarize(pil_img, model)
310
+ bin_arr = np.array(bin_pil)
311
+ del bin_models; clear_vram()
312
+ status.append(" OK")
313
+ except Exception as e:
314
+ return None, None, None, "", "", "", "", f"Binarization failed: {e}"
315
+
316
+ # ── Stage 2: Line Segmentation ──
317
+ try:
318
+ status.append("[2/6] Line Segmentation...")
319
+ yolo_model = _load_yolo()
320
+ truelines = segment_lines(bin_arr, yolo_model)
321
+ del yolo_model; clear_vram()
322
+ status.append(f" Found {len(truelines)} lines")
323
+ line_vis = draw_line_bboxes(bin_arr, truelines)
324
+ except Exception as e:
325
+ return bin_arr, None, None, "", "", "", "", f"Line Seg failed: {e}"
326
+
327
+ # ── Stage 3: Word Seg + OCR ──
328
+ try:
329
+ status.append("[3/6] Word Segmentation + OCR...")
330
+ words = segment_words(bin_arr, truelines)
331
+ proc, trocr_model = _load_trocr()
332
+ all_line_tuples, raw_lines = [], []
333
+ for ln in sorted(words.keys()):
334
+ if ln - 1 >= len(truelines):
335
+ continue
336
+ lx, ly, lw, lh = truelines[ln - 1]
337
+ line_tuples = []
338
+ for wn in sorted(words[ln].keys()):
339
+ wx1, wx2 = words[ln][wn]
340
+ ax1, ax2 = max(0, int(lx + wx1)), min(bin_arr.shape[1], int(lx + wx2))
341
+ ay1, ay2 = max(0, ly - 20), min(bin_arr.shape[0], ly + lh + 20)
342
+ crop_pil = Image.fromarray(bin_arr[ay1:ay2, ax1:ax2])
343
+ text = ocr_word(crop_pil, proc, trocr_model)
344
+ line_tuples.append((text, (ax1, ay1, ax2, ay2)))
345
+ raw_lines.append(" ".join(t[0] for t in line_tuples))
346
+ all_line_tuples.append(line_tuples)
347
+ del proc, trocr_model; clear_vram()
348
+ word_vis = draw_word_bboxes(bin_arr, all_line_tuples)
349
+ raw_text = "\n".join(raw_lines)
350
+ status.append(f" {len(raw_lines)} lines recognized")
351
+ except Exception as e:
352
+ return bin_arr, line_vis, None, "", "", "", "", f"OCR failed: {e}"
353
+
354
+ # ── Stage 4: Error Correction ──
355
+ try:
356
+ status.append("[4/6] Error Correction...")
357
+ ErrorCorrection.sendlines(len(truelines))
358
+ index_list, corrected_lines = [], []
359
+ for line_entries in all_line_tuples:
360
+ if not line_entries:
361
+ corrected_lines.append(""); index_list.append(0); continue
362
+ raw_tokens = [t[0].upper() for t in line_entries]
363
+ while len(raw_tokens) < 3:
364
+ raw_tokens.append("")
365
+ raw_tokens = raw_tokens[:3]
366
+ cleaned_first, index, _ = ErrorCorrection.handelfirstword(raw_tokens[0])
367
+ index_list.append(index)
368
+ simpler = ErrorCorrection.listsimplefunc[index]
369
+ if simpler[1] == 0:
370
+ bucket_idx = simpler[2]
371
+ if isinstance(bucket_idx, int) and bucket_idx < len(ErrorCorrection.listall):
372
+ bucket = ErrorCorrection.listall[bucket_idx]
373
+ if raw_tokens[1] and raw_tokens[1] not in bucket:
374
+ bucket.append(raw_tokens[1])
375
+ corrected_lines.append(f"{cleaned_first} {raw_tokens[1]} {raw_tokens[2]}")
376
+ corrected_text = "\n".join(corrected_lines)
377
+ status.append(" OK")
378
+ except Exception as e:
379
+ return bin_arr, line_vis, word_vis, raw_text, "", "", "", f"Error Correction failed: {e}\n{traceback.format_exc()}"
380
+
381
+ # ── Stage 5: Compilation ──
382
+ try:
383
+ status.append("[5/6] Compilation...")
384
+ linelist = []
385
+ for i in range(len(corrected_lines)):
386
+ idx = index_list[i] if i < len(index_list) else 0
387
+ line_obj = ErrorCorrection.toline(corrected_lines[i], idx, ErrorCorrection.giveindents())
388
+ linelist.append(line_obj)
389
+ listfunctions_out, listezfunctions_out = ErrorCorrection.giveinstructions()
390
+ topy.getinstructions(listfunctions_out, listezfunctions_out)
391
+ compiled = ["from language.createdpython import *"]
392
+ counterindent = 0
393
+ for i in range(1, len(linelist) + 1):
394
+ counterindent += topy.listofindentchanges[i]
395
+ compiled.append(" " * counterindent + topy.makepredict(linelist[i - 1], i))
396
+ compiled.append("printvars()")
397
+ compiled_code = "\n".join(compiled)
398
+ status.append(" OK")
399
+ except Exception as e:
400
+ return bin_arr, line_vis, word_vis, raw_text, corrected_text, "", "", f"Compilation failed: {e}\n{traceback.format_exc()}"
401
+
402
+ # ── Stage 6: Execution ──
403
+ try:
404
+ status.append("[6/6] Execution...")
405
+ exec_output = execute_code(compiled_code)
406
+ status.append(" Done!")
407
+ except Exception as e:
408
+ exec_output = f"Execution error: {e}"
409
+
410
+ return bin_arr, line_vis, word_vis, raw_text, corrected_text, compiled_code, exec_output, "\n".join(status)
411
+
412
+
413
+ # ══════════════════════════════════════════════════════════════
414
+ # 9. GRADIO UI
415
+ # ══════════════════════════════════════════════════════════════
416
+ with gr.Blocks(title="Tzefa - Handwritten Code to Execution", theme=gr.themes.Soft()) as demo:
417
+ gr.Markdown(
418
+ "# Tzefa - Handwritten Code to Execution\n"
419
+ "Upload a photo of handwritten Tzefa code. The pipeline runs binarization, "
420
+ "line detection, word OCR, error correction, compilation, and execution."
421
+ )
422
+
423
+ with gr.Row():
424
+ with gr.Column(scale=1):
425
+ input_image = gr.Image(type="pil", label="Upload Image")
426
+ bin_choice = gr.Dropdown(
427
+ choices=["mit_b3 (Standard)", "mit_b5 (HighRes)"],
428
+ value="mit_b5 (HighRes)",
429
+ label="Binarization Model",
430
+ )
431
+ run_btn = gr.Button("Run Full Pipeline", variant="primary", size="lg")
432
+ with gr.Column(scale=1):
433
+ status_box = gr.Textbox(label="Pipeline Status", lines=12, interactive=False)
434
+
435
+ with gr.Tabs():
436
+ with gr.Tab("Binarized"):
437
+ bin_out = gr.Image(label="Binarized Image")
438
+ with gr.Tab("Line Detection"):
439
+ line_out = gr.Image(label="Line Bounding Boxes")
440
+ with gr.Tab("Word Detection + OCR"):
441
+ word_out = gr.Image(label="Word Bboxes with OCR Labels")
442
+ with gr.Tab("Raw OCR"):
443
+ raw_out = gr.Textbox(label="Raw OCR (before correction)", lines=15, interactive=False)
444
+ with gr.Tab("Error Corrected"):
445
+ corrected_out = gr.Textbox(label="After Error Correction", lines=15, interactive=False)
446
+ with gr.Tab("Compiled Python"):
447
+ compiled_out = gr.Code(language="python", label="Generated Python Code")
448
+ with gr.Tab("Execution Output"):
449
+ exec_out = gr.Textbox(label="Program Output", lines=10, interactive=False)
450
+
451
+ run_btn.click(
452
+ fn=run_full_pipeline,
453
+ inputs=[input_image, bin_choice],
454
+ outputs=[bin_out, line_out, word_out, raw_out, corrected_out, compiled_out, exec_out, status_box],
455
+ )
456
+
457
+ gr.Examples(
458
+ examples=[["demo.png", "mit_b5 (HighRes)"]],
459
+ inputs=[input_image, bin_choice],
460
+ label="Example Images",
461
+ )
462
+
463
+ gr.Markdown(
464
+ "### Resources\n"
465
+ "| Component | Link |\n"
466
+ "|-----------|------|\n"
467
+ "| Binarization Demo | [WARAJA/Tzefa-Binarization](https://huggingface.co/spaces/WARAJA/Tzefa-Binarization) |\n"
468
+ "| OCR-Only Demo | [WARAJA/Tzefa-OCR](https://huggingface.co/spaces/WARAJA/Tzefa-OCR) |\n"
469
+ "| b5 Model | [WARAJA/b5_model](https://huggingface.co/WARAJA/b5_model) |\n"
470
+ "| YOLO Model | [WARAJA/Tzefa-Line-Segmentation-YOLO](https://huggingface.co/WARAJA/Tzefa-Line-Segmentation-YOLO) |\n"
471
+ "| TrOCR Model | [WARAJA/Tzefa-Word-OCR-TrOCR](https://huggingface.co/WARAJA/Tzefa-Word-OCR-TrOCR) |\n"
472
+ "| Binarization Dataset | [WARAJA/Tzefa-Binarization-Dataset](https://huggingface.co/datasets/WARAJA/Tzefa-Binarization-Dataset) |\n"
473
+ "| Line Seg Dataset | [WARAJA/Tzefa-Line-Segmentation-Dataset](https://huggingface.co/datasets/WARAJA/Tzefa-Line-Segmentation-Dataset) |\n"
474
+ "| Word OCR Dataset | [WARAJA/Tzefa-Word-OCR-Dataset](https://huggingface.co/datasets/WARAJA/Tzefa-Word-OCR-Dataset) |"
475
+ )
476
+
477
+ if __name__ == "__main__":
478
+ demo.queue().launch()
479
+
demo.png ADDED

Git LFS Details

  • SHA256: 96bb166ee0d15a28d3815b9548335479a48be821dad26a6f9dbfa2c4903d2d87
  • Pointer size: 132 Bytes
  • Size of remote file: 8.64 MB
language/ErrorCorrection.py ADDED
@@ -0,0 +1,373 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from language import Number2Name
2
+ from fast_edit_distance import edit_distance
3
+
4
+
5
+ def giveinstructions():
6
+ ### returns instructions for each function in the language for topy
7
+ return listfunctions, listezfunc
8
+
9
+
10
+ listofindents = []
11
+
12
+
13
+ def updatesizelistofindnets(size):
14
+ global listofindents
15
+ listofindents = [0] * (size + 1)
16
+
17
+
18
+ def tosimple(func):
19
+ simpler = ["a", "b", "c", "d"]
20
+ simpler[0] = func[0]
21
+ if func[1].startswith("NEW"):
22
+ simpler[1] = 0
23
+ else:
24
+ simpler[1] = 1
25
+ i = 1
26
+ j = 2
27
+ if func[i].endswith("INT"):
28
+ simpler[j] = 0
29
+ elif func[i].endswith("STR"):
30
+ simpler[j] = 1
31
+ elif func[i].endswith("LIST"):
32
+ simpler[j] = 2
33
+ elif func[i].endswith("BOOL"):
34
+ simpler[j] = 3
35
+ elif func[i].endswith("COND"):
36
+ simpler[j] = 4
37
+ elif func[i].endswith("STATE"):
38
+ simpler[j] = 5
39
+ elif func[i].endswith("TYPE"):
40
+ simpler[j] = 6
41
+ elif func[i].endswith("FUNC"):
42
+ simpler[j] = 7
43
+ elif func[i].endswith("TRUTH"):
44
+ simpler[j] = 8
45
+ elif func[i].endswith("COMPARE"):
46
+ simpler[j] = 9
47
+ elif func[i].endswith("NUMNAME"):
48
+ simpler[j] = 10
49
+ elif func[i].endswith("TEXT"):
50
+ simpler[j] = 11
51
+ i = 2
52
+ j = 3
53
+ if func[i].endswith("INT"):
54
+ simpler[j] = 0
55
+ elif func[i].endswith("STR"):
56
+ simpler[j] = 1
57
+ elif func[i].endswith("LIST"):
58
+ simpler[j] = 2
59
+ elif func[i].endswith("BOOL"):
60
+ simpler[j] = 3
61
+ elif func[i].endswith("COND"):
62
+ simpler[j] = 4
63
+ elif func[i].endswith("STATE"):
64
+ simpler[j] = 5
65
+ elif func[i].endswith("TYPE"):
66
+ simpler[j] = 6
67
+ elif func[i].endswith("FUNC"):
68
+ simpler[j] = 7
69
+ elif func[i].endswith("TRUTH"):
70
+ simpler[j] = 8
71
+ elif func[i].endswith("COMPARE"):
72
+ simpler[j] = 9
73
+ elif func[i].endswith("NUMNAME"):
74
+ simpler[j] = 10
75
+ elif func[i].endswith("TEXT"):
76
+ simpler[j] = 11
77
+ simpler.append(0)
78
+ return simpler
79
+
80
+
81
+
82
+ # CHANGED: Replaced NUM/INT with NUMNAME for immediate value reading (Index 10)
83
+ listfunctions = [
84
+ ["MAKEINTEGER", "NEWINT", "NUMNAME"],
85
+ ["MAKEBOOLEAN", "NEWBOOL", "TRUTH"],
86
+ ["MAKESTR", "NEWSTR", "TEXT"],
87
+ ["NEWLIST", "NEWLIST", "NUMNAME"],
88
+ ["BASICCONDITION", "NEWCOND", "COMPARE"],
89
+ ["LEFTSIDE", "COND", "INT"],
90
+ ["RIGHTSIDE", "COND", "INT"],
91
+ ["CHANGECOMPARE", "COND", "COMPARE"],
92
+ ["WHILE", "COND", "NUMNAME"],
93
+ ["COMPARE", "COND", "NUMNAME"],
94
+ ["ELSECOMPARE", "COND", "NUMNAME"],
95
+ ["ITERATE", "LIST", "NUMNAME"],
96
+ ["WHILETRUE", "BOOL", "NUMNAME"],
97
+ ["IFTRUE", "BOOL", "NUMNAME"],
98
+ ["ELSEIF", "BOOL", "NUMNAME"],
99
+ ["INTEGERFUNCTION", "NEWFUNC", "TYPE"],
100
+ ["STRINGFUNCTION", "NEWFUNC", "TYPE"],
101
+ ["LISTFUNCTION", "NEWFUNC", "TYPE"],
102
+ ["RETURN", "VALUE", "STATE"],
103
+ ["PRINTSTRING", "STR", "STATE"],
104
+ ["PRINTINTEGER", "INT", "STATE"],
105
+ ["SETINDEX", "LIST", "INT"],
106
+ ["TYPETOINT", "STR", "INT"],
107
+ ["GETSTRING", "LIST", "STR"],
108
+ ["GETINTEGER", "LIST", "INT"],
109
+ ["WRITEINTEGER", "LIST", "INT"],
110
+ ["WRITESTRING", "LIST", "STR"],
111
+ ["WRITEBOOL", "LIST", "BOOL"],
112
+ ["WRITELIST", "LIST", "LIST"],
113
+ ["GETLIST", "LIST", "LIST"],
114
+ ["GETBOOL", "LIST", "BOOL"],
115
+ ["GETTYPE", "LIST", "STR"],
116
+ ["LENGTH", "LIST", "INT"],
117
+ ["ADDVALUES", "INT", "INT"],
118
+ ["MULTIPLY", "INT", "INT"],
119
+ ["MATHPOW", "INT", "INT"],
120
+ ["DIVIDE", "INT", "INT"],
121
+ ["SIMPLEDIVIDE", "INT", "INT"],
122
+ ["SUBTRACT", "INT", "INT"],
123
+ ["MODULO", "INT", "INT"],
124
+ ["COMBINE", "STR", "STR"],
125
+ ["BLANKSPACES", "STR", "NUMNAME"],
126
+ ["ADDSIZE", "LIST", "INT"],
127
+ ["ASSSIGNINT", "INT", "INT"],
128
+ ["STRINGASSIGN", "STR", "STR"],
129
+ ["COPYLIST", "LIST", "LIST"],
130
+ ]
131
+ listsimplefunc = [tosimple(i) for i in listfunctions]
132
+ listofindents = []
133
+ listezfunc = [i[0] for i in listfunctions]
134
+
135
+ # Variable Names only
136
+ listintegers = ["TEMPORARY", "LOCALINT", "LOOPINTEGER"]
137
+
138
+ # Immediate Number Names (Index 10)
139
+ listnumnames = []
140
+ word_to_num = {}
141
+ for i in range(101):
142
+ name = Number2Name.get_name(i)
143
+ listnumnames.append(name)
144
+ word_to_num[name] = str(i)
145
+
146
+ liststrings = ["TEMPSTRING", "GLOBALSTR", "LOOPSTRING", "INTEGER", "STRING", "LIST", "BOOLEAN"]
147
+ listlists = ["GLOBALLIST", "LOOPLIST"]
148
+ listconds = ["THETRUTH"]
149
+ listbools = ["LOOPBOOL"]
150
+ liststate = ["STAY", "BREAK"]
151
+ listype = ["INTEGER", "STRING", "LIST", "BOOLEAN"]
152
+ lookuptype = {"INTEGER": "INT", "STRING": "STR", "LIST": "LIST", "BOOLEAN": "BOOL"}
153
+ listtruth = ["TRUE", "FALSE"]
154
+ listcompare = ["EQUALS", "BIGEQUALS", "BIGGER"]
155
+ listtext = [] # Placeholder for raw text arguments (Index 11)
156
+
157
+ listall = [
158
+ listintegers,
159
+ liststrings,
160
+ listlists,
161
+ listbools,
162
+ listconds,
163
+ liststate,
164
+ listype,
165
+ listezfunc,
166
+ listtruth,
167
+ listcompare,
168
+ listnumnames, # Index 10: Immediates
169
+ listtext, # Index 11: Text
170
+ ]
171
+ thetype = []
172
+ insidefunction = False
173
+ counter = 0
174
+
175
+
176
+ def getsimples():
177
+ return listsimplefunc
178
+
179
+
180
+ def sendlines(i):
181
+ global listofindents
182
+ listofindents = [0] * max(i + 1, 1000)
183
+
184
+
185
+ def giveindents():
186
+ return listofindents
187
+
188
+ def ocr_edit_distance(word1, word2):
189
+ """
190
+ Custom Levenshtein distance tailored for OCR.
191
+ Heavily penalizes distant letter swaps (H vs Q), but forgives common OCR shapes.
192
+ """
193
+ word1, word2 = word1.upper(), word2.upper()
194
+
195
+ # Common OCR confusions get a low penalty (0.5).
196
+ # Add more to this dictionary as you find specific model confusions!
197
+ low_cost_subs = {
198
+ ('O', '0'): 0.5, ('0', 'O'): 0.5,
199
+ ('I', '1'): 0.5, ('1', 'I'): 0.5,
200
+ ('I', 'L'): 0.5, ('L', 'I'): 0.5,
201
+ ('S', '5'): 0.5, ('5', 'S'): 0.5,
202
+ ('Z', '2'): 0.5, ('2', 'Z'): 0.5,
203
+ ('C', 'O'): 0.5, ('O', 'C'): 0.5,
204
+ ('C', 'G'): 0.5, ('G', 'C'): 0.5,
205
+ ('B', '8'): 0.5, ('8', 'B'): 0.5,
206
+ ('D', 'O'): 0.5, ('O', 'D'): 0.5,
207
+ ('E', 'F'): 0.5, ('F', 'E'): 0.5,
208
+ ('A', '4'): 0.5, ('4', 'A'): 0.5,
209
+ }
210
+
211
+ m, n = len(word1), len(word2)
212
+ dp = [[0.0] * (n + 1) for _ in range(m + 1)]
213
+
214
+ for i in range(m + 1):
215
+ dp[i][0] = i * 1.0 # Cost of deletion
216
+ for j in range(n + 1):
217
+ dp[0][j] = j * 1.0 # Cost of insertion
218
+
219
+ for i in range(1, m + 1):
220
+ for j in range(1, n + 1):
221
+ if word1[i-1] == word2[j-1]:
222
+ cost = 0.0
223
+ else:
224
+ sub_pair = (word1[i-1], word2[j-1])
225
+ # Generic substitution is penalized heavily (2.0)
226
+ cost = low_cost_subs.get(sub_pair, 2.0)
227
+
228
+ dp[i][j] = min(
229
+ dp[i-1][j] + 1.0, # deletion
230
+ dp[i][j-1] + 1.0, # insertion
231
+ dp[i-1][j-1] + cost # substitution
232
+ )
233
+ return dp[m][n]
234
+
235
+ def findword(somelist, word, use_ocr_weights=False):
236
+ """
237
+ Find the closest match to `word` in `somelist`.
238
+
239
+ use_ocr_weights=True → ocr_edit_distance (custom weighted, no cap)
240
+ used for function/command name lookups where OCR
241
+ can produce arbitrarily garbled prefixes/suffixes.
242
+ use_ocr_weights=False → standard edit_distance with a generous cap (32)
243
+ used for argument vocab lookups (short words, small lists).
244
+ """
245
+ min_dist = 999
246
+ tobereturned = [word, 0]
247
+ lentobereturned = 16
248
+ for b in range(len(somelist)):
249
+ lenword = len(word)
250
+ i = somelist[b]
251
+ lenofi = len(i)
252
+ if i == word:
253
+ return [i, b]
254
+ else:
255
+ if use_ocr_weights:
256
+ distance = ocr_edit_distance(word, i)
257
+ else:
258
+ distance = edit_distance(word, i, 32)
259
+ if distance < min_dist:
260
+ min_dist = distance
261
+ tobereturned = [i, b]
262
+ lentobereturned = len(tobereturned[0])
263
+ elif distance == min_dist:
264
+ if abs(lenword - lenofi) < abs(lenword - lentobereturned):
265
+ tobereturned = [i, b]
266
+ lentobereturned = len(tobereturned[0])
267
+
268
+ return tobereturned
269
+
270
+
271
+ def handelfirstword(firstword):
272
+ func, index = findword(listezfunc, firstword, use_ocr_weights=True)
273
+ # Check if Arg2 (Index 2 in definition) is NUMNAME (Index 10 in listall)
274
+ # We use listfunctions directly to check the string type
275
+ if listfunctions[index][2] == "NUMNAME":
276
+ return (func, index, 1)
277
+ else:
278
+ return (func, index, 0)
279
+
280
+
281
+ def toline(line, index, listofindents):
282
+ global counter
283
+ global thetype
284
+ global insidefunction
285
+ disthreeline = line.split(" ")
286
+ threeline = ["", "", ""]
287
+ problem = False
288
+ threeline[0] = listezfunc[index]
289
+ simpler = listsimplefunc[index]
290
+ if threeline[0] == "STRINGFUNCTION":
291
+ if insidefunction:
292
+ problem = True
293
+ else:
294
+ insidefunction = True
295
+ threeline[1] = disthreeline[1]
296
+ threeline[2] = findword(listype, disthreeline[2])[0]
297
+ thetype.append(threeline[2])
298
+ newsomething = [threeline[1], "STR", lookuptype[threeline[2]]]
299
+ listezfunc.append(newsomething[0])
300
+ listfunctions.append(newsomething)
301
+ simplerer = tosimple(newsomething)
302
+ listsimplefunc.append(simplerer)
303
+ elif threeline[0] == "INTEGERFUNCTION":
304
+ if insidefunction:
305
+ problem = True
306
+ else:
307
+ insidefunction = True
308
+ threeline[1] = disthreeline[1]
309
+ threeline[2] = findword(listype, disthreeline[2])[0]
310
+ thetype.append(threeline[2])
311
+ newsomething = [threeline[1], "INT", lookuptype[threeline[2]]]
312
+ listezfunc.append(newsomething[0])
313
+ listfunctions.append(newsomething)
314
+ simplerer = tosimple(newsomething)
315
+ listsimplefunc.append(simplerer)
316
+ elif threeline[0] == "LISTFUNCTION":
317
+ if insidefunction:
318
+ problem = True
319
+ else:
320
+ insidefunction = True
321
+ threeline[1] = disthreeline[1]
322
+ threeline[2] = findword(listype, disthreeline[2])[0]
323
+ thetype.append(threeline[2])
324
+ newsomething = [threeline[1], "LIST", lookuptype[threeline[2]]]
325
+ listezfunc.append(newsomething[0])
326
+ listfunctions.append(newsomething)
327
+ simplerer = tosimple(newsomething)
328
+ listsimplefunc.append(simplerer)
329
+ elif simpler[0] == "RETURN":
330
+ if len(thetype) == 0:
331
+ problem = True
332
+ else:
333
+ threeline[0] = "RETURN"
334
+ threeline[1] = findword(listall[listype.index(thetype[-1])], disthreeline[1])[0]
335
+ threeline[2] = findword(liststate, disthreeline[2])[0]
336
+ if threeline[2] == "BREAK":
337
+ insidefunction = False
338
+ thetype.pop()
339
+ listofindents[counter] = -1
340
+ else:
341
+ # Arg 1
342
+ if simpler[1] == 0:
343
+ listall[simpler[2]].append(disthreeline[1])
344
+ threeline[1] = disthreeline[1]
345
+ else:
346
+ threeline[1] = findword(listall[simpler[2]], disthreeline[1])[0]
347
+ # If Arg 1 is a NUMNAME, replace with actual value
348
+ if simpler[2] == 10:
349
+ threeline[1] = word_to_num[threeline[1]]
350
+
351
+ # Arg 2
352
+ if simpler[3] < len(listall):
353
+ threeline[2] = findword(listall[simpler[3]], disthreeline[2])[0]
354
+ # If Arg 2 is a NUMNAME, replace with actual value
355
+ if simpler[3] == 10:
356
+ threeline[2] = word_to_num[threeline[2]]
357
+ else:
358
+ threeline[2] = disthreeline[2]
359
+
360
+ # Use the now-numeric value in threeline[2] for indents
361
+ # Only actual control flow: WHILE, ITERATE, COMPARE, ELSECOMPARE, WHILETRUE, IFTRUE, ELSEIF
362
+ # NOT BASICCONDITION, CHANGECOMPARE (these aren't control flow, their arg2 isn't a line number)
363
+ control_flow = {"WHILE", "ITERATE", "COMPARE", "ELSECOMPARE", "WHILETRUE", "IFTRUE", "ELSEIF"}
364
+ if threeline[0] in control_flow:
365
+ listofindents[counter] = 1
366
+ listofindents[int(threeline[2])] = -1
367
+ elif threeline[0] == "DEFINE":
368
+ listfunctions.append(threeline[0])
369
+ listofindents[int(counter)] = 1
370
+ counter += 1
371
+ if len(threeline[1]) == 0 or len(threeline[2]) == 0:
372
+ problem = True
373
+ return threeline
language/Number2Name.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def get_name(number):
2
+ namearray = ['ZERO', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE', 'TEN', 'ELEVEN',
3
+ 'TWELVE', 'THIRTEEN', 'FOURTEEN', 'FIFTEEN', 'SIXTEEN', 'SEVENTEEN', 'EIGHTEEN', 'NINETEEN', 'TWENTY',
4
+ 'TWENTYONE', 'TWENTYTWO', 'TWENTYTHREE', 'TWENTYFOUR', 'TWENTYFIVE', 'TWENTYSIX', 'TWENTYSEVEN',
5
+ 'TWENTYEIGHT', 'TWENTYNINE', 'THIRTY', 'THIRTYONE', 'THIRTYTWO', 'THIRTYTHREE', 'THIRTYFOUR',
6
+ 'THIRTYFIVE', 'THIRTYSIX', 'THIRTYSEVEN', 'THIRTYEIGHT', 'THIRTYNINE', 'FORTY', 'FORTYONE', 'FORTYTWO',
7
+ 'FORTYTHREE', 'FORTYFOUR', 'FORTYFIVE', 'FORTYSIX', 'FORTYSEVEN', 'FORTYEIGHT', 'FORTYNINE', 'FIFTY',
8
+ 'FIFTYONE', 'FIFTYTWO', 'FIFTYTHREE', 'FIFTYFOUR', 'FIFTYFIVE', 'FIFTYSIX', 'FIFTYSEVEN', 'FIFTYEIGHT',
9
+ 'FIFTYNINE', 'SIXTY', 'SIXTYONE', 'SIXTYTWO', 'SIXTYTHREE', 'SIXTYFOUR', 'SIXTYFIVE', 'SIXTYSIX',
10
+ 'SIXTYSEVEN', 'SIXTYEIGHT', 'SIXTYNINE', 'SEVENTY', 'SEVENTYONE', 'SEVENTYTWO', 'SEVENTYTHREE',
11
+ 'SEVENTYFOUR', 'SEVENTYFIVE', 'SEVENTYSIX', 'SEVENTYSEVEN', 'SEVENTYEIGHT', 'SEVENTYNINE', 'EIGHTY',
12
+ 'EIGHTYONE', 'EIGHTYTWO', 'EIGHTYTHREE', 'EIGHTYFOUR', 'EIGHTYFIVE', 'EIGHTYSIX', 'EIGHTYSEVEN',
13
+ 'EIGHTYEIGHT', 'EIGHTYNINE', 'NINETY', 'NINETYONE', 'NINETYTWO', 'NINETYTHREE', 'NINETYFOUR',
14
+ 'NINETYFIVE', 'NINETYSIX', 'NINETYSEVEN', 'NINETYEIGHT', 'NINETYNINE', 'ONEHUNDRED']
15
+ return namearray[number]
language/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # language package for Tzefa HF Space
2
+
language/createdpython.py ADDED
@@ -0,0 +1,760 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### finally found the bug
2
+ ### here it is:
3
+ ### lets say function f calls a new instance of itself
4
+ ### the new instance creates cond b and a new instance of itself
5
+ ### the new instance closes and returns to the instance with cond b that also closes itself
6
+ ### now the original instance still owns cond b since no function was called to clean the stack or dict between the exiting calls
7
+ dicte = {"EQUALS": 0, "BIGEQUALS": 1, "BIGGER": 2}
8
+ listfunctions = [(lambda x, y: x == y), (lambda x, y: x >= y), (lambda x, y: x > y)]
9
+ import sys
10
+ import language.Number2Name as Number2Name
11
+ linecount = 0
12
+ currentline = 0
13
+ linelimit = 1000
14
+ functionlimit = 25
15
+ functioncount = 0
16
+ printed = ""
17
+ alltheconds = {}
18
+ reserveconds = {}
19
+ reserveloc = {}
20
+ reserveglob = {"INT": {}, "STR": {}, "LIST": {}, "BOOLEAN": {}}
21
+
22
+
23
+ def line(linenum):
24
+ global currentline
25
+ currentline = linenum
26
+ # if("LISTOFTWO" in allthevars["LIST"]):
27
+ # print(linenum,getvar("LIST","LISTOFTWO").values)
28
+ return True
29
+
30
+
31
+ class Node:
32
+ def __init__(self, value):
33
+ self.value = value
34
+ self.next = None
35
+
36
+ def setnext(self, nextvalue):
37
+ self.next = Node(value=nextvalue)
38
+
39
+ def setnextnode(self, next):
40
+ self.next = next
41
+
42
+ def getnext(self):
43
+ return self.next
44
+
45
+ def getvalue(self):
46
+ return self.value
47
+
48
+
49
+ class Stack:
50
+ def __init__(self):
51
+ self.top = None
52
+ self.list = []
53
+
54
+ def isempty(self):
55
+ return len(self.list) == 0
56
+
57
+ def push(self, value):
58
+ self.list.append(value)
59
+
60
+ def pop(self):
61
+ return self.list.pop()
62
+
63
+
64
+ functioncalls = Stack()
65
+
66
+
67
+ def addcond(name, compare):
68
+ global alltheconds
69
+ if (name in alltheconds):
70
+ errore.varexistserror(name)
71
+ else:
72
+ alltheconds[name] = COND(compare)
73
+
74
+
75
+ def addlocalcond(name, compare):
76
+ global alltheconds, allthelocalconds
77
+ if (name in alltheconds):
78
+ errore.varexistserror(name)
79
+ else:
80
+ alltheconds[name] = COND(compare)
81
+ allthelocalconds[name] = alltheconds[name]
82
+ return allthelocalconds
83
+
84
+
85
+ # import dis
86
+ # print(dis.dis(addlocalcond))
87
+ def movetonewconds(localconds):
88
+ global stackoflocalconds
89
+ global alltheconds
90
+ global reserveconds
91
+ for i in localconds:
92
+ del alltheconds[i]
93
+ stackoflocalconds.push(localconds)
94
+
95
+
96
+ def backtooldconds():
97
+ global stackoflocalconds
98
+ popped = stackoflocalconds.pop()
99
+ global alltheconds
100
+ global reserveconds
101
+ for i in reserveconds:
102
+ if i in alltheconds:
103
+ del alltheconds[i]
104
+ reserveconds = {}
105
+ for i in popped:
106
+ alltheconds[i] = popped[i]
107
+ reserveconds[i] = popped[i]
108
+ return popped
109
+
110
+
111
+ def getcond(name):
112
+ global alltheconds
113
+ if (name in alltheconds):
114
+ return alltheconds[name]
115
+ else:
116
+ errore.doesntexisterror(name)
117
+
118
+
119
+ def printvars():
120
+ global allthevars, printed
121
+ print("END OF PROGRAM")
122
+ print()
123
+ for i in allthevars:
124
+ print("All the vars used from type " + i)
125
+ for j in allthevars[i]:
126
+ if (allthevars[i][j].iswritable()):
127
+ print(j + " : " + allthevars[i][j].tostring())
128
+ else:
129
+ pass
130
+ print("")
131
+ print("All that was printed during the program")
132
+ print(printed)
133
+
134
+
135
+ def addvar(type, name, value):
136
+ global allthevars
137
+ if name in allthevars[type]:
138
+ errore.varexistserror(name)
139
+ if (type == "LIST"):
140
+ allthevars[type][name] = LIST(name, value, True, True, type)
141
+ else:
142
+ allthevars[type][name] = VALUE(name, value, True, True, type)
143
+
144
+
145
+ def getvar(type, name):
146
+ global allthevars
147
+ if (name in allthevars[type]):
148
+ return allthevars[type][name]
149
+ else:
150
+ errore.doesntexisterror(name)
151
+
152
+
153
+ def addlocalvar(type, name, value):
154
+ global dictlocalvars, allthevars
155
+ allthelocalrvars = dictlocalvars
156
+ if name in allthevars[type]:
157
+ errore.varexistserror(name)
158
+ if (type == "LIST"):
159
+ allthevars[type][name] = LIST(name, value, True, True, type)
160
+ allthelocalrvars[type][name] = allthevars[type][name]
161
+
162
+ else:
163
+ allthevars[type][name] = VALUE(name, value, True, True, type)
164
+ allthelocalrvars[type][name] = allthevars[type][name]
165
+
166
+
167
+ def switchtonewcall(dict1: dict, dict2: dict, stack: Stack):
168
+ for i in dict2:
169
+ for j in dict2[i]:
170
+ del dict1[i][j]
171
+ stack.push(dict2)
172
+ return {"INT": {}, "STR": {}, "LIST": {}, "BOOLEAN": {}}
173
+
174
+
175
+ def returntoolastcall(dict1: dict):
176
+ stack = localsvars
177
+ lastcall = stack.pop()
178
+ global reserveloc
179
+ for i in reserveloc:
180
+ for j in reserveloc[i]:
181
+ if j in dict1[i]:
182
+ del dict1[i][j]
183
+ reserveloc = {"INT": {}, "STR": {}, "LIST": {}, "BOOLEAN": {}}
184
+ for i in lastcall:
185
+ for j in lastcall[i]:
186
+ dict1[i][j] = lastcall[i][j]
187
+ reserveloc[i][j] = lastcall[i][j]
188
+ return lastcall
189
+
190
+
191
+ def Print(var, newline):
192
+ global printed
193
+ toprint = var.tostring() + newline * '\n' + ' ' * (1 - newline)
194
+ print(toprint, end='')
195
+ printed = printed + toprint
196
+
197
+
198
+ class VALUE:
199
+ def __init__(self, name, value, readable, writable, TYPE):
200
+ self.name = name
201
+ self.value = value
202
+ self.readable = readable
203
+ self.writable = writable
204
+ self.type = TYPE
205
+
206
+ def write(self, value):
207
+ if (self.writable == True):
208
+ self.value = value
209
+ else:
210
+ errore.writeerror(self.name, value)
211
+
212
+ def forcewrite(self, value):
213
+ self.value = value
214
+
215
+ def read(self):
216
+ if (self.readable == True):
217
+ return self.value
218
+ else:
219
+ errore.readerror(self.name)
220
+
221
+ def forceread(self):
222
+ return self.value
223
+
224
+ def changeread(self, readstatus):
225
+ self.readable = readstatus
226
+
227
+ def changewrite(self, writestatus):
228
+ self.writable = writestatus
229
+
230
+ def getname(self):
231
+ return self.name
232
+
233
+ def iswritable(self):
234
+ return self.writable
235
+
236
+ def isreadable(self):
237
+ return self.readable
238
+
239
+ def tostring(self):
240
+ return str(self.value)
241
+
242
+ def givetype(self):
243
+ return self.type
244
+
245
+ def override(self, value):
246
+ self.value = value
247
+
248
+ def makecopy(self):
249
+ return VALUE(self.name, self.value, self.readable, True, self.type)
250
+
251
+ def copyvar(self, vari):
252
+ if (self.type != vari.type):
253
+ errore.typeerror(self.name, self.type, vari.type)
254
+ else:
255
+ if (vari.isreadable() == False):
256
+ errore.readerror(vari.getname())
257
+ else:
258
+ self.value = vari.value
259
+
260
+
261
+ def add(Vali1, vali2):
262
+ getvar("INT", "TEMPORARY").forcewrite(getvar("INT", Vali1).read() + getvar("INT", vali2).read())
263
+
264
+
265
+ def dec(Vali1, vali2):
266
+ getvar("INT", "TEMPORARY").forcewrite(getvar("INT", Vali1).read() - getvar("INT", vali2).read())
267
+
268
+ def mult(Vali1, vali2):
269
+ getvar("INT", "TEMPORARY").forcewrite(getvar("INT", Vali1).read() * getvar("INT", vali2).read())
270
+
271
+
272
+ def div(Vali1, vali2):
273
+ if (getvar("INT", vali2).read() == 0):
274
+ errore.DIVZEROERROR(vali2)
275
+ getvar("INT", "TEMPORARY").forcewrite(getvar("INT", Vali1).read() // getvar("INT", vali2).read())
276
+
277
+
278
+ def betterdiv(Vali1, vali2):
279
+ if (getvar("INT", vali2).read() == 0):
280
+ errore.DIVZEROERROR(vali2)
281
+ getvar("INT", "TEMPORARY").forcewrite(getvar("INT", Vali1).read() / getvar("INT", vali2).read())
282
+
283
+
284
+ def pow(Vali1, vali2):
285
+ getvar("INT", "TEMPORARY").forcewrite(getvar("INT", Vali1).read() ** getvar("INT", vali2).read())
286
+
287
+
288
+ def mod(Vali1, vali2):
289
+ if (getvar("INT", vali2).read() == 0):
290
+ errore.DIVZEROERROR(vali2)
291
+ getvar("INT", "TEMPORARY").forcewrite(int(getvar("INT", Vali1).read() % getvar("INT", vali2).read()))
292
+
293
+
294
+ def comb(Vali1, vali2):
295
+ getvar("STR", "TEMPSTRING").forcewrite(getvar("STR", Vali1).read() + getvar("STR", vali2).read())
296
+
297
+
298
+ def addsize(Vali1, vali2):
299
+ getvar("LIST", Vali1).addsize(getvar("INT", vali2).read())
300
+
301
+
302
+ def assignlist(Vali1, vali2):
303
+ getvar("LIST", Vali1).copyvar(getvar("LIST", vali2))
304
+
305
+
306
+ def assignstr(Vali1, vali2):
307
+ getvar("STR", Vali1).copyvar(getvar("STR", vali2))
308
+
309
+
310
+ def assignint(Vali1, vali2):
311
+ getvar("INT", Vali1).copyvar(getvar("INT", vali2))
312
+
313
+
314
+ def blankspaces(Vali1, Vali2):
315
+ getvar("STR", Vali1).write(getvar("STR", Vali1).read() + ' ' * Vali2)
316
+
317
+
318
+ def typetoint(vali1, vali2):
319
+ lookuptable = {"INT": 0, "STR": 1, "BOOLEAN": 2, "LIST": 3}
320
+ if (getvar('STR', vali1).read() in lookuptable):
321
+ getvar('INT', vali2).write(lookuptable[getvar('STR', vali1).read()])
322
+ else:
323
+ errore.typetointerror(getvar('STR', vali1).read())
324
+
325
+
326
+ class COND:
327
+ def __init__(self, compare):
328
+ self.index = dicte[compare]
329
+ self.left = VALUE("0", 0, False, False, "INT")
330
+ self.right = VALUE("0", 0, False, False, "INT")
331
+
332
+ def changecompare(self, compare):
333
+ self.index = dicte[compare]
334
+
335
+ def changeleft(self, left):
336
+ self.left = left
337
+
338
+ def changeright(self, right):
339
+ self.right = right
340
+
341
+ def giveresult(self):
342
+ return listfunctions[self.index](self.left.read(), self.right.read())
343
+
344
+ def givetype(self):
345
+ return self.type
346
+
347
+
348
+ class EERROR(Exception):
349
+ global sizeoflistinuse, wantedindex
350
+
351
+ def __init__(self):
352
+ pass
353
+
354
+ def nameerror(self, type, name):
355
+ global currentline
356
+ globalline = currentline
357
+ print("Error Line: " + str(globalline))
358
+ print("Var of name " + name + " doesn't exist as type " + type)
359
+ print(" ")
360
+ printvars()
361
+ sys.exit(0)
362
+
363
+ def makeeindexrror(self, sizeoflistinuse, wantedindex, name, name2):
364
+ global currentline
365
+ globalline = currentline
366
+ print("Error Line: " + str(globalline))
367
+ print("Tried to change index of list " + name + " with size of " + str(sizeoflistinuse) + " to value " + str(
368
+ wantedindex) + " placed in " + str(name2))
369
+ print(" ")
370
+ printvars()
371
+ sys.exit(0)
372
+
373
+ def DIVZEROERROR(self, name):
374
+ global currentline
375
+ globalline = currentline
376
+ print("Error Line: " + str(globalline))
377
+ print("Cant divide by zero and var " + name + " has value of zero")
378
+ print(" ")
379
+ printvars()
380
+ sys.exit(0)
381
+
382
+ def doesntexisterror(self, name):
383
+ global currentline
384
+ globalline = currentline
385
+ print("Error Line: " + str(globalline))
386
+ print("No object with name " + str(name) + " exists")
387
+ printvars()
388
+ sys.exit(0)
389
+
390
+ def writeerror(self, name, value):
391
+ global currentline
392
+ globalline = currentline
393
+ print("Error Line: " + str(globalline))
394
+ print("Tried to write value of " + str(value) + " to unwritable variable " + name)
395
+ print(" ")
396
+ printvars()
397
+ sys.exit(0)
398
+
399
+ def typetointerror(self, value):
400
+ global currentline
401
+ globalline = currentline
402
+ print("Error Line: " + str(globalline))
403
+ print("No type such as " + str(value))
404
+ print(" ")
405
+ printvars()
406
+ sys.exit(0)
407
+
408
+ def readerror(self, name):
409
+ global currentline
410
+ globalline = currentline
411
+ print("Error Line: " + str(globalline))
412
+ print("Tried to read from unreadable variable " + name)
413
+ print(" ")
414
+ printvars()
415
+ sys.exit(0)
416
+
417
+ def linelimiterror(self):
418
+ global currentline
419
+ globalline = currentline
420
+ print("Error Line: " + str(currentline))
421
+ print("Program ran for too long")
422
+ print(" ")
423
+ printvars()
424
+ sys.exit(0)
425
+
426
+ def overflowerror(self, functioncalls):
427
+ global currentline
428
+ globalline = currentline
429
+ print("Error Line: " + str(globalline))
430
+ print("Executing too many function calls ")
431
+ print("List of function calls")
432
+ for i in functioncalls:
433
+ pass
434
+ print(" ")
435
+ printvars()
436
+ sys.exit(0)
437
+
438
+ def cantchangeindexerror(self, name, value):
439
+ global currentline
440
+ globalline = currentline
441
+ print("Error Line: " + str(globalline))
442
+ print("Tried to change indexes of list " + name + " and add size " + str(value) + " but list is unwritable")
443
+
444
+ def varexistserror(self, name):
445
+ global currentline
446
+ globalline = currentline
447
+ print("Error Line: " + str(globalline))
448
+ print("Tried to create object with name " + name + " but var already exists")
449
+ print(" ")
450
+ printvars()
451
+ sys.exit(0)
452
+
453
+ def typeerror(self, name, type1, type2):
454
+ global currentline
455
+ globalline = currentline
456
+ print("Error Line: " + str(globalline))
457
+ print("Mismatch of types " + type1 + " and " + type2 + " in list " + name)
458
+ print(" ")
459
+ printvars()
460
+ sys.exit(0)
461
+
462
+
463
+ class LIST:
464
+ def __init__(self, name, size, readable, writable, TYPE):
465
+ self.size = size
466
+ self.index = 0
467
+ self.values = [VALUE(name=(str(name) + " " + str(i)), value=0, writable=True, readable=True, TYPE="INT") for i
468
+ in range(size)]
469
+ self.types = ["INT" for i in range(size)]
470
+ self.readable = readable
471
+ self.writable = writable
472
+ self.name = name
473
+ self.type = TYPE
474
+
475
+ def addsize(self, added):
476
+ if (self.writable):
477
+ self.size = self.size + added
478
+ self.values = [
479
+ self.values[i] if listfunctions[2](self.size, i) else VALUE(name=(str(i) + " " + str(i)), value=0,
480
+ writable=True, readable=True, TYPE="INT")
481
+ for i in range(self.size + added)]
482
+ else:
483
+ errore.cantchangeindexerror(self.name, added)
484
+
485
+ def forceaddsize(self, added):
486
+ self.size = self.size + added
487
+ self.values = [
488
+ self.values[i] if listfunctions[2](self.size, i) else VALUE(name=(str(i) + " " + str(i)), value=0,
489
+ writable=True, readable=True, TYPE="INT") for i
490
+ in range(self.size + added)]
491
+
492
+ def changeindex(self, newindex):
493
+ if (self.readable):
494
+ if (newindex >= self.size):
495
+ errore.makeeindexrror(newindex, self.size, self.name)
496
+ else:
497
+ self.index = newindex
498
+ else:
499
+ errore.readerror(self.name)
500
+
501
+ def forcechangeindex(self, newindex):
502
+ if (newindex >= self.size):
503
+ errore.makeeindexrror(newindex, self.size, self.name)
504
+ else:
505
+ self.index = newindex
506
+
507
+ def placevalue(self, name, type):
508
+ if (self.writable):
509
+ thevar = getvar(type, name)
510
+ if (thevar.isreadable()):
511
+ self.types[self.index] = type
512
+ self.values[self.index] = thevar.makecopy()
513
+ else:
514
+ errore.readerror(name)
515
+ else:
516
+ errore.writeerror(self.name, name)
517
+
518
+ def forceplacevalue(self, name, type):
519
+ thevar = getvar(type, name)
520
+ if (thevar.isreadable()):
521
+ self.types[self.index] = type
522
+ self.values[self.index] = thevar.makecopy()
523
+ else:
524
+ errore.readerror()
525
+
526
+ def returnvalue(self):
527
+ if (self.readable):
528
+ return self.values[self.index]
529
+ else:
530
+ errore.readerror(self.name)
531
+
532
+ def read(self):
533
+ if (self.readable):
534
+ return self.values[self.index]
535
+ else:
536
+ errore.readerror(self.name)
537
+
538
+ def forcereturnvalue(self):
539
+ return self.values[self.index]
540
+
541
+ def copybyvalue(self, newvalue: VALUE):
542
+ if (self.types[self.index] == newvalue.givetype()):
543
+ newvalue.write(self.values[self.index].read())
544
+ else:
545
+ errore.typeerror(name=self.name, type1=self.types[self.index], type2=newvalue.givetype())
546
+
547
+ def returntype(self):
548
+ if (self.readable):
549
+ return self.types[self.index]
550
+ else:
551
+ errore.readerror(self.name)
552
+
553
+ def forcereturntype(self):
554
+ return self.types[self.index]
555
+
556
+ def tostring(self):
557
+ strei = ""
558
+ for i in self.values:
559
+ strei = strei + str(i.tostring()) + " "
560
+ return "[ " + strei + " ]"
561
+
562
+ def tostringoftypes(self):
563
+ if (self.readable):
564
+ stre = ""
565
+ for i in self.types:
566
+ stre = stre + i[0]
567
+ return stre
568
+ else:
569
+ errore.readerror(self.name)
570
+
571
+ def forcetostringoftypes(self):
572
+ stre = ""
573
+ for i in self.types:
574
+ stre = stre + i[0]
575
+ return stre
576
+
577
+ def changeread(self, readstatus):
578
+ self.readable = readstatus
579
+
580
+ def changewrite(self, writestatus):
581
+ self.writable = writestatus
582
+
583
+ def getname(self):
584
+ return self.name
585
+
586
+ def iswritable(self):
587
+ return self.writable
588
+
589
+ def isreadable(self):
590
+ return self.readable
591
+
592
+ def getvalues(self):
593
+ return self.values
594
+
595
+ def gettypes(self):
596
+ return self.types
597
+
598
+ def getsize(self):
599
+ return self.size
600
+
601
+ def makecopy(self):
602
+ thelist = LIST(self.name, self.size, self.readable, True, self.type)
603
+ thelist.types = self.types.copy()
604
+ thelist.values = [val.makecopy() for val in self.values]
605
+ return thelist
606
+
607
+ def override(self, values, types, size):
608
+ self.values = values
609
+ self.types = types
610
+ self.size = size
611
+
612
+ def givetype(self):
613
+ return self.type
614
+
615
+ def copyvar(self, listi):
616
+ if (self.type != listi.type):
617
+ errore.typeerror(self.name, self.type, listi.type)
618
+ else:
619
+ if (listi.isreadable() == False):
620
+ errore.readerror(listi.getname())
621
+ else:
622
+ self.type = 'LIST'
623
+ self.types = listi.types.copy()
624
+ self.size = listi.size
625
+ self.values = [var.makecopy() for var in listi.values]
626
+
627
+
628
+ def join(listi: LIST, linee):
629
+ if (listi.isreadable() == False):
630
+ errore.readerror(listi.name)
631
+ for i in range(listi.size):
632
+ listi.index = i
633
+ value = listi.values[i]
634
+ typi = listi.types[i]
635
+ goodloopvars[typi].copyvar(value)
636
+ getvar('STR', 'TEMPSTRING').forcewrite(typi)
637
+ line(linee)
638
+ endline()
639
+ yield value
640
+
641
+
642
+ def returntooldlocals(dictofglobals, dictoflocals):
643
+ global reserveglob
644
+ for i in reserveglob:
645
+ for j in reserveglob[i]:
646
+ del dictofglobals[i][j]
647
+ reserveglob = {"INT": {}, "STR": {}, "LIST": {}}
648
+ for i in dictoflocals:
649
+ for j in dictoflocals[i]:
650
+ dictofglobals[i][j] = dictoflocals[i][j]
651
+ reserveglob[i][j] = dictoflocals[i][j]
652
+
653
+
654
+ def endline():
655
+ global errore, linecount
656
+ linecount += 1
657
+ if (linecount == linelimit):
658
+ errore.linelimiterror()
659
+ else:
660
+ return True
661
+
662
+
663
+ def updateline():
664
+ global errore, linecount
665
+ linecount += 1
666
+ if (linecount == linelimit):
667
+ errore.linelimiterror()
668
+ else:
669
+ return True
670
+
671
+
672
+ def updatelinewithcall(type, namevarinput, function, typeoutput, nameoutput, lini):
673
+ line(lini)
674
+ global allthevars, functioncount, localsstack, programlocals, nameofprogramlocals, dictlocalvars, functionlimit, allthelocalconds, nameofprogramlocals
675
+ localsstack.push(programlocals)
676
+
677
+ varinput = getvar(type, namevarinput)
678
+ for i in nameofprogramlocals:
679
+ if (i == 'STR'):
680
+ allthevars[i][nameofprogramlocals[i]] = VALUE(nameofprogramlocals[i], '', False, False, 'STR')
681
+ elif (i == 'INT'):
682
+ allthevars[i][nameofprogramlocals[i]] = VALUE(nameofprogramlocals[i], 0, False, False, 'INT')
683
+ else:
684
+ allthevars[i][nameofprogramlocals[i]] = LIST(nameofprogramlocals[i], 8, False, False, 'LIST')
685
+ programlocals = {"INT": {"LOCALINT": allthevars["INT"]["LOCALINT"]},
686
+ "STR": {"LOCALSTR": allthevars["STR"]["LOCALSTR"]},
687
+ "LIST": {"LOCALLIST": allthevars["LIST"]["LOCALLIST"]}}
688
+ allthevars[type][nameofprogramlocals[type]].copyvar(varinput)
689
+ vartosend = allthevars[type][nameofprogramlocals[type]]
690
+ functioncount += 1
691
+ if (functioncount == functionlimit):
692
+ errore.overflowerror(functioncalls)
693
+ else:
694
+ dictlocalvars = switchtonewcall(allthevars, dictlocalvars, localsvars)
695
+ vartosend.changeread(True)
696
+ vartosend.changewrite(True)
697
+ movetonewconds(allthelocalconds)
698
+ allthelocalconds = {}
699
+ output = getvar(typeoutput, nameoutput)
700
+ outi = function()
701
+ output.copyvar(outi)
702
+ endline()
703
+
704
+
705
+ def updatelineexitingcall(type, namevaroutput):
706
+ global allthevars, localsstack, functioncount, allthelocalconds, dictlocalvars, localsvars
707
+ thevar = getvar(type, namevaroutput)
708
+ functioncount = functioncount - 1
709
+ popped = localsstack.pop()
710
+ ### because i can't remember
711
+ ### get old "global"
712
+ returntooldlocals(allthevars, popped)
713
+ ### get old locals
714
+ dictlocalvars = returntoolastcall(allthevars)
715
+ ### get old conds
716
+ allthelocalconds = backtooldconds()
717
+ endline()
718
+ return thevar
719
+
720
+ localsvars = Stack() #### the stack for locals created in function
721
+ localsvars.push({"INT": {}, "STR": {}, "LIST": {}})
722
+ localsstack = Stack() ###### the stack of the program locals
723
+ LOOPINTEGER = VALUE(name="LOOPINTEGER", value=0, readable=True, writable=False, TYPE="INT")
724
+ LOOPSTRING = VALUE(name="LOOPSTRING", value="", readable=True, writable=False, TYPE="STR")
725
+ LOOPBOOL = VALUE(name="LOOPBOOL", value=True, readable=True, writable=False, TYPE="BOOL")
726
+ LOOPLIST = LIST(name="LOOPLIST", size=8, readable=True, writable=False, TYPE="LIST")
727
+ TEMPORARY = VALUE(name="TEMPORARY", value=0, readable=True, writable=True, TYPE="INT")
728
+ LOCALINT = VALUE(name="LOCALINT", value=0, readable=0, writable=0, TYPE="INT")
729
+ loopvars = {"INT": {"LOOPINTEGER": LOOPINTEGER}, "STR": {"LOOPSTRING": LOOPSTRING}, "LIST": {"LOOPLIST": LOOPLIST},
730
+ "BOOLEAN": {"LOOPBOOL": LOOPBOOL}}
731
+ goodloopvars = {"INT": LOOPINTEGER, "STR": LOOPSTRING, "LIST": LOOPLIST, "BOOLEAN": LOOPBOOL}
732
+ TEMPSTRING = VALUE(name="TEMPSTRING", value="", readable=True, writable=False, TYPE="STR")
733
+ LOCALSTR = VALUE(name="LOCALSTR", value="", readable=0, writable=0, TYPE="STR")
734
+ INTEGER = VALUE(name="INTEGER", value="INT", readable=True, writable=False, TYPE="STR")
735
+ STRING = VALUE(name="STRING", value="STR", readable=True, writable=False, TYPE="STR")
736
+ LISTI = VALUE(name="LIST", value="LIST", readable=True, writable=False, TYPE="STR")
737
+ BOOLEAN = VALUE(name="BOOLEAN", value="BOOLEAN", readable=True, writable=False, TYPE="STR")
738
+ LOCALLIST = LIST(name="LOCALLIST", size=8, readable=0, writable=0, TYPE="LIST")
739
+ THETRUTH = COND('EQUALS')
740
+ THETRUTH.changeleft(TEMPORARY)
741
+ THETRUTH.changeright(TEMPORARY)
742
+ allthevars = {"INT": {"LOOPINTEGER": LOOPINTEGER, "TEMPORARY": TEMPORARY, "LOCALINT": LOCALINT},
743
+ "STR": {"LOOPSTRING": LOOPSTRING, "TEMPSTRING": TEMPORARY, "LOCALSTR": LOCALSTR, "INTEGER": INTEGER,
744
+ "STRING": STRING, "LIST": LISTI, "BOOLEAN": BOOLEAN},
745
+ "LIST": {"LOOPLIST": LOOPLIST, "LOCALLIST": LOCALLIST}, "BOOLEAN": {"LOOPBOOL": LOOPBOOL}}
746
+ # Number names (ZERO..ONEHUNDRED) are compile-time constants only.
747
+ # They are resolved to plain integer literals by the compiler (toline/word_to_num)
748
+ # and must NOT live in allthevars["INT"] — that would prevent users from naming
749
+ # their own variables ONE, ZERO, etc.
750
+ examplelocalvars = {"INT": {}, "STR": {}, "LIST": {}, "BOOLEAN": {}}
751
+ dictlocalvars = examplelocalvars.copy()
752
+ programlocals = {"INT": {"LOCALINT": allthevars["INT"]["LOCALINT"]}, "STR": {"LOCALSTR": allthevars["STR"]["LOCALSTR"]},
753
+ "LIST": {"LOCALLIST": allthevars["LIST"]["LOCALLIST"]}}
754
+ nameofprogramlocals = {"INT": "LOCALINT", "STR": "LOCALSTR", "LIST": "LOCALLIST"}
755
+ stackoflocalconds = Stack()
756
+ localsstack.push(programlocals)
757
+ dictlocalvars = examplelocalvars.copy()
758
+ allthelocalconds = {}
759
+ errore = EERROR()
760
+ alltheconds['THETRUTH'] = THETRUTH
language/topy.py ADDED
@@ -0,0 +1,454 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def makeparenthasis(listofvals):
2
+ stri = "("
3
+ for i in range(len(listofvals) - 1):
4
+ stri = stri + " " + str(listofvals[i]) + " " + ","
5
+ stri = stri + " " + str(listofvals[-1]) + " )"
6
+ return stri
7
+
8
+
9
+ def strreadvalue(type, name):
10
+ return "getvar" + makeparenthasis([tostri(type), tostri(name)]) + ".read()"
11
+
12
+
13
+ lineupdate = "endline() ;"
14
+ infunction = False
15
+ dictoffunct = {i[0]: i for i in [[0]]}
16
+ dictofinstructions = {i: "thetext" for i in dictoffunct}
17
+ listfunctionswithtypes = {i[0]: i for i in [[0]]}
18
+ listfunctionswithtypes["GREATESTDIV"] = ["GREATESTDIV", "LIST", "LIST"]
19
+ for i in listfunctionswithtypes:
20
+ for j in range(len(listfunctionswithtypes[i])):
21
+ if (listfunctionswithtypes[i][j] == "BOOL"):
22
+ listfunctionswithtypes[i][j] = "BOOLEAN"
23
+
24
+ listofindentchanges = [0 for i in range(1, 1000 + 1)]
25
+
26
+
27
+ def getinstructions(listfunctions, listezfunctions):
28
+ global dictoffunct, listfunctionswithtypes
29
+ dictoffunct = {i[0]: i for i in listezfunctions}
30
+ listfunctionswithtypes = {i[0]: i for i in listfunctions}
31
+
32
+
33
+ def tostri(value):
34
+ return "'" + str(value) + "'"
35
+
36
+
37
+ def MAKEINTEGER(name, value, linenum):
38
+ global infunction
39
+ inparan = makeparenthasis(['"INT"', tostri(name), value])
40
+ if (infunction):
41
+ declarestr = "addlocalvar" + inparan
42
+ else:
43
+ declarestr = "addvar" + inparan
44
+ stri = "line(" + str(linenum) + ")" + "; " + declarestr + "; " + lineupdate
45
+ return stri
46
+
47
+
48
+ def MAKESTR(name, value, linenum):
49
+ global infunction
50
+ inparan = makeparenthasis(['"STR"', tostri(name), "'" + str(value) + "'"])
51
+ if (infunction):
52
+ declarestr = "addlocalvar" + inparan
53
+ else:
54
+ declarestr = "addvar" + inparan
55
+ stri = "line(" + str(linenum) + ")" + "; " + declarestr + "; " + lineupdate
56
+ return stri
57
+
58
+
59
+ def MAKEBOOLEAN(name, value, linenum):
60
+ global infunction
61
+ if value == "TRUE":
62
+ value = "True"
63
+ elif value == "FALSE":
64
+ value = "False"
65
+ inparan = makeparenthasis(['"BOOLEAN"', tostri(name), value])
66
+ if (infunction):
67
+ declarestr = "addlocalvar" + inparan
68
+ else:
69
+ declarestr = "addvar" + inparan
70
+ stri = "line(" + str(linenum) + ")" + "; " + declarestr + "; " + lineupdate
71
+ return stri
72
+
73
+
74
+
75
+ def NEWLIST(name, value, linenum):
76
+ global infunction
77
+ # value is already a plain integer string (e.g. '6') resolved at compile time
78
+ inparan = makeparenthasis(['"LIST"', tostri(name), str(int(value))])
79
+ if (infunction):
80
+ declarestr = "addlocalvar" + inparan
81
+ else:
82
+ declarestr = "addvar" + inparan
83
+ stri = "line(" + str(linenum) + ")" + "; " + declarestr + "; " + lineupdate
84
+ return stri
85
+
86
+
87
+ def BASICCONDITION(name, compare, linenum):
88
+ global infunction
89
+ if (infunction == False):
90
+ declarestr = "addcond" + makeparenthasis([tostri(name), tostri(compare)])
91
+ else:
92
+ declarestr = "addlocalcond" + makeparenthasis([tostri(name), tostri(compare)])
93
+
94
+ stri = "line(" + str(linenum) + ")" + "; " + declarestr + "; " + lineupdate
95
+ return stri
96
+
97
+
98
+ def LEFTSIDE(name, othername, linenum):
99
+ thegetvar = "getvar" + makeparenthasis(['"INT"', tostri(othername)])
100
+ stri = "line(" + str(linenum) + ")" + "; " + \
101
+ "getcond" + makeparenthasis([tostri(name)]) + ".changeleft(" + thegetvar + ")" + "; " + lineupdate
102
+
103
+ return (stri)
104
+
105
+
106
+ def RIGHTSIDE(name, othername, linenum):
107
+ thegetvar = "getvar" + makeparenthasis(['"INT"', tostri(othername)])
108
+ stri = "line(" + str(linenum) + ")" + "; " + \
109
+ "getcond" + makeparenthasis([tostri(name)]) + ".changeright(" + thegetvar + ")" + "; " + lineupdate
110
+ return (stri)
111
+
112
+
113
+ def CHANGECOMPARE(name, valuecompare, linenum):
114
+ stri = "line(" + str(linenum) + ")" + "; " + \
115
+ "getcond" + makeparenthasis([tostri(name)]) + ".changecompare(" + tostri(
116
+ valuecompare) + ")" + "; " + lineupdate
117
+ return (stri)
118
+
119
+
120
+ def WHILE(compare, endline, linenum):
121
+ global listofindentchanges
122
+ lineofwhile = "while" + makeparenthasis(["line(" + str(linenum) + ") and " + (
123
+ "getcond" + makeparenthasis([tostri(compare)])) + ".giveresult() and endline()"]) + ":"
124
+ listofindentchanges[linenum + 1] = 1
125
+ listofindentchanges[int(endline) + 1] = -1
126
+ return (lineofwhile)
127
+
128
+
129
+ def ITERATE(listi, endline, linenum):
130
+ global listofindentchanges
131
+ lineofwhile = "for i in join" + makeparenthasis(["getvar('LIST'," + tostri(listi) + ")", str(linenum)]) + ":"
132
+ listofindentchanges[linenum + 1] = 1
133
+ listofindentchanges[int(endline) + 1] = -1
134
+ return lineofwhile
135
+
136
+
137
+ def COMPARE(compare, endline, linenum):
138
+ global listofindentchanges
139
+ lineofwhile = "if" + makeparenthasis(["line(" + str(linenum) + ") and " + (
140
+ "getcond" + makeparenthasis([tostri(compare)])) + ".giveresult() and endline()"]) + ":"
141
+ listofindentchanges[linenum + 1] = 1
142
+ listofindentchanges[int(endline) + 1] = -1
143
+ return (lineofwhile)
144
+
145
+
146
+ def ELSECOMPARE(compare, endline, linenum):
147
+ global listofindentchanges
148
+ lineofwhile = "elif" + makeparenthasis(["line(" + str(linenum) + ") and " + (
149
+ "getcond" + makeparenthasis([tostri(compare)])) + ".giveresult() and endline()"]) + ":"
150
+ listofindentchanges[linenum + 1] = 1
151
+ listofindentchanges[int(endline) + 1] = -1
152
+ return (lineofwhile)
153
+
154
+
155
+ def WHILETRUE(bool, endline, linenum):
156
+ global listofindentchanges
157
+ lineofwhile = "while" + makeparenthasis(["line(" + str(linenum) + ") and " + (
158
+ "getvar('BOOLEAN'," + tostri(bool) + ").read() " + "and endline()")]) + ":"
159
+ listofindentchanges[linenum + 1] = 1
160
+ listofindentchanges[int(endline) + 1] = -1
161
+ return (lineofwhile)
162
+
163
+
164
+ def IFTRUE(bool, endline, linenum):
165
+ global listofindentchanges
166
+ lineofwhile = "if" + makeparenthasis(["line(" + str(linenum) + ") and " + (
167
+ "getvar('BOOLEAN'," + tostri(bool) + ").read() " + "and endline()")]) + ":"
168
+ listofindentchanges[linenum + 1] = 1
169
+ listofindentchanges[int(endline) + 1] = -1
170
+ return (lineofwhile)
171
+
172
+
173
+ def ELSEIF(bool, endline, linenum):
174
+ global listofindentchanges
175
+ lineofwhile = "elif" + makeparenthasis(["line(" + str(linenum) + ") and " + (
176
+ "getvar('BOOLEAN'," + tostri(bool) + ").read() " + "and endline()")]) + ":"
177
+ listofindentchanges[linenum + 1] = 1
178
+ listofindentchanges[int(endline) + 1] = -1
179
+ return (lineofwhile)
180
+
181
+
182
+ def INTEGERFUNCTION(name, type, linenum):
183
+ global thetype, infunction
184
+ infunction = True
185
+ thetype = "INT"
186
+ listofindentchanges[linenum + 1] = 1
187
+ return "def " + name + "" + '():'
188
+
189
+
190
+ def STRINGFUNCTION(name, type, linenum):
191
+ global thetype, infunction
192
+ infunction = True
193
+ thetype = "STR"
194
+ listofindentchanges[linenum + 1] = 1
195
+ return "def " + name + "" + '():'
196
+
197
+
198
+ def LISTFUNCTION(name, type, linenum):
199
+ global thetype, infunction
200
+ infunction = True
201
+ thetype = "LIST"
202
+ listofindentchanges[linenum + 1] = 1
203
+ return "def " + name + "" + '():'
204
+
205
+
206
+ def RETURN(name, stay, linenum):
207
+ if (stay == "BREAK"):
208
+ listofindentchanges[linenum + 1] = -1
209
+ global infunction
210
+ infunction = False
211
+ return ("line(" + str(linenum) + "); " + "return(updatelineexitingcall" + makeparenthasis(
212
+ [tostri(thetype), tostri(name)]) + ")")
213
+
214
+
215
+ def PRINTSTRING(name, state, linenum):
216
+ if (state == "BREAK"):
217
+ state = "True"
218
+ else:
219
+ state = "False"
220
+ return "line(" + str(linenum) + "); " + "Print(" + "getvar('STR'," + tostri(name) + ")," + state + "); " + "endline()"
221
+
222
+
223
+ def PRINTINTEGER(name, state, linenum):
224
+ if (state == "BREAK"):
225
+ state = "True"
226
+ else:
227
+ state = "False"
228
+ return "line(" + str(linenum) + "); " + "Print(" + "getvar('INT'," + tostri(
229
+ name) + ")," + state + "); " + "endline()"
230
+
231
+
232
+ def SETINDEX(name, index, linenum):
233
+ # index is already a plain integer string resolved at compile time
234
+ return ("line(" + str(linenum) + "); getvar('LIST'," + tostri(name) + ").changeindex(" + str(int(index)) + "); endline()")
235
+
236
+
237
+ def GETSTRING(listname, name, linenum):
238
+ name = tostri(name)
239
+ listname = tostri(listname)
240
+ return ("line(" + str(
241
+ linenum) + ");getvar('STR'," + name + ").copyvar(getvar('LIST'," + listname + ").read()); endline()")
242
+
243
+
244
+ def GETINTEGER(listname, name, linenum):
245
+ name = tostri(name)
246
+ listname = tostri(listname)
247
+ return ("line(" + str(
248
+ linenum) + ");getvar('INT'," + name + ").copyvar(getvar('LIST'," + listname + ").read()); endline()")
249
+
250
+
251
+ def GETLIST(listname, name, linenum):
252
+ name = tostri(name)
253
+ listname = tostri(listname)
254
+ return ("line(" + str(
255
+ linenum) + ");getvar('LIST'," + name + ").copyvar(getvar('LIST'," + listname + ").read()); endline()")
256
+
257
+
258
+ def GETBOOL(listname, name, linenum):
259
+ name = tostri(name)
260
+ listname = tostri(listname)
261
+ return ("line(" + str(
262
+ linenum) + ");getvar('BOOLEAN'," + name + ").copyvar(getvar('LIST'," + listname + ").read()); endline()")
263
+
264
+
265
+ def WRITESTRING(listname, name, linenum):
266
+ name = tostri(name)
267
+ listname = tostri(listname)
268
+ return ("line(" + str(linenum) + ");getvar('LIST'," + listname + ") .placevalue(" + name + ',"STR"'"); endline()")
269
+
270
+
271
+ def WRITEINTEGER(listname, name, linenum):
272
+ name = tostri(name)
273
+ listname = tostri(listname)
274
+ return ("line(" + str(linenum) + ");getvar('LIST'," + listname + ") .placevalue(" + name + ',"INT"'"); endline()")
275
+
276
+
277
+ def WRITEBOOL(listname, name, linenum):
278
+ name = tostri(name)
279
+ listname = tostri(listname)
280
+ return ("line(" + str(
281
+ linenum) + ");getvar('LIST'," + listname + ") .placevalue(" + name + ',"BOOLEAN"'"); endline()")
282
+
283
+
284
+ def WRITELIST(listname, name, linenum):
285
+ name = tostri(name)
286
+ listname = tostri(listname)
287
+ return ("line(" + str(linenum) + ");getvar('LIST'," + listname + ") .placevalue(" + name + ',"LIST"'"); endline()")
288
+
289
+
290
+ def GETTYPE(listname, strname, linenum):
291
+ strname = tostri(strname)
292
+ listname = tostri(listname)
293
+ return ("line(" + str(
294
+ linenum) + ");getvar('STR'," + strname + ").write(getvar('LIST'," + listname + ").returntype()); endline()")
295
+
296
+
297
+ def LENGTH(listname, intname, linenum):
298
+ intname = tostri(intname)
299
+ listname = tostri(listname)
300
+ return ("line(" + str(
301
+ linenum) + ");getvar('INT'," + intname + ").write(getvar('LIST'," + listname + ").getsize()); endline()")
302
+
303
+
304
+ def ADDVALUES(vali, vali2, linenum):
305
+ return ("line(" + str(linenum) + "); " + "add" + makeparenthasis([tostri(vali), tostri(vali2)]) + "; endline()")
306
+
307
+
308
+ def MULTIPLY(vali, vali2, linenum):
309
+ return ("line(" + str(linenum) + "); " + "mult" + makeparenthasis([tostri(vali), tostri(vali2)]) + "; endline()")
310
+
311
+
312
+ def MATHPOW(vali, vali2, linenum):
313
+ return ("line(" + str(linenum) + "); " + "pow" + makeparenthasis([tostri(vali), tostri(vali2)]) + "; endline()")
314
+
315
+
316
+ def DIVIDE(vali, vali2, linenum):
317
+ return ("line(" + str(linenum) + "); " + "betterdiv" + makeparenthasis(
318
+ [tostri(vali), tostri(vali2)]) + "; endline()")
319
+
320
+
321
+ def SIMPLEDIVIDE(vali, vali2, linenum):
322
+ return ("line(" + str(linenum) + "); " + "div" + makeparenthasis([tostri(vali), tostri(vali2)]) + "; endline()")
323
+
324
+
325
+ def SUBTRACT(vali, vali2, linenum):
326
+ return ("line(" + str(linenum) + "); " + "dec" + makeparenthasis([tostri(vali), tostri(vali2)]) + "; endline()")
327
+
328
+
329
+ def MODULO(vali, vali2, linenum):
330
+ return ("line(" + str(linenum) + "); " + "mod" + makeparenthasis([tostri(vali), tostri(vali2)]) + "; endline()")
331
+
332
+
333
+ def COMBINE(vali, vali2, linenum):
334
+ return ("line(" + str(linenum) + "); " + "comb" + makeparenthasis([tostri(vali), tostri(vali2)]) + "; endline()")
335
+
336
+
337
+ def ADDSIZE(vali, vali2, linenum):
338
+ return ("line(" + str(linenum) + "); " + "addsize" + makeparenthasis([tostri(vali), tostri(vali2)]) + "; endline()")
339
+
340
+
341
+ def ASSSIGNINT(vali, vali2, linenum):
342
+ return ("line(" + str(linenum) + "); " + "assignint" + makeparenthasis(
343
+ [tostri(vali), tostri(vali2)]) + "; endline()")
344
+
345
+
346
+ def STRINGASSIGN(vali, vali2, linenum):
347
+ return ("line(" + str(linenum) + "); " + "assignstr" + makeparenthasis(
348
+ [tostri(vali), tostri(vali2)]) + "; endline()")
349
+
350
+
351
+ def COPYLIST(vali, vali2, linenum):
352
+ return ("line(" + str(linenum) + "); " + "assignlist" + makeparenthasis(
353
+ [tostri(vali), tostri(vali2)]) + "; endline()")
354
+
355
+
356
+ def BLANKSPACES(vali, vali2, linenum):
357
+ return ("line(" + str(linenum) + "); " + "blankspaces" + makeparenthasis([tostri(vali), vali2]) + "; endline()")
358
+
359
+
360
+ def TYPETOINT(vali, vali2, linenum):
361
+ return ("line(" + str(linenum) + "); " + "typetoint" + makeparenthasis(
362
+ [tostri(vali), tostri(vali2)]) + "; endline()")
363
+
364
+
365
+ dictofinstructions["MAKEINTEGER"] = MAKEINTEGER
366
+ dictofinstructions["MAKESTR"] = MAKESTR
367
+ dictofinstructions["MAKEBOOLEAN"] = MAKEBOOLEAN
368
+ dictofinstructions["NEWLIST"] = NEWLIST
369
+ dictofinstructions["BASICCONDITION"] = BASICCONDITION
370
+ dictofinstructions["LEFTSIDE"] = LEFTSIDE
371
+ dictofinstructions["RIGHTSIDE"] = RIGHTSIDE
372
+ dictofinstructions["CHANGECOMPARE"] = CHANGECOMPARE
373
+ dictofinstructions["WHILE"] = WHILE
374
+ dictofinstructions["ITERATE"] = ITERATE
375
+ dictofinstructions["COMPARE"] = COMPARE
376
+ dictofinstructions["ELSECOMPARE"] = ELSECOMPARE
377
+ dictofinstructions["WHILETRUE"] = WHILETRUE
378
+ dictofinstructions["IFTRUE"] = IFTRUE
379
+ dictofinstructions["ELSEIF"] = ELSEIF
380
+ dictofinstructions["SETINDEX"] = SETINDEX
381
+ dictofinstructions["INTEGERFUNCTION"] = INTEGERFUNCTION
382
+ dictofinstructions["STRINGFUNCTION"] = STRINGFUNCTION
383
+ dictofinstructions["LISTFUNCTION"] = LISTFUNCTION
384
+ dictofinstructions["PRINTSTRING"] = PRINTSTRING
385
+ dictofinstructions["PRINTINTEGER"] = PRINTINTEGER
386
+ dictofinstructions["GETSTRING"] = GETSTRING
387
+ dictofinstructions["GETINTEGER"] = GETINTEGER
388
+ dictofinstructions["GETLIST"] = GETLIST
389
+ dictofinstructions["GETBOOL"] = GETBOOL
390
+ dictofinstructions["WRITESTRING"] = WRITESTRING
391
+ dictofinstructions["WRITEINTEGER"] = WRITEINTEGER
392
+ dictofinstructions["WRITEBOOL"] = WRITEBOOL
393
+ dictofinstructions["WRITELIST"] = WRITELIST
394
+ dictofinstructions["GETTYPE"] = GETTYPE
395
+ dictofinstructions["LENGTH"] = LENGTH
396
+ dictofinstructions["ASSSIGNINT"] = ASSSIGNINT
397
+ dictofinstructions["ADDSIZE"] = ADDSIZE
398
+ dictofinstructions["STRINGASSIGN"] = STRINGASSIGN
399
+ dictofinstructions["COPYLIST"] = COPYLIST
400
+ dictofinstructions["ADDVALUES"] = ADDVALUES
401
+ dictofinstructions["MULTIPLY"] = MULTIPLY
402
+ dictofinstructions["MATHPOW"] = MATHPOW
403
+ dictofinstructions["DIVIDE"] = DIVIDE
404
+ dictofinstructions["SIMPLEDIVIDE"] = SIMPLEDIVIDE
405
+ dictofinstructions["SUBTRACT"] = SUBTRACT
406
+ dictofinstructions["MODULO"] = MODULO
407
+ dictofinstructions["COMBINE"] = COMBINE
408
+ dictofinstructions["BLANKSPACES"] = BLANKSPACES
409
+ dictofinstructions["RETURN"] = RETURN
410
+ dictofinstructions["TYPETOINT"] = TYPETOINT
411
+
412
+
413
+
414
+ def makepredict(listi, i):
415
+ if listi[0] in dictofinstructions:
416
+ return dictofinstructions[listi[0]](listi[1], listi[2], i)
417
+ else:
418
+ listfun = listfunctionswithtypes[listi[0]]
419
+ return ("updatelinewithcall" + makeparenthasis(
420
+ [tostri(listfun[1]), tostri(listi[1]), listi[0], tostri(listfun[2]), tostri(listi[2]), i]))
421
+
422
+
423
+ def makepyfile(listi):
424
+ from pathlib import Path
425
+
426
+ outfile = Path(__file__).parent / "test.py"
427
+ with outfile.open("w+", encoding="utf-8") as f:
428
+ f.write("from Tzefa_Language.createdpython import *\n")
429
+ counterindent = 0
430
+ indent = " "
431
+ for i in range(1, len(listi) + 1):
432
+ counterindent += listofindentchanges[i]
433
+ f.write(indent * counterindent + makepredict(listi[i - 1], i) + '\n')
434
+ f.write("printvars()")
435
+
436
+
437
+
438
+
439
+ if __name__ == '__main__':
440
+ listi = [["MAKEINTEGER", "THEINT", '2769'], ["MAKEINTEGER", "THEINTI", '1065'], ["MAKEINTEGER", "THROWONE", '1065'],
441
+ ["MAKEINTEGER", "THROWTWO", '1065'], ["NEWLIST", "LISTOFTWO", '2'], ["SETINDEX", "LISTOFTWO", '0'],
442
+ ["WRITEINTEGER", "LISTOFTWO", 'THEINT'], ["SETINDEX", "LISTOFTWO", '1'],
443
+ ["WRITEINTEGER", "LISTOFTWO", 'THEINTI'], ["MAKEINTEGER", "ZERO", '0'], ["ADDVALUES", "THEINT", 'THEINTI'],
444
+ ["PRINTINTEGER", "TEMPORARY", 'BREAK'], ["LISTFUNCTION", "GREATESTDIV", 'LIST'],
445
+ ["SETINDEX", "LISTOFTWO", '0'], ["GETINTEGER", "LISTOFTWO", 'THROWONE'], ["SETINDEX", "LISTOFTWO", '1'],
446
+ ["GETINTEGER", "LISTOFTWO", 'THROWTWO'], ["BASICCONDITION", "EUCLIDCOMPARE", 'EQUALS'],
447
+ ["LEFTSIDE", "EUCLIDCOMPARE", 'THROWTWO'], ["RIGHTSIDE", "EUCLIDCOMPARE", 'ZERO'],
448
+ ["COMPARE", "EUCLIDCOMPARE", '23'], ["WRITEINTEGER", "LISTOFTWO", 'THROWTWO'],
449
+ ["RETURN", "LISTOFTWO", "STAY"], ["RIGHTSIDE", "EUCLIDCOMPARE", 'THROWTWO']
450
+ , ["SETINDEX", "LISTOFTWO", '0'], ["WRITEINTEGER", "LISTOFTWO", 'THROWTWO'], ["MODULO", "THROWONE", 'THROWTWO'],
451
+ ["SETINDEX", "LISTOFTWO", '1'], ["WRITEINTEGER", "LISTOFTWO", 'TEMPORARY'],
452
+ ["GREATESTDIV", "LISTOFTWO", 'LISTOFTWO'], ["RETURN", "LISTOFTWO", 'BREAK'],
453
+ ["GREATESTDIV", "LISTOFTWO", 'LISTOFTWO']]
454
+ makepyfile(listi)
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ torch
2
+ torchvision
3
+ transformers
4
+ segmentation-models-pytorch
5
+ albumentations
6
+ ultralytics
7
+ timm
8
+ opencv-python-headless
9
+ pillow
10
+ numpy
11
+ gradio
12
+ huggingface_hub
13
+ fast_edit_distance
14
+