Exemple #1
0
    def process_case(self, parent: tl.CollectiveElement, index: int, builder: ab.AstBuilder,
                     lfp: tl.LineFilePos):
        index += 1
        cond_list = tl.CollectiveElement(tl.CE_BRACKET, lfp, None)
        ele = parent[index]
        while not (tl.is_brace(ele) or tl.identifier_of(ele, "->")):
            cond_list.append(ele)
            index += 1
            ele = parent[index]
        cond = self.parse_as_part(cond_list)
        if tl.identifier_of(ele, "->"):  # case expr
            index += 1
            ele = parent[index]
            if tl.is_brace(ele):
                body_block = self.parse_as_block(ele)
                builder.add_node(ast.CaseExpr(body_block, lfp, cond))
            else:
                body_list = tl.CollectiveElement(tl.CE_BRACKET, lfp, None)
                while not tl.identifier_of(ele, ";"):
                    body_list.append(ele)
                    index += 1
                    ele = parent[index]
                builder.add_node(ast.CaseExpr(self.parse_as_part(body_list), lfp, cond))
        else:  # case stmt
            body_block = self.parse_as_block(ele)
            builder.add_node(ast.CaseStmt(body_block, lfp, cond))

        return index
Exemple #2
0
    def process_default(self, parent: tl.CollectiveElement, index: int, builder: ab.AstBuilder,
                        lfp: tl.LineFilePos):
        index += 1
        ele = parent[index]
        if tl.is_brace(ele):
            builder.add_node(ast.CaseStmt(self.parse_as_block(ele), lfp))
        elif tl.identifier_of(ele, "->"):
            index += 1
            ele = parent[index]
            if tl.is_brace(ele):
                builder.add_node(ast.CaseExpr(self.parse_as_block(ele), lfp))
            else:
                body_list = tl.CollectiveElement(tl.CE_BRACKET, lfp, None)
                while not tl.identifier_of(ele, ";"):
                    body_list.append(ele)
                    index += 1
                    ele = parent[index]
                builder.add_node(ast.CaseExpr(self.parse_as_part(body_list), lfp))
        else:
            raise errs.TplParseError("Invalid syntax of 'default'. ", lfp)

        return index
Exemple #3
0
    def process_fn(self, parent: tl.CollectiveElement, index: int, builder: ab.AstBuilder, lfp: tl.LineFilePos):
        abstract = self.abstract
        self.abstract = False
        const = self.var_level == ast.VAR_CONST
        self.var_level = ast.VAR_VAR
        permission = self.permission
        self.permission = ast.PUBLIC
        inline = self.inline
        self.inline = False
        index += 1
        name_list = tl.CollectiveElement(tl.CE_BRACKET, lfp, None)
        next_ele = parent[index]
        while not tl.is_bracket(next_ele):
            name_list.append(next_ele)
            index += 1
            next_ele = parent[index]
        if len(name_list) == 0:
            fn_name = None
        else:
            fn_name = self.parse_as_part(name_list)

        param_list = next_ele
        params = self.parse_as_line(param_list)
        prob_arrow = parent[index + 1]
        if tl.identifier_of(prob_arrow, "->"):
            builder.add_node(ast.FunctionTypeExpr(params, lfp))
            return index

        index += 1
        rtype_list = tl.CollectiveElement(tl.CE_BRACKET, lfp, None)
        while not (tl.is_brace(parent[index]) or tl.identifier_of(parent[index], ";")):
            rtype_list.append(parent[index])
            index += 1
        rtype = self.parse_as_part(rtype_list)
        body_list = parent[index]
        if tl.identifier_of(body_list, ";"):
            body = None
        else:
            body = self.parse_as_block(body_list)

        if not abstract and body is None:
            raise errs.TplSyntaxError("Non-abstract method must have body. ", lfp)
        if abstract and body is not None:
            raise errs.TplSyntaxError("Abstract method must not have body. ", lfp)

        fd = ast.FunctionDef(fn_name, params, rtype, abstract, const, permission, body, lfp)
        fd.inline = inline
        builder.add_node(fd)
        return index
Exemple #4
0
    def process_switch(self, parent: tl.CollectiveElement, index: int, builder: ab.AstBuilder,
                       lfp: tl.LineFilePos):
        index += 1
        cond_list = tl.CollectiveElement(tl.CE_BRACKET, lfp, None)
        ele = parent[index]
        while not tl.is_brace(ele):
            cond_list.append(ele)
            index += 1
            ele = parent[index]
        cond = self.parse_as_part(cond_list)
        body_block = self.parse_as_block(ele)

        res = ab.parse_switch(cond, body_block, lfp)
        builder.add_node(res)

        return index
Exemple #5
0
    def process_export(self, parent: tl.CollectiveElement, index: int, builder: ab.AstBuilder, lfp: tl.LineFilePos):
        index += 1
        ele = parent[index]
        if tl.is_brace(ele):
            block = self.parse_as_block(ele)
            builder.add_node(ast.ExportStmt(block, lfp))
        elif isinstance(ele, tl.AtomicElement) and isinstance(ele.atom, tl.IdToken):
            block = ast.BlockStmt(lfp)
            line = ast.Line(lfp)
            line.parts.append(ast.NameNode(ele.atom.identifier, lfp))
            block.lines.append(line)
            builder.add_node(ast.ExportStmt(block, lfp))
        else:
            raise errs.TplCompileError("Invalid export. ", lfp)

        return index
    def process_one(self, parent: tl.CollectiveElement, index: int,
                    result_parent: tl.CollectiveElement) -> int:
        ele = parent[index]
        if isinstance(ele, tl.AtomicElement):
            if isinstance(ele.atom, tl.IdToken):
                symbol = ele.atom.identifier
                lf = ele.atom.lfp
                if symbol == "macro":
                    index += 1
                    name_ele = parent[index]
                    if isinstance(name_ele, tl.AtomicElement) and isinstance(
                            name_ele.atom, tl.IdToken):
                        name = name_ele.atom.identifier
                        index += 1
                        prob_params = parent[index]
                        if isinstance(prob_params, tl.CollectiveElement):
                            if prob_params.is_brace():  # macro name { ... }
                                macro = SimpleMacro(prob_params, lf)
                                self.macros.add_macro(name, macro, lf)
                                return index + 1
                            elif prob_params.is_bracket(
                            ):  # macro name(...) ...
                                index += 1
                                body = parent[index]
                                if tl.is_brace(body):
                                    macro = CallMacro(
                                        get_name_list(prob_params), body, lf)
                                    self.macros.add_macro(name, macro, lf)
                                    return index + 1
                    raise errs.TplSyntaxError("Invalid macro syntax. ", lf)
                elif symbol == "exportmacro":
                    index += 1
                    exports = parent[index]
                    if tl.is_brace(exports):
                        for exp in exports:
                            if isinstance(exp,
                                          tl.AtomicElement) and isinstance(
                                              exp.atom, tl.IdToken):
                                if exp.atom.identifier != ",":
                                    self.macros.add_export(exp.atom.identifier)
                            else:
                                raise errs.TplSyntaxError(
                                    "Invalid exportmacro syntax. ", lf)
                    elif isinstance(exports, tl.AtomicElement) and isinstance(
                            exports.atom, tl.IdToken):
                        self.macros.add_export(exports.atom.identifier)
                    else:
                        raise errs.TplSyntaxError(
                            "Invalid exportmacro syntax. ", lf)
                    return index + 1

                elif symbol == "import":
                    index += 1
                    includes = parent[index]
                    if isinstance(includes, tl.AtomicElement):
                        self.import_one(includes.atom, result_parent, lf)
                    elif tl.is_brace(includes):
                        for inc in includes:
                            if isinstance(inc, tl.AtomicElement):
                                self.import_one(inc.atom, result_parent, lf)
                            else:
                                raise errs.TplSyntaxError(
                                    "Invalid include. ", lf)
                    else:
                        raise errs.TplSyntaxError("Invalid include. ", lf)
                    return index + 1
                elif self.macros.is_macro(symbol):  # replace macro
                    macro = self.macros.get_macro(symbol)
                    if isinstance(macro, CallMacro):
                        index += 1
                        args = parent[index]
                        if not tl.is_bracket(args):
                            raise errs.TplSyntaxError("Invalid macro syntax. ",
                                                      args.lfp)

                        arg_list = list_ify_macro_arg(args)

                        if len(arg_list) != len(macro.params):
                            raise errs.TplSyntaxError(
                                "Macro syntax arity mismatch. ", args.lfp)

                        body_with_arg = tl.CollectiveElement(
                            tl.CE_BRACE, lf, None)
                        for body_ele in macro.body:
                            if isinstance(body_ele, tl.AtomicElement) and \
                                    isinstance(body_ele.atom, tl.IdToken) and \
                                    body_ele.atom.identifier in macro.params:
                                arg_index = macro.params.index(
                                    body_ele.atom.identifier)
                                body_with_arg.extend(arg_list[arg_index])
                            else:
                                body_with_arg.append(body_ele)
                        macro_res = self.process_block(body_with_arg, None)
                    else:
                        macro_res = self.process_block(macro.body, None)

                    result_parent.extend(macro_res)
                    return index + 1

            result_parent.append(ele)
        elif isinstance(ele, tl.CollectiveElement):
            res = self.process_block(ele, result_parent)
            result_parent.append(res)
        else:
            raise errs.TplError("Unexpected element. ", parent.lfp)

        return index + 1