/* BASIC Interpreter 
 *      for ttps://www.shroudoftheavatar.com/?p=39149#more-39149
 *          ttps://d2sx9mrt4zumaq.cloudfront.net/wp-content/uploads/2014/04/DND1_Complete.pdf
 *
 * Version 0.4a (未完成公開)
 *
 * 実装履歴
 *   2014-04-30 v0.1a (作業時間:約6時間)
 *      ・コマンドライン入力文のトークン分解
 *      ・プログラムリストの入力
 *      ・プログラムリストの出力(LIST)
 *      ・プログラムリストの開始(RUN)
 *      ・ジャンプ系の仮実装(GOTO,GOSUB,RETURN)
 *      ・配列添字の最小値設定の仮実装(BASE)
 *   2014-05-01 v0.2a (作業時間:約0.5時間)
 *      ・プログラムリストの出力の修正(LIST)
 *   2014-05-04 v0.3a (作業時間:約8時間)
 *      ・式の計算(演算子等,但し配列変数を除く)
 *      ・値の出力(PRINT)
 *      ・変数への代入(LET,但し配列変数を除く)
 *      ・関数(INT,ABS,RND,CLK,(VAL))
 *   2014-05-05 v0.4a (作業時間:約5時間)
 *      ・配列変数の操作(DIM,LET,式の計算)
 */
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.regex.*;

class Basic
{
	static final int major = 0;
	static final int minor = 4;
	static final char release = 'a';
	
	public static void main (String[] args) throws java.lang.Exception
	{
		System.out.printf("BASIC Interpreter - Version %d.%d%c", major, minor, release);
		System.out.println();
		System.out.println("Your code goes here!");
		System.out.println();
		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
			Excutor excutor = new Excutor();
			String line;
			while ((line = in.readLine()) != null) {
				try {
					List<Token> tokens = Tokenizer.tokenize(line);
					if (excutor.doEditorCommand(tokens) < 0) {
						break;
					}
				} catch (SyntaxError er) {
					System.out.println(er);
				}
			}
//			System.out.println(excutor);
		} catch (Exception ex) {
			System.out.println(ex);
		}
		
	}
}

final class Debug
{
	public static boolean isIDEONE() { return true; }
}

enum TokenType
{
	INT, DBL, STR, NAME, SYMBL, SHARP, SEMICOLON,
	OP_BRKT, CL_BRKT, COMMA, COLON, UNKNOWN
}

final class Token
{
	final TokenType type;
	final String token;
	
	public Token(TokenType type, String token)
	{
		this.type = type;
		this.token = token;
	}
	
	public TokenType getType() { return type; }
	public String getToken() { return token; }
	
	@Override
	public String toString()
	{
		return "[" + type + " : " + token + "]";
	}
	
	public boolean isInt() { return TokenType.INT.equals(type); }
	public boolean isStr() { return TokenType.STR.equals(type); }
	public boolean isDbl() { return TokenType.DBL.equals(type); }
	public boolean isName() { return TokenType.NAME.equals(type); }
	public boolean isSymbl() { return TokenType.SYMBL.equals(type); }
	public boolean isOpBrkt() { return TokenType.OP_BRKT.equals(type); }
	public boolean isClBrkt() { return TokenType.CL_BRKT.equals(type); }
	public boolean isColon() { return TokenType.COLON.equals(type); }
	public boolean isSemiColon() { return TokenType.SEMICOLON.equals(type); }
	public boolean isComma() { return TokenType.COMMA.equals(type); }
	public boolean isSharp() { return TokenType.SHARP.equals(type); }
}

class SyntaxError extends java.lang.Exception
{
	public SyntaxError(String msg) { super(msg); }
	public SyntaxError(Throwable ex) { super(ex); }
	public SyntaxError(List<Token> tokens, int index)
	{
		super("token index(" + index + "): " + tokens.toString());
	}
}

final class TokenError extends SyntaxError
{
	public TokenError(String line) { super(line); }
}

final class Tokenizer
{
	private static Pattern p_space = Pattern.compile("^\\s+");
	private static Pattern p_int = Pattern.compile("^\\d+");
	private static Pattern p_dbl = Pattern.compile("^\\d*\\.\\d+");
	private static Pattern p_str = Pattern.compile("^\"(\"\"|[^\"])*\"");
	private static Pattern p_name = Pattern.compile("^[A-Za-z][A-Za-z0-9]*\\$?");
	private static Pattern p_symbl = Pattern.compile("^(>=|<=|<>|[=<>+\\*/-])");
	
	public static List<Token> tokenize(String line) throws TokenError
	{
		List<Token> list = new ArrayList<Token>();
		Matcher m = null;
		TokenType type = null;
		String token = null;
		int offset = 0;
		
		while (line.length() > 0) {
			if ((m = p_space.matcher(line)).lookingAt()) {
				line = line.substring(m.end());
				continue;
			} else if ((m = p_dbl.matcher(line)).lookingAt()) {
				type = TokenType.DBL;
			} else if ((m = p_int.matcher(line)).lookingAt()) {
				type = TokenType.INT;
			} else if ((m = p_str.matcher(line)).lookingAt()) {
				type = TokenType.STR;
			} else if ((m = p_name.matcher(line)).lookingAt()) {
				type = TokenType.NAME;
			} else if ((m = p_symbl.matcher(line)).lookingAt()) {
				type = TokenType.SYMBL;
			} else {
				m = null;
				offset = 1;
				if (line.startsWith(token = "(")) {
					type = TokenType.OP_BRKT;
				} else if (line.startsWith(token = ")")) {
					type = TokenType.CL_BRKT;
				} else if (line.startsWith(token = ":")) {
					type = TokenType.COLON;
				} else if (line.startsWith(token = ",")) {
					type = TokenType.COMMA;
				} else if (line.startsWith(token = "#")) {
					type = TokenType.SHARP;
				} else if (line.startsWith(token = ";")) {
					type = TokenType.SEMICOLON;
				} else {
					throw new TokenError(line);
				}
			}
			if (m != null) {
				token = m.group();
				if (TokenType.NAME.equals(type)) {
					token = token.toUpperCase();
				}
				offset = m.end();
			}
			list.add(new Token(type, token));
			line = line.substring(offset);
		}
		return list;
	}
}

final class ExcuteError extends SyntaxError
{
	public ExcuteError(Throwable ex) { super(ex); } 
	public ExcuteError(String msg) { super(msg); } 
}

enum VarArrayType
{
	INT, DBL, STR, UNKNOWN
}

class VarArray
{
	int[] intarr = null;
	double[] dblarr = null;
	String[] strarr = null;
	VarArrayType type = VarArrayType.UNKNOWN;
	List<Integer> dim;
	int maxdim = 1;
	
	VarArray(List<Integer> dim) throws SyntaxError
	{
		if (dim == null || dim.size() < 1) {
			throw new NullPointerException();
		}
		this.dim = new ArrayList<Integer>(dim);
		for (Integer i : dim) {
			maxdim *= 1 + i.intValue();
		}
		if (maxdim < 1) {
			throw new SyntaxError("Invalid define array dimention");
		}
	}
	
	public VarArrayType getType()
	{
		return type;
	}
	
	public void setType(VarArrayType type) throws SyntaxError
	{
		if (VarArrayType.UNKNOWN.equals(this.type) == false) {
			throw new SyntaxError("already exist array");
		}
		this.type = type;
		switch (type) {
		case INT:
			intarr = new int[maxdim + 1];
			break;
		case DBL:
			dblarr = new double[maxdim + 1];
			break;
		case STR:
			strarr = new String[maxdim + 1];
			break;
		default:
			throw new SyntaxError("Invalid array type");
		}
	}
	
	private int getIndex(List<Integer> indexes, int base) throws SyntaxError
	{
		if (indexes == null || indexes.size() != dim.size()) {
			throw new SyntaxError("Invalid array indexes " + indexes);
		}
		int index = 0;
		int tmp = 1;
		for (int i = 0; i < dim.size(); i++) {
			int p = indexes.get(i).intValue();
			int max = dim.get(i).intValue();
			if (p < base || p > max) {
				throw new SyntaxError("array index out of bounds");
			}
			index += p * tmp;
			tmp *= max;
		}
		return index;
	}
	
	public void setInt(List<Integer> indexes, int base, int value) throws SyntaxError
	{
		if (VarArrayType.INT.equals(type) == false) {
			throw new SyntaxError("");
		}
		intarr[getIndex(indexes, base)] = value;
	}

	public void setDbl(List<Integer> indexes, int base, double value) throws SyntaxError {
		if (VarArrayType.DBL.equals(type) == false) {
			throw new SyntaxError("");
		}
		dblarr[getIndex(indexes, base)] = value;
	}

	public void setStr(List<Integer> indexes, int base, String value) throws SyntaxError
	{
		if (VarArrayType.STR.equals(type) == false) {
			throw new SyntaxError("");
		}
		strarr[getIndex(indexes, base)] = value;
	}
	
	public int getInt(List<Integer> indexes, int base) throws SyntaxError
	{
		if (VarArrayType.INT.equals(type) == false) {
			throw new SyntaxError("");
		}
		return intarr[getIndex(indexes, base)];
	}

	public double getDbl(List<Integer> indexes, int base) throws SyntaxError
	{
		if (VarArrayType.DBL.equals(type) == false) {
			throw new SyntaxError("");
		}
		return dblarr[getIndex(indexes, base)];
	}

	public String getStr(List<Integer> indexes, int base) throws SyntaxError
	{
		if (VarArrayType.STR.equals(type) == false) {
			throw new SyntaxError("");
		}
		String tmp = strarr[getIndex(indexes, base)];
		return tmp == null ? "" : tmp;
	}
	
}

enum ResultType
{
	INT, DBL, STR, EOL, UNKNOWN
}

class Result
{
	public static final Result getTrue()
	{
		return new Result((int)-1);
	}
	public static final Result getFalse()
	{
		return new Result((int)0);
	}
	public static final Result getBool(boolean bool)
	{
		return bool ? getTrue() : getFalse();
	}
	
	private int offset;
	private int intvalue = 0;
	private double dblvalue = 0;
	private String strvalue = null;
	private ResultType type;
	
	Result()
	{
		type = ResultType.EOL;
	}
	
	static Result getEOL(int offset)
	{
		Result temp = new Result();
		temp.offset = offset;
		return temp;
	}
	
	Result(int value)
	{
		intvalue = value;
		type = ResultType.INT;
	}


	Result(double value)
	{
		dblvalue = value;
		type = ResultType.DBL;
	}

	
	Result(Number value)
	{
		if (Integer.class.equals(value.getClass())) {
			intvalue = value.intValue();
			type = ResultType.INT;
		} else if (Double.class.equals(value.getClass())) {
			dblvalue = value.doubleValue();
			type = ResultType.DBL;
		} else {
			type = ResultType.UNKNOWN;
		}
	}
	
	Result(String value)
	{
		strvalue = value;
		type = ResultType.STR;
	}

	Result(int value, int offset)
	{
		this(value);
		this.offset = offset;
	}

	Result(double value, int offset)
	{
		this(value);
		this.offset = offset;
	}

	Result(Number value, int offset)
	{
		this(value);
		this.offset = offset;
	}

	Result(String value, int offset)
	{
		this(value);
		this.offset = offset;
	}

	
	public ResultType getType()
	{
		return type;
	}	
	
	public int getOffset()
	{
		return offset;
	}
	
	public void setOffset(int offset)
	{
		this.offset = offset;
	}
	
	public int getIntValue()
	{
		return intvalue;
	}
	
	public double getDblValue()
	{
		return dblvalue;
	}

	public Number getNumValue()
	{
		if (ResultType.INT.equals(type)) {
			return Integer.valueOf(intvalue);
		} else if (ResultType.DBL.equals(type)) {
			return Double.valueOf(dblvalue);
		} else {
			return null;
		}
	}
	public String getStrValue()
	{
		return strvalue;
	}
	
	public boolean isNumber()
	{
		return ResultType.INT.equals(type) || ResultType.DBL.equals(type);
	}

	public boolean isInt()
	{
		return ResultType.INT.equals(type);
	}

	public boolean isDbl()
	{
		return ResultType.DBL.equals(type);
	}
	
	public boolean isString()
	{
		return ResultType.STR.equals(type);
	}
}

final class Excutor
{
	private NavigableMap<Integer, List<Token>> program = new TreeMap<Integer, List<Token>>();

	private Map<String, VarArray> strarrs = new HashMap<String, VarArray>();
	private Map<String, VarArray> numarrs = new HashMap<String, VarArray>();
	private Map<String, String> strvars = new HashMap<String, String>();
	private Map<String, Number> numvars = new HashMap<String, Number>();
	
	private Integer programcounter = null;
	private Deque<Integer> programcounterstack = new ArrayDeque<Integer>();
	
	private int arraybase = 0;
	private boolean jumpflag = false;
	private boolean stopflag = false;
	private boolean endflag = false;
	
	private Set<String> editorcommandnames = new HashSet<String>();
	private Set<String> commandnames = new HashSet<String>();
	private Set<String> functionnames = new HashSet<String>();
	private Set<String> keywordnames = new HashSet<String>();
	
	private Map<String, Integer> opepriority = new HashMap<String, Integer>();

	private Random rand = new Random();
	private double lastrand = 0;
	
	private int tabcount = 0;

	public Excutor()
	{
		String[] edcmd = { "RUN", "LOAD", "SAVE", "LIST", "RENUM", "CONT", "NEW" };
		String[] cmd = { "PRINT", "INPUT", "LET", "REM", "STOP", "END", "GOTO",
			"GO", "TO", "GOSUB", "RETURN", "BASE", "DIM", "IF", "THEN", "ELSE", "ERASE",
			"FOR", "NEXT", "STEP", "BREAK", "RESTORE", "FILE", "READ", "DATA", "WRITE"};
		String[] fnc = { "INT", "STR$", "RND", "CLK", "ABS", "VAL", "SIN", "COS", "TAN",
			"SGN", "SQRT", "EXP", "LOG", "LEFT$", "RIGHT$", "MID$", "LEN"};
		String[] key = { "AND", "OR" };
		String[] ope = { "OR", "AND", "=", ">=", "<=", "<", ">", "+", "-", "*", "/" };
		
		
		for (String s : edcmd) editorcommandnames.add(s);
		for (String s : cmd) commandnames.add(s);
		for (String s : fnc) functionnames.add(s);
		for (String s : key) keywordnames.add(s);
		
		for (int i = 0; i < ope.length; i++) {
			opepriority.put(ope[i], Integer.valueOf(i));
		}
	}
	
	@Override
	public String toString()
	{
		return program.toString().replaceAll("(\\d+=\\[\\[)", "\n$1");
	}
		
	private boolean checkKeyword(String name)
	{
		return editorcommandnames.contains(name)
			|| commandnames.contains(name)
			|| functionnames.contains(name)
			|| keywordnames.contains(name);
	}
	
	private void printLine(List<Token> tokens)
	{
		printLine(Integer.valueOf(tokens.get(0).getToken()), tokens);
	}
	
	private void printLine(Integer linenum, List<Token> tokens)
	{
		int s = 0;
		if (linenum != null) {
			System.out.printf("%05d ", linenum.intValue());
			s = 1;
		}
		TokenType before = null, type;
		for (int i = s; i < tokens.size(); i++) {
			Token token = tokens.get(i);
			type = token.getType();
			if (TokenType.NAME.equals(before)) {
				switch (type) {
					case NAME:
					case INT:
					case DBL:
					case SHARP:
					case STR:
						System.out.print(' ');
						break;
					default:
						break;
				}
			}
			System.out.print(tokens.get(i).getToken());
			before = type;
		}
		System.out.println();
	}
	
	private Result checksign(Result temp, int sign) throws SyntaxError
	{
		switch (temp.getType()) {
		case INT:
			if (sign < 0) {
				return new Result( - temp.getNumValue().intValue(), temp.getOffset());
			}
			break;
		case DBL:
			if (sign < 0) {
				return new Result( - temp.getNumValue().doubleValue(), temp.getOffset());
			}
			break;
		case STR:
			if (sign == 0) {
				break;
			}
		default:
			throw new SyntaxError("invalid sign character");
		}
		return temp;
	}
	
	private Result calc2(int temp1, int temp2, String op) throws SyntaxError
	{
		int res = 0;
		switch (op) {
		case "+": 	res = temp1 + temp2; break; // TODO OverFlow どした
		case "-": 	res = temp1 - temp2; break;
		case "*": 	res = temp1 * temp2; break;
		case "/": 	if (temp2 == 0) {
						throw new ExcuteError("Zero divided");
					}
				  	res = temp1 / temp2; break;
		case "=": 	res = temp1 == temp2 ? -1 : 0; break;
		case ">":	res = temp1 > temp2 ? -1 : 0; break;
		case "<":	res = temp1 < temp2 ? -1 : 0; break;
		case ">=":	res = temp1 >= temp2 ? -1 : 0; break;
		case "<=":	res = temp1 <= temp2 ? -1 : 0; break;
		case "AND":	res = (temp1 & temp2) != 0 ? -1 : 0; break;
		case "OR":	res = (temp1 | temp2) != 0 ? -1 : 0; break;
		default:
			throw new SyntaxError("Invalid operator: " + op);
		}
		return new Result(res);
	}
	
	private Result calc2(double temp1, double temp2, String op) throws SyntaxError
	{
		double res = 0;
		switch (op) {
		case "+": 	res = temp1 + temp2; break; // TODO OverFlow どした
		case "-": 	res = temp1 - temp2; break;
		case "*": 	res = temp1 * temp2; break;
		case "/": 	if (temp2 == 0) {
						throw new ExcuteError("Zero divided");
					}
				  	res = temp1 / temp2; break;
		case "=": 	return Result.getBool(temp1 == temp2);
		case ">": 	return Result.getBool(temp1 > temp2);
		case "<": 	return Result.getBool(temp1 < temp2);
		case ">=": 	return Result.getBool(temp1 >= temp2);
		case "<=": 	return Result.getBool(temp1 <= temp2);
		case "AND": return Result.getBool(temp1 * temp2 != 0.0);
		case "OR":	return Result.getBool(temp1 != 0.0 || temp2 != 0.0);
		default:
			throw new SyntaxError("Invalid operator: " + op);
		}
		return new Result(res);
	}
	
	private Result calc2(String temp1, String temp2, String op) throws SyntaxError
	{
		String res;
		switch (op) {
		case "-":
		case "*":
		case "/":
		case "AND":
		case "OR":	throw new SyntaxError("Invalid str operetor: " + op);
		case "+":	return new Result(temp1 + temp2);
		case "=":	return Result.getBool(temp1.equals(temp2));
		case ">":	return Result.getBool(temp1.compareTo(temp2) > 0);
		case "<":	return Result.getBool(temp1.compareTo(temp2) < 0);
		case ">=":	return Result.getBool(temp1.compareTo(temp2) >= 0);
		case "<=":	return Result.getBool(temp1.compareTo(temp2) <= 0);
		default:
			throw new SyntaxError("Invalid operator: " + op);
		}
	}
	
	private Result calc2(Result temp1, Result temp2, String op) throws SyntaxError
	{
		if (temp1.getType().equals(temp2.getType())) {
			switch (temp1.getType()) {
			case INT:
				return calc2(temp1.getIntValue(), temp2.getIntValue(), op);
			case DBL:
				return calc2(temp1.getDblValue(), temp2.getDblValue(), op);
			case STR:
				return calc2(temp1.getStrValue(), temp2.getStrValue(), op);
			default:
				throw new ExcuteError("Invalid type value");
			}
		} else if (ResultType.INT.equals(temp1.getType())
				&& ResultType.DBL.equals(temp2.getType())) {
			return calc2(temp1.getNumValue().doubleValue(), temp2.getDblValue(), op);
		} else if (ResultType.DBL.equals(temp1.getType())
				&& ResultType.INT.equals(temp2.getType())) {
			return calc2(temp1.getDblValue(), temp2.getNumValue().doubleValue(), op);
		} else {
			throw new ExcuteError("Invalid type value");
		}
		
	}
	
	private boolean calccheck(String op1, String op2) throws SyntaxError
	{
		Integer p1 = opepriority.get(op1);
		Integer p2 = opepriority.get(op2);
		if (p1 == null || p2 == null) {
			throw new SyntaxError("Invalid expression symbol");
		}
		return p2.compareTo(p1) < 0;
	}
	
	private Result calc(List<Token> tokens, int index) throws SyntaxError
	{
		if (index >= tokens.size()) {
			throw new SyntaxError(tokens, index);
		}
		
		Deque<Result> r_stack = new ArrayDeque<Result>();
		Deque<String> s_stack = new ArrayDeque<String>();
		int sign = 0;
		int flag = 0;
		Result temp, temp2;

		for (; index < tokens.size(); index++) {
			Token cur = tokens.get(index);
			TokenType type = cur.getType();
			String token = cur.getToken();
		
			if (flag == 0) {
				flag = 1;
				switch (type) {
				case SYMBL:
					if (sign != 0) {
						throw new SyntaxError(tokens, index);
					}
					if ("+".equals(token)) {
						sign = 1;
					} else if ("-".equals(token)) {
						sign = -1;
					} else {
						throw new SyntaxError(tokens, index);
					}
					flag = 0;
					break;
				case INT:
					r_stack.push(checksign(new Result(Integer.parseInt(token), index), sign));
					break;
				case DBL:
					r_stack.push(checksign(new Result(Double.parseDouble(token), index), sign));
					break;
				case STR:
					r_stack.push(checksign(new Result(token.substring(1, token.length() - 1), index), sign));
					break;
				case OP_BRKT:
					temp = calc(tokens, index + 1);
					index = temp.getOffset();
					if (TokenType.CL_BRKT.equals(tokens.get(index).getType()) == false) {
						throw new SyntaxError(tokens, index);
					}
					r_stack.push(checksign(temp, sign));
					break;
				case NAME:
					if (functionnames.contains(token)) {
						temp = doFunction(tokens, index);
						index = temp.getOffset();
						r_stack.push(checksign(temp, sign));
					} else if (strarrs.containsKey(token)) {
						temp = get_strarr(tokens, index);
						index = temp.getOffset();
						r_stack.push(checksign(temp, sign));
					} else if (strvars.containsKey(token)) {
						r_stack.push(checksign(new Result(strvars.get(token), index), sign));
					} else if (numarrs.containsKey(token)) {
						temp = get_numarr(tokens, index);
						index = temp.getOffset();
						r_stack.push(checksign(temp, sign));
					} else if (numvars.containsKey(token)) {
						r_stack.push(checksign(new Result(numvars.get(token), index), sign));
					} else if (checkKeyword(token)) {
						throw new SyntaxError("Invalid name");
					} else if (token.lastIndexOf("$") > 0) {
						// 未定義 文字列 変数
						if (index + 1 < tokens.size() && "(".equals(tokens.get(index + 1).getToken())) {
							// 配列
							List<Integer> dims = new ArrayList<Integer>();
							dims.add(Integer.valueOf(10));
							VarArray arr = new VarArray(dims);
							arr.setType(VarArrayType.STR);
							strarrs.put(tokens.get(index).getToken(), arr);
							temp = get_strarr(tokens, index);
							index = temp.getOffset();
							r_stack.push(checksign(temp, sign));
						} else {
							strvars.put(token, "");
							r_stack.push(checksign(new Result("", index), sign));
						}
					} else {
						// 未定義 数値 変数
						if (index + 1 < tokens.size() && "(".equals(tokens.get(index + 1).getToken())) {
							// 配列
							List<Integer> dims = new ArrayList<Integer>();
							dims.add(Integer.valueOf(10));
							VarArray arr = new VarArray(dims);
							arr.setType(VarArrayType.INT);
							numarrs.put(tokens.get(index).getToken(), arr);
							temp = get_numarr(tokens, index);
							index = temp.getOffset();
							r_stack.push(checksign(temp, sign));
						} else {
							numvars.put(token, Integer.valueOf(0));
							r_stack.push(checksign(new Result((int)0, index), sign));
						}
					}
					break;
				default:
					throw new SyntaxError(tokens, index);
				}
			} else if (flag == 1) {
				flag = 0;
				sign = 0;
				switch (type) {
				case NAME:
					switch (token) {
					case "OR":
					case "AND":
						temp = r_stack.peek();
						if (ResultType.STR.equals(temp.getType())) {
							throw new ExcuteError("Invalid expression symbol");
						}
						break;
					default:
						throw new SyntaxError(tokens, index);
					}
				case SYMBL:
					switch (token) {
					case "-":
					case "*":
					case "/":
						temp = r_stack.peek();
						if (ResultType.STR.equals(temp.getType())) {
							throw new ExcuteError("Invalid expression symbol");
						}
					default:
						break;
					}
					while (s_stack.size() > 0 && calccheck(s_stack.peek(), token)) {
						if (r_stack.size() < 2) {
							throw new ExcuteError("Unknown error");
						}
						temp2 = r_stack.pop();
						temp = r_stack.pop();
						temp = calc2(temp, temp2, s_stack.pop());
						r_stack.push(temp);
					}
					s_stack.push(token);
					break;
				case COLON:
				case SEMICOLON:
				case COMMA:
				case CL_BRKT:
					while (s_stack.size() > 0) {
						if (r_stack.size() < 2) {
							throw new ExcuteError("Unknown error");
						}
						temp2 = r_stack.pop();
						temp = r_stack.pop();
						temp = calc2(temp, temp2, s_stack.pop());
						r_stack.push(temp);
					}
					if (r_stack.size() != 1) {
						throw new ExcuteError("Unknown error");
					}
					temp = r_stack.pop();
					temp.setOffset(index);
					return temp;
				default:
					throw new SyntaxError(tokens, index);
				}
			}
		}
		

		if (flag == 0) {
			if (r_stack.size() > 0 || s_stack.size() > 0) {
			System.out.println("hoge");
				throw new SyntaxError(tokens, index);
			}
			return Result.getEOL(index);
		}
		
		while (s_stack.size() > 0) {
			if (r_stack.size() < 2) {
				throw new ExcuteError("Unknown error");
			}
			temp2 = r_stack.pop();
			temp = r_stack.pop();
			temp = calc2(temp, temp2, s_stack.pop());
			r_stack.push(temp);
		}
		if (r_stack.size() != 1) {
			throw new ExcuteError("Unknown error");
		}
		temp = r_stack.pop();
		temp.setOffset(index);
		return temp;
	}
	
	public Result get_strarr(List<Token> tokens, int index) throws SyntaxError
	{
		if (index + 3 >= tokens.size()) {
			throw new SyntaxError(tokens, index);
		}
		String name = tokens.get(index).getToken();
		index++;
		if (TokenType.OP_BRKT.equals(tokens.get(index).getType()) == false) {
			throw new SyntaxError(tokens, index);
		}
		index++;
		List<Integer> indexes = new ArrayList<Integer>();
		for (; index < tokens.size(); index++) {
			Result temp = calc(tokens, index);
			switch (temp.getType()) {
			case INT: indexes.add(Integer.valueOf(temp.getIntValue())); break;
			case DBL: indexes.add(Integer.valueOf(temp.getNumValue().intValue())); break;
			default:  throw new SyntaxError(tokens, index);
			}
			index = temp.getOffset();
			if (index >= tokens.size()) {
				throw new SyntaxError(tokens, index);
			}
			switch (tokens.get(index).getType()) {
			case COMMA:
				break;
			case CL_BRKT:
				Result rs = new Result(strarrs.get(name).getStr(indexes, arraybase));
				rs.setOffset(index);
				return rs;
			default:
				throw new SyntaxError(tokens, index);
			}
		}
		throw new SyntaxError(tokens, index);
	}

	public Result get_numarr(List<Token> tokens, int index) throws SyntaxError
	{
		if (index + 3 >= tokens.size()) {
			throw new SyntaxError(tokens, index);
		}
		String name = tokens.get(index).getToken();
		index++;
		if (TokenType.OP_BRKT.equals(tokens.get(index).getType()) == false) {
			throw new SyntaxError(tokens, index);
		}
		index++;
		List<Integer> indexes = new ArrayList<Integer>();
		for (; index < tokens.size(); index++) {
			Result temp = calc(tokens, index);
			switch (temp.getType()) {
			case INT: indexes.add(Integer.valueOf(temp.getIntValue())); break;
			case DBL: indexes.add(Integer.valueOf(temp.getNumValue().intValue())); break;
			default:  throw new SyntaxError(tokens, index);
			}
			index = temp.getOffset();
			if (index >= tokens.size()) {
				throw new SyntaxError(tokens, index);
			}
			switch (tokens.get(index).getType()) {
			case COMMA:
				break;
			case CL_BRKT:
				VarArray arr = numarrs.get(name);
				Result rs = null;
				switch (arr.getType()) {
				case UNKNOWN:
					arr.setType(VarArrayType.INT);
				case INT:
					rs = new Result(arr.getInt(indexes, arraybase));
					break;
				case DBL:
					rs = new Result(arr.getDbl(indexes, arraybase));
					break;
				default:
					throw new ExcuteError("Unknown error");
				}
				rs.setOffset(index);
				return rs;
			default:
				throw new SyntaxError(tokens, index);
			}
		}
		throw new SyntaxError(tokens, index);
	}
	
	public Result doFunction(List<Token> tokens, int index) throws SyntaxError
	{
		if (index + 1 >= tokens.size()) {
			throw new SyntaxError(tokens, index);
		}
		if (TokenType.OP_BRKT.equals(tokens.get(index + 1).getType()) == false) {
			throw new SyntaxError(tokens, index);
		}
		String name = tokens.get(index).getToken();
		Result temp;
		switch (name) {
		case "INT":
			temp = calc(tokens, index + 2);
			index = temp.getOffset();
			if (TokenType.CL_BRKT.equals(tokens.get(index).getType())) {
				switch (temp.getType()) {
				case INT:
					return temp;
				case DBL:
					return new Result(temp.getNumValue().intValue(), index);
				default:
					break;
				}
			}
			throw new SyntaxError(tokens, index);
		case "RND":
			temp = calc(tokens, index + 2);
			index = temp.getOffset();
			if (TokenType.CL_BRKT.equals(tokens.get(index).getType())) {
				switch (temp.getType()) {
				case INT:
				case DBL:
					int s = temp.getNumValue().intValue();
					if (s == 0) {
						return new Result(lastrand = rand.nextDouble(), index);
					} else if (s > 0) {
						rand.setSeed((long)s);
						lastrand = rand.nextDouble();
					}
					return new Result(lastrand, index);
				default:
					break;
				}
			}
			throw new SyntaxError(tokens, index);
		case "CLK":
			temp = calc(tokens, index + 2);
			index = temp.getOffset();
			if (TokenType.CL_BRKT.equals(tokens.get(index).getType())) {
				switch (temp.getType()) {
				case INT:
				case DBL:
					double t = temp.getNumValue().doubleValue();
					t -= Math.floor(t);
					t *= 24;
					return new Result((int)t, index);
				default:
					break;
				}
			}
			throw new SyntaxError(tokens, index);
		case "ABS":
			temp = calc(tokens, index + 2);
			index = temp.getOffset();
			if (TokenType.CL_BRKT.equals(tokens.get(index).getType())) {
				switch (temp.getType()) {
				case INT:
					return new Result(Math.abs(temp.getIntValue()), index);
				case DBL:
					return new Result(Math.abs(temp.getDblValue()), index);
				default:
					break;
				}
			}
			throw new SyntaxError(tokens, index);
		case "VAL":
			temp = calc(tokens, index + 2);
			index = temp.getOffset();
			if (TokenType.CL_BRKT.equals(tokens.get(index).getType())) {
				switch (temp.getType()) {
				case STR:
					Matcher mt;
					if ((mt = Pattern.compile("^(\\d*\\.\\d+)").matcher(temp.getStrValue())).lookingAt()) {
						return new Result(Double.parseDouble(mt.group(1)), index);
					} else if ((mt = Pattern.compile("^(\\d+)").matcher(temp.getStrValue())).lookingAt()) {
						return new Result(Integer.parseInt(mt.group(1)), index);
					} else {
						return new Result(0.0, index);
					}
				default:
					break;
				}
			}
			throw new SyntaxError(tokens, index);
		default:
			break;
		}
		
		return Result.getEOL(index);
	}
	
	public int doEditorCommand(List<Token> tokens) throws SyntaxError
	{
		if (tokens == null || tokens.isEmpty()) {
			return 0;
		}
		
		Token first = tokens.get(0);
		String token = first.getToken();
		TokenType type = first.getType();
		
		if (TokenType.INT.equals(type)) {
			Integer tmpint = Integer.valueOf(token);
			if (tmpint.intValue() < 1) {
				throw new SyntaxError(token);
			}
			if (tokens.size() > 1) {
				program.put(tmpint, tokens);
			} else {
				program.remove(tmpint);
			}
			return 0;
		} else if (TokenType.NAME.equals(type) == false) {
			throw new ExcuteError(token);
		}
		
		/* */
		if (Debug.isIDEONE()) {
			printLine(null, tokens); // IDEONE上じゃ入力が見えないので
		}
		/* */
		
		switch (token) {
			case "CONT": // プログラムの再開
				// TODO 処理
				break;
			case "EXIT": // インタプリタの終了
				return -1;
			case "LIST": // プログラムの表示
				do_list(tokens);
				break;
			case "LOAD": // プログラムのロード
				// TODO 処理
				break;
			case "NEW":  // プログラムと変数の全消去
				// TODO 処理
				break;
			case "RENUM": // プログラムの行番号再割り当て
				// TODO 処理
				break;
			case "RUN":  // プログラムの実行
				do_run(tokens);
				break;
			case "SAVE": // プログラムの保存
				// TODO 処理
				break;
			default:
				excute(tokens, 0);
				break;
		}
		if (stopflag) {
			System.out.println("Stop");
			stopflag = false;
			return 0;
		}
		System.out.println("Ok");
		return 0;
	}
	
	private void do_list(List<Token> tokens) throws SyntaxError
	{
		Integer start = null;
		Integer end = null;
		Token first, second, third;
		Map<Integer, List<Token>> list = null;
		try {
			switch (tokens.size()) {
				case 1:
					list = program;
					break;
				case 2:
					first = tokens.get(1);
					if (TokenType.INT.equals(first.getType()) == false) {
						throw new SyntaxError(tokens ,1);
					}
					end = start = Integer.valueOf(first.getToken());
					if (start.intValue() < 1) {
						throw new SyntaxError(tokens ,1);
					}
					list = program.subMap(start, true, end, true);
					break;
				case 3:
					first = tokens.get(1);
					second = tokens.get(2);
					if ("-".equals(first.getToken())) {
						if (TokenType.INT.equals(second.getType()) == false) {
							throw new SyntaxError(tokens ,2);
						}
						end = Integer.valueOf(second.getToken());
						if (end.intValue() < 1) {
							throw new SyntaxError(tokens ,2);
						}
						list = program.headMap(end, true);
					} else if (TokenType.INT.equals(first.getType())) {
						start = Integer.valueOf(first.getToken());
						if (start.intValue() < 1) {
							throw new SyntaxError(tokens , 1);
						}
						if ("-".equals(second.getToken()) == false) {
							throw new SyntaxError(tokens ,2);
						}
						list = program.tailMap(start);
					} else {
						throw new SyntaxError(tokens ,1);
					}
					break;
				case 4:
					first = tokens.get(1);
					if (TokenType.INT.equals(first.getType()) == false) {
						throw new SyntaxError(tokens ,1);
					}
					start = Integer.valueOf(first.getToken());
					if (start.intValue() < 1) {
						throw new SyntaxError(tokens ,1);
					}
					if ("-".equals(tokens.get(2).getToken()) == false) {
						throw new SyntaxError(tokens ,2);
					}
					third = tokens.get(3);
					if (TokenType.INT.equals(third.getType()) == false) {
						throw new SyntaxError(tokens ,3);
					}
					end = Integer.valueOf(third.getToken());
					if (end.intValue() < 1) {
						throw new SyntaxError(tokens ,3);
					}
					list = program.subMap(start, true, end, true);
					break;
				default:
					throw new SyntaxError(tokens, 0);
			}
		} catch (SyntaxError er) {
			throw er;
		} catch (Exception ex) {
			throw new ExcuteError(ex);
		}
		
		if (list == null) {
			return;
		}
		
		for (Integer key: list.keySet()) {
			printLine(key, list.get(key));
		}
		
	}
	
	private void do_run(List<Token> tokens) throws SyntaxError
	{
		switch (tokens.size()) {
			case 1:
				programcounter = program.ceilingKey(Integer.valueOf(1));
				if (programcounter == null) {
					throw new SyntaxError("Program is not found");
				}
				break;
			case 2:
				Token first = tokens.get(1);
				if (TokenType.INT.equals(first.getType()) == false) {
					throw new SyntaxError("Illegal Argument");
				}
				programcounter = Integer.valueOf(first.getToken());
				if (programcounter.intValue() < 1) {
					throw new SyntaxError("Wrong Line Number");
				}
				if (program.containsKey(programcounter) == false) {
					throw new SyntaxError("Not found Line Number");
				}
				break;
			default:
				throw new SyntaxError("Illegal Arguments");
		}
		
		stopflag = endflag = false;
		List<Token> line = null;
		try {
			while (programcounter != null) {
				line = program.get(programcounter);
				excute(line, 1);
				if (jumpflag == false) {
					programcounter = program.higherKey(programcounter);
					if (stopflag) {
						break;
					} else if (endflag) {
						break;
					}
				} else {
					jumpflag = false;
				}
			}
		} catch (SyntaxError er) {
			printLine(line);
			throw er;
		}
		
	}
	
	private int excute(List<Token> tokens, int index) throws SyntaxError
	{
		if (index < 0 || index >= tokens.size()) {
			return tokens.size();
		}
		Token first = tokens.get(index);
		TokenType type = first.getType();
		
		while (TokenType.COLON.equals(type)) {
			index++;
			if (index == tokens.size()) {
				return index;
			}
			first = tokens.get(index);
			type = first.getType();
		}
		
		if (TokenType.NAME.equals(type) == false) {
			throw new SyntaxError(first.toString());
		}
		String cmd = first.getToken();
		int offset = index;
		switch (cmd) {
			case "BASE": // 配列の下限(0/1)の設定
				offset = cmd_base(tokens, index + 1);
				break;
			case "BREAK": // FORループの脱出
				// TODO 処理
				break;
			case "DATA": // データの列挙
				// TODO 処理
				break;
			case "DIM":  // 配列変数の宣言
				offset = cmd_dim(tokens, index + 1);
				break;
			case "ELSE": // IF文のELSE節の開始
				// TODO 処理
				break;
			case "END":  // プログラムの終了
				endflag = true;
				return tokens.size();
			case "FILE": // ファイルの割り当て
				// TODO 処理
				break;
			case "FOR":  // 繰り返し
				// TODO 処理
				break;
			case "GO":   // GOTOの分割トークン
				if (index + 2 >= tokens.size()) {
					throw new SyntaxError(tokens, index);
				}
				if ("TO".equals(tokens.get(index + 1).getToken()) == false) {
					throw new SyntaxError(tokens, index);
				}
				offset = cmd_goto(tokens, index + 2);
				break;
			case "GOTO": // ジャンプ
				offset = cmd_goto(tokens, index + 1);
				break;
			case "GOSUB": // サブルーチンジャンプ
				offset = cmd_gosub(tokens, index + 1);
				break;
			case "IF":    // 条件節
				// TODO 処理
				break;
			case "INPUT": // キーボードからの値の入力
				// TODO 処理
				break;
			case "LET":   // 変数への代入
				offset = cmd_let(tokens, index + 1);
				break;
			case "NEXT":  // FOR文の末端
				// TODO 処理
				break;
			case "PRINT": // 画面へ値を出力
				offset = cmd_print(tokens, index + 1);
				break;
			case "REM":   // コメント行
				offset = tokens.size();
				break;
			case "RESTORE": // データ・ファイルの読み込み位置のリセット
				// TODO 処理
				break;
			case "RETURN": // サブルーチンからの脱出
				offset = cmd_return(tokens, index);
				break;
			case "STOP":   // プログラムの中断
				stopflag = true;
				return tokens.size();
			default:
				offset = cmd_let(tokens, index);
				break;
		}
		return offset;
	}
	
	private int cmd_dim(List<Token> tokens, int index) throws SyntaxError
	{
		if (index + 3 >= tokens.size()) {
			throw new SyntaxError(tokens, index);
		}
		List<Integer> dims = new ArrayList<Integer>();
		int flag = 0;
		Token cur = null;
		String name = null;
		for (; index < tokens.size(); index++) {
			cur = tokens.get(index);
			switch (flag) {
			case 0:
				if (TokenType.NAME.equals(cur.getType()) == false) {
					throw new SyntaxError(tokens, index);
				}
				name = cur.getToken();
				if (checkKeyword(name)) {
					throw new SyntaxError("Invalid variable name:" + name);
				}
				flag = 1;
				break;
			case 1:
				if (TokenType.OP_BRKT.equals(cur.getType()) == false) {
					throw new SyntaxError(tokens, index);
				}
				dims.clear();
				flag = 2;
				break;
			case 2:
				if (TokenType.INT.equals(cur.getType()) == false) {
					throw new SyntaxError(tokens, index);
				}
				Integer n = Integer.valueOf(cur.getToken());
				if (n.intValue() < 1) {
					throw new SyntaxError("Invalid dimention size");
				}
				dims.add(n);
				flag = 3;
				break;
			case 3:
				switch (cur.getType()) {
				case COMMA:
					flag = 2;
					break;
				case CL_BRKT:
					VarArray temp = new VarArray(dims);
					if (name.lastIndexOf("$") > 0) {
						temp.setType(VarArrayType.STR);
						strarrs.put(name, temp);
					} else {
						numarrs.put(name, temp);
					}
					flag = 4;
					break;
				default:
					throw new SyntaxError(tokens, index);
				}
				break;
			case 4:
				switch (cur.getType()) {
				case COMMA:
					flag = 0;
					break;
				case COLON:
					return excute(tokens, index);
				default:
					throw new SyntaxError(tokens, index);
				}
				break;
			default:
				throw new SyntaxError(tokens, index);
			}
		}
		if (flag != 4) {
			throw new SyntaxError(tokens, index);
		}
		
		return excute(tokens, index);
	}

	private int cmd_goto(List<Token> tokens, int index) throws SyntaxError
	{
		if (index >= tokens.size()) {
			throw new SyntaxError(tokens, index);
		}
		if (index + 1 < tokens.size()) {
			if (TokenType.COLON.equals(tokens.get(index + 1).getType()) == false) {
				throw new SyntaxError(tokens, index + 1);
			}
		}
		// TODO 未テスト コード
		Token first = tokens.get(index);
		if (TokenType.INT.equals(first.getType()) == false) {
			throw new SyntaxError(tokens, index);
		}
		Integer next = Integer.valueOf(first.getToken());
		if (program.containsKey(next) == false) {
			throw new SyntaxError(tokens, index);
		}
		programcounter = next;
		jumpflag = true;
		return tokens.size();
	}

	private int cmd_gosub(List<Token> tokens, int index) throws SyntaxError
	{
		if (index >= tokens.size()) {
			throw new SyntaxError(tokens, index);
		}
		if (index + 1 < tokens.size()) {
			if (TokenType.COLON.equals(tokens.get(index + 1).getType()) == false) {
				throw new SyntaxError(tokens, index + 1);
			}
		}
		Token first = tokens.get(index);
		if (TokenType.INT.equals(first.getType()) == false) {
			throw new SyntaxError(tokens, index);
		}
		Integer next = Integer.valueOf(first.getToken());
		if (program.containsKey(next) == false) {
			throw new SyntaxError(tokens, index);
		}
		// TODO 未テスト コード
		// WRONG CODE : RETURNはGOSUBの次の行だけじゃなく次の命令文(コロンがある)から始まることも
		try {
			programcounterstack.push(programcounter);
			programcounter = next;
			jumpflag = true;
			return tokens.size();
		} catch (Exception ex) {
			throw new ExcuteError(ex);
		}
	}
	
	private int cmd_return(List<Token> tokens, int index) throws SyntaxError
	{
		if (index < tokens.size()) {
			if (TokenType.COLON.equals(tokens.get(index).getType()) == false) {
				throw new SyntaxError(tokens, index);
			}
		}
		// TODO 未テスト コード
		// WRONG CODE : RETURNはGOSUBの次の行だけじゃなく次の命令文(コロンがある)から始まることも
		try {
			Integer back = programcounterstack.pop();
			programcounter = program.higherKey(back);
			jumpflag = true;
			return tokens.size();
		} catch (Exception ex) {
			throw new ExcuteError(ex);
		}
	}

	
	private int cmd_base(List<Token> tokens, int index) throws SyntaxError
	{
		// TODO 未テスト コード
		// N-88 BASIC の OPTION BASE の場合は
		// どのDIMよりも先に使う必要があり、プログラム中１回しか使えないらしい
		try {
			Token first = tokens.get(index);
			if (TokenType.INT.equals(first.getType()) == false) {
				throw new SyntaxError(tokens, index);
			}
			int tmpint = Integer.parseInt(first.getToken());
			if (tmpint != 0 && tmpint != 1) {
				throw new SyntaxError(tokens, index + 1);
			}
			arraybase = tmpint;
			return excute(tokens, index + 1);
		} catch (SyntaxError er) {
			throw er;
		} catch (Exception ex) {
			throw new ExcuteError(ex);
		}
	}
	
	private int cmd_print(List<Token> tokens, int index) throws SyntaxError
	{
		if (index == tokens.size()) {
			tabcount = 0;
			System.out.println();
			return tokens.size();
		} else if (index > tokens.size()) {
			throw new ExcuteError("Unknown error");
		}
		StringBuilder output = new StringBuilder();
		boolean nl = true;
		for (; index < tokens.size(); index++) {
			Token cur = tokens.get(index);
			switch (cur.getType()) {
			case COLON:
				if (nl) {
					tabcount = 0;
					System.out.println(output);
				} else {
					tabcount += output.length();
					System.out.print(output);
				}
				return excute(tokens, index + 1);
			case COMMA:
				output.append('\t');
				nl = false;
				break;
			case SEMICOLON:
				nl = false;
				break;
			case INT:
			case DBL:
			case STR:
			case NAME:
				Result temp = calc(tokens, index);
				index = temp.getOffset() - 1;
				switch (temp.getType()) {
				case INT: output.append(temp.getIntValue()); break;
				case DBL: output.append(temp.getDblValue()); break;
				case STR: output.append(temp.getStrValue()); break;
				default:
					throw new ExcuteError("Unknown error");
				}
				nl = true;
				break;
			}
		}
		if (nl) {
			tabcount = 0;
			System.out.println(output);
		} else {
			tabcount += output.length();
			System.out.print(output);
		}
		return excute(tokens, index);	
	}
	
	private int getIndexes(List<Token> tokens, int index, List<Integer> indexes) throws SyntaxError
	{
		for (; index < tokens.size(); index++) {
			Result temp = calc(tokens, index);
			switch (temp.getType()) {
			case INT: indexes.add(Integer.valueOf(temp.getIntValue())); break;
			case DBL: indexes.add(Integer.valueOf(temp.getNumValue().intValue())); break;
			default: throw new SyntaxError(tokens, index);
			}
			index = temp.getOffset();
			switch (tokens.get(index).getType()) {
			case COMMA:
				break;
			case CL_BRKT:
				return index;
			default:
				throw new SyntaxError(tokens, index);
			}
		}
		throw new SyntaxError(tokens, index);
	}

	private int cmd_let(List<Token> tokens, int index) throws SyntaxError
	{
		try {
			if (index + 2 >= tokens.size()) {
				throw new SyntaxError(tokens, index);
			}
			Token first = tokens.get(index);
			String name = first.getToken();
			if (checkKeyword(name)) { // 予約語チェック
			     throw new SyntaxError("Wrong variable name: " + name); 
			}
			index++;
			Result temp;
			if (name.lastIndexOf("$") > 0) {
				if (strarrs.containsKey(name)) {
					if (TokenType.OP_BRKT.equals(tokens.get(index).getType()) == false) {
						throw new SyntaxError(tokens, index);
					}
					index++;
					List<Integer> indexes = new ArrayList<Integer>();
					index = getIndexes(tokens, index, indexes);
					index++;
					if ("=".equals(tokens.get(index).getToken()) == false) {
						throw new SyntaxError(tokens, index);
					}
					index++;
					temp = calc(tokens, index);
					if (ResultType.STR.equals(temp.getType()) == false) {
						throw new ExcuteError("Invalid type value");
					}
					index = temp.getOffset();
					strarrs.get(name).setStr(indexes, arraybase, temp.getStrValue());
				} else  {
					if ("=".equals(tokens.get(index).getToken()) == false) {
						throw new SyntaxError(tokens, index);
					}
					index++;
					temp = calc(tokens, index);
					if (ResultType.STR.equals(temp.getType()) == false) {
						throw new ExcuteError("Invalid type value");
					}
					index = temp.getOffset();
					strvars.put(name, temp.getStrValue());
				}
			} else {
				if (numarrs.containsKey(name)) {
					if (TokenType.OP_BRKT.equals(tokens.get(index).getType()) == false) {
						throw new SyntaxError(tokens, index);
					}
					index++;
					List<Integer> indexes = new ArrayList<Integer>();
					index = getIndexes(tokens, index, indexes);
					index++;
					if ("=".equals(tokens.get(index).getToken()) == false) {
						throw new SyntaxError(tokens ,index);
					}
					index++;
					temp = calc(tokens, index);
					index = temp.getOffset();
					VarArray arr = numarrs.get(name);
					switch (temp.getType()) {
					case INT:
						switch (arr.getType()) {
						case UNKNOWN:
							arr.setType(VarArrayType.INT);
						case INT:
							arr.setInt(indexes, arraybase, temp.getIntValue());
							break;
						case DBL:
							arr.setDbl(indexes, arraybase, Double.valueOf(temp.getNumValue().doubleValue()));
							break;
						default:
							throw new ExcuteError("Invalid type value");
						}
						break;
					case DBL:
						switch (arr.getType()) {
						case UNKNOWN:
							arr.setType(VarArrayType.DBL);
						case DBL:
							arr.setDbl(indexes, arraybase, temp.getDblValue());
							break;
						case INT:
							arr.setInt(indexes, arraybase, Integer.valueOf(temp.getNumValue().intValue()));
							break;
						default:
							throw new ExcuteError("Invalid type value");
						}						break;
					default:
						throw new ExcuteError("Invalid type value");
					}
				} else if (numvars.containsKey(name)) {
					if ("=".equals(tokens.get(index).getToken()) == false) {
						throw new SyntaxError(tokens ,index);
					}
					index++;
					temp = calc(tokens, index);
					index = temp.getOffset();
					Number num = numvars.get(name);
					switch (temp.getType()) {
					case INT:
						if (Integer.class.equals(num.getClass())) {
							numvars.put(name, temp.getNumValue());
						} else if (Double.class.equals(num.getClass())) {
							numvars.put(name, Double.valueOf(temp.getNumValue().doubleValue()));
						} else {
							throw new ExcuteError("Invalid type value");
						}
						break;
					case DBL:
						if (Integer.class.equals(num.getClass())) {
							numvars.put(name, Integer.valueOf(temp.getNumValue().intValue()));
						} else if (Double.class.equals(num.getClass())) {
							numvars.put(name, temp.getNumValue());
						} else {
							throw new ExcuteError("Invalid type value");
						}
						break;
					default:
						throw new ExcuteError("Invalid type value");
					}
				} else {
					if ("=".equals(tokens.get(index).getToken()) == false) {
						throw new SyntaxError(tokens, index);
					}
					index++;
					temp = calc(tokens, index);
					index = temp.getOffset();
					switch (temp.getType()) {
					case INT:
					case DBL:
						numvars.put(name, temp.getNumValue());
						break;
					default:
						throw new ExcuteError("Invalid type value");
					}
				}
			}
			return excute(tokens, index + 1);
		} catch (SyntaxError er) {
			throw er;
		} catch (Exception ex) {
			// ex.printStackTrace();
			throw new ExcuteError(tokens.toString());
		}
		
	}

}