#!/usr/bin/env nomsu -V3.5.5.6
#
    This file contains some definitions of text escape sequences, including ANSI console
    color codes.

use "core/metaprogramming.nom"

test:
    assume (("x" + "y") == "xy")
    %s = "list:\[1, 2, 3]"
    assume (%s == "list:[1, 2, 3]")
    assume ("foo = \(1 + 2)!" == "foo = 3!")
    assume (..)
        ".."
            one
            two
        ..== "one\ntwo"
    assume (..)
        ".."
            no\
            ..gap
        ..== "nogap"
    parse [アクション %spec %body] as (action %spec %body)
test:
    %こんにちは = "こんにちは"
    アクション [% と言う] "\(%)世界"
    assume ((%こんにちは と言う) == "こんにちは世界") or barf ".."
        Unicode doesn't work

# Text functions
test:
    assume ((["x", "y"] joined with ",") == "x,y") or barf "joined with failed"
    assume ((["x", "y"] joined) == "xy") or barf "joined failed"
action [%texts joined with %glue] (..)
    lua> ".."
        local text_bits = {}
        for i,bit in ipairs(\%texts) do text_bits[i] = stringify(bit) end
        return table.concat(text_bits, \%glue)

parse [joined %texts, %texts joined] as (%texts joined with "")

test:
    assume ((byte 2 of "BAR") == 65)
    assume ((bytes 1 to 2 of "BAR") == [66, 65])
compile [byte %i of %text] to (..)
    Lua value "(\(%text as lua expr)):byte(\(%i as lua expr))"

compile [bytes %start to %stop of %text] to (..)
    Lua value ".."
        list{(\(%text as lua expr)):byte(\(%start as lua expr), \(%stop as lua expr))}

test:
    assume (("asdf" capitalized) == "Asdf")
compile [capitalized %text, %text capitalized] to (..)
    Lua value "(\(%text as lua expr)):gsub('%l', string.upper, 1)"

test:
    assume (("asdf" uppercase) == "ASDF")
compile [uppercase %text, %text uppercase] to (..)
    Lua value "(\(%text as lua expr)):upper()"

test:
    assume (("asdf" with "X" instead of "s") == "aXdf") or barf ".."
        substitution failed
compile [..]
    %text with %sub instead of %patt, %text with %patt replaced by %sub
    %text s/ %patt / %sub
..to (..)
    Lua value ".."
        ((\(%text as lua expr)):gsub(\(%patt as lua expr), \(%sub as lua expr)))

test:
    assume (..)
        (..)
            lines in ".."
                one
                two
        ..== ["one", "two"]
action [lines in %text, lines of %text] (..)
    lua> ".."
        local result = list{}
        for line in (\%text):gmatch('[^\\n]+') do
            result[#result+1] = line
        end
        return result

compile [for %match in %text matching %patt %body] to (..)
    Lua ".."
        for \(%match as lua expr) in (\(%text as lua expr)):gmatch(\(%patt as lua expr)) do
            \(%body as lua statements)
            \(compile as (===next %match ===))
        end
        \(compile as (===stop %match ===))

compile [%expr for %match in %text matching %patt] to (..)
    Lua value ".."
        (function()
            local ret = list{}
            for \(%match as lua expr) in (\(%text as lua expr)):gmatch(\(..)
            %patt as lua expr
        ..) do
                ret[#ret+1] = \(%expr as lua statements)
            end
            return ret
        end)()

compile [%text matches %pattern] to (..)
    Lua value ".."
        ((\(%text as lua expr)):match(\(%pattern as lua expr)) and true or false)

compile [%text matching %pattern] to (..)
    Lua value "(\(%text as lua expr)):match(\(%pattern as lua expr))"

test:
    assume ("\n" == (newline)) or barf "Text literals failed."

# Text literals
lua> ".."
    do
        local escapes = {
            nl="\\\\n", newline="\\\\n", tab="\\\\t", bell="\\\\a", cr="\\\\r",
            ["carriage return"]="\\\\r", backspace="\\\\b", ["form feed"]="\\\\f",
            formfeed="\\\\f", ["vertical tab"]="\\\\v",
        };
        for name, e in pairs(escapes) do
            local lua = "'"..e.."'"
            COMPILE_ACTIONS[name] = function(nomsu, tree)
                return LuaCode.Value(tree.source, lua)
            end
        end
    end