lucidaflow 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of lucidaflow might be problematic. Click here for more details.
- lucidaflow/__init__.py +0 -0
- lucidaflow/lucida_analyzer.py +1043 -0
- lucidaflow/lucida_ast.py +321 -0
- lucidaflow/lucida_errors.py +26 -0
- lucidaflow/lucida_interpreter.py +821 -0
- lucidaflow/lucida_lexer.py +248 -0
- lucidaflow/lucida_parser.py +584 -0
- lucidaflow/lucida_stdlib.py +249 -0
- lucidaflow/lucida_symbols.py +176 -0
- lucidaflow-1.0.0.dist-info/METADATA +1567 -0
- lucidaflow-1.0.0.dist-info/RECORD +14 -0
- lucidaflow-1.0.0.dist-info/WHEEL +5 -0
- lucidaflow-1.0.0.dist-info/licenses/LICENSE +21 -0
- lucidaflow-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Copie e cole TODO este conteúdo em seu arquivo lucida_stdlib.py
|
|
2
|
+
|
|
3
|
+
# --- Importações do Python ---
|
|
4
|
+
import math
|
|
5
|
+
import time
|
|
6
|
+
import os
|
|
7
|
+
import datetime
|
|
8
|
+
|
|
9
|
+
from lib.web import NATIVE_WEB_MODULE, register_semantics as register_web_semantics
|
|
10
|
+
from lib.json import NATIVE_JSON_MODULE, register_semantics as register_json_semantics
|
|
11
|
+
from lib.dado import NATIVE_DADO_MODULE, register_semantics as register_dado_semantics
|
|
12
|
+
|
|
13
|
+
# --- Importações dos Símbolos da Lucida-Flow ---
|
|
14
|
+
# (Necessário para a parte de descrição semântica)
|
|
15
|
+
from lucida_symbols import (
|
|
16
|
+
VarSymbol, BuiltInFunctionSymbol, ScopedSymbolTable, BuiltInTypeSymbol,
|
|
17
|
+
ListTypeSymbol, DictTypeSymbol, TupleTypeSymbol
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# ==============================================================================
|
|
22
|
+
# PARTE 1: IMPLEMENTAÇÃO EM TEMPO DE EXECUÇÃO (PARA O INTERPRETADOR)
|
|
23
|
+
# ==============================================================================
|
|
24
|
+
|
|
25
|
+
# --- Funções do Módulo 'math' ---
|
|
26
|
+
def lf_sqrt(args):
|
|
27
|
+
if len(args) != 1:
|
|
28
|
+
raise TypeError(f"sqrt() espera 1 argumento, mas recebeu {len(args)}")
|
|
29
|
+
return math.sqrt(args[0])
|
|
30
|
+
|
|
31
|
+
def lf_sin(args):
|
|
32
|
+
if len(args) != 1:
|
|
33
|
+
raise TypeError(f"sin() espera 1 argumento, mas recebeu {len(args)}")
|
|
34
|
+
return math.sin(args[0])
|
|
35
|
+
|
|
36
|
+
# --- Funções do Módulo 'time' ---
|
|
37
|
+
def lf_now(args):
|
|
38
|
+
if len(args) != 0:
|
|
39
|
+
raise TypeError(f"now() espera 0 argumentos, mas recebeu {len(args)}")
|
|
40
|
+
return time.time()
|
|
41
|
+
|
|
42
|
+
# --- Funções do Módulo 'fs' ---
|
|
43
|
+
def lf_fs_write(args):
|
|
44
|
+
if len(args) != 2:
|
|
45
|
+
raise TypeError(f"write() espera 2 argumentos (caminho, conteudo), mas recebeu {len(args)}")
|
|
46
|
+
filepath, content = str(args[0]), str(args[1])
|
|
47
|
+
with open(filepath, 'w', encoding='utf-8') as f:
|
|
48
|
+
f.write(content)
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
def lf_fs_read(args):
|
|
52
|
+
if len(args) != 1:
|
|
53
|
+
raise TypeError(f"read() espera 1 argumento (caminho), mas recebeu {len(args)}")
|
|
54
|
+
filepath = str(args[0])
|
|
55
|
+
try:
|
|
56
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
57
|
+
return f.read()
|
|
58
|
+
except FileNotFoundError:
|
|
59
|
+
raise FileNotFoundError(f"O arquivo '{filepath}' não foi encontrado.")
|
|
60
|
+
|
|
61
|
+
def lf_fs_exists(args):
|
|
62
|
+
if len(args) != 1:
|
|
63
|
+
raise TypeError(f"exists() espera 1 argumento (caminho), mas recebeu {len(args)}")
|
|
64
|
+
return os.path.exists(str(args[0]))
|
|
65
|
+
|
|
66
|
+
def lf_fs_delete(args):
|
|
67
|
+
if len(args) != 1:
|
|
68
|
+
raise TypeError(f"delete() espera 1 argumento (caminho), mas recebeu {len(args)}")
|
|
69
|
+
try:
|
|
70
|
+
os.remove(str(args[0]))
|
|
71
|
+
except FileNotFoundError:
|
|
72
|
+
pass
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
def lf_datetime_now(args):
|
|
76
|
+
if len(args) != 0:
|
|
77
|
+
raise TypeError(f"datetime.now() espera 0 argumentos, mas recebeu {len(args)}")
|
|
78
|
+
return time.time() # Retorna o timestamp Unix atual
|
|
79
|
+
|
|
80
|
+
def lf_datetime_format(args):
|
|
81
|
+
if len(args) != 2:
|
|
82
|
+
raise TypeError(f"datetime.format() espera 2 argumentos (timestamp, formato), mas recebeu {len(args)}")
|
|
83
|
+
timestamp, fmt_string = args[0], args[1]
|
|
84
|
+
dt_object = datetime.datetime.fromtimestamp(timestamp)
|
|
85
|
+
return dt_object.strftime(fmt_string)
|
|
86
|
+
|
|
87
|
+
def lf_datetime_parse(args):
|
|
88
|
+
if len(args) != 2:
|
|
89
|
+
raise TypeError(f"datetime.parse() espera 2 argumentos (data_string, formato), mas recebeu {len(args)}")
|
|
90
|
+
date_string, fmt_string = args[0], args[1]
|
|
91
|
+
dt_object = datetime.datetime.strptime(date_string, fmt_string)
|
|
92
|
+
return dt_object.timestamp()
|
|
93
|
+
|
|
94
|
+
# --- REGISTRO CENTRAL DE MÓDULOS NATIVOS (PARA O INTERPRETADOR) ---
|
|
95
|
+
NATIVE_MODULES = {
|
|
96
|
+
"math": {
|
|
97
|
+
"pi": math.pi,
|
|
98
|
+
"sqrt": lf_sqrt,
|
|
99
|
+
"sin": lf_sin,
|
|
100
|
+
},
|
|
101
|
+
"time": {
|
|
102
|
+
"now": lf_now,
|
|
103
|
+
},
|
|
104
|
+
"fs": {
|
|
105
|
+
"write": lf_fs_write,
|
|
106
|
+
"read": lf_fs_read,
|
|
107
|
+
"exists": lf_fs_exists,
|
|
108
|
+
"delete": lf_fs_delete,
|
|
109
|
+
},
|
|
110
|
+
"datetime": {
|
|
111
|
+
"now": lf_datetime_now,
|
|
112
|
+
"format": lf_datetime_format,
|
|
113
|
+
"parse": lf_datetime_parse,
|
|
114
|
+
},
|
|
115
|
+
"web": NATIVE_WEB_MODULE,
|
|
116
|
+
"json": NATIVE_JSON_MODULE,
|
|
117
|
+
"dado": NATIVE_DADO_MODULE,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# ==============================================================================
|
|
121
|
+
# PARTE 2: DESCRIÇÃO SEMÂNTICA (PARA O ANALISADOR)
|
|
122
|
+
# ==============================================================================
|
|
123
|
+
|
|
124
|
+
# --- Tipos Comuns para Reutilização ---
|
|
125
|
+
string_type = BuiltInTypeSymbol('string')
|
|
126
|
+
float_type = BuiltInTypeSymbol('float')
|
|
127
|
+
bool_type = BuiltInTypeSymbol('bool')
|
|
128
|
+
int_type = BuiltInTypeSymbol('int')
|
|
129
|
+
null_type = BuiltInTypeSymbol('null')
|
|
130
|
+
any_type = BuiltInTypeSymbol('any')
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# --- Definição Semântica para Métodos de Dicionário ---
|
|
134
|
+
dict_semantic_scope = ScopedSymbolTable('dict', scope_level=2)
|
|
135
|
+
|
|
136
|
+
# Definição para .get() (já está correta)
|
|
137
|
+
dict_semantic_scope.define(
|
|
138
|
+
BuiltInFunctionSymbol(
|
|
139
|
+
name='get',
|
|
140
|
+
params=[
|
|
141
|
+
VarSymbol('key', any_type),
|
|
142
|
+
VarSymbol('default', any_type, is_optional=True)
|
|
143
|
+
],
|
|
144
|
+
return_type=any_type
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
# --- Definição Semântica do Módulo 'math' ---
|
|
150
|
+
math_semantic_scope = ScopedSymbolTable('math', scope_level=2)
|
|
151
|
+
math_semantic_scope.define(
|
|
152
|
+
VarSymbol('pi', float_type)
|
|
153
|
+
)
|
|
154
|
+
math_semantic_scope.define(
|
|
155
|
+
BuiltInFunctionSymbol(name='sqrt', params=[VarSymbol('x', float_type)], return_type=float_type)
|
|
156
|
+
)
|
|
157
|
+
math_semantic_scope.define(
|
|
158
|
+
BuiltInFunctionSymbol(name='sin', params=[VarSymbol('x', float_type)], return_type=float_type)
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# --- Definição Semântica do Módulo 'time' ---
|
|
163
|
+
time_semantic_scope = ScopedSymbolTable('time', scope_level=2)
|
|
164
|
+
time_semantic_scope.define(
|
|
165
|
+
BuiltInFunctionSymbol(name='now', params=[], return_type=float_type)
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# --- Definição Semântica do Módulo 'fs' ---
|
|
169
|
+
fs_semantic_scope = ScopedSymbolTable('fs', scope_level=2)
|
|
170
|
+
fs_semantic_scope.define(
|
|
171
|
+
BuiltInFunctionSymbol(name='write', params=[VarSymbol('caminho', string_type), VarSymbol('conteudo', string_type)], return_type=null_type)
|
|
172
|
+
)
|
|
173
|
+
fs_semantic_scope.define(
|
|
174
|
+
BuiltInFunctionSymbol(name='read', params=[VarSymbol('caminho', string_type)], return_type=string_type)
|
|
175
|
+
)
|
|
176
|
+
fs_semantic_scope.define(
|
|
177
|
+
BuiltInFunctionSymbol(name='exists', params=[VarSymbol('caminho', string_type)], return_type=bool_type)
|
|
178
|
+
)
|
|
179
|
+
fs_semantic_scope.define(
|
|
180
|
+
BuiltInFunctionSymbol(name='delete', params=[VarSymbol('caminho', string_type)], return_type=null_type)
|
|
181
|
+
)
|
|
182
|
+
# --- Definição Semântica do Módulo 'datetime' ---
|
|
183
|
+
datetime_semantic_scope = ScopedSymbolTable('datetime', scope_level=2)
|
|
184
|
+
datetime_semantic_scope.define(
|
|
185
|
+
BuiltInFunctionSymbol(name='now', params=[], return_type=float_type)
|
|
186
|
+
)
|
|
187
|
+
datetime_semantic_scope.define(
|
|
188
|
+
BuiltInFunctionSymbol(
|
|
189
|
+
name='format',
|
|
190
|
+
params=[VarSymbol('timestamp', float_type), VarSymbol('formato', string_type)],
|
|
191
|
+
return_type=string_type
|
|
192
|
+
)
|
|
193
|
+
)
|
|
194
|
+
datetime_semantic_scope.define(
|
|
195
|
+
BuiltInFunctionSymbol(
|
|
196
|
+
name='parse',
|
|
197
|
+
params=[VarSymbol('data_string', string_type), VarSymbol('formato', string_type)],
|
|
198
|
+
return_type=float_type
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
# --- REGISTRO CENTRAL DA SEMÂNTICA (PARA O ANALISADOR) ---
|
|
204
|
+
NATIVE_MODULES_SEMANTICS = {
|
|
205
|
+
"math": math_semantic_scope,
|
|
206
|
+
"time": time_semantic_scope,
|
|
207
|
+
"fs": fs_semantic_scope,
|
|
208
|
+
"datetime": datetime_semantic_scope,
|
|
209
|
+
"web": register_web_semantics(),
|
|
210
|
+
"json": register_json_semantics(),
|
|
211
|
+
"dado": register_dado_semantics(),
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
# ==============================================================================
|
|
215
|
+
# PARTE 3: MÉTODOS DE TIPOS NATIVOS (PARA O INTERPRETADOR)
|
|
216
|
+
# ==============================================================================
|
|
217
|
+
|
|
218
|
+
NATIVE_TYPE_METHODS = {
|
|
219
|
+
'string': {
|
|
220
|
+
# O primeiro argumento 'instance' é a própria string.
|
|
221
|
+
# 'args' são os argumentos passados na chamada do método em Lucida.
|
|
222
|
+
'to_upper': lambda instance, args: instance.upper(),
|
|
223
|
+
'to_lower': lambda instance, args: instance.lower(),
|
|
224
|
+
'trim': lambda instance, args: instance.strip(),
|
|
225
|
+
'split': lambda instance, args: instance.split(args[0] if args else None),
|
|
226
|
+
# --- ADIÇÕES AQUI ---
|
|
227
|
+
'replace': lambda instance, args: instance.replace(args[0], args[1]),
|
|
228
|
+
'contains': lambda instance, args: args[0] in instance,
|
|
229
|
+
'starts_with': lambda instance, args: instance.startswith(args[0]),
|
|
230
|
+
'ends_with': lambda instance, args: instance.endswith(args[0]),
|
|
231
|
+
# O slice do Python pode receber até 3 args (start, stop, step),
|
|
232
|
+
# aqui vamos simplificar para start e stop.
|
|
233
|
+
'slice': lambda instance, args: instance[args[0]:args[1]],
|
|
234
|
+
'length': lambda instance, args: len(instance),
|
|
235
|
+
},
|
|
236
|
+
'list': {
|
|
237
|
+
# 'pop', 'sort', etc. podem ser adicionados aqui no futuro.
|
|
238
|
+
# instance é a própria lista, args[0] é o primeiro argumento passado
|
|
239
|
+
'append': lambda instance, args: instance.append(args[0]),
|
|
240
|
+
'pop': lambda instance, args: instance.pop(),
|
|
241
|
+
'length': lambda instance, args: len(instance),
|
|
242
|
+
},
|
|
243
|
+
# --- ADIÇÕES PARA DICIONÁRIO AQUI ---
|
|
244
|
+
'dict': {
|
|
245
|
+
'keys': lambda instance, args: list(instance.keys()),
|
|
246
|
+
'values': lambda instance, args: list(instance.values()),
|
|
247
|
+
'get': lambda instance, args: instance.get(args[0], args[1] if len(args) > 1 else None),
|
|
248
|
+
},
|
|
249
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# lucida_symbols.py
|
|
2
|
+
class Symbol:
|
|
3
|
+
def __init__(self, name, type=None):
|
|
4
|
+
self.name = name
|
|
5
|
+
self.type = type
|
|
6
|
+
|
|
7
|
+
def __repr__(self):
|
|
8
|
+
return f"<{self.name}>"
|
|
9
|
+
|
|
10
|
+
class VarSymbol(Symbol):
|
|
11
|
+
# Garanta que o __init__ esteja exatamente assim
|
|
12
|
+
def __init__(self, name, type, is_const=False, is_optional=False):
|
|
13
|
+
super().__init__(name, type)
|
|
14
|
+
self.is_const = is_const
|
|
15
|
+
self.is_optional = is_optional
|
|
16
|
+
|
|
17
|
+
def __repr__(self):
|
|
18
|
+
type_str = self.type.name if self.type else 'any'
|
|
19
|
+
return f"<VarSymbol(name='{self.name}', type='{type_str}')>"
|
|
20
|
+
|
|
21
|
+
class TypeSymbol(Symbol):
|
|
22
|
+
def __init__(self, name, parent_type_symbol=None):
|
|
23
|
+
super().__init__(name)
|
|
24
|
+
self.parent_type_symbol = parent_type_symbol # <-- Para lembrar o pai
|
|
25
|
+
self.fields = {}
|
|
26
|
+
self.methods = {}
|
|
27
|
+
|
|
28
|
+
def __repr__(self):
|
|
29
|
+
parent_str = f" < {self.parent_type_symbol.name}" if self.parent_type_symbol else ""
|
|
30
|
+
return f"<TypeSymbol(name='{self.name}{parent_str}')>"
|
|
31
|
+
|
|
32
|
+
def lookup_member(self, name):
|
|
33
|
+
"""
|
|
34
|
+
Procura por um membro (campo ou método) neste tipo
|
|
35
|
+
ou em qualquer um dos seus tipos pais, recursivamente.
|
|
36
|
+
"""
|
|
37
|
+
# 1. Procura nos membros deste próprio tipo
|
|
38
|
+
symbol = self.fields.get(name) or self.methods.get(name)
|
|
39
|
+
if symbol:
|
|
40
|
+
return symbol
|
|
41
|
+
|
|
42
|
+
# 2. Se não encontrou, e tem um pai, procura no pai
|
|
43
|
+
if self.parent_type_symbol:
|
|
44
|
+
return self.parent_type_symbol.lookup_member(name)
|
|
45
|
+
|
|
46
|
+
# 3. Se não tem pai e não encontrou, o membro não existe
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
class BuiltInTypeSymbol(TypeSymbol):
|
|
50
|
+
def __init__(self, name):
|
|
51
|
+
# Agora chama o __init__ de TypeSymbol
|
|
52
|
+
super().__init__(name)
|
|
53
|
+
|
|
54
|
+
# Não precisa mais de __repr__, pois herdará um bom de TypeSymbol.
|
|
55
|
+
|
|
56
|
+
class BuiltInFunctionSymbol(Symbol):
|
|
57
|
+
# A definição agora inclui 'return_type=None'
|
|
58
|
+
def __init__(self, name, params=None, return_type=None):
|
|
59
|
+
# Chama o __init__ da classe Symbol base, mas sem passar o tipo ainda
|
|
60
|
+
super().__init__(name)
|
|
61
|
+
self.params = params if params is not None else []
|
|
62
|
+
self.return_type = return_type
|
|
63
|
+
|
|
64
|
+
# --- MUDANÇA PRINCIPAL ---
|
|
65
|
+
# Cria um tipo função para si mesmo e o armazena no atributo .type
|
|
66
|
+
# que herdamos da classe Symbol.
|
|
67
|
+
param_types = [p.type for p in self.params]
|
|
68
|
+
self.type = FunctionTypeSymbol(
|
|
69
|
+
name=name,
|
|
70
|
+
param_types=param_types,
|
|
71
|
+
return_type=return_type
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
class ProcessSymbol(Symbol):
|
|
75
|
+
def __init__(self, name, params=None, return_type=None):
|
|
76
|
+
super().__init__(name)
|
|
77
|
+
self.params = params if params is not None else []
|
|
78
|
+
self.return_type = return_type
|
|
79
|
+
# A nova propriedade para saber a qual classe um método pertence
|
|
80
|
+
self.defining_class_symbol = None # <--- ADICIONE ESTA LINHA
|
|
81
|
+
|
|
82
|
+
def __repr__(self):
|
|
83
|
+
return f"<ProcessSymbol(name='{self.name}', params={self.params})>"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class ModuleSymbol(Symbol):
|
|
87
|
+
def __init__(self, name, symbol_table=None):
|
|
88
|
+
super().__init__(name)
|
|
89
|
+
self.symbol_table = symbol_table
|
|
90
|
+
|
|
91
|
+
class ScopedSymbolTable:
|
|
92
|
+
def __init__(self, scope_name, scope_level, enclosing_scope=None):
|
|
93
|
+
self._symbols = {}
|
|
94
|
+
self.scope_name = scope_name
|
|
95
|
+
self.scope_level = scope_level
|
|
96
|
+
self.enclosing_scope = enclosing_scope
|
|
97
|
+
if scope_level == 1:
|
|
98
|
+
self.define(BuiltInTypeSymbol('int'))
|
|
99
|
+
self.define(BuiltInTypeSymbol('float'))
|
|
100
|
+
self.define(BuiltInTypeSymbol('string'))
|
|
101
|
+
self.define(BuiltInTypeSymbol('bool'))
|
|
102
|
+
self.define(BuiltInTypeSymbol('null'))
|
|
103
|
+
|
|
104
|
+
def define(self, symbol):
|
|
105
|
+
self._symbols[symbol.name] = symbol
|
|
106
|
+
|
|
107
|
+
def lookup(self, name, current_scope_only=False):
|
|
108
|
+
symbol = self._symbols.get(name)
|
|
109
|
+
if symbol is not None:
|
|
110
|
+
return symbol
|
|
111
|
+
if current_scope_only:
|
|
112
|
+
return None
|
|
113
|
+
if self.enclosing_scope is not None:
|
|
114
|
+
return self.enclosing_scope.lookup(name)
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
class ListTypeSymbol(TypeSymbol):
|
|
118
|
+
"""Representa o tipo de uma lista, por exemplo: 'list[int]'."""
|
|
119
|
+
def __init__(self, element_type):
|
|
120
|
+
# O nome é construído dinamicamente
|
|
121
|
+
super().__init__(f'list[{element_type.name}]')
|
|
122
|
+
self.element_type = element_type
|
|
123
|
+
|
|
124
|
+
def __repr__(self):
|
|
125
|
+
return f"<ListTypeSymbol(element_type='{self.element_type.name}')>"
|
|
126
|
+
|
|
127
|
+
class TupleTypeSymbol(TypeSymbol):
|
|
128
|
+
"""Representa o tipo de uma tupla, ex: 'tuple[int, string]'."""
|
|
129
|
+
def __init__(self, element_types):
|
|
130
|
+
# O nome é construído dinamicamente
|
|
131
|
+
element_names = ", ".join([t.name for t in element_types])
|
|
132
|
+
super().__init__(f'tuple[{element_names}]')
|
|
133
|
+
self.element_types = element_types
|
|
134
|
+
|
|
135
|
+
def __repr__(self):
|
|
136
|
+
return f"<TupleTypeSymbol(element_types={[t.name for t in self.element_types]})>"
|
|
137
|
+
|
|
138
|
+
class DictTypeSymbol(TypeSymbol):
|
|
139
|
+
"""Representa o tipo de um dicionário, por exemplo: 'dict[string, float]'."""
|
|
140
|
+
def __init__(self, key_type, value_type):
|
|
141
|
+
super().__init__(f'dict[{key_type.name}, {value_type.name}]')
|
|
142
|
+
self.key_type = key_type
|
|
143
|
+
self.value_type = value_type
|
|
144
|
+
|
|
145
|
+
def __repr__(self):
|
|
146
|
+
return f"<DictTypeSymbol(key='{self.key_type.name}', value='{self.value_type.name}')>"
|
|
147
|
+
|
|
148
|
+
class EnumSymbol(TypeSymbol):
|
|
149
|
+
""" Representa o tipo de um enum, ex: 'Status'. """
|
|
150
|
+
def __init__(self, name):
|
|
151
|
+
super().__init__(name)
|
|
152
|
+
# Os membros serão armazenados aqui durante a análise
|
|
153
|
+
self.members = {}
|
|
154
|
+
|
|
155
|
+
def __repr__(self):
|
|
156
|
+
return f"<EnumSymbol(name='{self.name}')>"
|
|
157
|
+
|
|
158
|
+
class EnumMemberSymbol(Symbol):
|
|
159
|
+
""" Representa um membro de um enum, ex: 'Status.CONECTADO'. """
|
|
160
|
+
def __init__(self, name, enum_type):
|
|
161
|
+
super().__init__(name, enum_type)
|
|
162
|
+
|
|
163
|
+
def __repr__(self):
|
|
164
|
+
return f"<EnumMemberSymbol(name='{self.name}', type='{self.type.name}')>"
|
|
165
|
+
|
|
166
|
+
class FunctionTypeSymbol(TypeSymbol):
|
|
167
|
+
""" Representa o tipo de uma função ou processo. """
|
|
168
|
+
def __init__(self, name, param_types, return_type):
|
|
169
|
+
super().__init__(name)
|
|
170
|
+
self.param_types = param_types
|
|
171
|
+
self.return_type = return_type
|
|
172
|
+
|
|
173
|
+
def __repr__(self):
|
|
174
|
+
param_str = ", ".join([p.name for p in self.param_types])
|
|
175
|
+
return_str = self.return_type.name if self.return_type else 'void'
|
|
176
|
+
return f"<FunctionTypeSymbol(params=({param_str}) -> {return_str})>"
|