/interpreter/tags/at2dist041108/src/edu/vub/at/objects/natives/grammar/AGImport.java
Java | 172 lines | 88 code | 21 blank | 63 comment | 13 complexity | f1984d65afa3a5e7f616bb3186cd6d5c MD5 | raw file
1/** 2 * AmbientTalk/2 Project 3 * AGImport.java created on 6-mrt-2007 at 21:34:54 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.grammar; 29 30import edu.vub.at.eval.Evaluator; 31import edu.vub.at.eval.Import; 32import edu.vub.at.exceptions.InterpreterException; 33import edu.vub.at.exceptions.XIllegalArgument; 34import edu.vub.at.objects.ATContext; 35import edu.vub.at.objects.ATObject; 36import edu.vub.at.objects.grammar.ATExpression; 37import edu.vub.at.objects.grammar.ATImport; 38import edu.vub.at.objects.natives.NATTable; 39import edu.vub.at.objects.natives.NATText; 40 41import java.util.HashSet; 42import java.util.Hashtable; 43import java.util.Set; 44 45/** 46 * The public interface to a native import AST component, which is of the form: 47 * 'import <expression> (alias (symbol := symbol)+ )? (exclude symbol (, symbol)* )?' 48 * 49 * @see edu.vub.at.objects.grammar.ATImport 50 * 51 * @author tvcutsem 52 */ 53public class AGImport extends NATAbstractGrammar implements ATImport { 54 55 private final ATExpression importedObjectExp_; 56 57 private final ATExpression aliasDeclarations_; 58 59 private final ATExpression excludesDeclarations_; 60 61 /** 62 * For efficiency purposes, the table form of the alias mapping is preprocessed 63 * into a hashtable format. 64 */ 65 private Hashtable aliasedSymbols_; // maps ATSymbols to ATSymbols 66 67 /** 68 * For efficiency purposes, the table form of the excluded symbols is preprocessed 69 * into a hashset format. 70 */ 71 private HashSet excludedSymbols_; // contains ATSymbols 72 73 /** create a new import statement. The alias and excludes declaration tables may still contain quoted expressions */ 74 public AGImport(ATExpression importedObjectExp, ATExpression aliasDeclarations, ATExpression excludesDeclarations) { 75 importedObjectExp_ = importedObjectExp; 76 aliasDeclarations_ = aliasDeclarations; 77 excludesDeclarations_ = excludesDeclarations; 78 // cannot already preprocess the import statement here, as it may contain 79 // unquotes which need to be evaluated to symbols first 80 } 81 82 public ATExpression base_aliasedSymbols() throws InterpreterException { 83 return aliasDeclarations_; 84 } 85 86 public ATExpression base_excludedSymbols() throws InterpreterException { 87 return excludesDeclarations_; 88 } 89 90 public ATExpression base_importedObjectExpression() throws InterpreterException { 91 return importedObjectExp_; 92 } 93 94 /** 95 * AGIMPORT(exp,aliases,excludes).eval(ctx) = 96 * import(exp.eval(ctx), ctx, preprocess(aliases), preprocess(excludes)) ; 97 * NIL 98 */ 99 public ATObject meta_eval(ATContext ctx) throws InterpreterException { 100 if (aliasedSymbols_ == null) { 101 aliasedSymbols_ = Import.preprocessAliases(aliasDeclarations_.asTable()); 102 excludedSymbols_ = Import.preprocessExcludes(excludesDeclarations_.asTable()); 103 } 104 return Import.performImport(importedObjectExp_.meta_eval(ctx), ctx, aliasedSymbols_, excludedSymbols_); 105 } 106 107 /** 108 * Quoting an import statement results in a new quoted import statement. 109 * 110 * AGIMPORT(exp,aliases,excludes).quote(ctx) = AGIMPORT(exp.quote(ctx), aliases.quote(ctx), excludes.quote(ctx)) 111 */ 112 public ATObject meta_quote(ATContext ctx) throws InterpreterException { 113 return new AGImport(importedObjectExp_.meta_quote(ctx).asExpression(), 114 aliasDeclarations_.meta_quote(ctx).asExpression(), 115 excludesDeclarations_.meta_quote(ctx).asExpression()); 116 } 117 118 public NATText meta_print() throws InterpreterException { 119 StringBuffer expression = new StringBuffer("import " + importedObjectExp_.meta_print().javaValue); 120 if (aliasDeclarations_ != NATTable.EMPTY) { 121 expression.append(" alias "); 122 if (aliasDeclarations_.isTable()) { 123 ATObject[] aliases = aliasDeclarations_.asNativeTable().elements_; 124 // append first alias 125 printAliasBinding(expression, aliases[0].asNativeTable()); 126 for (int i = 1; i < aliases.length; i++) { 127 // append rest of the aliases 128 expression.append(","); 129 printAliasBinding(expression, aliases[i].asNativeTable()); 130 } 131 } else { 132 // list of aliases is a quatation 133 expression.append(aliasDeclarations_.meta_print().javaValue); 134 } 135 } 136 if (excludesDeclarations_ != NATTable.EMPTY) { 137 expression.append(" exclude "); 138 if (excludesDeclarations_.isTable()) { 139 expression.append(Evaluator.printElements(excludesDeclarations_.asNativeTable().elements_, "", ",", "").javaValue); 140 } else { 141 // list of excluded symbols is a quotation 142 expression.append(excludesDeclarations_.meta_print().javaValue); 143 } 144 } 145 146 return NATText.atValue(expression.toString()); 147 } 148 149 private void printAliasBinding(StringBuffer buff, NATTable aliasBinding) throws InterpreterException { 150 ATObject[] binding = aliasBinding.elements_; 151 if (binding.length != 2) { 152 throw new XIllegalArgument("Alias binding of import statement is not a table of size two: " + aliasBinding.meta_print().javaValue); 153 } 154 buff.append(binding[0].meta_print().javaValue).append(" := ").append(binding[1].meta_print().javaValue); 155 } 156 157 /** 158 * FV(import objExp alias nam1 := nam2 exclude nam3) = FV(objExp) 159 */ 160 public Set impl_freeVariables() throws InterpreterException { 161 return importedObjectExp_.impl_freeVariables(); 162 } 163 164 165 public Set impl_quotedFreeVariables() throws InterpreterException { 166 Set qfv = importedObjectExp_.impl_quotedFreeVariables(); 167 qfv.addAll(aliasDeclarations_.impl_quotedFreeVariables()); 168 qfv.addAll(excludesDeclarations_.impl_quotedFreeVariables()); 169 return qfv; 170 } 171 172}