changeset 1189:73d754b1889f

add stringify
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 23 Feb 2018 01:40:04 -0700
parents 9f5edbef3f55
children db7d31f4089a
files src/luan/LuanTable.java src/luan/modules/BasicLuan.java src/luan/modules/Io.luan src/luan/modules/Luan.luan src/luan/modules/lucene/Web_search.luan src/luan/modules/parsers/LuanToString.java website/src/manual.html.luan
diffstat 7 files changed, 119 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/LuanTable.java	Thu Feb 22 23:21:06 2018 -0700
+++ b/src/luan/LuanTable.java	Fri Feb 23 01:40:04 2018 -0700
@@ -113,6 +113,11 @@
 		return list!=null ? list : Collections.emptyList();
 	}
 
+	public Map rawMap() {
+		check();
+		return map!=null ? map : Collections.emptyMap();
+	}
+
 	public String toString(LuanState luan) throws LuanException {
 		Object h = getHandler(luan,"__to_string");
 		if( h == null )
--- a/src/luan/modules/BasicLuan.java	Thu Feb 22 23:21:06 2018 -0700
+++ b/src/luan/modules/BasicLuan.java	Fri Feb 23 01:40:04 2018 -0700
@@ -13,6 +13,7 @@
 import luan.LuanFunction;
 import luan.LuanException;
 import luan.LuanMethod;
+import luan.modules.parsers.LuanToString;
 
 
 public final class BasicLuan {
@@ -223,4 +224,9 @@
 		}
 	}
 
+	public static String stringify(Object obj,Boolean strict) throws LuanException {
+		boolean b = strict!=null ? strict : true;
+		return LuanToString.toString(obj,b);
+	}
+
 }
--- a/src/luan/modules/Io.luan	Thu Feb 22 23:21:06 2018 -0700
+++ b/src/luan/modules/Io.luan	Fri Feb 23 01:40:04 2018 -0700
@@ -136,23 +136,6 @@
 end
 
 
--- useful for SimplyHTML responsiveness
-
-local NO = {}
-Io.NO = NO
-
-function Io.dont_write_when_no(write_fn)
-	return function(...)
-		for v in values(...) do
-			if v == NO then
-				return
-			end
-		end
-		write_fn(...)
-	end
-end
-
-
 -- debug
 
 function Io.debug(prompt)
--- a/src/luan/modules/Luan.luan	Thu Feb 22 23:21:06 2018 -0700
+++ b/src/luan/modules/Luan.luan	Fri Feb 23 01:40:04 2018 -0700
@@ -17,6 +17,7 @@
 Luan.raw_len = BasicLuan.raw_len
 Luan.raw_set = BasicLuan.raw_set
 Luan.set_metatable = BasicLuan.set_metatable
+Luan.stringify = BasicLuan.stringify
 Luan.to_string = BasicLuan.to_string
 Luan.try = BasicLuan.try_
 Luan.type = BasicLuan.type
--- a/src/luan/modules/lucene/Web_search.luan	Thu Feb 22 23:21:06 2018 -0700
+++ b/src/luan/modules/lucene/Web_search.luan	Fri Feb 23 01:40:04 2018 -0700
@@ -4,8 +4,8 @@
 local ipairs = Luan.ipairs or error()
 local range = Luan.range or error()
 local to_string = Luan.to_string or error()
+local stringify = Luan.stringify or error()
 local Io = require "luan:Io.luan"
-local repr = Io.repr or error()
 local Http = require "luan:http/Http.luan"
 local String = require "luan:String.luan"
 local string_to_number = String.to_number or error()
@@ -136,7 +136,7 @@
 					<%
 					for col in range(1, #headers) do
 						local val = row[col]
-						%><td><%= val and repr(val) or "" %></td><%
+						%><td><%= val and stringify(val) or "" %></td><%
 					end
 					%>
 				</tr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/modules/parsers/LuanToString.java	Fri Feb 23 01:40:04 2018 -0700
@@ -0,0 +1,100 @@
+package luan.modules.parsers;
+
+import java.util.List;
+import java.util.Map;
+import luan.Luan;
+import luan.LuanTable;
+import luan.LuanException;
+
+
+public final class LuanToString {
+
+	public static String toString(Object obj,boolean strict) throws LuanException {
+		StringBuilder sb = new StringBuilder();
+		new LuanToString(strict).toString(obj,sb,0);
+		return sb.toString();
+	}
+
+	private final boolean strict;
+
+	private LuanToString(boolean strict) {
+		this.strict = strict;
+	}
+
+	private void toString(Object obj,StringBuilder sb,int indented) throws LuanException {
+		if( obj == null ) {
+			sb.append( "nil" );
+			return;
+		}
+		if( obj instanceof Boolean ) {
+			sb.append( obj );
+			return;
+		}
+		if( obj instanceof Number ) {
+			sb.append( Luan.toString((Number)obj) );
+			return;
+		}
+		if( obj instanceof String ) {
+			toString((String)obj,sb);
+			return;
+		}
+		if( obj instanceof LuanTable ) {
+			toString((LuanTable)obj,sb,indented);
+			return;
+		}
+		if( strict )
+			throw new LuanException("can't handle type "+obj.getClass().getName());
+		sb.append( '<' );
+		sb.append( obj );
+		sb.append( '>' );
+	}
+
+	private void toString(final String s,StringBuilder sb) {
+		sb.append( '"' );
+		sb.append( Luan.stringEncode(s) );
+		sb.append( '"' );
+	}
+
+	private void toString(LuanTable tbl,StringBuilder sb,int indented) throws LuanException {
+		List list = tbl.asList();
+		Map map = tbl.rawMap();
+		sb.append( '{' );
+		if( !list.isEmpty() ) {
+			indent(sb,indented+1);
+			for( Object obj : list ) {
+				toString(obj,sb,indented+1);
+				sb.append( ", " );
+			}
+		}
+		for( Object obj : map.entrySet() ) {
+			Map.Entry entry = (Map.Entry)obj;
+			indent(sb,indented+1);
+			toString(entry,sb,indented+1);
+		}
+		if( !list.isEmpty() || !map.isEmpty() )
+			indent(sb,indented);
+		sb.append( '}' );
+		return;
+	}
+
+	private void toString(Map.Entry entry,StringBuilder sb,int indented) throws LuanException {
+		Object key = entry.getKey();
+		if( key instanceof String && ((String)key).matches("[a-zA-Z_][a-zA-Z_0-9]*") ) {
+			sb.append( (String)key );
+		} else {
+			sb.append( '[' );
+			toString( key, sb, indented );
+			sb.append( ']' );
+		}
+		sb.append( " = " );
+		toString( entry.getValue(), sb, indented );
+	}
+
+	private void indent(StringBuilder sb,int indented) {
+		sb.append( '\n' );
+		for( int i=0; i<indented; i++ ) {
+			sb.append( '\t' );
+		}
+	}
+
+}
--- a/website/src/manual.html.luan	Thu Feb 22 23:21:06 2018 -0700
+++ b/website/src/manual.html.luan	Fri Feb 23 01:40:04 2018 -0700
@@ -2081,6 +2081,11 @@
 raises an error.
 
 
+<h4 heading><a name="Luan.stringify" href="#Luan.stringify"><code>Luan.stringify (v [,strict])</code></a></h4>
+
+<p>
+Receives a value of any type and converts it to a string that is a Luan expression.  <code>strict</code> is a boolean.  If <code>strict</code> is true then invalid types throw an error.  If <code>strict</code> is false then invalid types are represented but the resulting expression is invalid.  <code>strict</code> defaults to <b>true</b>.
+
 
 <h4 heading><a name="Luan.to_string" href="#Luan.to_string"><code>Luan.to_string (v)</code></a></h4>