/// <summary> /// Defines a constant variable. /// </summary> /// <param name="name">The name of the constant to define</param> /// <param name="dataType">The data type to use</param> /// <param name="value">The value of the constant</param> /// <exception cref="ConstantAlreadyDefinedException"></exception> public void DefineConstant(string name, ConfigVariableDataType dataType, object value, int trackingLineNumber = -1) { CheckIdentifier(name, trackingLineNumber); if (DefinedConstants.ContainsKey(name)) { throw new ConstantAlreadyDefinedException(name, trackingLineNumber); } DefinedConstants[name] = new ConfigVariable() { Name = name, DataType = dataType, Value = value }; }
/// <summary> /// Parse a variable from string. /// </summary> /// <param name="str">The variable string to parse</param> /// <returns>A variable constructed from the specified string</returns> private ConfigVariable ParseVar(string str) { string variableName = str.Substring(0, str.IndexOf(' ')); string rightHandValue = str.Substring(str.IndexOf(' ') + 1).Trim(); ConfigVariableDataType dataType = ConfigVariableDataType.Integer; // Assume integer at first if ((rightHandValue == "true") || (rightHandValue == "false")) { return new ConfigVariable { DataType = ConfigVariableDataType.Boolean, Name = variableName, Value = bool.Parse(rightHandValue) } } ; else if (rightHandValue == "null") { return new ConfigVariable { DataType = ConfigVariableDataType.Null, Name = variableName, Value = new ConfigNullValue() } } ; bool escapeMode = false; //Are we in escape char mode? bool literalTerminated = false; bool literalTypeFound = false; string resultantString = ""; int resultantInt = 0; List <string> resultantList = new List <string>(); for (int i = 0; i < rightHandValue.Length; i++) { if (rightHandValue[i] == '\\') { escapeMode = true; continue; } else if ((rightHandValue[i] == '"') && (!escapeMode)) //Found a string quote { if (!literalTypeFound) { literalTypeFound = true; dataType = ConfigVariableDataType.String; continue; } //This is a string terminator literalTerminated = true; break; //Exit the loop } switch (dataType) { case ConfigVariableDataType.String: if (escapeMode) { switch (rightHandValue[i]) { case 't': resultantString += '\t'; break; case 'n': resultantString += '\n'; break; case 'a': resultantString += '\a'; break; case '"': resultantString += '"'; break; } } else { resultantString += rightHandValue[i]; } break; case ConfigVariableDataType.Integer: if (rightHandValue[i] == ' ') { break; //Reached the end of literal } resultantString += rightHandValue[i]; //String like operation break; } if (escapeMode) { escapeMode = false; continue; } } if ((dataType == ConfigVariableDataType.String) && (!literalTerminated)) { throw new StringLiteralNotTerminatedException(variableName, lineNumber); } if (dataType == ConfigVariableDataType.Integer) { resultantInt = int.Parse(resultantString.Trim()); } return(new ConfigVariable { DataType = dataType, Name = variableName, Value = new Func <object>(() => { if (dataType == ConfigVariableDataType.Integer) { return resultantInt; } else { return resultantString; } })() }); //TODO optimize code here pls }