view src/luan/modules/Io.luan @ 1189:73d754b1889f

add stringify
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 23 Feb 2018 01:40:04 -0700
parents e54ae41e9501
children e15a41a8b4b2
line wrap: on
line source

java()
local IoLuan = require "java:luan.modules.IoLuan"
local System = require "java:java.lang.System"

local Io = {}

Io.ip = IoLuan.ip
Io.my_ips = IoLuan.my_ips
Io.read_console_line = IoLuan.read_console_line
Io.schemes = IoLuan.newSchemes()
Io.uri = IoLuan.uri
Io.stdin = IoLuan.defaultStdin.table()
Io.socket_server = IoLuan.socket_server
Io.stdout = IoLuan.textWriter(System.out)
Io.stderr = IoLuan.textWriter(System.err)
Io.unrestricted = IoLuan.unrestricted

-- used by http and rpc
Io.password = "password"

local Luan = require "luan:Luan.luan"
local error = Luan.error
local to_string = Luan.to_string or error()
local type = Luan.type or error()
local try = Luan.try or error()
local ipairs = Luan.ipairs or error()
local pairs = Luan.pairs or error()
local values = Luan.values or error()
local load = Luan.load or error()
local Table = require "luan:Table.luan"
local unpack = Table.unpack or error()
local String = require "luan:String.luan"
local encode = String.encode or error()
local matches = String.matches or error()


-- do not change
function Io.template_write(...)
	return Io.stdout.write(...)
end


function Io.print_to(out,...)
	local list = {}
	for v in values(...) do
		list[#list+1] = to_string(v)
		list[#list+1] = '\t'
	end
	if #list > 0 then
		list[#list] = '\n'
		out.write( unpack(list) )
	end
end

function Io.print(...)
	Io.print_to(Io.stdout,...)
end


function Io.output_to(out,fn,...)
	local old_out = Io.stdout
	return try( {
		function(...)
			Io.stdout = out
			fn(...)
		end;
		finally = function()
			Io.stdout = old_out
		end;
	}, ... )
end

local uri = Io.uri  -- make local

function Io.output_of(fn,...)
	local string_uri = uri "string:"
	local out = string_uri.text_writer()
	Io.output_to(out,fn,...)
	out.close()
	return string_uri.read_text()
end


-- repr

local function do_repr(out,obj,strict,done)
	local tp = type(obj)
	if tp == "table" then
		if done[obj] == true then
			strict and error "circular reference"
			out.write "<circular reference>"
			return
		end
		done[obj] = true
		out.write( "{" )
		local is_first = true
		local in_list = {}
		for key, value in ipairs(obj) do
			if is_first then is_first = false else out.write ", " end
			do_repr(out,value,strict,done)
			in_list[key] = true
		end
		for key, value in pairs(obj) do
			if in_list[key] ~= true then
				if is_first then is_first = false else out.write ", " end
				if type(key) == "string" and matches(key,"^[a-zA-Z_][a-zA-Z_0-9]*$") ~= nil then
					out.write( key )
				elseif type(key) == "table" then
					out.write( "[<", key, ">]" )
				else
					out.write "["
					do_repr(out,key,strict,done)
					out.write "]"
				end
				out.write "="
				do_repr(out,value,strict,done)
			end
		end
		out.write "}"
	elseif tp == "string" then
		out.write( '"', encode(obj), '"' )
	elseif tp == "nil" or tp == "boolean" or tp == "number" then
		out.write( obj )
	else
		strict and error("can't repr type '"..tp.."' of "..obj)
		out.write( "<", obj, ">" )
	end
end

function Io.repr(obj,strict)
	local string_uri = uri "string:"
	local out = string_uri.text_writer()
	do_repr(out,obj,strict or false,{})
	out.close()
	return string_uri.read_text()
end


-- debug

function Io.debug(prompt)
	prompt = prompt or "luan_debug> "
	local function console()
		return Io.read_console_line(prompt)
	end
	local env = {}
	for line in console do
		try {
			function()
				local fn
				try {
					function()
						fn = load("return "..line,"stdin",env)
					end
					catch = function(e)
						fn = load(line,"stdin",env)
					end
				}
				Io.print( fn() )
			end
			catch = function(e)
				Io.print(e)
			end
		}
	end
end


return Io