Inheritance: IBfsExpNode
        private static void ColorExpression(BfsExpGroup group)
        {
            if (group == null)
                return;

            foreach (IBfsExpNode node in group.Members)
            {
                //Put nodes here that should have been replaced in the TypeLinking phase.
                //if (node is BfsUnresolvedVariableExp)
                    //throw new Exception("Unresolved variable expression detected!");

                if (node is BfsExpGroup)
                    ColorExpression(node as BfsExpGroup);
                else if (node is BfsBooleanExp)
                {
                    BfsBooleanExp exp = node as BfsBooleanExp;
                    ColorRange(exp.SourceRange, keywordcolor);
                }
                else if (node is BfsNumberExp)
                {
                    BfsNumberExp val = node as BfsNumberExp;
                    ColorRange(val.SourceRange, numbercolor);
                }
                else if (node is BfsOperator)
                {
                    //TODO
                }
                else if (node is BfsValueExp)
                {
                    BfsValueExp val = node as BfsValueExp;
                    ColorRange(val.SourceRange, keywordcolor);
                }
                else if (node is BfsEnumAliasExp)
                {
                    BfsEnumAliasExp val = node as BfsEnumAliasExp;
                    ColorRange(val.SourceRange, enumaliascolor);
                }
                else if (node is BfsCallExp)
                {
                    BfsCallExp val = node as BfsCallExp;
                    ColorRange(val.NameSourceRange, keywordcolor);
                    ColorRange(val.ArgumentSourceRange, typecolor);
                }
            }
        }
Exemple #2
0
        private void ConvertExpNodes( BfsExpGroup group, PegNode node )
        {
            HashSet<EBinaryFileSchemaParser> groupnodes = new HashSet<EBinaryFileSchemaParser>(
                new EBinaryFileSchemaParser[] { EBinaryFileSchemaParser.logical, EBinaryFileSchemaParser.bitwise,
                    EBinaryFileSchemaParser.comp, EBinaryFileSchemaParser.shift, EBinaryFileSchemaParser.sum, EBinaryFileSchemaParser.prod });

            for (PegNode startnode = node.child_; startnode != null; startnode = startnode.next_)
            {
                //If the node is an operator: logical, bitwise, comparisson, bitshift, sum or product
                if (groupnodes.Contains(GetNodeId(startnode)))
                {
                    //Recursively generate subgroups
                    BfsExpGroup subgroup = new BfsExpGroup();
                    subgroup.SourceRange = GetSourceRange(startnode);
                    ConvertExpNodes(subgroup, startnode);
                    group.Members.Add(subgroup);
                }
                else
                {
                    switch (GetNodeId(startnode))
                    {
                        case EBinaryFileSchemaParser.number:
                            BfsNumberExp number = new BfsNumberExp();
                            StoreSourceRange(startnode, number);
                            number.Value = long.Parse( GetNodeText(startnode), CultureInfo.InvariantCulture );
                            group.Members.Add( number );
                            break;
                        case EBinaryFileSchemaParser.named_value:
                            BfsUnresolvedVariableExp var = new BfsUnresolvedVariableExp();
                            StoreSourceRange(startnode, var);
                            for (PegNode v = startnode.child_; v != null; v = v.next_)
                                var.NameHierarchy.Add(GetNodeText(v));
                            group.Members.Add(var);
                            break;
                        case EBinaryFileSchemaParser.call:
                            BfsCallExp call = new BfsCallExp();
                            call.SourceRange = GetSourceRange(startnode);
                            call.FunctionName = GetNodeText(startnode.child_);
                            call.NameSourceRange = GetSourceRange(startnode.child_);
                            call.FunctionArgument = GetNodeText(startnode.child_.next_);
                            call.ArgumentSourceRange = GetSourceRange(startnode.child_.next_);
                            group.Members.Add(call);
                            break;
                        //Operators
                        default:
                            BfsOperator op = new BfsOperator();
                            StoreSourceRange(startnode, op);
                            op.Operator = GetNodeText(startnode);
                            group.Members.Add(op);
                            break;
                    }
                }
            }
        }
        private void CheckType(BfsExpGroup group, BfsPrimitiveTypeEnum type, IBfsDataBlock block)
        {
            //If boolean and non-boolean types are mixed.
            if((group.PrimitiveType == BfsPrimitiveTypeEnum.Bool && type > BfsPrimitiveTypeEnum.Bool))
                BfsCompiler.ReportError(group.SourceRange, "Cannot mix boolean and " + type + " types");
            else if(type == BfsPrimitiveTypeEnum.Bool && group.PrimitiveType > BfsPrimitiveTypeEnum.Bool)
                BfsCompiler.ReportError(group.SourceRange, "Cannot mix boolean and " + group.PrimitiveType + " types");

            //if (type == BfsPrimitiveTypeEnum.FunctionType || group.PrimitiveType == BfsPrimitiveTypeEnum.FunctionType)
            //    BfsCompiler.ReportError(group.SourceRange, "You cannot use function typed variables in expressions");

            if (type == BfsPrimitiveTypeEnum.Undetermined)
                BfsCompiler.ReportError(group.SourceRange,"Undetermined type of variable");

            //If all is well then it will pick the largest type that can contain the variable.
            //Hiearchy: Undetermined,Bool,Ubyte,Sbyte,Ushort,Short,Uint,Int,Ulong,Long
            BfsPrimitiveTypeEnum a = group.PrimitiveType;
            BfsPrimitiveTypeEnum b = type;
            group.PrimitiveType = (a > b) ? a : b;
        }
        private void CheckGroup( BfsExpGroup group, IBfsDataBlock block )
        {
            foreach (IBfsExpNode node in group.Members)
            {
                if (node is BfsNumberExp)
                    CheckType(group, BfsPrimitiveTypeEnum.Int, block);
                else if (node is BfsBooleanExp)
                    CheckType(group, BfsPrimitiveTypeEnum.Bool, block);
                else if (node is BfsCallExp)
                    CheckType(group, BfsPrimitiveTypeEnum.CallExpression, block);
                else if (node is BfsExpressionVariable)
                {
                    BfsExpressionVariable expvar = node as BfsExpressionVariable;

                    //Check if the type of the variable is a function type (like ascii("Hello"))
                    if (expvar.LastField is BfsStructField)
                        if ((expvar.LastField as BfsStructField).FieldType is BfsFunctionType)
                            BfsCompiler.ReportError(expvar.SourceRange, "Cannot have function types in expressions!");

                    CheckType(group, expvar.PrimitiveType, block);

                    //Checking if any part of an expression variable references a variable that is array-extended
                    foreach( IBfsNamedField field in expvar.NameHierarchy )
                        if (field is BfsStructField)
                        {
                            BfsStructField f = field as BfsStructField;
                            if (f != null)
                            {
                                if (f.FieldType.ArrayExtension != null)
                                    BfsCompiler.ReportError(expvar.SourceRange,
                                        "Cannot use array-extended type in expression: '" + expvar + "'");

                                if (f.Skip)
                                    BfsCompiler.ReportError(expvar.SourceRange,
                                        "The variable '" + expvar + "' has been marked as skipped data and therefore cannot be used in expressions.");
                            }
                        }
                }
                else if (node is BfsEnumAliasExp)
                    CheckType(group, BfsPrimitiveTypeEnum.EnumMember, block);
                else if (node is BfsOperator)
                    CheckOperator(group, node as BfsOperator);
                else if (node is BfsExpGroup)
                {
                    BfsExpGroup g = node as BfsExpGroup;
                    CheckGroup(g, block);
                    //Compare the subgroups type to the parents (this) type.
                    CheckType(group, g.PrimitiveType, block);

                    //If the group consists of comparissons then the type of the group must be boolean.
                    if (g.OperatorPrecedenceLevel == BfsExpGroupOperatorLevel.Comparisson)
                        group.PrimitiveType = BfsPrimitiveTypeEnum.Bool;
                }
            }
        }
 private void CheckOperator(BfsExpGroup group, BfsOperator op)
 {
     //Just a formality check if the operators in the same group actually do belong to the same operator precedence-group
     if (group.OperatorPrecedenceLevel == BfsExpGroupOperatorLevel.Undetermined)
         group.OperatorPrecedenceLevel = op.PrecendenceLevel;
     else if (group.OperatorPrecedenceLevel != op.PrecendenceLevel)
         BfsCompiler.ReportError(op.SourceRange,"Mixed operator-precedence groups! '"
             + op + "' doesn't belong in '"+group.OperatorPrecedenceLevel+"'");
 }