Removed old src
This commit is contained in:
parent
8f01e49479
commit
ff025bdc7f
223
old/src/Basic.py
223
old/src/Basic.py
@ -1,223 +0,0 @@
|
|||||||
from sly import Lexer
|
|
||||||
from sly import Parser
|
|
||||||
|
|
||||||
|
|
||||||
class BasicLexer(Lexer):
|
|
||||||
tokens = {NAME, NUMBER, STRING, IF, THEN, ELSE, FOR, FUN, TO, ARROW, EQEQ}
|
|
||||||
ignore = '\t '
|
|
||||||
|
|
||||||
literals = {'=', '+', '-', '/', '*', '(', ')', ',', ';'}
|
|
||||||
|
|
||||||
# Define tokens
|
|
||||||
IF = r'IF'
|
|
||||||
THEN = r'THEN'
|
|
||||||
ELSE = r'ELSE'
|
|
||||||
FOR = r'FOR'
|
|
||||||
FUN = r'FUN'
|
|
||||||
TO = r'TO'
|
|
||||||
ARROW = r'->'
|
|
||||||
NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
|
|
||||||
STRING = r'\".*?\"'
|
|
||||||
|
|
||||||
EQEQ = r'=='
|
|
||||||
|
|
||||||
@_(r'\d+')
|
|
||||||
def NUMBER(self, t):
|
|
||||||
t.value = int(t.value)
|
|
||||||
return t
|
|
||||||
|
|
||||||
@_(r'#.*')
|
|
||||||
def COMMENT(self, t):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@_(r'\n+')
|
|
||||||
def newline(self, t):
|
|
||||||
self.lineno = t.value.count('\n')
|
|
||||||
|
|
||||||
|
|
||||||
class BasicParser(Parser):
|
|
||||||
tokens = BasicLexer.tokens
|
|
||||||
|
|
||||||
precedence = (
|
|
||||||
('left', '+', '-'),
|
|
||||||
('left', '*', '/'),
|
|
||||||
('right', 'UMINUS'),
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.env = {}
|
|
||||||
|
|
||||||
@_('')
|
|
||||||
def statement(self, p):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@_('FOR var_assign TO expr THEN statement')
|
|
||||||
def statement(self, p):
|
|
||||||
return ('for_loop', ('for_loop_setup', p.var_assign, p.expr), p.statement)
|
|
||||||
|
|
||||||
@_('IF condition THEN statement ELSE statement')
|
|
||||||
def statement(self, p):
|
|
||||||
return ('if_stmt', p.condition, ('branch', p.statement0, p.statement1))
|
|
||||||
|
|
||||||
@_('FUN NAME "(" ")" ARROW statement')
|
|
||||||
def statement(self, p):
|
|
||||||
return ('fun_def', p.NAME, p.statement)
|
|
||||||
|
|
||||||
@_('NAME "(" ")"')
|
|
||||||
def statement(self, p):
|
|
||||||
return ('fun_call', p.NAME)
|
|
||||||
|
|
||||||
@_('expr EQEQ expr')
|
|
||||||
def condition(self, p):
|
|
||||||
return ('condition_eqeq', p.expr0, p.expr1)
|
|
||||||
|
|
||||||
@_('var_assign')
|
|
||||||
def statement(self, p):
|
|
||||||
return p.var_assign
|
|
||||||
|
|
||||||
@_('NAME "=" expr')
|
|
||||||
def var_assign(self, p):
|
|
||||||
return ('var_assign', p.NAME, p.expr)
|
|
||||||
|
|
||||||
@_('NAME "=" STRING')
|
|
||||||
def var_assign(self, p):
|
|
||||||
return ('var_assign', p.NAME, p.STRING)
|
|
||||||
|
|
||||||
@_('expr')
|
|
||||||
def statement(self, p):
|
|
||||||
return (p.expr)
|
|
||||||
|
|
||||||
@_('expr "+" expr')
|
|
||||||
def expr(self, p):
|
|
||||||
return ('add', p.expr0, p.expr1)
|
|
||||||
|
|
||||||
@_('expr "-" expr')
|
|
||||||
def expr(self, p):
|
|
||||||
return ('sub', p.expr0, p.expr1)
|
|
||||||
|
|
||||||
@_('expr "*" expr')
|
|
||||||
def expr(self, p):
|
|
||||||
return ('mul', p.expr0, p.expr1)
|
|
||||||
|
|
||||||
@_('expr "/" expr')
|
|
||||||
def expr(self, p):
|
|
||||||
return ('div', p.expr0, p.expr1)
|
|
||||||
|
|
||||||
@_('"-" expr %prec UMINUS')
|
|
||||||
def expr(self, p):
|
|
||||||
return p.expr
|
|
||||||
|
|
||||||
@_('NAME')
|
|
||||||
def expr(self, p):
|
|
||||||
return ('var', p.NAME)
|
|
||||||
|
|
||||||
@_('NUMBER')
|
|
||||||
def expr(self, p):
|
|
||||||
return ('num', p.NUMBER)
|
|
||||||
|
|
||||||
|
|
||||||
class BasicExecute:
|
|
||||||
|
|
||||||
def __init__(self, tree, env):
|
|
||||||
self.env = env
|
|
||||||
result = self.walkTree(tree)
|
|
||||||
if result is not None and isinstance(result, int):
|
|
||||||
print(result)
|
|
||||||
if isinstance(result, str) and result[0] == '"':
|
|
||||||
print(result)
|
|
||||||
|
|
||||||
def walkTree(self, node):
|
|
||||||
|
|
||||||
if isinstance(node, int):
|
|
||||||
return node
|
|
||||||
if isinstance(node, str):
|
|
||||||
return node
|
|
||||||
|
|
||||||
if node is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if node[0] == 'program':
|
|
||||||
if node[1] == None:
|
|
||||||
self.walkTree(node[2])
|
|
||||||
else:
|
|
||||||
self.walkTree(node[1])
|
|
||||||
self.walkTree(node[2])
|
|
||||||
|
|
||||||
if node[0] == 'num':
|
|
||||||
return node[1]
|
|
||||||
|
|
||||||
if node[0] == 'str':
|
|
||||||
return node[1]
|
|
||||||
|
|
||||||
if node[0] == 'if_stmt':
|
|
||||||
result = self.walkTree(node[1])
|
|
||||||
if result:
|
|
||||||
return self.walkTree(node[2][1])
|
|
||||||
return self.walkTree(node[2][2])
|
|
||||||
|
|
||||||
if node[0] == 'condition_eqeq':
|
|
||||||
return self.walkTree(node[1]) == self.walkTree(node[2])
|
|
||||||
|
|
||||||
if node[0] == 'fun_def':
|
|
||||||
self.env[node[1]] = node[2]
|
|
||||||
|
|
||||||
if node[0] == 'fun_call':
|
|
||||||
try:
|
|
||||||
return self.walkTree(self.env[node[1]])
|
|
||||||
except LookupError:
|
|
||||||
print("Undefined function '%s'" % node[1])
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if node[0] == 'add':
|
|
||||||
return self.walkTree(node[1]) + self.walkTree(node[2])
|
|
||||||
elif node[0] == 'sub':
|
|
||||||
return self.walkTree(node[1]) - self.walkTree(node[2])
|
|
||||||
elif node[0] == 'mul':
|
|
||||||
return self.walkTree(node[1]) * self.walkTree(node[2])
|
|
||||||
elif node[0] == 'div':
|
|
||||||
return self.walkTree(node[1]) / self.walkTree(node[2])
|
|
||||||
|
|
||||||
if node[0] == 'var_assign':
|
|
||||||
self.env[node[1]] = self.walkTree(node[2])
|
|
||||||
return node[1]
|
|
||||||
|
|
||||||
if node[0] == 'var':
|
|
||||||
try:
|
|
||||||
return self.env[node[1]]
|
|
||||||
except LookupError:
|
|
||||||
print("Undefined variable '" + node[1] + "' found!")
|
|
||||||
return 0
|
|
||||||
|
|
||||||
if node[0] == 'for_loop':
|
|
||||||
if node[1][0] == 'for_loop_setup':
|
|
||||||
loop_setup = self.walkTree(node[1])
|
|
||||||
|
|
||||||
loop_count = self.env[loop_setup[0]]
|
|
||||||
loop_limit = loop_setup[1]
|
|
||||||
|
|
||||||
for i in range(loop_count + 1, loop_limit + 1):
|
|
||||||
res = self.walkTree(node[2])
|
|
||||||
if res is not None:
|
|
||||||
print(res)
|
|
||||||
self.env[loop_setup[0]] = i
|
|
||||||
del self.env[loop_setup[0]]
|
|
||||||
|
|
||||||
if node[0] == 'for_loop_setup':
|
|
||||||
return (self.walkTree(node[1]), self.walkTree(node[2]))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
lexer = BasicLexer()
|
|
||||||
parser = BasicParser()
|
|
||||||
env = {}
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
text = input('basic > ')
|
|
||||||
except EOFError:
|
|
||||||
break
|
|
||||||
if text:
|
|
||||||
tokens = lexer.tokenize(text)
|
|
||||||
tree = parser.parse(tokens)
|
|
||||||
for t in tree:
|
|
||||||
print(t)
|
|
||||||
# BasicExecute(tree, env)
|
|
@ -1,22 +0,0 @@
|
|||||||
# hi1
|
|
||||||
// hi2
|
|
||||||
|
|
||||||
public lib Main {
|
|
||||||
class Program {
|
|
||||||
var test: bool = false;
|
|
||||||
var test2: Program2 = empty;
|
|
||||||
var test3: Program2 = Test(34);
|
|
||||||
|
|
||||||
func Main(): empty {
|
|
||||||
#func Main {
|
|
||||||
var hallo: any;
|
|
||||||
#output('Hello');
|
|
||||||
#output(this.isTrue(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
func isTrue(value: bool): bool {
|
|
||||||
#func isTrue {
|
|
||||||
#return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
from typing import Optional
|
|
||||||
|
|
||||||
from Interpreter.Validator import Validator
|
|
||||||
from Interpreter.Lexer import Lexer
|
|
||||||
from Interpreter.Parser import Parser
|
|
||||||
from Interpreter.Repo import Repo
|
|
||||||
from Interpreter.Utils import Utils
|
|
||||||
from Models.AbstractSyntaxTree.AbstractSyntaxTree import AbstractSyntaxTree
|
|
||||||
|
|
||||||
|
|
||||||
class Interpreter:
|
|
||||||
|
|
||||||
def __init__(self, repo: Repo, utils: Utils) -> None:
|
|
||||||
self.__repo = repo
|
|
||||||
self.__utils = utils
|
|
||||||
self.__lexer = Lexer(repo, utils)
|
|
||||||
self.__parser = Parser(repo, utils)
|
|
||||||
self.__validator = Validator(repo, utils)
|
|
||||||
|
|
||||||
def interpret(self, line_str: str) -> None:
|
|
||||||
"""
|
|
||||||
Interprets code line
|
|
||||||
:param line_str:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
tokens = []
|
|
||||||
ast: Optional[AbstractSyntaxTree] = None
|
|
||||||
|
|
||||||
if self.__repo.error is None:
|
|
||||||
tokens = self.__lexer.tokenize(line_str)
|
|
||||||
|
|
||||||
if self.__repo.error is None:
|
|
||||||
ast = self.__parser.parse(tokens)
|
|
||||||
|
|
||||||
""" print('#####\n')
|
|
||||||
if ast is not None:
|
|
||||||
for lib in ast.libraries:
|
|
||||||
print('lib', lib.name)
|
|
||||||
for cl in lib.classes:
|
|
||||||
print('class', cl.name)
|
|
||||||
for var in cl.variables:
|
|
||||||
print('cl var', var.name)
|
|
||||||
|
|
||||||
for func in cl.functions:
|
|
||||||
print('func', func.name)
|
|
||||||
for arg in func.args:
|
|
||||||
print('func arg', arg.name)
|
|
||||||
|
|
||||||
for var in func.variables:
|
|
||||||
print('func var', var.name)
|
|
||||||
|
|
||||||
for ins in func.instructions:
|
|
||||||
print('ins', ins)
|
|
||||||
"""
|
|
||||||
|
|
||||||
# if self.__repo.is_error is None:
|
|
||||||
# self.__validator.validate(self.__repo.AST)
|
|
@ -1,171 +0,0 @@
|
|||||||
from typing import List
|
|
||||||
|
|
||||||
from Interpreter.Repo import Repo
|
|
||||||
from Interpreter.Utils import Utils
|
|
||||||
from Models.Token.Token import Token
|
|
||||||
from Models.Token.TokenTypes import TokenTypes, UnresolvedTokenTypes
|
|
||||||
|
|
||||||
|
|
||||||
class Lexer:
|
|
||||||
|
|
||||||
def __init__(self, repo: Repo, utils: Utils) -> None:
|
|
||||||
self.__repo = repo
|
|
||||||
self.__utils = utils
|
|
||||||
|
|
||||||
self.__is_ml_comment = False
|
|
||||||
|
|
||||||
def __add_tok(self, tokens: List[Token], value: str, input_token_type: UnresolvedTokenTypes) -> None:
|
|
||||||
"""
|
|
||||||
Creates token object
|
|
||||||
:param value:
|
|
||||||
:param input_token_type:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
token_type: TokenTypes = TokenTypes.Empty
|
|
||||||
|
|
||||||
if value != '':
|
|
||||||
if input_token_type == UnresolvedTokenTypes.Word:
|
|
||||||
if value in self.__repo.keywords:
|
|
||||||
token_type = TokenTypes.Keyword
|
|
||||||
|
|
||||||
elif value in self.__repo.datatypes:
|
|
||||||
token_type = TokenTypes.Type
|
|
||||||
|
|
||||||
elif value in self.__repo.bool_values:
|
|
||||||
token_type = TokenTypes.Bool
|
|
||||||
|
|
||||||
elif value == UnresolvedTokenTypes.Empty:
|
|
||||||
token_type = TokenTypes.Empty
|
|
||||||
|
|
||||||
else:
|
|
||||||
token_type = TokenTypes.Name
|
|
||||||
|
|
||||||
elif input_token_type == UnresolvedTokenTypes.Number:
|
|
||||||
token_type = TokenTypes.Number
|
|
||||||
|
|
||||||
elif input_token_type == UnresolvedTokenTypes.String:
|
|
||||||
token_type = TokenTypes.String
|
|
||||||
|
|
||||||
elif input_token_type == UnresolvedTokenTypes.Expression_Character:
|
|
||||||
token_type = TokenTypes.Expression_Character
|
|
||||||
|
|
||||||
elif input_token_type == UnresolvedTokenTypes.Bool_Expression_Character:
|
|
||||||
token_type = TokenTypes.Bool_Expression_Character
|
|
||||||
|
|
||||||
elif input_token_type == UnresolvedTokenTypes.Format_Character:
|
|
||||||
token_type = TokenTypes.Format_Character
|
|
||||||
|
|
||||||
tokens.append(Token(token_type, value))
|
|
||||||
|
|
||||||
def tokenize(self, line: str) -> List[Token]:
|
|
||||||
"""
|
|
||||||
Creates token list from code line
|
|
||||||
:param line:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
tokens: List[Token] = []
|
|
||||||
word = ''
|
|
||||||
ol_comment = False
|
|
||||||
is_string1 = False # 'hello'
|
|
||||||
is_string2 = False # "hello"
|
|
||||||
is_number = False
|
|
||||||
is_expr_char = False
|
|
||||||
|
|
||||||
for i in range(0, len(line)):
|
|
||||||
c = line[i]
|
|
||||||
# ignore comments and spaces
|
|
||||||
if not ol_comment and not self.__is_ml_comment:
|
|
||||||
# comment filtering
|
|
||||||
if c == '#' and not is_string1 and not is_string2:
|
|
||||||
ol_comment = True
|
|
||||||
|
|
||||||
elif line[i - 1] == '/' and c == '/':
|
|
||||||
ol_comment = True
|
|
||||||
|
|
||||||
elif line[i - 1] == '/' and c == '*':
|
|
||||||
self.__is_ml_comment = True
|
|
||||||
i += 2
|
|
||||||
|
|
||||||
# end of number
|
|
||||||
elif not c.isdigit() and c != '.' and is_number:
|
|
||||||
self.__add_tok(tokens, word, UnresolvedTokenTypes.Number)
|
|
||||||
local_tokens = self.tokenize(c)
|
|
||||||
for local_token in local_tokens:
|
|
||||||
tokens.append(local_token)
|
|
||||||
|
|
||||||
word = ''
|
|
||||||
is_number = False
|
|
||||||
|
|
||||||
# end of expression char
|
|
||||||
elif c not in self.__repo.expr_chars and is_expr_char:
|
|
||||||
self.__add_tok(tokens, word, UnresolvedTokenTypes.Expression_Character)
|
|
||||||
word = ''
|
|
||||||
is_expr_char = False
|
|
||||||
|
|
||||||
# begin of is_string1
|
|
||||||
elif c == '\'' and not is_string1:
|
|
||||||
is_string1 = True
|
|
||||||
word = ''
|
|
||||||
|
|
||||||
# end of is_string1
|
|
||||||
elif c == '\'' and is_string1:
|
|
||||||
is_string1 = False
|
|
||||||
self.__add_tok(tokens, word, UnresolvedTokenTypes.String)
|
|
||||||
word = ''
|
|
||||||
|
|
||||||
# begin of is_string2
|
|
||||||
elif c == '\"' and not is_string2:
|
|
||||||
is_string2 = True
|
|
||||||
word = ''
|
|
||||||
|
|
||||||
# end of is_string2
|
|
||||||
elif c == '\"' and is_string2:
|
|
||||||
is_string2 = False
|
|
||||||
self.__add_tok(tokens, word, UnresolvedTokenTypes.String)
|
|
||||||
word = ''
|
|
||||||
|
|
||||||
# format char
|
|
||||||
elif c in self.__repo.format_chars:
|
|
||||||
self.__add_tok(tokens, word, UnresolvedTokenTypes.Word)
|
|
||||||
self.__add_tok(tokens, c, UnresolvedTokenTypes.Format_Character)
|
|
||||||
word = ''
|
|
||||||
|
|
||||||
# begin of number
|
|
||||||
elif c.isdigit() and not is_number and word == '':
|
|
||||||
word += c
|
|
||||||
is_number = True
|
|
||||||
|
|
||||||
# continue number
|
|
||||||
elif (c.isdigit() or c == '.') and is_number:
|
|
||||||
word += c
|
|
||||||
|
|
||||||
# begin expression char
|
|
||||||
elif c in self.__repo.expr_chars and not is_expr_char:
|
|
||||||
word += c
|
|
||||||
is_expr_char = True
|
|
||||||
|
|
||||||
# continue expression char
|
|
||||||
elif c in self.__repo.expr_chars and is_expr_char:
|
|
||||||
word += c
|
|
||||||
|
|
||||||
# bool expression char
|
|
||||||
elif c in self.__repo.bool_expr_chars:
|
|
||||||
self.__add_tok(tokens, word, UnresolvedTokenTypes.Word)
|
|
||||||
self.__add_tok(tokens, c, UnresolvedTokenTypes.Bool_Expression_Character)
|
|
||||||
word = ''
|
|
||||||
|
|
||||||
# end of word
|
|
||||||
elif c == ' ' and not is_string1 and not is_string2 or c == '\n':
|
|
||||||
self.__add_tok(tokens, word, UnresolvedTokenTypes.Word)
|
|
||||||
word = ''
|
|
||||||
|
|
||||||
else:
|
|
||||||
word += c
|
|
||||||
|
|
||||||
if c == '\n' and ol_comment:
|
|
||||||
ol_comment = False
|
|
||||||
|
|
||||||
if line[i - 1] == '*' and c == '/':
|
|
||||||
self.__is_ml_comment = False
|
|
||||||
|
|
||||||
return tokens
|
|
@ -1,415 +0,0 @@
|
|||||||
from typing import List, Optional, Union
|
|
||||||
|
|
||||||
from Interpreter.Repo import Repo
|
|
||||||
from Interpreter.Utils import Utils
|
|
||||||
from Models.AbstractSyntaxTree.AbstractSyntaxTree import LibraryDefinitionNode, ClassDefinitionNode, AbstractSyntaxTree, \
|
|
||||||
FunctionDefinitionNode, VariableDefinitionNode, CallDefinitionNode, ValueNode, ASTElement
|
|
||||||
from Models.Interpreter.Datatypes import Datatypes
|
|
||||||
from Models.Interpreter.Error import Error, ErrorCodes
|
|
||||||
from Models.Token.Token import Token
|
|
||||||
from Models.Token.TokenTypes import TokenTypes
|
|
||||||
from Models.Token.TokenValueTypes import Keywords, FormatCharacters, ExpressionCharacters
|
|
||||||
|
|
||||||
|
|
||||||
class Parser:
|
|
||||||
|
|
||||||
def __init__(self, repo: Repo, utils: Utils) -> None:
|
|
||||||
self.__repo = repo
|
|
||||||
self.__utils = utils
|
|
||||||
|
|
||||||
self.__ast: AbstractSyntaxTree = AbstractSyntaxTree()
|
|
||||||
self.__saved_tokens: List[Token] = []
|
|
||||||
self.__expected_tokens: List[Token] = []
|
|
||||||
|
|
||||||
# for validation if type is created
|
|
||||||
self.__is_saving_type = False
|
|
||||||
self.__is_saving_value = False
|
|
||||||
self.__is_saving_call = False
|
|
||||||
self.__is_end = False
|
|
||||||
|
|
||||||
self.__saved_ast_elements: List[ASTElement] = []
|
|
||||||
|
|
||||||
def parse(self, tokens: List[Token]) -> AbstractSyntaxTree:
|
|
||||||
self.__is_end = False
|
|
||||||
|
|
||||||
if len(tokens) > 0:
|
|
||||||
toks = []
|
|
||||||
for tok in tokens:
|
|
||||||
toks.append({tok.type.name, tok.value})
|
|
||||||
|
|
||||||
print(self.__repo.line_number, toks)
|
|
||||||
|
|
||||||
for i in range(0, len(tokens)):
|
|
||||||
token = tokens[i]
|
|
||||||
|
|
||||||
self.__check_for_expected_tokens(token)
|
|
||||||
|
|
||||||
# keywords
|
|
||||||
if token.type == TokenTypes.Keyword:
|
|
||||||
if token.value == Keywords.Public.value:
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
print('save public')
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Library.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Class.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Function.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Variable.value)
|
|
||||||
|
|
||||||
elif token.value == Keywords.Library.value:
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
print('save lib')
|
|
||||||
self.__add_expected_token(TokenTypes.Name)
|
|
||||||
|
|
||||||
elif token.value == Keywords.Class.value:
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
print('save class')
|
|
||||||
self.__add_expected_token(TokenTypes.Name)
|
|
||||||
|
|
||||||
elif token.value == Keywords.Function.value:
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
print('save function')
|
|
||||||
self.__add_expected_token(TokenTypes.Name)
|
|
||||||
|
|
||||||
elif token.value == Keywords.Variable.value:
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
print('save var')
|
|
||||||
self.__add_expected_token(TokenTypes.Name)
|
|
||||||
|
|
||||||
# names
|
|
||||||
elif token.type == TokenTypes.Name:
|
|
||||||
if self.__is_saving_variable() and self.__is_saving_value:
|
|
||||||
self.__save_name(token)
|
|
||||||
if self.__is_saving_variable():
|
|
||||||
self.__is_saving_call = True
|
|
||||||
|
|
||||||
# names could be variable types, validation check in evaluator
|
|
||||||
elif self.__is_saving_variable() and self.__is_saving_type:
|
|
||||||
self.__save_type(token)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Left_Parenthesis.value)
|
|
||||||
|
|
||||||
elif self.__is_saving_variable():
|
|
||||||
self.__save_name(token)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Colon.value)
|
|
||||||
|
|
||||||
elif self.__is_saving_function():
|
|
||||||
self.__save_name(token)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Left_Parenthesis.value)
|
|
||||||
|
|
||||||
elif self.__is_saving_library() or self.__is_saving_class():
|
|
||||||
self.__save_name(token)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Left_Brace.value)
|
|
||||||
|
|
||||||
# format chars
|
|
||||||
elif token.type == TokenTypes.Format_Character:
|
|
||||||
if token.value == FormatCharacters.Left_Brace.value:
|
|
||||||
if self.__is_saving_library():
|
|
||||||
self.__save_library()
|
|
||||||
|
|
||||||
elif self.__is_saving_class():
|
|
||||||
self.__save_class()
|
|
||||||
|
|
||||||
elif token.value == FormatCharacters.Colon.value:
|
|
||||||
if self.__is_saving_variable():
|
|
||||||
self.__is_saving_type = True
|
|
||||||
self.__add_expected_token(TokenTypes.Type)
|
|
||||||
self.__add_expected_token(TokenTypes.Name)
|
|
||||||
|
|
||||||
elif token.value == FormatCharacters.Semicolon.value:
|
|
||||||
self.__end_line()
|
|
||||||
|
|
||||||
elif token.value == FormatCharacters.Left_Parenthesis.value:
|
|
||||||
self.__add_expected_token(TokenTypes.Name)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Right_Parenthesis.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.This.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Name)
|
|
||||||
self.__add_expected_token(TokenTypes.Empty)
|
|
||||||
self.__add_expected_token(TokenTypes.Number)
|
|
||||||
self.__add_expected_token(TokenTypes.String)
|
|
||||||
self.__add_expected_token(TokenTypes.Bool)
|
|
||||||
|
|
||||||
if self.__is_saving_call:
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
|
|
||||||
elif token.value == FormatCharacters.Right_Parenthesis.value:
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Semicolon.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Colon.value)
|
|
||||||
|
|
||||||
if self.__is_saving_call:
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
self.__save_call()
|
|
||||||
self.__is_saving_call = False
|
|
||||||
|
|
||||||
# expr chars
|
|
||||||
elif token.type == TokenTypes.Expression_Character:
|
|
||||||
if token.value == ExpressionCharacters.Equal.value:
|
|
||||||
self.__is_saving_value = True
|
|
||||||
self.__add_expected_token(TokenTypes.Bool)
|
|
||||||
self.__add_expected_token(TokenTypes.Number)
|
|
||||||
self.__add_expected_token(TokenTypes.String)
|
|
||||||
self.__add_expected_token(TokenTypes.Empty)
|
|
||||||
self.__add_expected_token(TokenTypes.Name)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.This.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Input.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Range.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Length.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Left_Parenthesis.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Type, Datatypes.Empty.value)
|
|
||||||
|
|
||||||
# types
|
|
||||||
elif token.type == TokenTypes.Type:
|
|
||||||
if self.__is_saving_variable() and self.__is_saving_value:
|
|
||||||
self.__save_value(token)
|
|
||||||
|
|
||||||
elif self.__is_saving_variable():
|
|
||||||
self.__save_type(token)
|
|
||||||
|
|
||||||
# values
|
|
||||||
elif token.type == TokenTypes.Bool or token.type == TokenTypes.Number or token.type == TokenTypes.String:
|
|
||||||
if self.__is_saving_call:
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
|
|
||||||
elif self.__is_saving_value:
|
|
||||||
self.__save_value(token)
|
|
||||||
|
|
||||||
return self.__ast
|
|
||||||
|
|
||||||
"""
|
|
||||||
Utils
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __save_name(self, token: Token):
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
print('save name')
|
|
||||||
|
|
||||||
def __add_expected_token(self, token_type: TokenTypes, value: str = ''):
|
|
||||||
self.__expected_tokens.append(Token(token_type, value))
|
|
||||||
|
|
||||||
def __check_for_expected_tokens(self, token: Token):
|
|
||||||
error_token: Optional[Token] = None
|
|
||||||
is_error = True
|
|
||||||
|
|
||||||
for expected_token in self.__expected_tokens:
|
|
||||||
if self.__is_end or token.type != expected_token.type or expected_token.value != '' and token.value != expected_token.value:
|
|
||||||
error_token = token
|
|
||||||
else:
|
|
||||||
is_error = False
|
|
||||||
|
|
||||||
if error_token is not None and is_error:
|
|
||||||
self.__utils.error(Error(ErrorCodes.Unexpected, f'{error_token.type.name} {error_token.value}'))
|
|
||||||
|
|
||||||
self.__expected_tokens = []
|
|
||||||
|
|
||||||
def __end_line(self):
|
|
||||||
if self.__is_saving_variable():
|
|
||||||
self.__save_variable()
|
|
||||||
|
|
||||||
self.__is_end = True
|
|
||||||
self.__expected_tokens = []
|
|
||||||
self.__is_saving_type = False
|
|
||||||
self.__is_saving_value = False
|
|
||||||
|
|
||||||
"""
|
|
||||||
Library
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __is_saving_library(self) -> bool:
|
|
||||||
found = False
|
|
||||||
for token in self.__saved_tokens:
|
|
||||||
if token.type == TokenTypes.Keyword and token.value == Keywords.Library.value:
|
|
||||||
found = True
|
|
||||||
|
|
||||||
return found
|
|
||||||
|
|
||||||
def __save_library(self) -> None:
|
|
||||||
is_public = False
|
|
||||||
name_token: Optional[Token] = None
|
|
||||||
|
|
||||||
for token in self.__saved_tokens:
|
|
||||||
if token.type == TokenTypes.Name:
|
|
||||||
name_token = token
|
|
||||||
elif token.type == TokenTypes.Keyword and token.value == Keywords.Public.value:
|
|
||||||
is_public = True
|
|
||||||
|
|
||||||
if name_token is not None:
|
|
||||||
self.__ast.libraries.append(LibraryDefinitionNode(is_public, name_token.value))
|
|
||||||
self.__saved_tokens = []
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Public.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Class.value)
|
|
||||||
print('saved library')
|
|
||||||
|
|
||||||
"""
|
|
||||||
Class
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __is_saving_class(self) -> bool:
|
|
||||||
found = False
|
|
||||||
for token in self.__saved_tokens:
|
|
||||||
if token.type == TokenTypes.Keyword and token.value == Keywords.Class.value:
|
|
||||||
found = True
|
|
||||||
|
|
||||||
return found
|
|
||||||
|
|
||||||
def __save_class(self) -> None:
|
|
||||||
is_public = False
|
|
||||||
name_token: Optional[Token] = None
|
|
||||||
|
|
||||||
for token in self.__saved_tokens:
|
|
||||||
if token.type == TokenTypes.Name:
|
|
||||||
name_token = token
|
|
||||||
elif token.type == TokenTypes.Keyword and token.value == Keywords.Public.value:
|
|
||||||
is_public = True
|
|
||||||
|
|
||||||
if name_token is not None:
|
|
||||||
self.__ast.libraries[len(self.__ast.libraries) - 1].classes.append(ClassDefinitionNode(is_public, name_token.value))
|
|
||||||
self.__saved_tokens = []
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Public.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Variable.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Keyword, Keywords.Function.value)
|
|
||||||
print('saved class')
|
|
||||||
|
|
||||||
"""
|
|
||||||
Call
|
|
||||||
"""
|
|
||||||
def __save_call(self) -> None:
|
|
||||||
name_token: Optional[Token] = None
|
|
||||||
args: List[ValueNode] = []
|
|
||||||
remove_tokens = []
|
|
||||||
is_call = False
|
|
||||||
|
|
||||||
for i in range(0, len(self.__saved_tokens)):
|
|
||||||
token = self.__saved_tokens[i]
|
|
||||||
last_token: Optional[Token] = None
|
|
||||||
if i-1 > 0:
|
|
||||||
last_token = self.__saved_tokens[i-1]
|
|
||||||
|
|
||||||
if token.type == TokenTypes.Name and last_token is not None and last_token.type == TokenTypes.Format_Character and last_token.value == FormatCharacters.Left_Parenthesis.value:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if token.type == TokenTypes.Format_Character and token.value == FormatCharacters.Left_Parenthesis.value and last_token is not None and last_token.type == TokenTypes.Name:
|
|
||||||
name_token = last_token
|
|
||||||
remove_tokens.append(last_token)
|
|
||||||
remove_tokens.append(token)
|
|
||||||
is_call = True
|
|
||||||
elif is_call and token.type == TokenTypes.Format_Character and token.value == FormatCharacters.Right_Parenthesis.value:
|
|
||||||
remove_tokens.append(token)
|
|
||||||
elif is_call and token.type == TokenTypes.Bool or token.type == TokenTypes.Number or token.type == TokenTypes.String:
|
|
||||||
args.append(ValueNode(token.value, Datatypes[token.type.name]))
|
|
||||||
remove_tokens.append(token)
|
|
||||||
|
|
||||||
if name_token is not None:
|
|
||||||
call = CallDefinitionNode(name_token.value)
|
|
||||||
call.args = args
|
|
||||||
self.__saved_ast_elements.append(call)
|
|
||||||
|
|
||||||
for token in remove_tokens:
|
|
||||||
self.__saved_tokens.remove(token)
|
|
||||||
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Semicolon.value)
|
|
||||||
print('saved call')
|
|
||||||
|
|
||||||
"""
|
|
||||||
Function
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __is_saving_function(self) -> bool:
|
|
||||||
found = False
|
|
||||||
for token in self.__saved_tokens:
|
|
||||||
if token.type == TokenTypes.Keyword and token.value == Keywords.Function.value:
|
|
||||||
found = True
|
|
||||||
|
|
||||||
return found
|
|
||||||
|
|
||||||
def __save_function(self) -> None:
|
|
||||||
is_public = False
|
|
||||||
name_token: Optional[Token] = None
|
|
||||||
return_type: Optional[Token] = None
|
|
||||||
|
|
||||||
for token in self.__saved_tokens:
|
|
||||||
if token.type == TokenTypes.Name:
|
|
||||||
name_token = token
|
|
||||||
elif token.type == TokenTypes.Keyword and token.value == Keywords.Public.value:
|
|
||||||
is_public = True
|
|
||||||
elif token.type == TokenTypes.Type:
|
|
||||||
return_type = token
|
|
||||||
|
|
||||||
if name_token is not None and return_type is not None:
|
|
||||||
self.__ast.libraries[len(self.__ast.libraries) - 1].classes[len(self.__ast.libraries) - 1].functions.append(
|
|
||||||
FunctionDefinitionNode(is_public, name_token.value, Datatypes[return_type.value]))
|
|
||||||
self.__saved_tokens = []
|
|
||||||
print('saved function')
|
|
||||||
|
|
||||||
"""
|
|
||||||
Variable
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __is_saving_variable(self) -> bool:
|
|
||||||
found = False
|
|
||||||
for token in self.__saved_tokens:
|
|
||||||
if token.type == TokenTypes.Keyword and token.value == Keywords.Variable.value:
|
|
||||||
found = True
|
|
||||||
|
|
||||||
return found
|
|
||||||
|
|
||||||
def __save_type(self, token: Token) -> None:
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Semicolon.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Expression_Character, ExpressionCharacters.Equal.value)
|
|
||||||
self.__is_saving_type = False
|
|
||||||
print('save type')
|
|
||||||
|
|
||||||
def __save_variable(self):
|
|
||||||
is_public = False
|
|
||||||
name_token: Optional[Token] = None
|
|
||||||
datatype: Optional[Token] = None
|
|
||||||
value: Optional[Union[str, Token, CallDefinitionNode]] = None
|
|
||||||
|
|
||||||
reset_saved_ast = False
|
|
||||||
|
|
||||||
for token in self.__saved_tokens:
|
|
||||||
if token.type == TokenTypes.Name and name_token is None:
|
|
||||||
name_token = token
|
|
||||||
elif token.type == TokenTypes.Keyword and token.value == Keywords.Public.value:
|
|
||||||
is_public = True
|
|
||||||
elif token.type == TokenTypes.Type or name_token is not None and token.type == TokenTypes.Name:
|
|
||||||
datatype = token
|
|
||||||
|
|
||||||
value = Token(TokenTypes.Empty, TokenTypes.Empty.value)
|
|
||||||
|
|
||||||
for saved_ast_element in self.__saved_ast_elements:
|
|
||||||
if isinstance(saved_ast_element, CallDefinitionNode):
|
|
||||||
value = saved_ast_element
|
|
||||||
reset_saved_ast = True
|
|
||||||
|
|
||||||
if reset_saved_ast:
|
|
||||||
self.__saved_ast_elements = []
|
|
||||||
|
|
||||||
if name_token is not None and datatype is not None and value is not None:
|
|
||||||
if not isinstance(value, CallDefinitionNode):
|
|
||||||
value = value.value
|
|
||||||
|
|
||||||
if datatype.type == TokenTypes.Name:
|
|
||||||
variable = VariableDefinitionNode(is_public, name_token.value, datatype.value, value)
|
|
||||||
else:
|
|
||||||
variable = VariableDefinitionNode(is_public, name_token.value, Datatypes[str(datatype.value).capitalize()], value)
|
|
||||||
|
|
||||||
if len(self.__ast.libraries) > 0:
|
|
||||||
lib = self.__ast.libraries[len(self.__ast.libraries) - 1]
|
|
||||||
if len(lib.classes) > 0:
|
|
||||||
cl = lib.classes[len(lib.classes) - 1]
|
|
||||||
if len(cl.functions) == 0:
|
|
||||||
cl.variables.append(variable)
|
|
||||||
else:
|
|
||||||
cl.functions[len(cl.functions) - 1].variables.append(variable)
|
|
||||||
|
|
||||||
self.__saved_tokens = []
|
|
||||||
print('saved variable')
|
|
||||||
|
|
||||||
"""
|
|
||||||
Value
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __save_value(self, token: Token):
|
|
||||||
self.__saved_tokens.append(token)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Left_Parenthesis.value)
|
|
||||||
self.__add_expected_token(TokenTypes.Format_Character, FormatCharacters.Semicolon.value)
|
|
||||||
self.__is_saving_value = False
|
|
||||||
print('save value')
|
|
@ -1,73 +0,0 @@
|
|||||||
from Models.Interpreter.Datatypes import Datatypes
|
|
||||||
from Models.Token.TokenValueTypes import FormatCharacters, Booleans, Keywords, ExpressionCharacters
|
|
||||||
|
|
||||||
|
|
||||||
class Repo:
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.debug = True
|
|
||||||
self.line_number: int = 0
|
|
||||||
|
|
||||||
# interpreter
|
|
||||||
self.keywords = [
|
|
||||||
# define keywords
|
|
||||||
Keywords.Library.value,
|
|
||||||
Keywords.Class.value,
|
|
||||||
Keywords.Function.value,
|
|
||||||
Keywords.Variable.value,
|
|
||||||
Keywords.Use.value,
|
|
||||||
Keywords.From.value,
|
|
||||||
# builtin functions
|
|
||||||
Keywords.Output.value,
|
|
||||||
Keywords.Input.value,
|
|
||||||
Keywords.Length.value,
|
|
||||||
Keywords.Range.value,
|
|
||||||
Keywords.Exit.value,
|
|
||||||
# normal keywords
|
|
||||||
Keywords.If.value,
|
|
||||||
Keywords.ElseIf.value,
|
|
||||||
Keywords.Else.value,
|
|
||||||
Keywords.Continue.value,
|
|
||||||
Keywords.If.value,
|
|
||||||
Keywords.Return.value,
|
|
||||||
# loops
|
|
||||||
Keywords.While.value,
|
|
||||||
Keywords.For.value,
|
|
||||||
# access
|
|
||||||
Keywords.Public.value,
|
|
||||||
Keywords.This.value
|
|
||||||
]
|
|
||||||
self.datatypes = [
|
|
||||||
Datatypes.Empty.value,
|
|
||||||
Datatypes.Any.value,
|
|
||||||
Datatypes.Number.value,
|
|
||||||
Datatypes.String.value,
|
|
||||||
Datatypes.Bool.value,
|
|
||||||
Datatypes.List.value,
|
|
||||||
Datatypes.Dict.value
|
|
||||||
]
|
|
||||||
self.format_chars = [
|
|
||||||
FormatCharacters.Left_Brace.value,
|
|
||||||
FormatCharacters.Right_Brace.value,
|
|
||||||
FormatCharacters.Left_Parenthesis.value,
|
|
||||||
FormatCharacters.Right_Parenthesis.value,
|
|
||||||
FormatCharacters.Left_Bracket.value,
|
|
||||||
FormatCharacters.Right_Bracket.value,
|
|
||||||
FormatCharacters.Semicolon.value,
|
|
||||||
FormatCharacters.Colon.value,
|
|
||||||
FormatCharacters.Comma.value,
|
|
||||||
FormatCharacters.Point.value
|
|
||||||
]
|
|
||||||
self.expr_chars = [
|
|
||||||
ExpressionCharacters.Plus.value,
|
|
||||||
ExpressionCharacters.Minus.value,
|
|
||||||
ExpressionCharacters.Asterisk.value,
|
|
||||||
ExpressionCharacters.Slash.value,
|
|
||||||
ExpressionCharacters.Equal.value,
|
|
||||||
ExpressionCharacters.Caret.value
|
|
||||||
]
|
|
||||||
self.bool_expr_chars = ['<', '>', '!', '!=', '==', '>=', '<=', '&&', '||']
|
|
||||||
self.bool_values = [Booleans.Right.value, Booleans.Wrong.value]
|
|
||||||
|
|
||||||
# runtime
|
|
||||||
self.error = None
|
|
@ -1,26 +0,0 @@
|
|||||||
from termcolor import colored
|
|
||||||
|
|
||||||
from Interpreter.Repo import Repo
|
|
||||||
from Models.Interpreter.Error import Error
|
|
||||||
|
|
||||||
|
|
||||||
class Utils:
|
|
||||||
|
|
||||||
def __init__(self, repo: Repo) -> None:
|
|
||||||
self.__repo = repo
|
|
||||||
|
|
||||||
def input(self, prefix: str) -> str:
|
|
||||||
return input(prefix)
|
|
||||||
|
|
||||||
def output(self, text: str) -> None:
|
|
||||||
print(f'-> {text}')
|
|
||||||
|
|
||||||
def error(self, error: Error) -> None:
|
|
||||||
self.__repo.error = error
|
|
||||||
print(colored(f'Error in line {self.__repo.line_number}\n{self.__repo.error.msg}', 'red'))
|
|
||||||
# exit()
|
|
||||||
|
|
||||||
def runtime_error(self, error: Error) -> None:
|
|
||||||
self.__repo.error = error
|
|
||||||
print(colored(f'{self.__repo.error.msg}', 'red'))
|
|
||||||
# exit()
|
|
@ -1,12 +0,0 @@
|
|||||||
from Interpreter.Repo import Repo
|
|
||||||
from Interpreter.Utils import Utils
|
|
||||||
|
|
||||||
|
|
||||||
class Validator:
|
|
||||||
|
|
||||||
def __init__(self, repo: Repo, utils: Utils) -> None:
|
|
||||||
self.__repo = repo
|
|
||||||
self.__utils = utils
|
|
||||||
|
|
||||||
def validate(self, ast: []) -> None:
|
|
||||||
pass
|
|
@ -1,92 +0,0 @@
|
|||||||
from typing import List, Union
|
|
||||||
|
|
||||||
from Models.Interpreter.Datatypes import Datatypes
|
|
||||||
from Models.Token.TokenValueTypes import ExpressionCharacters
|
|
||||||
|
|
||||||
|
|
||||||
class AbstractSyntaxTree:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.libraries: List[LibraryDefinitionNode] = []
|
|
||||||
|
|
||||||
|
|
||||||
class ASTElement:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ValueNode(ASTElement):
|
|
||||||
def __init__(self, value: str, datatype: Datatypes):
|
|
||||||
super().__init__()
|
|
||||||
self.value = value
|
|
||||||
self.type = datatype
|
|
||||||
|
|
||||||
|
|
||||||
class BinaryOperationNode(ASTElement):
|
|
||||||
def __init__(self, left: str, op_token: str, right: str):
|
|
||||||
super().__init__()
|
|
||||||
self.left = left
|
|
||||||
self.op_token = op_token
|
|
||||||
self.right = right
|
|
||||||
|
|
||||||
self.operation_chars = [
|
|
||||||
ExpressionCharacters.Plus.value,
|
|
||||||
ExpressionCharacters.Minus.value,
|
|
||||||
ExpressionCharacters.Asterisk.value,
|
|
||||||
ExpressionCharacters.Slash.value,
|
|
||||||
ExpressionCharacters.Caret.value
|
|
||||||
]
|
|
||||||
|
|
||||||
def eval(self):
|
|
||||||
if self.op_token in self.operation_chars:
|
|
||||||
return eval(f'{self.left} {self.op_token} {self.right}')
|
|
||||||
|
|
||||||
|
|
||||||
class LibraryDefinitionNode(ASTElement):
|
|
||||||
|
|
||||||
def __init__(self, is_public: bool, name: str):
|
|
||||||
super().__init__()
|
|
||||||
self.is_public = is_public
|
|
||||||
self.name = name
|
|
||||||
self.classes: List[ClassDefinitionNode] = []
|
|
||||||
|
|
||||||
|
|
||||||
class ClassDefinitionNode(ASTElement):
|
|
||||||
|
|
||||||
def __init__(self, is_public: bool, name: str):
|
|
||||||
super().__init__()
|
|
||||||
self.is_public = is_public
|
|
||||||
self.name = name
|
|
||||||
self.variables: [VariableDefinitionNode] = []
|
|
||||||
self.functions: List[FunctionDefinitionNode] = []
|
|
||||||
|
|
||||||
|
|
||||||
class CallDefinitionNode(ASTElement):
|
|
||||||
|
|
||||||
def __init__(self, name: str):
|
|
||||||
super().__init__()
|
|
||||||
self.name = name
|
|
||||||
self.args: List[ValueNode] = []
|
|
||||||
|
|
||||||
|
|
||||||
class FunctionDefinitionNode(ASTElement):
|
|
||||||
|
|
||||||
def __init__(self, is_public: bool, name: str, return_type: Datatypes):
|
|
||||||
super().__init__()
|
|
||||||
self.is_public = is_public
|
|
||||||
self.name = name
|
|
||||||
self.args: List[VariableDefinitionNode] = []
|
|
||||||
self.return_type = return_type
|
|
||||||
self.variables: [VariableDefinitionNode] = []
|
|
||||||
self.instructions: List[ASTElement] = []
|
|
||||||
|
|
||||||
|
|
||||||
class VariableDefinitionNode(ASTElement):
|
|
||||||
|
|
||||||
def __init__(self, is_public: bool, name: str, datatype: Union[str, Datatypes], value: Union[str, CallDefinitionNode]):
|
|
||||||
super().__init__()
|
|
||||||
self.is_public = is_public
|
|
||||||
self.name = name
|
|
||||||
self.datatype = datatype
|
|
||||||
self.value = value
|
|
@ -1,77 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class TokenDefinition(Enum):
|
|
||||||
""" Keywords """
|
|
||||||
# define keywords
|
|
||||||
Library = r'lib'
|
|
||||||
Class = r'class'
|
|
||||||
Function = r'func'
|
|
||||||
Variable = r'var'
|
|
||||||
Use = r'use'
|
|
||||||
From = r'from'
|
|
||||||
As = r'as'
|
|
||||||
|
|
||||||
# builtin functions
|
|
||||||
Output = r'output'
|
|
||||||
Input = r'input'
|
|
||||||
Length = r'length'
|
|
||||||
Range = r'range'
|
|
||||||
Round = r'round'
|
|
||||||
Exit = r'exit'
|
|
||||||
|
|
||||||
# normal keywords
|
|
||||||
If = r'if'
|
|
||||||
ElseIf = r'elseif'
|
|
||||||
Else = r'else'
|
|
||||||
Continue = r'continue'
|
|
||||||
Return = r'return'
|
|
||||||
|
|
||||||
# loops
|
|
||||||
While = r'while'
|
|
||||||
For = r'for'
|
|
||||||
In = r'in'
|
|
||||||
|
|
||||||
# access
|
|
||||||
Public = r'public'
|
|
||||||
This = r'this'
|
|
||||||
|
|
||||||
""" Chars """
|
|
||||||
# format
|
|
||||||
LeftBrace = r'\{'
|
|
||||||
RightBrace = r'\}'
|
|
||||||
LeftParenthesis = r'\('
|
|
||||||
RightParenthesis = r'\)'
|
|
||||||
LeftBracket = r'\['
|
|
||||||
RightBracket = r'\]'
|
|
||||||
Semicolon = r'\;'
|
|
||||||
Colon = r'\:'
|
|
||||||
Comma = r'\,'
|
|
||||||
Point = r'\.'
|
|
||||||
# expr
|
|
||||||
Plus = r'\+'
|
|
||||||
Minus = r'\-'
|
|
||||||
Asterisk = r'\*'
|
|
||||||
Slash = r'\/'
|
|
||||||
Equal = r'\='
|
|
||||||
Caret = r'\^'
|
|
||||||
|
|
||||||
""" Values """
|
|
||||||
ValueString = r'\".*?\"'
|
|
||||||
ValueNumber = r'\d+'
|
|
||||||
|
|
||||||
# bool
|
|
||||||
BoolTrue = r'true'
|
|
||||||
BoolFalse = r'false'
|
|
||||||
|
|
||||||
""" Datatypes """
|
|
||||||
Empty = r'empty'
|
|
||||||
Number = r'Number'
|
|
||||||
String = r'string'
|
|
||||||
Bool = r'bool'
|
|
||||||
List = r'list'
|
|
||||||
Dict = r'dict'
|
|
||||||
Void = r'void'
|
|
||||||
|
|
||||||
""" other """
|
|
||||||
Name = r'[a-zA-Z_][a-zA-Z0-9_]*'
|
|
@ -1,12 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class Datatypes(Enum):
|
|
||||||
|
|
||||||
Empty = 'empty'
|
|
||||||
Any = 'any'
|
|
||||||
Number = 'number'
|
|
||||||
String = 'string'
|
|
||||||
Bool = 'bool'
|
|
||||||
List = 'list'
|
|
||||||
Dict = 'dict'
|
|
@ -1,28 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class ErrorCodes(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'
|
|
||||||
|
|
||||||
|
|
||||||
class Error:
|
|
||||||
|
|
||||||
def __init__(self, code: ErrorCodes, msg: str = '') -> None:
|
|
||||||
self.code = code
|
|
||||||
|
|
||||||
self.msg = code.value.format(msg)
|
|
@ -1,8 +0,0 @@
|
|||||||
from Models.Token import TokenTypes
|
|
||||||
|
|
||||||
|
|
||||||
class Token:
|
|
||||||
|
|
||||||
def __init__(self, token_type: TokenTypes, value: str) -> None:
|
|
||||||
self.type: TokenTypes = token_type
|
|
||||||
self.value: str = value
|
|
@ -1,24 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class TokenTypes(Enum):
|
|
||||||
Empty = 0
|
|
||||||
Keyword = 1
|
|
||||||
Type = 2
|
|
||||||
Name = 3
|
|
||||||
Bool = 4
|
|
||||||
String = 5
|
|
||||||
Number = 6
|
|
||||||
Expression_Character = 7
|
|
||||||
Bool_Expression_Character = 8
|
|
||||||
Format_Character = 9
|
|
||||||
|
|
||||||
|
|
||||||
class UnresolvedTokenTypes(Enum):
|
|
||||||
Empty = 0
|
|
||||||
Word = 1
|
|
||||||
Number = 2
|
|
||||||
String = 3
|
|
||||||
Expression_Character = 4
|
|
||||||
Bool_Expression_Character = 5
|
|
||||||
Format_Character = 6
|
|
@ -1,62 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
|
|
||||||
|
|
||||||
class Keywords(Enum):
|
|
||||||
# define keywords
|
|
||||||
Library = 'lib'
|
|
||||||
Class = 'class'
|
|
||||||
Function = 'func'
|
|
||||||
Variable = 'var'
|
|
||||||
Use = 'use'
|
|
||||||
From = 'from'
|
|
||||||
|
|
||||||
# builtin functions
|
|
||||||
Output = 'output'
|
|
||||||
Input = 'input'
|
|
||||||
Length = 'length'
|
|
||||||
Range = 'range'
|
|
||||||
Exit = 'exit'
|
|
||||||
|
|
||||||
# normal keywords
|
|
||||||
If = 'if'
|
|
||||||
ElseIf = 'elseif'
|
|
||||||
Else = 'else'
|
|
||||||
Continue = 'continue'
|
|
||||||
In = 'in'
|
|
||||||
Return = 'return'
|
|
||||||
|
|
||||||
# loops
|
|
||||||
While = 'while'
|
|
||||||
For = 'for'
|
|
||||||
|
|
||||||
# access
|
|
||||||
Public = 'public'
|
|
||||||
This = 'this'
|
|
||||||
|
|
||||||
|
|
||||||
class Booleans(Enum):
|
|
||||||
Right = 'true'
|
|
||||||
Wrong = 'false'
|
|
||||||
|
|
||||||
|
|
||||||
class ExpressionCharacters(Enum):
|
|
||||||
Plus = '+'
|
|
||||||
Minus = '-'
|
|
||||||
Asterisk = '*'
|
|
||||||
Slash = '/'
|
|
||||||
Equal = '='
|
|
||||||
Caret = '^'
|
|
||||||
|
|
||||||
|
|
||||||
class FormatCharacters(Enum):
|
|
||||||
Left_Brace = '{'
|
|
||||||
Right_Brace = '}'
|
|
||||||
Left_Parenthesis = '('
|
|
||||||
Right_Parenthesis = ')'
|
|
||||||
Left_Bracket = '['
|
|
||||||
Right_Bracket = ']'
|
|
||||||
Semicolon = ';'
|
|
||||||
Colon = ':'
|
|
||||||
Comma = ','
|
|
||||||
Point = '.'
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
|||||||
from Interpreter.Interpreter import Interpreter
|
|
||||||
# from CCLang_sly.Interpreter import Interpreter as SlyCCLangInterpreter
|
|
||||||
from Interpreter.Utils import Utils
|
|
||||||
from Interpreter.Repo import Repo
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceInitializer:
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.repo = Repo()
|
|
||||||
self.utils = Utils(self.repo)
|
|
||||||
self.interpreter = Interpreter(self.repo, self.utils)
|
|
||||||
# self.sly_cclang_interpreter = SlyCCLangInterpreter(self.repo, self.utils)
|
|
@ -1,53 +0,0 @@
|
|||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from Models.Interpreter.Error import Error, ErrorCodes
|
|
||||||
from ServiceInitializer import ServiceInitializer
|
|
||||||
|
|
||||||
|
|
||||||
class Main:
|
|
||||||
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.__services = ServiceInitializer()
|
|
||||||
self.__utils = self.__services.utils
|
|
||||||
self.__repo = self.__services.repo
|
|
||||||
self.__interpreter = self.__services.interpreter
|
|
||||||
|
|
||||||
def console(self) -> None:
|
|
||||||
"""
|
|
||||||
Getting code from console input
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
i = 0
|
|
||||||
while self.__repo.error is None:
|
|
||||||
self.__repo.line_number = i + 1
|
|
||||||
self.__interpreter.interpret(input('> '))
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
def files(self, file: str) -> None:
|
|
||||||
"""
|
|
||||||
Getting input from file
|
|
||||||
:param file:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
if not os.path.isfile(file):
|
|
||||||
self.__utils.runtime_error(Error(ErrorCodes.FileNotFound))
|
|
||||||
return
|
|
||||||
|
|
||||||
if not file.endswith('.ccl'):
|
|
||||||
self.__utils.runtime_error(Error(ErrorCodes.WrongFileType))
|
|
||||||
return
|
|
||||||
|
|
||||||
f = open(file, 'r', encoding='utf-8').readlines()
|
|
||||||
for i in range(0, len(f)):
|
|
||||||
self.__repo.line_number = i + 1
|
|
||||||
self.__interpreter.interpret(f[i])
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main = Main()
|
|
||||||
print(sys.argv)
|
|
||||||
if len(sys.argv) == 2:
|
|
||||||
main.files(sys.argv[1])
|
|
||||||
else:
|
|
||||||
main.console()
|
|
@ -1,27 +0,0 @@
|
|||||||
# olc test 1
|
|
||||||
// olc test 2
|
|
||||||
/* mlc Test 1 */
|
|
||||||
/*
|
|
||||||
mlc Test 2
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public lib Main {
|
|
||||||
class Program {
|
|
||||||
var test: bool = false;
|
|
||||||
var test2: Program2 = empty;
|
|
||||||
var test3: Program2 = Test(34);
|
|
||||||
|
|
||||||
func Main(): void {
|
|
||||||
#func Main {
|
|
||||||
var hallo: any;
|
|
||||||
#output('Hello');
|
|
||||||
#output(this.isTrue(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
func isTrue(value: bool): bool {
|
|
||||||
#func isTrue {
|
|
||||||
#return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
test = 3 ** 2
|
|
||||||
print(test)
|
|
||||||
print(eval('3**2'))
|
|
Loading…
Reference in New Issue
Block a user