Beispiel #1
0
    def start(self) -> None:
        """
        todo: add support for in-place value mutations
        """
        def to_dict(_ast):
            return _ast if _ast.name == 'running_name' else {
                'op': _ast.op,
                'left': to_dict(_ast.left),
                'right': to_dict(_ast.right)
            }

        _path = [self.start_token]
        _identifier, path = next(self.header, None), None
        if _identifier.name not in {
                'colon', 'dot', 'lparent', 'assign', 'increment', 'decrement',
                'inplace'
        }:
            raise lang_exceptions.InvalidSyntax(
                f"In '{self.file}', line {self.line_counter.line_number}:\nInvalid Syntax: invalid syntax with name '{_identifier.value}'"
            )
        _path.extend(list(self.attr_lookup(_identifier)))
        _identifier = next(self.header, None)
        if _identifier.name in {'assign', 'inplace'}:
            _full_ast, *_ = ast_creator.AST.create_ast(
                self.reverse_op, lang_utility_objs.ast_delimeters())
            return lang_utility_objs.NameAction(_path, None, _identifier,
                                                _full_ast)
        if _identifier.name == 'colon':
            _type_ast, _, _last = ast_creator.AST.create_ast(
                self.reverse_op, lang_utility_objs.ast_delimeters("assign"))
            self.header = iter([_last, *self.header])
            _check_next = next(self.header, None)
            if _check_next is None:
                raise lang_exceptions.InvalidTypeDeclaration(
                    f"In '{self.file}', line {self.line_counter.line_number}:\nInvalid Type Declaration: expecting assignment expression"
                )
            if _check_next.name != 'assign':
                lang_exceptions.InvalidSyntax(
                    f"In '{self.file}', line {self.line_counter.line_number}:\nInvalid Assignment Expression: expecting value assignment"
                )
            _assignment_ast, *_ = ast_creator.AST.create_ast(
                self.reverse_op, lang_utility_objs.ast_delimeters())
            return lang_utility_objs.NameAction(_path, _type_ast, _check_next,
                                                _assignment_ast)
        if _identifier.name in {'increment', 'decrement'}:
            _check_next = next(self.header, None)
            if _check_next is not None:
                raise lang_exceptions.InvalidInplaceExpression(
                    f"In '{self.file}', line {self.line_counter.line_number}:\nInvalid Inplace Expression: invalid {_identifier.name} expression"
                )
            return lang_utility_objs.InPlaceAction(_path, _identifier)
        raise lang_exceptions.InvalidSyntax(
            f"In '{self.file}', line {self.line_counter.line_number}:\nInvalid Syntax: invalid syntax with name '{_identifier.value}'"
        )
Beispiel #2
0
 def attr_lookup(self, _c):
     while _c.name == 'dot':
         _attr = next(self.header, None)
         if _attr is None:
             raise lang_exceptions.InvalidSyntax(
                 f"In '{self.file}', line {self.line_counter.line_number}:\nInvalid Syntax: unexpected termination of expression"
             )
         if _attr.name != 'variable':
             raise lang_exceptions.InvalidSyntax(
                 f"In '{self.file}', line {self.line_counter.line_number}:\nInvalid Syntax: '{attr.value}'"
             )
         yield _attr
         _c = next(self.header, None)
     if _c is not None:
         self.header = iter([_c, *self.header])
Beispiel #3
0
 def start(self) -> None:
     _start, _queue = next(self.header, None), []
     while _start is not None and _start.name not in self.delimeter:
         if _start.token_type in {'name', 'boolean', 'value', 'lang_type'}:
             _queue.append(
                 NameLookup(
                     [_start, *self.attr_lookup(next(self.header, None))]))
         elif _start.token_type in {'operator'}:
             _queue.append(OperatorObj(_start))
         elif _start.name == 'lparen':
             _signature = []
             while True:
                 _param, end, _ending_token = self.__class__.create_ast(
                     self.from_source,
                     lang_utility_objs.ast_delimeters('comma', 'rparen'))
                 if _param:
                     _signature.append(_param)
                 if _ending_token is None or _ending_token.name == 'rparen':
                     break
             _queue.append(Signature(_signature))
         elif _start.name == 'dot':
             _lookup = list(self.attr_lookup(_start))
             if not _lookup:
                 raise lang_exceptions.InvalidSyntax(
                     f"In '{self.file}', line {self.line_counter.line_number}:\nInvalid Syntax: '{_start.value}'"
                 )
             _queue.append(TrailingNameLookup(_lookup))
         _start = next(self.header, None)
     return _queue, self.delimeter, _start
Beispiel #4
0
 def push(self, _name_action) -> None:
     if _name_action.ast_type == 'trailing_name_lookup' and (
             not self.names or
         (self.names and self.names[-1].ast_type != 'signature')):
         raise lang_exceptions.InvalidSyntax(
             f"In '{self.file}', line {self.line_counter.line_number}:\nInvalid Syntax: '.'"
         )
     self.names.append(_name_action)
Beispiel #5
0
 def get_obj_ast(cls, _, _parser_obj, _header: typing.Iterator,
                 _lines: typing.Iterator, _line_counter: LineCount,
                 _file: str, _current_level: int,
                 scope: Scope) -> typing.Any:
     _identifier = next(_header, None)
     if _identifier is None:
         raise lang_exceptions.InvalidSyntax(
             f"In '{_file}', line {_line_counter.line_number}:\nInvalid Syntax Error: expected identifier name"
         )
     if _identifier.value not in cls.idenifiers:
         raise lang_exceptions.InvalidIdentifier(
             f"In '{_file}', line {_line_counter.line_number}:\nInvalid Indentifier: '{_identifier.value}'"
         )
     _ = cls.idenifiers[_identifier.value].init_identifier(
         _parser_obj, _header, _lines, _line_counter, _file,
         _current_level + 4, scope)
Beispiel #6
0
 def start(self) -> None:
     _start = next(self, None)
     while _start is not None:
         _t, *_trailing = _start
         if self.level and not _t.is_space or _t.is_space and self.level != len(
                 _t):
             raise lang_exceptions.IndentationError(
                 f"In '{self.file}', line {self.line_count.line_number}:\nIndentationError: expected {self.level}, got {len(_t)}"
             )
         _trailing = iter(_trailing)
         if _t.is_space:
             _t, *_trailing = _trailing
             _trailing = iter(_trailing)
         if _t.token_type not in self.token_matcher:
             raise lang_exceptions.InvalidSyntax(
                 f"In '{self.file}', line {self.line_count.line_number}:\nInvalid Syntax: invalid identifier '{_t.value}'"
             )
         executable_ast = self.token_matcher[_t.token_type].get_obj_ast(
             _t, self.__class__, _trailing, self.stream, self.line_count,
             self.file, self.level, self.scope)
         print('got executable ast: ', executable_ast)
         print('-' * 20)
         _start = next(self, None)
         next(self.line_count)