Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
// Copyright (c) 2013-2014, Webit Team. All Rights Reserved.
package webit.script.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import webit.script.Engine;
import webit.script.exceptions.ParseException;
import webit.script.global.GlobalManager;
import webit.script.util.Stack;
import webit.script.util.StringUtil;
/**
*
* @author Zqq
*/
public class VariantManager {
private int varCount;
private final Stack stairStack;
private final List stairs;
private final VarStair root;
private final GlobalManager globalManager;
VariantManager(Engine engine) {
this.globalManager = engine.getGlobalManager();
this.stairs = new ArrayList();
this.stairStack = new Stack();
this.root = push(-1);
this.root.assignVarsIfAbsent(engine.getVars());
}
private VarStair push(int parentId) {
final VarStair stair = new VarStair(this.stairs.size(), parentId);
this.stairs.add(stair);
this.stairStack.push(stair);
return stair;
}
public void push() {
push(stairStack.peek().id);
}
public int getVarCount() {
return varCount;
}
public int pop() {
return stairStack.pop().id;
}
public VariantIndexer[] getIndexers() {
final List varStairs = this.stairs;
final int size = varStairs.size();
final VariantIndexer[] result = new VariantIndexer[size];
for (int i = 0; i < size; i++) {
VarStair stair = varStairs.get(i);
//assert i == stair.id
//remove consts
final Map indexerMap = stair.values;
if (stair.constMap != null) {
for (String key : stair.constMap.keySet()) {
indexerMap.remove(key);
}
}
result[i] = getVariantIndexer(i, stair.parentId >= 0 ? result[stair.parentId] : null, indexerMap);
}
return result;
}
public int assignVariant(String name, int line, int column) {
return stairStack.peek().assignVar(name, line, column);
}
public void assignConst(String name, Object value, int line, int column) {
stairStack.peek().assignConst(name, value, line, column);
}
public VarAddress locateAtUpstair(String name, int upstair, int line, int column) {
VarAddress address = stairStack.peek(upstair).locate(name);
if (address != null) {
return address;
}
throw new ParseException("Can't locate vars: ".concat(name), line, column);
}
public VarAddress locate(String name, int fromUpstair, boolean force, int line, int column) {
//local var/const
for (; fromUpstair < stairStack.size(); fromUpstair++) {
VarAddress address = stairStack.peek(fromUpstair).locate(name);
if (address != null) {
return address;
}
}
//global var/const
final GlobalManager globalMgr = this.globalManager;
final int index = globalMgr.getGlobalIndex(name);
if (index >= 0) {
return global(index);
}
if (globalMgr.hasConst(name)) {
return constValue(globalMgr.getConst(name));
}
//failed
if (force) {
throw new ParseException("Can't locate vars: ".concat(name), line, column);
}
//assign at root
return context(root.assignVar(name, line, column));
}
private static VariantIndexer getVariantIndexer(final int id, final VariantIndexer parent, final Map map) {
if (map.isEmpty()) {
if (parent != null) {
return parent;
}
return new VariantIndexer(id, null, StringUtil.EMPTY_ARRAY, null);
}
final int size = map.size();
final String[] names = new String[size];
final int[] indexs = new int[size];
int i = 0;
for (Map.Entry entry : map.entrySet()) {
names[i] = entry.getKey();
indexs[i] = entry.getValue();
i++;
}
return new VariantIndexer(id, parent, names, indexs);
}
static VarAddress context(int index) {
return new VarAddress(VarAddress.CONTEXT, index, null);
}
static VarAddress global(int index) {
return new VarAddress(VarAddress.GLOBAL, index, null);
}
static VarAddress constValue(Object value) {
return new VarAddress(VarAddress.CONST, -1, value);
}
private class VarStair {
final int id;
final int parentId;
final Map values;
Map constMap;
VarStair(int id, int parentId) {
this.id = id;
this.parentId = parentId;
this.values = new HashMap();
}
VarAddress locate(String name) {
Integer index = this.values.get(name);
if (index == null) {
return null;
}
if (index < 0) {
return constValue(this.constMap.get(name));
}
return context(index);
}
void checkDuplicate(final String name, int line, int column) {
if (this.values.containsKey(name)) {
throw new ParseException("Duplicate Variant declare: ".concat(name), line, column);
}
}
Integer assignVar(final String name, int line, int column) {
checkDuplicate(name, line, column);
//XXX: rewrite
int index = VariantManager.this.varCount++;
this.values.put(name, index);
return index;
}
void assignConst(final String name, final Object value, int line, int column) {
checkDuplicate(name, line, column);
if (this.constMap == null) {
this.constMap = new HashMap();
}
this.values.put(name, -1);
this.constMap.put(name, value);
}
void assignVarsIfAbsent(String[] vars) {
if (vars == null) {
return;
}
for (String var : vars) {
if (!this.values.containsKey(var)) {
assignVar(var, -1, -1);
}
}
}
}
public static class VarAddress {
public static final int CONTEXT = 0;
public static final int GLOBAL = 1;
public static final int CONST = 2;
public final int type;
public final int index;
public final Object constValue;
VarAddress(int type, int index, Object constValue) {
this.type = type;
this.index = index;
this.constValue = constValue;
}
}
}