public int getValueInt(String name) { for (int i = 0; i < stack.Count; i++) { VariableStore.ValueType type = getStackInLevel(i).getValueType(name); if (type == VariableStore.ValueType.Number) { return(getStackInLevel(i).getValueInt(name)); } } throw new Exception(name + " : There's no such a number variable that has the name in the stack.."); }
public VariableStore.ValueType getValueType(String name) { for (int i = 0; i < stack.Count; i++) { VariableStore.ValueType type = getStackInLevel(i).getValueType(name); if (type != VariableStore.ValueType.NoExist) { return(type); } } return(VariableStore.ValueType.NoExist); }
public String calculate(String syntex) { if (syntex == null || syntex.Length == 0) { return(""); } String tempNum = ""; String tempName = ""; String tempOp = ""; String tempString = ""; syntex = syntex.Trim(); UnitType nowEditing = UnitType.None; //if (syntex.LastIndexOf('\n') != 0) syntex += '\n'; //맨 뒤에 줄바꿈 표시가 없으면 추가해 준다. 아래의 parsing에서 parsing을 끝내는 역할을 한다. syntex = "(" + syntex + ")"; String editingsyntex = ""; foreach (Char a in syntex) { editingsyntex += a; if (nowEditing != UnitType.String && a.Equals('\n') == false && Char.IsWhiteSpace(a)) //문자입력중이 아니라면 공백은 무시 { continue; } #region 현재 편집중인 유닛이 취소되는 조건. if (nowEditing == UnitType.Name && Char.IsLetterOrDigit(a) == false) { VariableStore.ValueType type = valueStack.getValueType(tempName); if (type != VariableStore.ValueType.NoExist) { _unit.Push(valueStack.getValue(tempName)); tempName = ""; nowEditing = UnitType.None; } else { throw new Exception(tempName + ": there's no such a variable's name in the variable stack." + "\n" + editingsyntex + "^"); } } else if (nowEditing == UnitType.Number && Char.IsDigit(a) == false && a.Equals('.') == false) { _unit.Push(tempNum); tempNum = ""; nowEditing = UnitType.None; } else if (nowEditing == UnitType.String && a.Equals('\"')) { int countBS = 0; for (int i = tempString.Length - 1; i >= 0; i--) { if (tempString[i].Equals('\\')) { countBS++; } else { break; //처음으로 \가 아닌 것이 나왔을 때 룹을 나간다. } } if (countBS % 2 == 0) //과거에 \가 짝수로 나왔다면 마지막 나온 따옴표와는 관계가 없다. 예을 들어, \\"는 {\,"}이므로, 따옴표가 닫히는 구문이다. { _unit.Push("\"" + tempString + "\""); //trim으로 처리하기 위해서 처음과 끝에 스페이스를 붙인다. 스페이스를 붙이는 이유는 숫자로 parsing되지 않게 하기 위해서이다. tempString = ""; nowEditing = UnitType.None; continue; } } else if (nowEditing == UnitType.Op && (Char.IsLetterOrDigit(a) || a.Equals('.') || a.Equals('\"') || "_$#@".IndexOf(a) >= 0)) { if (_opList.isOp(tempOp)) { _op.Push(tempOp); //checkStack(); //op가 끝나고 나면, 우선순위에 따라서 계산을 하면서 진행함.. tempOp = ""; nowEditing = UnitType.None; } else { throw new Exception(tempOp + " : there's no such a operator in the operator stack." + "\n" + editingsyntex + "^"); } } if (a.Equals('\n')) { _op.Push("\n"); checkStack(); break; }//한줄이 끝나면 구문을 나가고 후처리를 한다. #endregion if (nowEditing == UnitType.None) //다른 unit을 편집중이 아닐 때.. { if (a.Equals('\"')) { nowEditing = UnitType.String; tempString = ""; continue; } if (a.Equals('.')) //.으로 시작하면 소수점 앞의 0을 생략한 것으로 본다. { nowEditing = UnitType.Number; tempNum += "0" + a; continue; } if (Char.IsDigit(a)) { //숫자로 시작한다면 숫자이다. nowEditing = UnitType.Number; tempNum += a; continue; } if (Char.IsLetter(a) || "_$#@".IndexOf(a) >= 0) { //문자로 시작하거나 _$#@로 시작한다면 변수명이다. nowEditing = UnitType.Name; tempName += a; continue; } if (a.Equals(')')) { //괄호를 닫으면 그 괄호까지의 작업을 처리해 준다. _op.Push("" + a); tempOp = ""; checkStack(); continue; } if (_opList.getAllOperators().IndexOf(a) >= 0) { //op에서 사용되는 문자일 때는 operator라고 본다. nowEditing = UnitType.Op; tempOp += a; continue; } throw new Exception(a + " : this character cannot be used in this program." + "\n" + editingsyntex + "^"); } if (nowEditing == UnitType.String) { tempString += a; continue; } if (nowEditing == UnitType.Name) { tempName += a; continue; } if (nowEditing == UnitType.Number) { tempNum += a; continue; } if (nowEditing == UnitType.Op) { if (tempOp.Equals("(")) //다른 op가 들어왔는데 이전에 (였다면, 부호를 넣은 것이다. +와 -, (만 허용해야 함. { if (a.Equals('+') || a.Equals('-')) { _unit.Push("0"); //-1은 0-1과 같다. _op.Push(tempOp); //앞의 것은 스택에 넣고 tempOp = "" + a; //다음것만 유지한다. continue; } else if (a.Equals('(')) { _op.Push(tempOp); //앞의 것은 스택에 넣고 tempOp = "" + a; //다음것만 유지한다. continue; } else { throw new Exception("you cannot use the syntex like (" + a + "number) ... you tried : " + editingsyntex + "^"); } } else if (a.Equals('(')) //어떠한 부호가 있은 다음 괄호가 나오는 경우. { _op.Push(tempOp); //앞의 것은 스택에 넣고 tempOp = "" + a; //다음것만 유지한다. continue; } else { tempOp += a; if (_opList.isOp(tempOp)) { _op.Push(tempOp); tempOp = ""; nowEditing = UnitType.None; } else { throw new Exception("you cannot use the operator like " + tempOp + " in this program. : " + editingsyntex + "^"); } } continue; } } //checkStack(); return(_unit.Pop()); }