aboutsummaryrefslogtreecommitdiff
path: root/parser.py
blob: 97717bfd626e3eda0f36c6a834f97142904ab298 (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
50
from tokens import *


def peek(inp):
    if len(inp) == 0:
        return None
    return inp[0]

def parse_expression(tkns):
    symbol = None
    args = []
    add_idx = 0
    for idx, t in enumerate(tkns):
        # if we evaluated a nested expression, skip ahead
        if add_idx > 0:
            add_idx -= 1
            continue
        if idx == 0:
            if not isinstance(t, NebSymbol):
                raise Exception("expressions must start with a symbol")
            else:
                symbol = t
        elif isinstance(t, NebClose):
            return NebExpression(symbol, args), tkns[idx + 1:], idx + 1
        # nested expressions
        elif isinstance(t, NebOpen):
            expr, remainder, add_idx = parse_expression(tkns[idx + 1:])
            args.append(expr)
        else:
            args.append(t)
            
    raise Exception("couldn't parse expression!")

def parse(tkns, parsed):
    nxt = peek(tkns)
    if nxt is None:
        return parsed
    if isinstance(nxt, NebOpen):
        expr, remainder, _ = parse_expression(tkns[1:])
        parsed.append(expr)
        return parse(remainder, parsed)
    elif isinstance(nxt, NebLiteral):
        parsed.append(nxt)
        return parse(tkns[1:], parsed)
    elif isinstance(nxt, NebSymbol):
        parsed.append(nxt)
        return parse(tkns[1:], parsed)
    else:
        raise Exception("expecting an expression or a literal")