/
space_verse
/
LambdaLanguage
Обзор
Документация
Войти
/
space_verse
/
LambdaLanguage
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
src/parser/ast/codespace.py
112 строк
3 KB
spacer
FIXED: bug with parsing math expressions
19 авг 2025, 01:59
19 авг 2025, 01:59
5d6b218
Код
Авторство
О чём код?
from abc import abstractmethod from dataclasses import dataclass from typing import Any, Optional, Protocol from parser.ast.types import types @dataclass class Implementation[T]: type: str value: T NoneTypeImpl = Implementation(types.NONETYPE.value, types.NONETYPE) UncnownTypeImpl = Implementation(types.UNKNOWN.value, types.UNKNOWN) class AbstractNode(Protocol): @abstractmethod def eval(self, codespace: "CodespaceNode") -> Implementation: raise NotImplementedError class NoneNode: def eval(self, codespace: "CodespaceNode") -> Implementation: return NoneTypeImpl class UnknownNode: def eval(self, codespace: "CodespaceNode") -> Implementation: return UncnownTypeImpl @dataclass class CodespaceNode: def __init__( self, variables: dict[str, Implementation] | None = None, upcodespace: Optional["CodespaceNode"] = None, statements: list[AbstractNode] = [], ) -> None: self.upcodespace = upcodespace self.variables = variables if variables is not None else dict() self.statements = statements def statements_update(self, statements: list[AbstractNode]) -> None: self.statements = statements def var_update(self, name: str, value: Any) -> None: if not self.var_exist(name=name): raise NameError("Variable %r is not exitst" % name) if name in self.variables: self.variables[name].value = value else: if self.upcodespace: self.upcodespace.var_update(name=name, value=value) def new_var(self, name: str, impl: Implementation) -> None: if self.var_exist(name=name): raise NameError("Variable %r already exist" % name) self.variables[name] = impl def var_exist(self, name: str) -> bool: if name not in self.variables: if self.upcodespace is not None: return self.upcodespace.var_exist(name=name) return False return True def var_get(self, name: str) -> Implementation: if name not in self.variables: if self.upcodespace is not None: return self.upcodespace.var_get(name=name) raise NameError("Variable whith name=%r not found" % name) return self.variables[name] def eval(self, codespace: "CodespaceNode") -> Implementation: result = NoneTypeImpl for statement in self.statements: result = statement.eval(codespace=self) return result @dataclass class VariableNode: name: str def eval(self, codespace: "CodespaceNode") -> Implementation: var = codespace.var_get(name=self.name) return var @dataclass class DeclareAssignNode: type: str name: str expression: AbstractNode = NoneNode() def eval(self, codespace: "CodespaceNode") -> Implementation: expr_result = self.expression.eval(codespace=codespace) if all([ expr_result.type != types.UNKNOWN.value, expr_result.type != self.type, (self.type, expr_result.type) != ("float", "int"), ]): raise TypeError("Uncorrent type value for %r: should be %s, got %s" % (self.name, self.type, expr_result.type)) codespace.new_var( name=self.name, impl=Implementation(self.type, expr_result.value)) return NoneTypeImpl