~kf5jwc/imp-parser

ref: 9a694fa0d8b73f01beb051b54cdab8a2b000be09 imp-parser/imp_parser/parser/statements.py -rw-r--r-- 1.6 KiB View raw
9a694fa0 — Kyle Jones I've done more type annotating, which.... helped? 1 year, 6 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
from ..ast import AssignStatement, CompoundStatement, IfStatement, WhileStatement, RelopBexp
from .arithmetic import aexp, ID, keyword
from .boolean import bexp
from .combinators import Alternate, Exp, Lazy, Opt, Process

from typing import Tuple, Any


def assign_stmt() -> Process:
    def process(parsed):
        ((name, _), exp) = parsed
        return AssignStatement(name, exp)

    return ID + keyword(":=") + aexp() ^ process


def stmt_list() -> Exp:
    separator = keyword(";") ^ (lambda x: lambda l, r: CompoundStatement(l, r))
    return Exp(stmt(), separator)


def if_stmt() -> Process:
    # Okay, so at this point I *hate* how this combinator return structure is organized.
    def process(parsed: Tuple[Tuple[Tuple[Tuple[Tuple[str, RelopBexp], str], AssignStatement], Tuple[str, AssignStatement]], str]):
        (((((_, condition), _), true_stmt), false_parsed), _) = parsed

        if false_parsed:
            (_, false_stmt) = false_parsed
        else:
            false_stmt = None

        return IfStatement(condition, true_stmt, false_stmt)

    return keyword("if") + bexp() \
         + keyword("then") + Lazy(stmt_list) \
         + Opt(keyword("else") + Lazy(stmt_list)) \
         + keyword("end") ^ process

def while_stmt() -> Process:
    def process(parsed):
        ((((_, condition), _), body), _) = parsed
        return WhileStatement(condition, body)

    return keyword("while") + bexp() \
         + keyword("do") + Lazy(stmt_list) \
         + keyword("end") ^ process


def stmt() -> Alternate:
    return assign_stmt() \
         | if_stmt() \
         | while_stmt()