public synchronized void add(ScopeSymbol symbol) { if (symbol.isFunction()) { // Create hash? if (functions == null) functions = new AutoHashMap<String, List<ScopeSymbol>>(new LinkedList<ScopeSymbol>()); // Add function by name functions.getOrCreate(symbol.getName()).add(symbol); } else symbols.put(symbol.getName(), symbol); }
/** Find a function that matches a function call */ public ScopeSymbol findFunction(String functionName, Args args) { // Retrieve all functions with the same name List<ScopeSymbol> ssfuncs = getFunctions(functionName); // Find best matching function... ScopeSymbol bestSsfunc = null; int bestScore = Integer.MAX_VALUE; for (ScopeSymbol ssfunc : ssfuncs) { boolean ok = false; int score = 0; TypeFunc sstype = (TypeFunc) ssfunc.getType(); // Find the ones with the same number of parameters int argc = args.size(); if (argc == sstype.getParameters().size()) { ok = true; // Find the ones with matching exact parameters for (int i = 0; i < args.size(); i++) { Type argType = args.getArguments()[i].getReturnType(); Type funcType = sstype.getParameters().getType(i); // Same argument? if ((argType != null) && !argType.equals(funcType)) { // Can we cast? if (argType.canCast(funcType)) score++; // Add a point if we can cast else ok = false; } } } // Found anything? if (ok) { // Perfect match? Don't look any further if (score == 0) return ssfunc; // Get the one with less argument casts if (score < bestScore) { bestScore = score; bestSsfunc = ssfunc; } } } return bestSsfunc; }
@Override public String serializeSave(BdsSerializer serializer) { StringBuilder out = new StringBuilder(); out.append("Scope"); out.append("\t" + serializer.serializeSaveValue(id)); out.append("\t" + serializer.serializeSaveValue(parent != null ? parent.getNodeId() : "")); out.append("\t" + serializer.serializeSaveValue(node)); out.append("\n"); for (ScopeSymbol ss : symbols.values()) { if (ss.getType().isNative()) {; // Do not save native functions } else out.append(serializer.serializeSave(ss)); } if (parent != null) out.append(serializer.serializeSave(parent)); return out.toString(); }