1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.millscript.millscript.functions;
23
24 import org.millscript.commons.util.EMap;
25 import org.millscript.commons.util.IList;
26 import org.millscript.commons.util.IMap;
27 import org.millscript.commons.util.ListIterator;
28 import org.millscript.commons.util.Maplet;
29 import org.millscript.millscript.alert.Alerts;
30 import org.millscript.millscript.vm.Machine;
31
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35
36 /**
37 * This is the base class of all map construction functions.
38 */
39 abstract class MapFunction extends Function {
40
41 /**
42 * @see org.millscript.millscript.functions.Function#apply(org.millscript.millscript.vm.Machine, int)
43 */
44 @Override
45 public void apply( final Machine mc, final int nargs ) {
46 EMap map = newEmptyMap();
47 initialize( mc, nargs, map );
48 mc.pushObject( map );
49 }
50
51 /**
52 * Initialises the specified map with the specified number of arguments
53 * from the machine.
54 *
55 * @param mc the machine to get arguments from
56 * @param nargs the number of arguments available
57 * @param map the map to populate with the arguments
58 */
59 @SuppressWarnings( "unchecked" )
60 private static void initialize( final Machine mc, final int nargs, final EMap map ) {
61 if ( nargs >= 1 ) {
62 Object obj = mc.popObject();
63
64
65 initialize( mc, nargs - 1, map );
66
67 if ( obj instanceof IList ) {
68 ListIterator it = ((IList) obj).iterator( true );
69 while ( it.hasNext() ) {
70 map.insert( it.nextValue(), it.nextValue() );
71 }
72 } else if ( obj instanceof IMap ) {
73 map.insertAll( (IMap) obj );
74 } else if ( obj instanceof Map ) {
75 Iterator it = ((Map) obj).entrySet().iterator();
76 while ( it.hasNext() ) {
77 Map.Entry maplet = (Map.Entry) it.next();
78 map.insert( maplet.getKey(), maplet.getValue() );
79 }
80 } else if ( obj instanceof Maplet ) {
81 map.insert( (Maplet) obj );
82 } else if ( obj instanceof Map.Entry ) {
83 Map.Entry maplet = (Map.Entry) obj;
84 map.insert( maplet.getKey(), maplet.getValue() );
85 } else if ( obj instanceof List ) {
86 Iterator it = ((List) obj).iterator();
87 while ( it.hasNext() ) {
88 map.insert( it.next(), it.next() );
89 }
90 } else {
91 throw(
92 Alerts.eval(
93 "Invalid initial value for Map construction",
94 "Only Maps, Maplets or Lists allowed"
95 ).culprit( "object", obj ).mishap()
96 );
97 }
98 }
99 }
100
101 /**
102 * Returns the new empty mutable map for this function.
103 *
104 * @return a new empty mutable Map
105 */
106 public abstract EMap newEmptyMap();
107
108 }