/// <summary> /// Конструктор создания переменной, ссылающейся на объект /// </summary> /// <param name="name"></param> /// <param name="obj"></param> public Identifier(string name, EvalObject obj) { Literal = name; Value = obj; SystemType = (obj != null) ? (SystemTypes?)Value.SystemType : null; Type = LexemType.Identifier; }
/// <summary> /// Конструктор создания константы /// </summary> /// <param name="value"></param> public Identifier(EvalObject value) { Literal = value.ToString(); Value = value; SystemType = Value.SystemType; Type = LexemType.Constant; }
/// <summary> /// Удаляет объект из памяти /// </summary> /// <param name="obj"></param> /// <returns></returns> static bool RemoveObj(EvalObject obj) { var index = LocateObject(obj.ToString()); if (index != null) { Objects.Remove((uint)index); return(true); } return(false); }
/// <summary> /// Определяет операцию сложения типов /// </summary> /// <param name="obj"></param> /// <returns></returns> public virtual EvalObject Add(EvalObject obj) { if (SystemType != obj.SystemType) { throw new TypeMismatchException("Can't use operator + on two different types"); } var var1 = GetValue(); var var2 = obj.GetValue(); return(Memory.CreateObjectFromValue((var1 + var2).ToString())); }
public override EvalObject Multiply(EvalObject obj) { if (SystemType != obj.SystemType) { return(Memory.CreateObjectFromValue((GetValue() & obj.GetValue()).ToString())); } else { throw new TypeMismatchException(); } }
/// <summary> /// Переопределяет значение идентификатора /// </summary> /// <param name="id"></param> /// <param name="obj"></param> public static void ReAssign(ref Identifier id, EvalObject obj) { if (Identifiers.Contains(id)) { int index = Identifiers.IndexOf(id); Identifiers[index].Value = obj; id = Identifiers[index]; } else { id.Value = obj; Identifiers.Add(id); } }
/// <summary> /// Выполняет постфиксную запись лексем /// </summary> /// <param name="Postfix"></param> /// <returns></returns> static public Identifier Evaluate(List <ILexem> Postfix) { Stack <ILexem> buffer = new Stack <ILexem>(); foreach (var item in Postfix) { if (item.Type == LexemType.Identifier || item.Type == LexemType.Constant) { buffer.Push(item); } else { // получаю функцию, взаимодействующую с операторами ICallable func; if (item.Type == LexemType.Operator) { func = (Operator)item; } else { func = (Function)item; } // достаю параметры функции List <Identifier> parameters = new List <Identifier>(); for (int i = 0; i < func.ParamCount - 1; i++) { parameters.Add((Identifier)buffer.Pop()); } Identifier op1 = (Identifier)buffer.Pop(); if (op1.Value == null && item.Literal != "=") { throw new VariableException(op1.Literal, "Not assigned, but referenced"); } if (parameters.Any((lex) => lex.Address == null)) { throw new VariableException("Not assigned, but referenced"); } // выполняю вычисление EvalObject result = func.Evaluate(ref op1, parameters.ToArray()); buffer.Push(new Identifier(result)); } } var res = (Identifier)buffer.Pop(); IdentifierManager.Refresh(ref res); return(res); }
/// <summary> /// Создаёт объект из строкового представления /// </summary> /// <param name="value"></param> /// <returns></returns> public static EvalObject CreateObjectFromValue(string value) { uint?index = LocateObject(value); if (index != null) { return(Objects[(uint)index]); } else { EvalObject obj; try { // Попытка распознать тип объекта switch (EvalObject.Recognise(value)) { case SystemTypes.Char: obj = new CharObject(value); break; case SystemTypes.String: obj = new StringObject(value); break; case SystemTypes.Float: obj = new FloatObject(float.Parse(value)); break; case SystemTypes.Int: obj = new IntObject(int.Parse(value)); break; case SystemTypes.Bool: obj = new BoolObject((value == "True")); break; default: throw new LexemException($"Can't recognize {value} type"); } return(obj); } catch (Exception) { return(null); } } }
public override EvalObject Add(EvalObject obj) { string sstr1 = GetValue(); string sstr2 = obj.GetValue(); string sub1 = sstr1.Substring(1, sstr1.Length - 2); string sub2; if (obj.SystemType == SystemTypes.Char) { sub2 = $"{sstr2[1]}"; } else if (obj.SystemType == SystemTypes.String) { sub2 = sstr2.Substring(1, sstr2.Length - 2); } else { throw new TypeMismatchException(); } return((StringObject)Memory.CreateObjectFromValue($"\"{sub1}{sub2}\"")); }
/// <summary> /// Создаёт идентификатор переменной /// </summary> /// <param name="value"></param> /// <param name="type"></param> /// <param name="obj"></param> /// <returns></returns> public static Identifier ReferrenceIdentifier(string value, SystemTypes?type = null, EvalObject obj = null) { Identifier item = (obj == null) ? item = new Identifier(value, type) : item = new Identifier(value, obj); for (int i = 0; i < Identifiers.Count; i++) { if (Identifiers[i].Literal == item.Literal) { if (item.Value != null) { Identifiers[i].Value = item.Value; } return(Identifiers[i]); } } Identifiers.Add(item); return(item); }
/// <summary> /// Создаёт обхект в памяти /// </summary> /// <param name="obj"></param> /// <returns></returns> static bool CreateObj(EvalObject obj) { Objects.Add(MemAddress += (uint)obj.SizeOf(), obj); return(true); }