preparing for ast gen

This commit is contained in:
Sven Heidemann 2020-05-25 22:04:56 +02:00
parent 9b25f36eb3
commit cb54261118
11 changed files with 20 additions and 258 deletions

View File

@ -23,10 +23,12 @@ lib Tests
if (error != empty) if (error != empty)
{ {
output(error.code + ' ' + error.message); output(error.code + ' ' + error.message);
return true;
} }
else else
{ {
output('continue'); output('continue');
return false;
} }
} }
} }

View File

@ -1,7 +1,7 @@
lib Tests { lib Tests {
public class test2 { public class test2 {
string_a = string1(); var string_a = string1();
public func continue() { public func continue(): void {
input(string_a.string1 + ': '); input(string_a.string1 + ': ');
} }
} }

View File

@ -16,6 +16,7 @@ class Interpreter:
def interpret(self, line_int: int, line_str: str) -> bool: def interpret(self, line_int: int, line_str: str) -> bool:
toks = [] toks = []
ast = []
self.__utils.line_number = line_int self.__utils.line_number = line_int
if self.__repo.error is None: if self.__repo.error is None:
@ -24,11 +25,11 @@ class Interpreter:
self.__repo.output_tokens(toks) self.__repo.output_tokens(toks)
if self.__repo.error is None: if self.__repo.error is None:
self.__parser.parse(toks) ast = self.__parser.parse(toks)
self.__repo.output_ast() # self.__repo.output_ast(ast)
if self.__repo.error is None: if self.__repo.error is None:
self.__validator.validate() self.__validator.validate(ast)
return self.__repo.error is None return self.__repo.error is None

View File

@ -2,9 +2,9 @@ from Interpreter.Repo import Repo
from Interpreter.Utils import Utils from Interpreter.Utils import Utils
from Models.Interpreter.Error import Error from Models.Interpreter.Error import Error
from Models.Interpreter.Token import Token from Models.Interpreter.Token import Token
from Models.Language.Class import Class from Models.Nodes.Class import Class
from Models.Language.Func import Func from Models.Nodes.Func import Func
from Models.Language.Lib import Lib from Models.Nodes.Lib import Lib
class Parser: class Parser:
@ -13,25 +13,11 @@ class Parser:
self.__repo = repo self.__repo = repo
self.__utils = utils self.__utils = utils
# runtime representation self.__ast = []
self.__lib = None
self.__class = None
self.__func = None
# helpers def parse(self, toks: list) -> []:
self.__tokens = [] # reset each line
self.__i = 0 # for loop index
self.__token_storage = []
self.__is_start_lib = False
self.__is_start_class = False
self.__is_start_func = False
self.__is_public = False
def parse(self, toks: list) -> None:
self.__tokens = toks self.__tokens = toks
self.__ast = []
# output # output
if len(toks) > 0: if len(toks) > 0:
tokens = [] tokens = []
@ -55,226 +41,9 @@ class Parser:
print('___') print('___')
# print(self.__repo.ast, '\n') # print(self.__repo.ast, '\n')
""" parser helpers """ return self.__ast
def __get_next_token(self) -> Token:
if len(self.__tokens) > self.__i + 1:
return self.__tokens[self.__i + 1]
else:
return Token('EOL', 'EOL')
def __get_last_token(self) -> Token: def __check(self) -> None:
if len(self.__tokens) >= self.__i - 1: for i in range(0, len(self.__tokens)):
return self.__tokens[self.__i - 1] tok = self.__tokens[i]
else: # print(tok.value, tok.type)
return Token('EOL', 'EOL')
def __get_token_by_i_dif(self, delta: int) -> Token:
if 0 < self.__i + delta < len(self.__tokens):
return self.__tokens[self.__i + delta]
else:
return Token('EOL', 'EOL')
def __add_ast(self, tok: Token) -> None:
if self.__lib is not None and self.__class is None and self.__func is None:
self.__lib.ast.append(tok)
elif self.__lib is not None and self.__class is not None and self.__func is None:
self.__class.ast.append(tok)
elif self.__lib is not None and self.__class is not None and self.__func is not None:
self.__func.ast.append(tok)
def __is_scope_started(self) -> bool:
return self.__is_start_lib or self.__is_start_class or self.__is_start_func
def __is_only_lib_started(self) -> bool:
return self.__is_start_lib and not self.__is_start_class and not self.__is_start_func
def __is_only_class_started(self) -> bool:
return not self.__is_start_lib and self.__is_start_class and not self.__is_start_func
def __is_only_func_started(self) -> bool:
return not self.__is_start_lib and not self.__is_start_class and self.__is_start_func
def __is_only_var_started(self) -> bool:
return not self.__is_start_lib and not self.__is_start_class and not self.__is_start_func
""" token checks """
def __check(self):
# check tokens
for self.__i in range(0, len(self.__tokens)):
tok = self.__tokens[self.__i]
if not self.__is_scope_started() and tok.type == 'keyword':
self.__check_keyword(tok)
elif tok.type == 'type' or tok.type in self.__repo.types:
self.__check_type(tok)
elif tok.type == 'format_char':
self.__check_format_char(tok)
elif not self.__is_scope_started() and tok.type == 'expr_char':
self.__check_expr_char(tok)
elif not self.__is_scope_started() and tok.type == 'bool_expr_char':
self.__check_bool_expr_char(tok)
elif tok.type == 'name':
self.__check_name(tok)
else:
self.__utils.error(Error(3.11, f'{tok.type}: {tok.value}'))
def __check_keyword(self, tok: Token) -> None:
if tok.value == 'use':
pass
elif tok.value == 'from':
pass
elif tok.value == 'lib':
self.__is_start_lib = True
elif tok.value == 'class':
self.__is_start_class = True
elif tok.value == 'func':
self.__is_start_func = True
elif tok.value == 'public':
next = self.__get_next_token()
if next.type == 'keyword' and (next.value == 'class' or next.value == 'func'):
self.__is_public = True
else:
if next.type == 'EOL':
self.__utils.error(Error(3.10))
else:
self.__utils.error(Error(3.11, next.value))
elif tok.value == 'var':
next = self.__get_next_token()
if next.type == 'name':
self.__is_start_var = True
else:
if next.type == 'EOL':
self.__utils.error(Error(3.10))
else:
self.__utils.error(Error(3.11, next.value))
elif tok.value == 'output':
pass
elif tok.value == 'input':
pass
elif tok.value == 'range':
pass
elif tok.value == 'length':
pass
elif tok.value == 'pass':
pass
elif tok.value == 'exit':
pass
else:
self.__utils.error(Error(3.11, f'{tok.type}: {tok.value}'))
def __check_format_char(self, tok: Token) -> None:
if tok.value == '{':
# token in storage must be name!
if len(self.__token_storage) > 0 and self.__token_storage[0].type == 'name':
# lib
if self.__is_only_lib_started():
self.__lib = Lib(self.__token_storage[0].value)
self.__token_storage = []
self.__is_start_lib = False
# class
elif self.__is_only_class_started():
access = ''
if self.__is_public:
access = 'public'
self.__is_public = False
self.__class = Class(self.__token_storage[0].value, access=access)
self.__token_storage = []
self.__is_start_class = False
# func
elif self.__is_only_func_started():
access = ''
if len(self.__token_storage) > 1 and self.__token_storage[1].type == 'type':
if self.__is_public:
access = 'public'
self.__is_public = False
self.__func = Func(self.__token_storage[0].value, self.__token_storage[1].value, access=access)
self.__token_storage = []
self.__is_start_func = False
else:
self.__utils.error(Error(3.7))
else:
self.__utils.error(Error(3.11, f'{tok.type}: {tok.value}'))
elif not self.__is_scope_started() and tok.value == '}':
if self.__lib is not None and self.__class is None and self.__func is None:
self.__repo.ast.append(self.__lib)
self.__lib = None
elif self.__lib is not None and self.__class is not None and self.__func is None:
self.__lib.ast.append(self.__class)
self.__class = None
elif self.__lib is not None and self.__class is not None and self.__func is not None:
self.__class.ast.append(self.__func)
self.__func = None
else:
self.__utils.error(Error(3.11, f'{tok.type}: {tok.value}'))
elif not self.__is_scope_started() and tok.value in self.__repo.format_chars:
pass
elif tok.value == ':':
if self.__is_only_func_started():
next = self.__get_next_token()
if next.type == 'type':
self.__token_storage.append(next)
else:
self.__utils.error(Error(3.7))
else:
self.__utils.error(Error(3.11, f'{tok.type}: {tok.value}'))
elif tok.value == '(':
pass
elif tok.value == ')':
pass
else:
self.__utils.error(Error(3.11, f'{tok.type}: {tok.value}'))
def __check_name(self, tok: Token) -> None:
if self.__is_start_lib or self.__is_start_class or self.__is_start_func:
if len(self.__token_storage) == 0:
self.__token_storage.append(tok)
else:
self.__utils.error(Error(3.11, f'{tok.type}: {tok.value}'))
def __check_type(self, tok: Token) -> None:
pass
# self.__utils.error(Error(3.11, f'{tok.type}: {tok.value}'))
def __check_expr_char(self, tok: Token) -> None:
pass
def __check_bool_expr_char(self, tok: Token) -> None:
pass

View File

@ -58,13 +58,3 @@ class Repo:
print(outp_toks) print(outp_toks)
# print('\n') # print('\n')
def output_ast(self) -> None:
if len(self.ast) > 0:
outp_toks = []
for tok in self.ast:
outp_toks.append({tok.value: tok.type})
# print({tok.value: tok.type})
print(outp_toks)
# print('\n')

View File

@ -8,5 +8,5 @@ class Validator:
self.__repo = repo self.__repo = repo
self.__utils = utils self.__utils = utils
def validate(self) -> None: def validate(self, ast: []) -> None:
pass pass