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