/// <summary> /// Обработка управляющих символов /// </summary> private void HandleControlChar(string controlChar) { var trigger = controlChar.Substring(0, controlChar.Length - 8); switch (trigger) { case "DEFINE": var defineVarType = (string)TypeStack.Peek().GetValue(); var defineVarName = (string)NamePtrStack.Peek().GetValue(); if (CommonTables.Variables.ContainsKey(defineVarName)) { throw new CompilatorException($"'{defineVarName}' is already declared"); } switch (defineVarType) { case "int": CommonTables.Variables[defineVarName] = 0; break; case "float": CommonTables.Variables[defineVarName] = 0f; break; case "string": CommonTables.Variables[defineVarName] = ""; break; } break; case "ADD": case "SUB": case "MULT": case "DIV": case "POW": var addN2 = ValuePtrStack.Pop().GetValue(); var addN1 = ValuePtrStack.Pop().GetValue(); Arithmetic(addN1, addN2, trigger); break; case "EQUATION": var equationLeft = (string)NamePtrStack.Peek().GetValue(); var equationRight = ValuePtrStack.Pop().GetValue(); if (!CommonTables.Variables.ContainsKey(equationLeft)) { throw new CompilatorException($"Variable wasn't initialized: {equationLeft}"); } var identificatorType = CommonTables.Variables[equationLeft].GetType(); var valueType = equationRight.GetType(); if (valueType != identificatorType) { if (identificatorType == typeof(int) && valueType == typeof(float)) { throw new CompilatorException("you are not allowed to appropriate float as int"); } if (identificatorType == typeof(float) && valueType == typeof(int)) { equationRight = equationRight as float? ?? (int)equationRight; } else if (identificatorType == typeof(string) && (valueType == typeof(float) || valueType == typeof(int))) { equationRight = equationRight.ToString(); } else { throw new CompilatorException($"Trying to approptiate '{valueType}' to '{identificatorType}'"); } } CommonTables.Variables[equationLeft] = equationRight; Console.WriteLine($"Eq: {equationLeft} = {equationRight}"); break; case "GET": var getName = (string)NamePtrStack.Pop().GetValue(); if (!CommonTables.Variables.ContainsKey(getName)) { throw new CompilatorException($"Variable wasn't initialized: {getName}"); } var getValue = CommonTables.Variables[getName]; ValuePtrStack.Push(CommonTables.SaveConstant(getValue)); break; case "UNARYPP": case "UNARYMM": UnaryOperation(trigger); break; case "REMOVE_IDENT": NamePtrStack.Pop(); break; } }
/// <summary> /// Обработка арифметических операций от управляющих символов /// </summary> private void Arithmetic(object N1obj, object N2obj, string type) { object addNew = null; if (N1obj is int && N2obj is int) { var N1 = (int)N1obj; var N2 = (int)N2obj; switch (type) { case "ADD": addNew = N1 + N2; break; case "SUB": addNew = N1 - N2; break; case "DIV": if (N2 == 0) { throw new CompilatorException("dividing by zero"); } addNew = N1 / N2; break; case "MULT": addNew = N1 * N2; break; case "POW": addNew = (int)Math.Pow(N1, N2); break; } } else if (N1obj is float || N2obj is float) { var N1 = N1obj as float? ?? (int)N1obj; var N2 = N2obj as float? ?? (int)N2obj; switch (type) { case "ADD": addNew = N1 + N2; break; case "SUB": addNew = N1 - N2; break; case "DIV": if (Math.Abs(N2) < 0.0001) { throw new CompilatorException("dividing by zero"); } addNew = N1 / N2; break; case "MULT": addNew = N1 * N2; break; case "POW": addNew = (float)Math.Pow(N1, N2); break; } } else if (N1obj is string || N2obj is string) { var N1 = N1obj.ToString(); var N2 = N2obj.ToString(); if (type == "ADD") { addNew = N1 + N2; } else { throw new CompilatorException($"Operation {type} for string types is not currently available, please do not shot at your leg"); } } ValuePtrStack.Push(CommonTables.SaveConstant(addNew)); }