PageRenderTime 22ms CodeModel.GetById 7ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/interpreter/tags/at2dist220411/src/edu/vub/at/objects/natives/NATField.java

http://ambienttalk.googlecode.com/
Java | 184 lines | 120 code | 20 blank | 44 comment | 6 complexity | a12201386adc0ab79bd25b0a86cc46bf MD5 | raw file
  1/**
  2 * AmbientTalk/2 Project
  3 * NATField.java created on Jul 27, 2006 at 2:27:53 AM
  4 * (c) Programming Technology Lab, 2006 - 2007
  5 * Authors: Tom Van Cutsem & Stijn Mostinckx
  6 * 
  7 * Permission is hereby granted, free of charge, to any person
  8 * obtaining a copy of this software and associated documentation
  9 * files (the "Software"), to deal in the Software without
 10 * restriction, including without limitation the rights to use,
 11 * copy, modify, merge, publish, distribute, sublicense, and/or
 12 * sell copies of the Software, and to permit persons to whom the
 13 * Software is furnished to do so, subject to the following
 14 * conditions:
 15 *
 16 * The above copyright notice and this permission notice shall be
 17 * included in all copies or substantial portions of the Software.
 18 *
 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 21 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 22 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 23 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 24 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 26 * OTHER DEALINGS IN THE SOFTWARE.
 27 */
 28package edu.vub.at.objects.natives;
 29
 30import java.util.HashMap;
 31
 32import edu.vub.at.eval.Evaluator;
 33import edu.vub.at.exceptions.InterpreterException;
 34import edu.vub.at.exceptions.XIllegalOperation;
 35import edu.vub.at.exceptions.XSelectorNotFound;
 36import edu.vub.at.exceptions.XTypeMismatch;
 37import edu.vub.at.objects.ATContext;
 38import edu.vub.at.objects.ATField;
 39import edu.vub.at.objects.ATMethod;
 40import edu.vub.at.objects.ATObject;
 41import edu.vub.at.objects.ATTable;
 42import edu.vub.at.objects.coercion.NativeTypeTags;
 43import edu.vub.at.objects.grammar.ATSymbol;
 44import edu.vub.at.objects.mirrors.PrimitiveMethod;
 45import edu.vub.at.objects.natives.grammar.AGSymbol;
 46import edu.vub.util.TempFieldGenerator;
 47
 48/**
 49 * NATField implements a causally connected field of an object. Rather than storing
 50 * these fields directly in every object, we choose to only make people pay when they
 51 * choose to reify them. 
 52 * 
 53 * @author smostinc, tvcutsem
 54 */
 55public class NATField extends NATByRef implements ATField {
 56
 57	private final ATSymbol name_;
 58	private final ATObject host_;
 59	
 60	/**
 61	 * Constructs a new native field object linked to the field of a base-level
 62	 * AmbientTalk object
 63	 */
 64	public NATField(ATSymbol name, ATObject host) {
 65		name_ = name;
 66		host_ = host;
 67	}
 68
 69	public ATSymbol base_name() {
 70		return name_;
 71	}
 72
 73	public ATObject base_readField() throws InterpreterException {
 74		return host_.meta_invokeField(host_, name_);
 75	}
 76
 77	public ATObject base_writeField(ATObject newValue) throws InterpreterException {
 78		return host_.impl_invoke(host_, name_.asAssignmentSymbol(), NATTable.of(newValue));
 79	}
 80	
 81	public NATText meta_print() throws InterpreterException {
 82		return NATText.atValue("<field:"+name_.meta_print().javaValue+">");
 83	}
 84	
 85	public NATText impl_asCode(TempFieldGenerator objectMap) throws InterpreterException {
 86		return this.impl_asCode(objectMap, false);
 87	}
 88	
 89	public NATText impl_asCode(TempFieldGenerator objectMap, boolean isIsolate) throws InterpreterException {
 90		if(objectMap.contains(this)) {
 91			return objectMap.getName(this);
 92		}
 93		String def = "";
 94		String nameAsCode = name_.meta_print().javaValue;
 95		if(nameAsCode != "super")
 96			def += "def ";
 97		//if(isIsolate) // why was this necessary?
 98		//	def += "self.";
 99		return NATText.atValue(def + nameAsCode + " := " + base_readField().impl_asCode(objectMap).javaValue);
100	}
101	
102    public boolean isNativeField() {
103        return true;
104    }
105
106	public ATField asField() throws XTypeMismatch {
107		return this;
108	}
109	
110	/**
111	 * Fields can be re-initialized when installed in an object that is being cloned.
112	 * They expect the new owner of the field as the sole instance to their 'new' method
113	 */
114	public ATObject meta_newInstance(ATTable initargs) throws InterpreterException {
115		if (initargs.base_length() != NATNumber.ONE) {
116			return super.meta_newInstance(initargs);
117		} else {
118			ATObject newhost = initargs.base_at(NATNumber.ONE);
119			return new NATField(name_, (NATCallframe) newhost);
120		}
121	}
122	
123    public ATTable meta_typeTags() throws InterpreterException {
124    	return NATTable.of(NativeTypeTags._FIELD_);
125    }
126    
127    public ATMethod base_accessor() throws InterpreterException {
128    	return accessorForField(this);
129    }
130    
131    public ATMethod base_mutator() throws InterpreterException {
132    	return mutatorForField(this);
133    }
134    
135    public static ATMethod accessorForField(final ATField f) throws InterpreterException {
136    	return new PrimitiveMethod(f.base_name(), NATTable.EMPTY, new PrimitiveMethod.PrimitiveBody() {
137    		public ATObject meta_eval(ATContext ctx) throws InterpreterException {
138    			return f.base_readField();
139    		}
140    		public NATText meta_print() throws InterpreterException {
141    			return NATText.atValue(f.base_readField().toString());
142    		}
143    		public NATText impl_asCode(TempFieldGenerator objectMap) throws InterpreterException {
144    			return f.base_readField().impl_asCode(objectMap);
145    		}
146    	}) {
147    		public NATText meta_print() throws InterpreterException {
148    			return NATText.atValue("<accessor method for:"+f.base_name()+">");
149    		}
150    		public NATText impl_asCode(TempFieldGenerator objectMap) throws InterpreterException {
151    			return NATText.atValue("def "
152    					+ f.base_name().impl_asCode(objectMap).javaValue 
153    					+ "(){"+f.base_name().impl_asCode(objectMap).javaValue
154    					+ "}");
155    		}
156    	};
157    }
158    
159    public static ATMethod mutatorForField(final ATField f) throws InterpreterException {
160    	return new PrimitiveMethod(f.base_name().asAssignmentSymbol(), NATTable.of(AGSymbol.jAlloc("v")), new PrimitiveMethod.PrimitiveBody() {
161    		public ATObject meta_eval(ATContext ctx) throws InterpreterException {
162    			return f.base_writeField(ctx.base_lexicalScope().impl_callField(AGSymbol.jAlloc("v")));
163    		}
164    		public NATText meta_print() throws InterpreterException {
165    			return NATText.atValue(""+f.base_name()+" := v");
166    		}
167    		public NATText impl_asCode(TempFieldGenerator objectMap) throws InterpreterException {
168    			return NATText.atValue(""+f.base_name()+" := v");
169    		}
170    	}) {
171    		public NATText meta_print() throws InterpreterException {
172    			return NATText.atValue("<mutator method for:"+f.base_name()+">");
173    		}
174    		public NATText impl_asCode(TempFieldGenerator objectMap) throws InterpreterException {
175    			return NATText.atValue("def "
176    					+ f.base_name().impl_asCode(objectMap).javaValue
177    					+ ".:=(v){"
178    					+ f.base_name().impl_asCode(objectMap).javaValue
179    					+ ":=v}");
180    		}
181    	};
182    }
183
184}