aboutsummaryrefslogtreecommitdiff
path: root/lib/utils2.nom
blob: c31d5ab168b24abfbf98472b0c9610eb6ccd418e (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
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:
    if ((%str's "type") == "String"):
        "nomsu:writeln(\(%str as lua))"
    ..else:
        "nomsu:writeln(nomsu:stringify(\(%str as lua)))"

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

# 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 "vars.eq and vars.eq.type == 'Word' and vars.eq.value == '='") ".."
            |Invalid format for 'with' statement. List entries must have the form %var = (value)
        %value = (%tokens -> 3)
        add (d{i=%i; var=%var; value=%value}) to %data
    %foo = (..)
        join (..)
            "local old_value\(%->"i") = \((%->"var") as lua); \((%->"var") as lua) = \((%->"value") as lua);"
            ..for all %data
        ..with glue "\n    "
    ".."
        |do
        |    \(%foo)
        |    local fell_through = false;
        |    local ok, ret1, ret2 = pcall(function(nomsu, vars)
        |        \(%action as lua statements);
        |        fell_through = true;
        |    end, nomsu, vars);
        |    \(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