~kf5jwc/imp-parser

ref: 4a8b0d0c4a9b3e235854c13031f981f55fc7ece5 imp-parser/imp_parser/parser/statements.py -rw-r--r-- 1.4 KiB View raw
4a8b0d0c — Kyle Jones More typing! 1 year, 7 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
from ..ast import AssignStatement, CompoundStatement, IfStatement, WhileStatement
from .arithmetic import aexp, ID, keyword
from .boolean import bexp
from .combinators import Alternate, Exp, Lazy, Opt, Process


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:
    def process(parsed):
        # Okay, so at this point I *hate* how this combinator return structure is organized.
        (((((_, 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()