aboutsummaryrefslogtreecommitdiff
path: root/lib/utils2.nom
blob: 8077203f51eaf96b3e8dcd7c25a1c7b01437dc0a (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
51
52
53
54
55
56
57
58
59
60
61
62
63
require "lib/metaprogramming.nom"
require "lib/utils.nom"
require "lib/control_flow.nom"
require "lib/operators.nom"
require "lib/collections.nom"


compile [say %str] to:
    "nomsu:writeln(\(%str as lua))" if ((%str's "type") == "String")
    ..else "nomsu:writeln(nomsu:stringify(\(%str as lua)))"

compile [do %action] to code:
    (%action as lua statements) if ((%action's "type") == "Thunk")
    ..else "(\(%action as lua))(nomsu);"

# With statement
compile [with %assignments %action] to code:
    %data = []
    for %i = %assignment in (%assignments' "value"):
        %tokens = (%assignment's "value")
        %var = (%tokens -> 1)
        %eq = (%tokens -> 2)
        assert (=lua "\%eq and \%eq.type == 'Word' and \%eq.value == '='") ".."
            Invalid format for 'with' statement. List entries must have the form %var = (value)
        %value = (%tokens -> 3)
        add {i=%i, var=%var, value=%value} to %data
    %setup = (..)
        join (..)
            "local old_value\(%->"i") = \((%->"var") as lua); \((%->"var") as lua) = \((%->"value") as lua);"
            ..for all %data
        ..with glue "\n    "
    return ".."
        do
            \%setup
            local fell_through = false;
            local ok, ret1, ret2 = pcall(function(nomsu)
                \(%action as lua statements);
                fell_through = true;
            end, nomsu);
            \(join ("\((%->"var") as lua) = old_value\(%->"i");" for all %data) with glue "\n    ")
            if not ok then nomsu:error(ret1); end
            if not fell_through then
                return ret1, ret2;
            end
        end
parse [with %thing = %value %action] as: with [%thing = %value] %action

# Any/all/none
compile [all of %items, all %items] to:
    "(\(join ((% as lua) for all (%items' "value")) with glue " and "))"
    ..if (%items' "type") == "List" else "nomsu.utils.all(\(%items as lua))"
parse [not all of %items, not all %items] as: not (all of %items)
compile [any of %items, any %items] to:
    "(\(join ((% as lua) for all (%items' "value")) with glue " or "))"
    ..if (%items' "type") == "List" else "nomsu.utils.any(\(%items as lua))"
parse [none of %items, none %items] as: not (any of %items)

compile [sum of %items, sum %items] to:
    "(\(join ((% as lua) for all (%items' "value")) with glue " + "))"
    ..if (%items' "type") == "List" else "nomsu.utils.sum(\(%items as lua))"
compile [product of %items, product %items] to:
    "(\(join ((% as lua) for all (%items' "value")) with glue " * "))"
    ..if (%items' "type") == "List" else "nomsu.utils.product(\(%items as lua))"