1 /* $Author: hansonr $ 2 * $Date: 2007-09-09 21:37:07 -0500 (Sun, 09 Sep 2007) $ 3 * $Revision: 8231 $ 4 * 5 * Copyright (C) 2002-2005 The Jmol Development Team 6 * 7 * Contact: jmol-developers@lists.sf.net 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 */ 23 24 package org.jmol.script; 25 26 import javajs.util.AU; 27 import javajs.util.Lst; 28 import javajs.util.SB; 29 30 import java.util.Hashtable; 31 32 import java.util.Map; 33 34 import org.jmol.api.JmolScriptFunction; 35 36 public class ScriptFunction implements JmolScriptFunction { 37 38 // / functions 39 40 /** 41 * functions are either local or global (static). The idea there is that a set 42 * of applets might share a set of functions. The default is global; prefix 43 * underscore makes them local. 44 * 45 * functions have contexts. Or, more specifically, contexts may have associated 46 * functions. 47 * 48 * Bob Hanson -- 11.3.29 49 * 50 * includes parallel, catch 51 * 52 */ 53 54 int pt0; 55 int chpt0; 56 int cmdpt0 = -1; 57 protected String typeName; 58 String name; 59 int nParameters; 60 Lst<String> names = new Lst<String>(); 61 int tok; 62 63 Map<String, String> variables = new Hashtable<String, String>(); isVariable(String ident)64 boolean isVariable(String ident) { 65 return variables.containsKey(ident); 66 } 67 68 SV returnValue; 69 T[][] aatoken; 70 int[][] lineIndices; 71 short[] lineNumbers; 72 String script; 73 74 boolean isPrivate; 75 ScriptFunction()76 public ScriptFunction() { 77 // for reflection with ScriptParallelProcessor 78 } 79 ScriptFunction(String name, int tok)80 protected ScriptFunction(String name, int tok) { 81 set(name, tok); 82 typeName = T.nameOf(tok); 83 } 84 set(String name, int tok)85 public void set(String name, int tok) { 86 this.name = name; 87 this.tok = tok; 88 } 89 setVariables(Map<String, SV> contextVariables, Lst<SV> params)90 void setVariables(Map<String, SV> contextVariables, Lst<SV> params) { 91 int nParams = (params == null ? 0 : params.size()); 92 for (int i = names.size(); --i >= 0;) { 93 String name = names.get(i).toLowerCase(); 94 SV var = (i < nParameters && i < nParams ? params.get(i) : null); 95 if (var != null && var.tok != T.varray) // TODO: list type? 96 var = SV.newT(var); 97 contextVariables.put(name, (var == null ? 98 SV.newS("").setName(name) : var)); 99 } 100 if (tok != T.trycmd) { 101 contextVariables.put("_argcount", SV.newI(params == null ? 0 : params.size())); 102 contextVariables.put( 103 "_arguments", 104 (params == null ? SV.getVariableAI(new int[] {}) : SV 105 .getVariableList(params))); 106 107 } 108 109 contextVariables.put("_retval", SV.newI(tok == T.trycmd ? Integer.MAX_VALUE : 0)); 110 } 111 unsetVariables(Map<String, SV> contextVariables, Lst<SV> params)112 void unsetVariables(Map<String, SV> contextVariables, Lst<SV> params) { 113 // note: this method is never called. 114 // set list values in case they have changed. 115 int nParams = (params == null ? 0 : params.size()); 116 int nNames = names.size(); 117 if (nParams == 0 || nNames == 0) 118 return; 119 for (int i = 0; i < nNames && i < nParams; i++) { 120 SV global = params.get(i); 121 if (global.tok != T.varray) // TODO: list type? 122 continue; 123 SV local = contextVariables.get(names.get(i).toLowerCase()); 124 if (local.tok != T.varray) // TODO: list type? 125 continue; 126 global.value = local.value; 127 } 128 } 129 addVariable(String name, boolean isParameter)130 void addVariable(String name, boolean isParameter) { 131 variables.put(name, name); 132 names.addLast(name); 133 if (isParameter) 134 nParameters++; 135 } 136 setFunction(ScriptFunction function, String script, int ichCurrentCommand, int pt, short[] lineNumbers, int[][] lineIndices, Lst<T[]> lltoken)137 static void setFunction(ScriptFunction function, String script, 138 int ichCurrentCommand, int pt, short[] lineNumbers, 139 int[][] lineIndices, Lst<T[]> lltoken) { 140 int cmdpt0 = function.cmdpt0; 141 int chpt0 = function.chpt0; 142 int nCommands = pt - cmdpt0; 143 function.setScript(script.substring(chpt0, ichCurrentCommand)); 144 T[][] aatoken = function.aatoken = new T[nCommands][]; 145 function.lineIndices = AU.newInt2(nCommands); 146 function.lineNumbers = new short[nCommands]; 147 short line0 = (short) (lineNumbers[cmdpt0] - 1); 148 for (int i = 0; i < nCommands; i++) { 149 function.lineNumbers[i] = (short) (lineNumbers[cmdpt0 + i] - line0); 150 function.lineIndices[i] = new int[] {lineIndices[cmdpt0 + i][0] - chpt0, lineIndices[cmdpt0 + i][1] - chpt0 }; 151 //System.out.println("Line " + i + ": " + function.script.substring(function.lineIndices[i][0], function.lineIndices[i][1])); 152 aatoken[i] = lltoken.get(cmdpt0 + i); 153 // adjust intValues, which are pointers into the command stack, 154 // by the 0-point offset of the command pointer 155 // negative less negative;positive less positive 156 if (aatoken[i].length > 0) { 157 T tokenCommand = aatoken[i][0]; 158 if (T.tokAttr(tokenCommand.tok, T.flowCommand)) 159 tokenCommand.intValue -= (tokenCommand.intValue < 0 ? -cmdpt0 160 : cmdpt0); 161 } 162 } 163 for (int i = pt; --i >= cmdpt0;) { 164 lltoken.removeItemAt(i); 165 lineIndices[i][0] = lineIndices[i][1] = 0; 166 } 167 } 168 setScript(String s)169 private void setScript(String s) { 170 script = s; 171 if (script != null && script != "" && !script.endsWith("\n")) 172 script += "\n"; 173 } 174 175 @Override toString()176 public String toString() { 177 SB s = new SB().append("/*\n * ").append(name) 178 .append("\n */\n").append(getSignature()).append(" {\n"); 179 if (script != null) 180 s.append(script); 181 s.append("}\n"); 182 return s.toString(); 183 } 184 185 @Override getSignature()186 public String getSignature() { 187 if (typeName == null) 188 return T.nameOf(tok); 189 SB s = new SB().append(typeName) 190 .append(" ").append(name).append("("); 191 for (int i = 0; i < nParameters; i++) { 192 if (i > 0) 193 s.append(", "); 194 s.append(names.get(i)); 195 } 196 s.append(")"); 197 return s.toString(); 198 } 199 200 @Override geTokens()201 public Object geTokens() { 202 return aatoken; 203 } 204 205 @Override getName()206 public String getName() { 207 return name; 208 } 209 210 @Override getTok()211 public int getTok() { 212 return tok; 213 } 214 } 215