Added logic to handle lib & class declaration
This commit is contained in:
parent
793ca62ddd
commit
2b02341336
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"WorkspaceSettings": {
|
"WorkspaceSettings": {
|
||||||
"DefaultProject": "cc-lang",
|
"DefaultProject": "cc-lang-interpreter",
|
||||||
"Projects": {
|
"Projects": {
|
||||||
|
"cc-lang-interpreter": "src/cc_lang_interpreter/cc-lang-interpreter.json",
|
||||||
"cc-lang": "src/cc_lang/cc-lang.json",
|
"cc-lang": "src/cc_lang/cc-lang.json",
|
||||||
"parser": "src/parser/parser.json",
|
"parser": "src/parser/parser.json",
|
||||||
"lexer": "src/lexer/lexer.json",
|
"lexer": "src/lexer/lexer.json",
|
||||||
"runtime": "src/runtime/runtime.json",
|
"runtime": "src/runtime/runtime.json"
|
||||||
"cc-lang-interpreter": "src/cc_lang_interpreter/cc-lang-interpreter.json"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,7 +16,8 @@
|
|||||||
"LicenseName": "",
|
"LicenseName": "",
|
||||||
"LicenseDescription": "",
|
"LicenseDescription": "",
|
||||||
"Dependencies": [
|
"Dependencies": [
|
||||||
"sh_cpl==2021.4.0.post2"
|
"sh_cpl-core==2021.10.0.post1",
|
||||||
|
"sh_cpl-query==2021.10.0.post1"
|
||||||
],
|
],
|
||||||
"PythonVersion": ">=3.9.2",
|
"PythonVersion": ">=3.9.2",
|
||||||
"PythonPath": {
|
"PythonPath": {
|
||||||
|
@ -4,8 +4,11 @@ from cpl_core.application import ApplicationABC
|
|||||||
from cpl_core.configuration import ConfigurationABC
|
from cpl_core.configuration import ConfigurationABC
|
||||||
from cpl_core.console import Console
|
from cpl_core.console import Console
|
||||||
from cpl_core.dependency_injection import ServiceProviderABC
|
from cpl_core.dependency_injection import ServiceProviderABC
|
||||||
|
from cpl_query.extension.list import List
|
||||||
|
|
||||||
from lexer.abc.lexer_abc import LexerABC
|
from lexer.abc.lexer_abc import LexerABC
|
||||||
|
from lexer.model.token import Token
|
||||||
|
from parser.abc.ast import AST
|
||||||
from parser.abc.parser_abc import ParserABC
|
from parser.abc.parser_abc import ParserABC
|
||||||
from runtime.abc.runtime_service_abc import RuntimeServiceABC
|
from runtime.abc.runtime_service_abc import RuntimeServiceABC
|
||||||
|
|
||||||
@ -22,15 +25,17 @@ class Application(ApplicationABC):
|
|||||||
self._path = config.get_configuration('p')
|
self._path = config.get_configuration('p')
|
||||||
|
|
||||||
def _interpret(self, line: str):
|
def _interpret(self, line: str):
|
||||||
tokens = self._lexer.tokenize(line)
|
tokens: List[Token] = self._lexer.tokenize(line)
|
||||||
ast = self._parser.create_ast(tokens)
|
ast: List[AST] = self._parser.create_ast(tokens)
|
||||||
|
|
||||||
line.replace("\n", "").replace("\t", "")
|
line.replace("\n", "").replace("\t", "")
|
||||||
# Console.write_line(f'<{self._runtime.line_count}> LINE: {line}')
|
Console.write_line(f'<{self._runtime.line_count}> LINE: {line}')
|
||||||
# header, values = ['Type', 'Value'], []
|
# header, values = ['Type', 'Value'], []
|
||||||
# tokens.for_each(lambda t: values.append([t.type, t.value]))
|
# tokens.for_each(lambda t: values.append([t.type, t.value]))
|
||||||
# Console.table(header, values)
|
# Console.table(header, values)
|
||||||
|
|
||||||
|
Console.write(ast, '\n')
|
||||||
|
|
||||||
def _console(self):
|
def _console(self):
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
@ -62,8 +67,7 @@ class Application(ApplicationABC):
|
|||||||
self._runtime.line_count = i + 1
|
self._runtime.line_count = i + 1
|
||||||
self._interpret(f[i])
|
self._interpret(f[i])
|
||||||
|
|
||||||
def configure(self):
|
def configure(self): pass
|
||||||
pass
|
|
||||||
|
|
||||||
def main(self):
|
def main(self):
|
||||||
if self._path is None:
|
if self._path is None:
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
"LicenseDescription": "",
|
"LicenseDescription": "",
|
||||||
"Dependencies": [
|
"Dependencies": [
|
||||||
"sh_cpl-core==2021.10.0.post1",
|
"sh_cpl-core==2021.10.0.post1",
|
||||||
"sh_cpl-query==2021.10.0"
|
"sh_cpl-query==2021.10.0.post1"
|
||||||
],
|
],
|
||||||
"PythonVersion": ">=3.9.2",
|
"PythonVersion": ">=3.9.2",
|
||||||
"PythonPath": {
|
"PythonPath": {
|
||||||
|
@ -23,8 +23,8 @@ class Startup(StartupABC):
|
|||||||
return config
|
return config
|
||||||
|
|
||||||
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironment) -> ServiceProviderABC:
|
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironment) -> ServiceProviderABC:
|
||||||
|
services.add_singleton(RuntimeServiceABC, RuntimeService)
|
||||||
services.add_singleton(LexerABC, LexerService)
|
services.add_singleton(LexerABC, LexerService)
|
||||||
services.add_singleton(ParserABC, ParserService)
|
services.add_singleton(ParserABC, ParserService)
|
||||||
services.add_singleton(RuntimeServiceABC, RuntimeService)
|
|
||||||
|
|
||||||
return services.build_service_provider()
|
return services.build_service_provider()
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
"LicenseName": "",
|
"LicenseName": "",
|
||||||
"LicenseDescription": "",
|
"LicenseDescription": "",
|
||||||
"Dependencies": [
|
"Dependencies": [
|
||||||
"sh_cpl==2021.4.0.post2"
|
"sh_cpl-core==2021.10.0.post1",
|
||||||
|
"sh_cpl-query==2021.10.0.post1"
|
||||||
],
|
],
|
||||||
"PythonVersion": ">=3.9.2",
|
"PythonVersion": ">=3.9.2",
|
||||||
"PythonPath": {
|
"PythonPath": {
|
||||||
|
@ -19,5 +19,8 @@ class Token:
|
|||||||
def value(self, value: str):
|
def value(self, value: str):
|
||||||
self._value = value
|
self._value = value
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f'Token <Type: {self._type}> <Value: {self._value}>'
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f'Token: Type: {self._type}, Value: {self._value}'
|
return f'Token: Type: {self._type}, Value: {self._value}'
|
||||||
|
34
src/parser/abc/ast.py
Normal file
34
src/parser/abc/ast.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from typing import Optional, Union
|
||||||
|
from cpl_query.extension.list import List
|
||||||
|
from parser.model.ast_types_enum import ASTTypesEnum
|
||||||
|
|
||||||
|
|
||||||
|
class AST():
|
||||||
|
|
||||||
|
def __init__(self, type: ASTTypesEnum, value: Union[str, List['AST']], start: Optional[int] = None, end: Optional[int] = None):
|
||||||
|
self._type = type
|
||||||
|
self._value = value
|
||||||
|
self._start = start
|
||||||
|
self._end = end
|
||||||
|
|
||||||
|
@property
|
||||||
|
def type(self) -> ASTTypesEnum:
|
||||||
|
return self._type
|
||||||
|
|
||||||
|
@property
|
||||||
|
def value(self) -> Union[str, List['AST']]:
|
||||||
|
return self._value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def start(self) -> Optional[int]:
|
||||||
|
return self._start
|
||||||
|
|
||||||
|
@property
|
||||||
|
def end(self) -> Optional[int]:
|
||||||
|
return self._end
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f'AST <Type: {self._type}> <Value: {self._value}> <{self._start},{self._end}>'
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return f'AST <Type: {self._type}> <Value: {self._value}> <{self._start},{self._end}>'
|
@ -1,7 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
|
|
||||||
class AST(ABC):
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def __init__(self): pass
|
|
@ -2,7 +2,7 @@ from abc import ABC, abstractmethod
|
|||||||
|
|
||||||
from cpl_query.extension.list import List
|
from cpl_query.extension.list import List
|
||||||
|
|
||||||
from parser.abc.ast_abc import AST
|
from parser.abc.ast import AST
|
||||||
from lexer.model.token import Token
|
from lexer.model.token import Token
|
||||||
|
|
||||||
class ParserABC(ABC):
|
class ParserABC(ABC):
|
||||||
|
1
src/parser/model/__init__.py
Normal file
1
src/parser/model/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
# imports
|
12
src/parser/model/ast_types_enum.py
Normal file
12
src/parser/model/ast_types_enum.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class ASTTypesEnum(Enum):
|
||||||
|
|
||||||
|
Access = 'access'
|
||||||
|
Keyword = 'keyword'
|
||||||
|
Name = 'name'
|
||||||
|
|
||||||
|
LibraryDeclaration = 'library_declaration'
|
||||||
|
ClassDeclaration = 'class_declaration'
|
||||||
|
|
18
src/parser/model/class_ast.py
Normal file
18
src/parser/model/class_ast.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from parser.abc.ast import AST
|
||||||
|
|
||||||
|
from cpl_query.extension.list import List
|
||||||
|
|
||||||
|
|
||||||
|
class ClassAST(AST):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
AST.__init__(self)
|
||||||
|
self._body = List(AST)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def body(self) -> List['AST']:
|
||||||
|
return self._body
|
||||||
|
|
||||||
|
@body.setter
|
||||||
|
def body(self, value: List['AST']):
|
||||||
|
self._body = value
|
18
src/parser/model/library_ast.py
Normal file
18
src/parser/model/library_ast.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
from parser.abc.ast import AST
|
||||||
|
|
||||||
|
from cpl_query.extension.list import List
|
||||||
|
|
||||||
|
|
||||||
|
class LibraryAST(AST):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
AST.__init__(self)
|
||||||
|
self._body = List(AST)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def body(self) -> List['AST']:
|
||||||
|
return self._body
|
||||||
|
|
||||||
|
@body.setter
|
||||||
|
def body(self, value: List['AST']):
|
||||||
|
self._body = value
|
8
src/parser/model/parser_state_enum.py
Normal file
8
src/parser/model/parser_state_enum.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class ParserStateEnum(Enum):
|
||||||
|
|
||||||
|
Default = 0
|
||||||
|
Library = 1
|
||||||
|
Class = 2
|
@ -16,7 +16,8 @@
|
|||||||
"LicenseName": "",
|
"LicenseName": "",
|
||||||
"LicenseDescription": "",
|
"LicenseDescription": "",
|
||||||
"Dependencies": [
|
"Dependencies": [
|
||||||
"sh_cpl==2021.4.0.post2"
|
"sh_cpl-core==2021.10.0.post1",
|
||||||
|
"sh_cpl-query==2021.10.0.post1"
|
||||||
],
|
],
|
||||||
"PythonVersion": ">=3.9.2",
|
"PythonVersion": ">=3.9.2",
|
||||||
"PythonPath": {
|
"PythonPath": {
|
||||||
|
@ -1,19 +1,108 @@
|
|||||||
|
from parser.abc.ast import AST
|
||||||
|
from parser.abc.parser_abc import ParserABC
|
||||||
|
from parser.model.ast_types_enum import ASTTypesEnum
|
||||||
|
|
||||||
|
from cc_lang.model.language_definition_classes import FormatCharacters, Keywords
|
||||||
from cpl_core.console.console import Console
|
from cpl_core.console.console import Console
|
||||||
from cpl_query.extension.list import List
|
from cpl_query.extension.list import List
|
||||||
from lexer.model.token import Token
|
from lexer.model.token import Token
|
||||||
from parser.abc.ast_abc import AST
|
from lexer.model.token_types import TokenTypes
|
||||||
from parser.abc.parser_abc import ParserABC
|
from pynput.keyboard import Key
|
||||||
|
from parser.model.parser_state_enum import ParserStateEnum
|
||||||
|
from runtime.abc.runtime_service_abc import RuntimeServiceABC
|
||||||
|
from runtime.model.error import Error
|
||||||
|
from runtime.model.error_codes_enum import ErrorCodesEnum
|
||||||
|
|
||||||
|
|
||||||
class ParserService(ParserABC):
|
class ParserService(ParserABC):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, runtime: RuntimeServiceABC):
|
||||||
pass
|
self._runtime = runtime
|
||||||
|
|
||||||
|
self._access_keywords = [
|
||||||
|
Keywords.Public.value,
|
||||||
|
Keywords.Private.value,
|
||||||
|
Keywords.Static.value,
|
||||||
|
Keywords.This.value,
|
||||||
|
]
|
||||||
|
|
||||||
|
def _parse_library_or_class(self, tokens: List[Token], cls=False) -> AST:
|
||||||
|
""" Handles library declaration
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tokens (List[Token]): Tokens from lexer
|
||||||
|
|
||||||
|
AST:
|
||||||
|
lib Main {
|
||||||
|
<lib, class> <name> <end>
|
||||||
|
public lib Main {
|
||||||
|
<access> <lib, class> <name> <end>
|
||||||
|
public lib Main {}
|
||||||
|
<access> <lib, class> <name> <end> <end>
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AST: Library or class AST
|
||||||
|
"""
|
||||||
|
end = None
|
||||||
|
ast = List(AST)
|
||||||
|
for i in range(0, tokens.count()):
|
||||||
|
token: Token = tokens[i]
|
||||||
|
|
||||||
|
# if line contains }
|
||||||
|
if token.type == TokenTypes.Format_Character and token.value == FormatCharacters.Right_Brace.value:
|
||||||
|
end = self._runtime.line_count
|
||||||
|
elif i == tokens.count()-1 and token.type == TokenTypes.Format_Character and token.value == FormatCharacters.Left_Brace.value:
|
||||||
|
break
|
||||||
|
elif i == tokens.count()-1:
|
||||||
|
self._runtime.error(
|
||||||
|
Error(ErrorCodesEnum.Expected, FormatCharacters.Left_Brace.value))
|
||||||
|
|
||||||
|
if i == 0 and token.type == TokenTypes.Keyword and token.value in self._access_keywords:
|
||||||
|
ast.append(AST(ASTTypesEnum.Access, token.value,
|
||||||
|
self._runtime.line_count, self._runtime.line_count))
|
||||||
|
|
||||||
|
if i <= 1 and token.type == TokenTypes.Keyword and token.value == Keywords.Library.value:
|
||||||
|
ast.append(AST(ASTTypesEnum.Keyword, token.value,
|
||||||
|
self._runtime.line_count, self._runtime.line_count))
|
||||||
|
|
||||||
|
if i >= 1 and token.type == TokenTypes.Name:
|
||||||
|
ast.append(AST(ASTTypesEnum.Name, token.value,
|
||||||
|
self._runtime.line_count, self._runtime.line_count))
|
||||||
|
|
||||||
|
return AST(ASTTypesEnum.LibraryDeclaration if not cls else ASTTypesEnum.ClassDeclaration, ast, self._runtime.line_count, end)
|
||||||
|
|
||||||
|
def _parse_variable(self, tokens: List[AST]) -> AST:
|
||||||
|
""" Parses variable declarations
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tokens (List[Token]): Tokens from lexer
|
||||||
|
|
||||||
|
AST:
|
||||||
|
var test: number;
|
||||||
|
<var> <name> <type> <end>
|
||||||
|
var test: number = 0;
|
||||||
|
<var> <name> <type> <value | int, str, bool> <end>
|
||||||
|
var test: number = test;
|
||||||
|
<var> <name> <type> <name> <end>
|
||||||
|
var test: number = TestClass();
|
||||||
|
<var> <name> <type> <object-assign> <end>
|
||||||
|
private var test: number = 0;
|
||||||
|
<access> <var> <name> <type> <end>
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AST: Library or class AST
|
||||||
|
"""
|
||||||
|
|
||||||
def create_ast(self, tokens: List[Token]) -> List[AST]:
|
def create_ast(self, tokens: List[Token]) -> List[AST]:
|
||||||
for i in range(0, tokens.count()):
|
self._ast = List(AST)
|
||||||
prev_token = tokens[i-1] if i-1 > 0 else None
|
|
||||||
token = tokens[i]
|
|
||||||
next_token = tokens[i+1] if i+1 < tokens.count() else None
|
|
||||||
|
|
||||||
Console.write_line(token)
|
if tokens.where(lambda t: t.type == TokenTypes.Keyword and t.value == Keywords.Library.value).count() > 0:
|
||||||
|
self._ast.append(self._parse_library_or_class(tokens))
|
||||||
|
|
||||||
|
elif tokens.where(lambda t: t.type == TokenTypes.Keyword and t.value == Keywords.Class.value).count() > 0:
|
||||||
|
self._ast.append(self._parse_library_or_class(tokens, True))
|
||||||
|
|
||||||
|
elif tokens.where(lambda t: t.type == TokenTypes.Keyword and t.value == Keywords.Variable.value).count() > 0:
|
||||||
|
self._ast.append(self._parse_variable(tokens, True))
|
||||||
|
|
||||||
|
return self._ast
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
from cpl_core.console.console import Console
|
||||||
|
from cpl_core.console.foreground_color_enum import ForegroundColorEnum
|
||||||
|
|
||||||
|
from runtime.model.error import Error
|
||||||
|
|
||||||
|
|
||||||
class RuntimeServiceABC(ABC):
|
class RuntimeServiceABC(ABC):
|
||||||
|
|
||||||
@ -13,3 +18,15 @@ class RuntimeServiceABC(ABC):
|
|||||||
@line_count.setter
|
@line_count.setter
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def line_count(self, line_count: int): pass
|
def line_count(self, line_count: int): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def input(self, prefix: str) -> str: pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def output(self, text: str): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def error(self, error: Error): pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def runtime_error(self, error: Error): pass
|
||||||
|
1
src/runtime/model/__init__.py
Normal file
1
src/runtime/model/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
# imports
|
16
src/runtime/model/error.py
Normal file
16
src/runtime/model/error.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from runtime.model.error_codes_enum import ErrorCodesEnum
|
||||||
|
|
||||||
|
|
||||||
|
class Error:
|
||||||
|
|
||||||
|
def __init__(self, code: ErrorCodesEnum, msg: str):
|
||||||
|
self._code = code
|
||||||
|
self._msg = code.value.format(msg)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def code(self) -> ErrorCodesEnum:
|
||||||
|
return self._code
|
||||||
|
|
||||||
|
@property
|
||||||
|
def message(self) -> str:
|
||||||
|
return self._msg
|
21
src/runtime/model/error_codes_enum.py
Normal file
21
src/runtime/model/error_codes_enum.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorCodesEnum(Enum):
|
||||||
|
|
||||||
|
StartFailed = 'Start failed'
|
||||||
|
FileNotFound = 'File not found'
|
||||||
|
WrongFileType = 'Wrong file type'
|
||||||
|
|
||||||
|
Unknown = 'Unknown {}'
|
||||||
|
Inaccessible = '{} inaccessible'
|
||||||
|
Unexpected = 'Unexpected {}'
|
||||||
|
Expected = 'Expected {}'
|
||||||
|
|
||||||
|
LibInLib = 'Lib in lib'
|
||||||
|
LibInClass = 'Lib in class'
|
||||||
|
LibInFunc = 'Lib in func'
|
||||||
|
ClassInClass = 'Class in class'
|
||||||
|
ClassInFunc = 'Class in func'
|
||||||
|
FuncInLib = 'Func in lib'
|
||||||
|
FuncInFunc = 'Func in func'
|
@ -16,7 +16,8 @@
|
|||||||
"LicenseName": "",
|
"LicenseName": "",
|
||||||
"LicenseDescription": "",
|
"LicenseDescription": "",
|
||||||
"Dependencies": [
|
"Dependencies": [
|
||||||
"sh_cpl==2021.4.0.post2"
|
"sh_cpl-core==2021.10.0.post1",
|
||||||
|
"sh_cpl-query==2021.10.0.post1"
|
||||||
],
|
],
|
||||||
"PythonVersion": ">=3.9.2",
|
"PythonVersion": ">=3.9.2",
|
||||||
"PythonPath": {
|
"PythonPath": {
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
from cpl_core.console import Console, ForegroundColorEnum
|
||||||
from runtime.abc.runtime_service_abc import RuntimeServiceABC
|
from runtime.abc.runtime_service_abc import RuntimeServiceABC
|
||||||
|
from runtime.model.error import Error
|
||||||
|
|
||||||
|
|
||||||
class RuntimeService(RuntimeServiceABC):
|
class RuntimeService(RuntimeServiceABC):
|
||||||
@ -13,3 +15,21 @@ class RuntimeService(RuntimeServiceABC):
|
|||||||
@line_count.setter
|
@line_count.setter
|
||||||
def line_count(self, line_count: int):
|
def line_count(self, line_count: int):
|
||||||
self._line_count = line_count
|
self._line_count = line_count
|
||||||
|
|
||||||
|
def input(self, prefix: str) -> str:
|
||||||
|
return Console.read_line(prefix)
|
||||||
|
|
||||||
|
def output(self, text: str) -> None:
|
||||||
|
Console.write_line(f'> {text}')
|
||||||
|
|
||||||
|
def error(self, error: Error) -> None:
|
||||||
|
Console.set_foreground_color(ForegroundColorEnum.red)
|
||||||
|
Console.write_line(f'Error in line {self._line_count}\n{error.message}')
|
||||||
|
Console.color_reset()
|
||||||
|
exit()
|
||||||
|
|
||||||
|
def runtime_error(self, error: Error) -> None:
|
||||||
|
Console.set_foreground_color(ForegroundColorEnum.red)
|
||||||
|
Console.write_line(f'{error.message}', 'red')
|
||||||
|
Console.color_reset()
|
||||||
|
exit()
|
||||||
|
Loading…
Reference in New Issue
Block a user