public void BindField(FieldInfo field, HotloaderClass cls) { string name = field.Name; HotloaderVariable v = cls.GetVariable(name); if (v == null) { v = new HotloaderVariable(name, this); if (!cls.AddVariable(v)) { throw new Exception( String.Format( "Cannot bind field. Name \"{0}\" already in use.", name)); } } BindField(field, v); }
private void handleBlock( List <HotloaderVariable> variables, HotloaderFile file, byte *blockPtr, byte *blockEnd, int currentLine, int currentColumn, ref bool negativeFlag, ref parserMode mode, ref HotloaderAccessor currentAccessor, ref HotloaderVariable currentVariable, ref HotloaderExpression currentExpression, ref HotloaderClass currentClass) { //read the block as a string string block = readString(blockPtr, blockEnd); //hash the string so we can do quick compares with keywords int hash = block.GetHashCode(); #region include if (hash == STRING_INCLUDE_HASH) { //valid? if (mode != parserMode.NONE) { throw new HotloaderParserException( file, currentLine, currentColumn, "Unexpected include"); } mode = parserMode.INCLUDE; return; } #endregion #region reserve word check /*since we detect errors if some keywords * are used anyway, some are discarded here.*/ if (mode != parserMode.ASSIGNMENT) { if (hash == STRING_TRUE_HASH || hash == STRING_FALSE_HASH) { throw new HotloaderParserException( file, currentLine, currentColumn, String.Format( "Unexpected use of symbol \"{0}\"", block)); } } #endregion #region accessors bool isConst = hash == STRING_CONST_HASH; bool isStatic = hash == STRING_STATIC_HASH; //valid mode? if (mode != parserMode.NONE) { if (isConst || isStatic) { throw new HotloaderParserException( file, currentLine, currentColumn, "Unexpected accessor"); } } if (isConst) { currentAccessor |= HotloaderAccessor.CONST; } if (isStatic) { currentAccessor |= HotloaderAccessor.STATIC; } if (isConst || isStatic) { return; } #endregion #region end of a class? if (hash == STRING_END_HASH) { //verify that we can end a class if (currentClass.Parent == null || mode != parserMode.NONE) { throw new HotloaderParserException( file, currentLine, currentColumn, "Unexpected end of class token."); } //end the class by just setting //the current class to the parent currentClass = currentClass.Parent; return; } #endregion #region class declaration //are we expecting a class name? if (mode == parserMode.CLASS) { //a class cannot have accessors! if (currentAccessor != HotloaderAccessor.NONE) { throw new HotloaderParserException( file, currentLine, currentColumn, "Classes cannot have accessors"); } //get the class HotloaderClass cls = currentClass.GetClass(block); if (cls == null) { cls = new HotloaderClass(block, this); //only reason this will return false is //if it already exists! if (!currentClass.AddClass(cls)) { throw new HotloaderParserException( file, currentLine, currentColumn, String.Format( "Cannot declare class \"{0}\". Name already used elsewhere.", block)); } } //set the current class to the newly created one //so every variable/class added will be added //to this one. currentClass = cls; //we are no longer reading a class mode = parserMode.NONE; return; } #endregion #region variable declaration //we must be in assignment mode by now.. if (mode == parserMode.VARIABLE) { throw new HotloaderParserException( file, currentLine, currentColumn, "Unexpected variable declaration"); } //we assume this is an alpha-numerical string if (mode == parserMode.NONE) { //does this variable already exist? //if not, add it. currentVariable = currentClass.GetVariable(block); if (currentVariable == null) { //if the add function returns false, then //the variable name is already taken! currentVariable = new HotloaderVariable(block, this); if (!currentClass.AddVariable(currentVariable)) { throw new HotloaderParserException( file, currentLine, currentColumn, String.Format( "Cannot declare variable \"{0}\". Name already used elsewhere.", block)); } } //add to the list of added variables from the file variables.Add(currentVariable); //if we can't change this variable (it's marked as static //just set the current variable to a dummy one. if ((currentVariable.Accessors & HotloaderAccessor.STATIC) == HotloaderAccessor.STATIC) { currentVariable = new HotloaderVariable("dummy", this); currentVariable.changeParent(currentClass); } //set expression currentExpression = currentVariable.Value; currentExpression.Clear(); //set accessors currentVariable.Accessors = currentAccessor; currentAccessor = HotloaderAccessor.NONE; //wait for assignment etc.. mode = parserMode.VARIABLE; } #endregion #region variable assignment if (mode == parserMode.ASSIGNMENT) { #region boolean string blockLower = block.ToLower(); if (blockLower == "true" || blockLower == "false") { currentExpression.AddOperand( (block == "true"), HotloaderValueType.BOOLEAN, currentLine, currentColumn, file); return; } #endregion #region numerical? double decimalValue; bool isDecimal = Double.TryParse(block, out decimalValue); if (isDecimal) { //is it an actual decimal or integer? bool explicitDecimal = block.Contains("."); //negate? if (negativeFlag) { decimalValue = -decimalValue; negativeFlag = false; } //deturmine value type HotloaderValueType type = explicitDecimal ? HotloaderValueType.DECIMAL : HotloaderValueType.NUMERICAL; //deturmine raw object for the string object raw = decimalValue; if (!explicitDecimal) { raw = (long)decimalValue; } currentExpression.AddOperand( raw, type, currentLine, currentColumn, file); return; } #endregion #region base conversion if (block.Length > 2 && *blockPtr == '0') { //detect base conversion int sourceBase = -1; byte sourceBaseByte = *(blockPtr + 1); if (sourceBaseByte == 'x') { sourceBase = 16; } else if (sourceBaseByte == 'b') { sourceBase = 2; } //is it actually a conversion? if (sourceBase != -1) { string convert = block.Substring(2); //attempt to convert try { long converted = Convert.ToInt64(convert, sourceBase); //add the operand currentExpression.AddOperand( converted, HotloaderValueType.NUMERICAL, currentLine, currentColumn, file); } catch { throw new HotloaderParserException( file, currentLine, currentColumn, String.Format( "Unable to convert {0} from base {1}", convert, sourceBase)); } return; } } #endregion #region variable? //verify the name while (blockPtr != blockEnd) { byte current = *(blockPtr++); if (!isNameCharacter(current)) { throw new HotloaderParserException( file, currentLine, currentColumn, String.Format( "Invalid variable name \"{0}\"", block)); } } //default to a variable reference currentExpression.AddOperand( block, HotloaderValueType.VARIABLE, currentLine, currentColumn, file); #endregion } #endregion }