View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi-jtrolog
4    * %%
5    * Copyright (C) 2012 - 2018 WorkLogic Project
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as
9    * published by the Free Software Foundation, either version 2.1 of the
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
20   * #L%
21   */
22  package jTrolog.engine;
23  
24  import jTrolog.terms.Int;
25  import jTrolog.terms.Struct;
26  import jTrolog.terms.StructAtom;
27  import jTrolog.terms.Term;
28  
29  import java.util.*;
30  
31  /**
32   * Map of Prolog operators. A LinkedHashMap is set up to store each registered
33   * operator as: 'name type' = priority
34   * 
35   * @author ivar.orstavik@hist.no
36   */
37  @SuppressWarnings({ "rawtypes", "unchecked","serial" })
38  class OperatorTable implements java.io.Serializable {
39  
40  	/** current known operators */
41  	private HashMap[] operatorMap = new HashMap[] { new LinkedHashMap(), new LinkedHashMap(), new LinkedHashMap(), new LinkedHashMap(), new LinkedHashMap(), new LinkedHashMap(), new LinkedHashMap() };
42  
43  	/**
44  	 * Creates a new operator. If the operator is already provided, it replaces
45  	 * it with the new one
46  	 */
47  	protected void addOperator(String name, int type, int prio) {
48  		if (prio >= Prolog.OP_LOW && prio <= Prolog.OP_HIGH)
49  			operatorMap[type].put(name, new Integer(prio));
50  	}
51  
52  	/**
53  	 * @return the priority of an operator (0 if the operator is not defined).
54  	 */
55  	int getOperatorPriority(String name, int type) {
56  		Integer prio = (Integer) operatorMap[type].get(name);
57  		return (prio == null) ? 0 : prio.intValue();
58  	}
59  
60  	/**
61  	 * @return a list of Struct Objects representing the operators currently
62  	 *         defined, ordered by insertionOrder
63  	 */
64  	Iterator getAllOperators() {
65  		return new OperatorIterator(operatorMap);
66  	}
67  
68  	private static class OperatorIterator implements Iterator {
69  		Iterator underlyingIT;
70  		Map[] underlyingMap;
71  		int pos = 0;
72  
73  		public OperatorIterator(Map[] map) {
74  			this.underlyingIT = map[pos].keySet().iterator();
75  			this.underlyingMap = map;
76  		}
77  
78  		public boolean hasNext() {
79  			boolean b = underlyingIT.hasNext();
80  			if (b)
81  				return true;
82  			pos++;
83  			if (pos < underlyingMap.length) {
84  				underlyingIT = underlyingMap[pos].keySet().iterator();
85  				return hasNext();
86  			}
87  			return false;
88  		}
89  
90  		public Object next() {
91  			if (!hasNext())
92  				throw new RuntimeException("check hasNext before calling next on OperatorIterator.");
93  			String name = (String) underlyingIT.next();
94  			int prio = ((Integer) underlyingMap[pos].get(name)).intValue();
95  			String type;
96  			switch (pos) {
97  			case Prolog.FX:
98  				type = "fx";
99  				break;
100 			case Prolog.FY:
101 				type = "fy";
102 				break;
103 			case Prolog.XFX:
104 				type = "xfx";
105 				break;
106 			case Prolog.YFX:
107 				type = "yfx";
108 				break;
109 			case Prolog.XFY:
110 				type = "xfy";
111 				break;
112 			case Prolog.XF:
113 				type = "xf";
114 				break;
115 			default:
116 				type = "yf";
117 			}
118 			return new Struct("op", new Term[] { new Int(prio), new StructAtom(type), new StructAtom(name) });
119 		}
120 
121 		public void remove() {
122 			throw new UnsupportedOperationException("can't delete on the operator iterator");
123 		}
124 	}
125 
126 }