Пример #1
0
    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);
    }
Пример #2
0
    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
    }