summaryrefslogtreecommitdiff
path: root/projects/hackc/statements.py
blob: e8bc0b3ba48a07ab80fcd009b087463d9ed54cc2 (plain)
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 .expressions import Expression

class Statement:
    def __init__(self):
        pass

    @classmethod
    def from_tokens(cls, tokens: list) -> tuple:
        for StatementClass in [LetStatement]:
            stmt, dt = StatementClass.from_tokens(tokens)
            if stmt is not None:
                return (stmt, dt)

        return (None, 0)

class LetStatement:
    def __init__(self, name, expr):
        self.name = name
        self.expr = expr

    @classmethod
    def from_tokens(cls, tokens: list) -> tuple:
        """Construct let statement.

        Format:
        'let' <name> '=' <expression> ';'
        """
        if len(tokens) < 5 or tokens[0] != "let":
            return (None, 0)

        name = tokens[1]
        if name.type != "identifier":
            raise JackSyntaxError(f"Expected variable name, got `{name}` instead", name)

        if tokens[2] != "=":
            raise JackSyntaxError(f"Expected `=`, got `{tokens[2]}` instead", tokens[2])

        t = 3
        expr, dt = Expression.from_tokens(tokens[t:])
        if expr is None:
            raise JackSyntaxError(f"Expected expression", tokens[3])
        t += dt

        if tokens[t] != ";":
            raise JackSyntaxError(f"Expected `;`, got `{tokens[t]}` instead", tokens[t])

        t += 1
        return (LetStatement(name, expr), t)