Mercurial Hosting > luan
comparison src/luan/modules/parsers/LuanToString.java @ 1623:582384548a69
LuanToString takes function
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Sun, 01 Aug 2021 18:59:01 -0600 |
parents | a37ffe2d1b14 |
children | f8f5c51f5b36 |
comparison
equal
deleted
inserted
replaced
1622:b7f8418fb7ba | 1623:582384548a69 |
---|---|
11 import luan.LuanException; | 11 import luan.LuanException; |
12 import luan.LuanRuntimeException; | 12 import luan.LuanRuntimeException; |
13 | 13 |
14 | 14 |
15 public final class LuanToString { | 15 public final class LuanToString { |
16 private static final Set<String> settingsKeys = new HashSet<String>(); | |
17 static { | |
18 Collections.addAll(settingsKeys | |
19 ,"strict" | |
20 ,"number_types" | |
21 ,"compressed" | |
22 ,"long_strings" | |
23 ,"inline" | |
24 ,"no_name_keys" | |
25 ); | |
26 } | |
27 | |
28 private static void checkOptions(LuanTable options) throws LuanException { | |
29 for( Map.Entry entry : options.rawIterable() ) { | |
30 if( !settingsKeys.contains(entry.getKey()) ) | |
31 throw new LuanException("invalid option: "+entry.getKey()); | |
32 if( !(entry.getValue() instanceof Boolean) ) | |
33 throw new LuanException("options values must be boolean"); | |
34 } | |
35 } | |
36 | |
16 public static class Settings implements Cloneable { | 37 public static class Settings implements Cloneable { |
17 public boolean strict = false; | 38 public boolean strict = false; |
18 public boolean numberTypes = false; | 39 public boolean numberTypes = false; |
19 public boolean compressed = false; | 40 public boolean compressed = false; |
20 public boolean longStrings = false; | 41 public boolean longStrings = false; |
21 public boolean inline = false; | 42 public boolean inline = false; |
43 public boolean noNameKeys = false; | |
22 | 44 |
23 void applyOptions(LuanTable options) throws LuanException { | 45 void applyOptions(LuanTable options) throws LuanException { |
46 checkOptions(options); | |
24 Boolean b; | 47 Boolean b; |
25 b = (Boolean)options.rawGet("strict"); | 48 b = (Boolean)options.rawGet("strict"); |
26 if( b != null ) | 49 if( b != null ) |
27 strict = b; | 50 strict = b; |
28 b = (Boolean)options.rawGet("number_types"); | 51 b = (Boolean)options.rawGet("number_types"); |
35 if( b != null ) | 58 if( b != null ) |
36 longStrings = b; | 59 longStrings = b; |
37 b = (Boolean)options.rawGet("inline"); | 60 b = (Boolean)options.rawGet("inline"); |
38 if( b != null ) | 61 if( b != null ) |
39 inline = b; | 62 inline = b; |
63 b = (Boolean)options.rawGet("no_name_keys"); | |
64 if( b != null ) | |
65 noNameKeys = b; | |
40 } | 66 } |
41 | 67 |
42 public Settings cloneSettings() { | 68 public Settings cloneSettings() { |
43 try { | 69 try { |
44 return (Settings)clone(); | 70 return (Settings)clone(); |
46 throw new RuntimeException(e); | 72 throw new RuntimeException(e); |
47 } | 73 } |
48 } | 74 } |
49 } | 75 } |
50 private static final Settings keySettings = new Settings(); | 76 private static final Settings keySettings = new Settings(); |
51 private static final Set<String> settingsKeys = new HashSet<String>(); | |
52 static { | |
53 Collections.addAll(settingsKeys,"strict","number_types","compressed","long_strings","inline"); | |
54 } | |
55 | |
56 private static void checkOptions(LuanTable options) throws LuanException { | |
57 for( Map.Entry entry : options.rawIterable() ) { | |
58 if( !settingsKeys.contains(entry.getKey()) ) | |
59 throw new LuanException("invalid option: "+entry.getKey()); | |
60 if( !(entry.getValue() instanceof Boolean) ) | |
61 throw new LuanException("options values must be boolean"); | |
62 } | |
63 } | |
64 | 77 |
65 public final Settings settingsInit = new Settings(); | 78 public final Settings settingsInit = new Settings(); |
66 public Luan luan = null; | 79 private final Luan luan; |
67 private final LuanTable subOptions; | 80 private final LuanFunction fnOptions; |
68 | 81 private final LuanTable stack = new LuanTable(); |
69 public LuanToString(LuanTable options,LuanTable subOptions) throws LuanException { | 82 |
70 this.subOptions = subOptions; | 83 public LuanToString() { |
71 if( options != null ) { | 84 this.luan = null; |
72 checkOptions(options); | 85 this.fnOptions = null; |
86 } | |
87 | |
88 public LuanToString(Luan luan) throws LuanException { | |
89 this.luan = luan; | |
90 this.fnOptions = null; | |
91 } | |
92 | |
93 public LuanToString(Luan luan,LuanTable options) throws LuanException { | |
94 this.luan = luan; | |
95 this.fnOptions = null; | |
96 settingsInit.applyOptions(options); | |
97 } | |
98 | |
99 public LuanToString(Luan luan,LuanFunction fnOptions) throws LuanException { | |
100 this.luan = luan; | |
101 this.fnOptions = fnOptions; | |
102 LuanTable options = getOptions(); | |
103 if( options != null ) | |
73 settingsInit.applyOptions(options); | 104 settingsInit.applyOptions(options); |
74 } | 105 } |
75 if( subOptions != null ) { | 106 |
76 for( Map.Entry entry : subOptions.rawIterable() ) { | 107 private LuanTable getOptions() throws LuanException { |
77 /* | 108 if( fnOptions == null ) |
78 if( !(entry.getKey() instanceof String) ) | 109 return null; |
79 throw new LuanException("sub_options keys must be strings"); | 110 Object rtn = fnOptions.call(luan,stack); |
80 */ | 111 if( !(rtn==null || rtn instanceof LuanTable) ) |
81 if( !(entry.getValue() instanceof LuanTable) ) | 112 throw new LuanException("options-function must return table or nil"); |
82 throw new LuanException("sub_options keys must be tables"); | 113 return (LuanTable)rtn; |
83 LuanTable tbl = (LuanTable)entry.getValue(); | |
84 checkOptions(tbl); | |
85 } | |
86 } | |
87 } | 114 } |
88 | 115 |
89 public String toString(Object obj) throws LuanException { | 116 public String toString(Object obj) throws LuanException { |
90 StringBuilder sb = new StringBuilder(); | 117 StringBuilder sb = new StringBuilder(); |
91 toString(obj,sb,0,settingsInit); | 118 toString(obj,sb,0,settingsInit); |
210 } | 237 } |
211 sb.append( '}' ); | 238 sb.append( '}' ); |
212 return; | 239 return; |
213 } | 240 } |
214 | 241 |
215 private void toString(Map.Entry entry,StringBuilder sb,int indented,Settings settings) throws LuanException { | 242 private void toString(Map.Entry entry,StringBuilder sb,int indented,Settings settings) |
243 throws LuanException | |
244 { | |
216 Object key = entry.getKey(); | 245 Object key = entry.getKey(); |
217 if( key instanceof String && ((String)key).matches("[a-zA-Z_][a-zA-Z_0-9]*") ) { | 246 if( key instanceof String && !settings.noNameKeys && ((String)key).matches("[a-zA-Z_][a-zA-Z_0-9]*") ) { |
218 sb.append( (String)key ); | 247 sb.append( (String)key ); |
219 } else { | 248 } else { |
220 sb.append( '[' ); | 249 sb.append( '[' ); |
221 toString( key, sb, indented, keySettings ); | 250 toString( key, sb, indented, keySettings ); |
222 sb.append( ']' ); | 251 sb.append( ']' ); |
223 } | 252 } |
224 sb.append( settings.compressed ? "=" : " = " ); | 253 sb.append( settings.compressed ? "=" : " = " ); |
225 if( subOptions != null ) { | 254 stack.rawAdd(key); // push |
226 LuanTable options = (LuanTable)subOptions.rawGet(key); | 255 LuanTable options = getOptions(); |
227 if( options != null ) { | 256 if( options != null ) { |
228 settings = settings.cloneSettings(); | 257 settings = settings.cloneSettings(); |
229 settings.applyOptions(options); | 258 settings.applyOptions(options); |
230 } | |
231 } | 259 } |
232 toString( entry.getValue(), sb, indented, settings ); | 260 toString( entry.getValue(), sb, indented, settings ); |
261 stack.removeFromList(stack.rawLength()); // pop | |
233 } | 262 } |
234 | 263 |
235 private void indent(StringBuilder sb,int indented) { | 264 private void indent(StringBuilder sb,int indented) { |
236 sb.append( '\n' ); | 265 sb.append( '\n' ); |
237 for( int i=0; i<indented; i++ ) { | 266 for( int i=0; i<indented; i++ ) { |