-
Notifications
You must be signed in to change notification settings - Fork 0
/
program.py
138 lines (114 loc) · 3.89 KB
/
program.py
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
# This file is part of Edia.
#
# Ediap is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
#
# Edia is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Edia. If not, see <http://www.gnu.org/licenses/>
# Copyright 2014 Matthieu Gautier [email protected]
import utils
from language import grammar
from picoparse import NoMatch
class Line:
def __init__(self, lineno, lineText):
self.lineno = lineno
self.update_text(lineText)
def update_text(self, text):
self.text = text
self.empty = not bool(self.text) or self.text.isspace()
self.level = None
self.parsed = None
if not self.empty:
self.level = grammar.get_level(text)
try:
self.parsed = grammar.parse_instruction(self.text)
except NoMatch:
self.parsed = None
def __bool__(self):
raise NotImplemented
def __str__(self):
return self.text
@property
def is_nop(self):
if self.parsed is None:
return True
return self.parsed.is_nop
@property
def klass(self):
if self.parsed is None:
return None
return self.parsed.klass
class Step:
def __init__(self, instruction, state):
self.instruction = instruction
self.state = state
self.help = {}
@property
def lineno(self):
return self.instruction.lineno
def add_help(self, lineno, content):
self.help[lineno] = content
class ExtendList(list):
def __getitem__(self, index):
if index is None:
return Step(None, list.__getitem__(self,-1).state)
return list.__getitem__(self, index)
class Program(utils.EventSource):
def __init__(self, lib):
utils.EventSource.__init__(self)
self.lib = lib
self.source = []
self.init_steps()
self.current = (None, None)
self.watchdog = 1000
self.fileName = None
def to_many_step(self):
return len(self.steps) >= self.watchdog
def init_steps(self):
self.steps = ExtendList()
self._displayedStep = None
def load_file(self, fileName):
self.fileName = fileName
self.source = []
try:
with open(fileName, 'r') as f:
lines = f.readlines()
if lines[-1] == "\n":
lines = lines[:-1]
for lineno, line in enumerate(lines, 1):
self.source.append(Line(lineno, line[:-1]))
except FileNotFoundError:
pass
def set_source(self, lines):
self.source = []
for lineno, line in enumerate(lines, 1):
self.source.append(Line(lineno, line))
def update_text(self, index, text):
if index < len(self.source):
if text != self.source[index].text:
self.source[index].update_text(text)
else:
self.source.append(Line(index+1, text))
def clean_after(self, index):
self.source[index+1:] = []
@property
def displayedStep(self):
return self._displayedStep
@displayedStep.setter
def displayedStep(self, value):
if value is not None:
value = min(value, len(self.steps)-1)
if value == -1:
value = None
self._displayedStep = value
self.event("activeStep_changed")(value)
def set_current(self, current):
self.current = current
self.event("current_changed")()