コード例 #1
1
ファイル: TypeLinking.cs プロジェクト: Andos/BinaryFileSchema
        private static void CheckActionList(IList<IBfsAction> actions, IBfsDataBlock block)
        {
            if (actions == null)
                return;

            for( int index = 0; index < actions.Count; index++)
            {
                IBfsAction action = actions[index];

                if (action is BfsActionUnresolvedAssignment)
                {
                    BfsActionUnresolvedAssignment unresolved = action as BfsActionUnresolvedAssignment;
                    BfsActionAssignment assignment = new BfsActionAssignment();
                    assignment.Expression = unresolved.Expression;
                    assignment.SourceRange = unresolved.SourceRange;
                    if (block.LocalFields.ContainsKey(unresolved.UnresolvedVariableName))
                        assignment.LocalVariable = block.LocalFields[unresolved.UnresolvedVariableName];
                    else
                        BfsCompiler.ReportError(assignment.SourceRange,
                            "Could not find local variable: '"+unresolved.UnresolvedVariableName+"'");

                    actions.Insert(index, assignment);
                    actions.Remove(action);
                }
            }
        }
コード例 #2
0
ファイル: Inspector.cs プロジェクト: Andos/BinaryFileSchema
 private void ReadDataBlock(IBfsDataBlock block, TreeNode parent)
 {
     if (block is BfsStruct)
         ReadStruct(block as BfsStruct, parent);
     else if (block is BfsEnum)
         ReadEnum(block as BfsEnum, parent);
     else if (block is BfsBitfield)
         ReadBitField(block as BfsBitfield, parent);
 }
コード例 #3
0
 public bool MakeActionList(IBfsDataBlock owner, List<string> actionList, IList<IBfsAction> actions)
 {
     //This loop is terminated when encountering an error statement.
     foreach (IBfsAction action in actions)
     {
         if (action is BfsActionAssignment)
         {
             BfsActionAssignment assignment = action as BfsActionAssignment;
             actionList.Add( owner.Name.ToLower() + "." + assignment.LocalVariable + " = " + CSHelper.MakeExpression(assignment.Expression,owner)+";");
         }
         else if (action is BfsActionOutput)
         {
             BfsActionOutput output = action as BfsActionOutput;
             if (output.FunctionName == "error")
             {
                 actionList.Add("throw new Exception(" + output.Argument + ");");
                 return false;
             }
             else if (output.FunctionName == "warning")
                 actionList.Add("//WARNING: " + output.Argument);
         }
     }
     return true;
 }
コード例 #4
0
ファイル: Hierarchy.cs プロジェクト: Andos/BinaryFileSchema
 private void CheckExpression(BfsExpression expression, IBfsDataBlock block)
 {
     CheckExpressionNode(expression, expression.ExpressionGroup, block);
     CheckForEnumMembers(expression.ExpressionGroup, block);
 }
コード例 #5
0
ファイル: Hierarchy.cs プロジェクト: Andos/BinaryFileSchema
        private void CheckForEnumMembers(BfsExpGroup group, IBfsDataBlock block)
        {
            //For each expression variable in the expression group
            for (int index = 0; index < group.Members.Count; index++)
            {
                //Recursively visit the sub-expressions
                IBfsExpNode node = group.Members[index];
                if (node is BfsExpGroup)
                {
                    CheckForEnumMembers(node as BfsExpGroup, block);
                    continue;
                }

                //Ignore irrelevant objects (operators and known variables)
                if (!(node is BfsExpressionVariable))
                    continue;
                BfsExpressionVariable expressionvar = node as BfsExpressionVariable;
                if (!(expressionvar.LastField is BfsExpressionUnknown))
                    continue;

                //Only interested in resolving the BfsExpressionUnknowns
                BfsExpressionUnknown unknown = expressionvar.LastField as BfsExpressionUnknown;

                BfsExpressionVariable candidatevar = null;
                bool resolvedTheVar = false;

                BfsOperator op = null;

                if (index >= 2 && group.Members[index - 2] is BfsExpressionVariable)
                {
                    op = group.Members[index - 1] as BfsOperator;
                    candidatevar = group.Members[index - 2] as BfsExpressionVariable;
                }
                else if (index + 2 < group.Members.Count && group.Members[index + 2] is BfsExpressionVariable)
                {
                    op = group.Members[index + 1] as BfsOperator;
                    candidatevar = group.Members[index + 2] as BfsExpressionVariable;
                }

                if ( candidatevar != null
                    && candidatevar.LastField is BfsStructField
                    && (candidatevar.LastField as BfsStructField).FieldType is BfsNamedType)
                {
                    BfsStructField field = candidatevar.LastField as BfsStructField;
                    BfsNamedType fieldtype = field.FieldType as BfsNamedType;

                    if (fieldtype.DataBlock is BfsEnum && (fieldtype.DataBlock as BfsEnum).EnumAliases.ContainsKey(unknown.Name))
                    {
                        resolvedTheVar = true;
                        BfsEnumFieldAlias enumalias = (fieldtype.DataBlock as BfsEnum).EnumAliases[unknown.Name];
                        BfsEnumAliasExp aliasExp = new BfsEnumAliasExp();
                        aliasExp.EnumBlock = fieldtype.DataBlock as BfsEnum;
                        aliasExp.Alias = enumalias;
                        aliasExp.SourceRange = unknown.SourceRange;

                        //Only allow equality operators on EnumAliases
                        if (op.Operator == "==" || op.Operator == "!=")
                        {
                            group.Members.Insert(index, aliasExp);
                            group.Members.Remove(node);
                        }
                        else
                            BfsCompiler.ReportError(op.SourceRange,
                                "The operator '"+op.Operator+"' cannot be used with the enum alias '"+enumalias.Name+"'. Only == and != are allowed.");

                        expressionvar.LastField = aliasExp;
                    }
                }

                if(!resolvedTheVar)
                    BfsCompiler.ReportError(unknown.SourceRange,
                        "Unresolved variable name: '" + unknown.Name + "'");
            }
        }
コード例 #6
0
ファイル: Hierarchy.cs プロジェクト: Andos/BinaryFileSchema
        private void CheckExpressionNode(BfsExpression exp, BfsExpGroup group, IBfsDataBlock block)
        {
            for (int index = 0; index < group.Members.Count; index++)
            {
                IBfsExpNode node = group.Members[index];

                if (node is BfsOperator)
                    continue;

                if (node is BfsExpGroup)
                    CheckExpressionNode(exp, node as BfsExpGroup, block);
                else if (node is BfsCallExp)
                {
                    BfsCallExp call = node as BfsCallExp;
                    if (call.FunctionName != "sizeof")
                    {
                        BfsCompiler.ReportError(call.NameSourceRange,
                            "Unknown function: '" + call.FunctionName + "'");
                        break;
                    }
                    //If the argument in sizeof(data-block) can be found.
                    else if (schema.DataBlocks.ContainsKey(call.FunctionArgument))
                    {
                        if (schema.DataBlocks[call.FunctionArgument] is IBfsStructType)
                            CalculateStructSize(call.SourceRange, schema.DataBlocks[call.FunctionArgument] as IBfsStructType);

                        call.SizeInBytes = schema.DataBlocks[call.FunctionArgument].SizeInBytes;
                        continue;
                    }
                    else
                        BfsCompiler.ReportError(call.ArgumentSourceRange,
                            "Could not find the data-block: '"+call.FunctionArgument+"'");
                }
                else if (node is BfsUnresolvedVariableExp)
                {
                    BfsUnresolvedVariableExp unresolved = node as BfsUnresolvedVariableExp;

                    //Boolean(true/false)?
                    if (unresolved.ToString() == "true" || unresolved.ToString() == "false")
                    {
                        BfsBooleanExp booleanExp = new BfsBooleanExp();
                        booleanExp.SourceRange = unresolved.SourceRange;
                        booleanExp.Value = (unresolved.ToString() == "true") ? true : false;
                        group.Members.Insert(index, booleanExp);
                        group.Members.Remove(unresolved);
                        continue;
                    }

                    //Value expression?
                    if (unresolved.ToString() == "value")
                    {
                        if (block is IBfsConsumptionType)
                        {
                            BfsValueExp valueExp = new BfsValueExp();
                            valueExp.SourceRange = unresolved.SourceRange;
                            group.Members.Insert(index, valueExp);
                            group.Members.Remove(unresolved);
                            continue;
                        }
                        else
                        {
                            BfsCompiler.ReportError(unresolved.SourceRange,
                                "The 'value' expression variable may only be used in consumed types.");
                            continue;
                        }
                    }

                    //Else it is a named variable.
                    BfsExpressionVariable namedVar = new BfsExpressionVariable();

                    namedVar.SourceRange = node.SourceRange;

                    group.Members.Insert(index, namedVar);
                    group.Members.Remove(node);

                    string containertype = block.ToString();

                    //Check hiearchy
                    IBfsDataBlock container = block;
                    for (int i = 0; i < unresolved.NameHierarchy.Count; i++)
                    {
                        string varname = unresolved.NameHierarchy[i];
                        if (container == null)
                        {
                            BfsCompiler.ReportError(node.SourceRange,
                                "Variable '" + unresolved.NameHierarchy[i - 1] + "' cannot contain any variables because it of type: " + containertype);
                            break;
                        }

                        if (container.LocalFields.ContainsKey(varname))
                        {
                            namedVar.NameHierarchy.Add(container.LocalFields[varname]);
                            containertype = " local variable";
                            container = null;
                        }
                        else if (container is IBfsStructType && (container as IBfsStructType).StructFields.ContainsKey(varname))
                        {
                            IBfsType type = (container as IBfsStructType).StructFields[varname].FieldType;
                            IBfsNamedField namedtype = (container as IBfsStructType).StructFields[varname];

                            if (type is BfsNamedType)
                            {
                                container = (type as BfsNamedType).DataBlock;

                                if (container is IBfsConsumptionType)
                                {
                                    IBfsConsumptionType consumed = container as IBfsConsumptionType;
                                    namedtype.PrimitiveType = consumed.PrimitiveType;
                                }

                                namedVar.NameHierarchy.Add(namedtype);
                            }
                            else if (type is BfsPrimitiveType)
                            {
                                containertype = "primitive type";
                                namedVar.NameHierarchy.Add(namedtype);
                                container = null;
                            }
                            else if (type is BfsFunctionType)
                            {
                                containertype = "function type";
                                namedVar.NameHierarchy.Add(namedtype);
                                container = null;
                            }
                            else BfsCompiler.ReportError(container.SourceRange, "Unexpected error. Unknown type.");
                        }
                        else
                        {
                            containertype = "unknown variable or enum-alias.";
                            BfsExpressionUnknown unknown = new BfsExpressionUnknown();
                            unknown.Name = varname;
                            unknown.SourceRange = unresolved.SourceRange;
                            namedVar.NameHierarchy.Add(unknown);
                            container = null;
                        }
                    }
                    //Building map over dependant variables.
                    exp.DependantVariables.Add(namedVar);
                }
            }
        }
コード例 #7
0
        public CodeClass MakeClass(IBfsDataBlock block)
        {
            //Append all local fields no matter the type
            CodeClass codeClass = new CodeClass(block.Name);
            foreach (BfsLocalField localField in block.LocalFieldList)
                codeClass.CodeFields.Add( localField.PrimitiveType.PrimitiveType.ToString().ToLower() + " " + localField.Name + ";");

            if (block is BfsStruct)
            {
                BfsStruct dataStruct = block as BfsStruct;
                MakeStruct(codeClass, dataStruct);
                return codeClass;
            }
            else if (block is BfsEnum)
            {
                BfsEnum dataEnum = block as BfsEnum;
                MakeEnum(codeClass, dataEnum);
                return codeClass;
            }
            else if (block is BfsBitfield)
            {
                BfsBitfield dataField = block as BfsBitfield;
                MakeBitfield(codeClass, dataField);
                return codeClass;
            }
            else if (block is BfsAbsOffset || block is BfsRelOffset)
            {
                BfsCompiler.ReportError(block.BlockTypeSourceRange,"Not yet implemented: Support for abs_offset or rel_offset!");
            }

            return null;
        }
コード例 #8
0
ファイル: AstConvert.cs プロジェクト: Andos/BinaryFileSchema
        private void ConvertLocalField(PegNode node, IBfsDataBlock block)
        {
            BfsLocalField localfield = new BfsLocalField();
            StoreSourceRange(node, localfield);
            localfield.Name = GetNodeText(node.child_);
            localfield.PrimitiveType = ConvertPrimitiveType(node.child_.next_);

            node = node.child_.next_.next_;
            if (node != null && GetNodeId(node) == EBinaryFileSchemaParser.expression)
                localfield.AssignmentExpression = ConvertExpression(node);

            block.LocalFieldList.Add(localfield);
        }
コード例 #9
0
        //Recursive visit of expression groups
        public static string VisitExpGroup(BfsExpGroup group, IBfsDataBlock owner)
        {
            StringBuilder b = new StringBuilder();
            b.Append("(");

            for (int i = 0; i < group.Members.Count; i++)
            {
                IBfsExpNode node = group.Members[i];

                if (node is BfsExpGroup)
                    b.Append(VisitExpGroup(node as BfsExpGroup, owner));
                else if (node is BfsExpressionVariable)
                {
                    BfsExpressionVariable expVar = node as BfsExpressionVariable;
                    b.Append(owner.Name.ToLower());

                    foreach (IBfsNamedField namedField in expVar.NameHierarchy)
                        b.Append("." + namedField.Name);

                    //Only append this last reading into the enum type if the value is being compared against an EnumAliasExp
                    if ((group.Members.Count > i + 2 && group.Members[i + 2] is BfsEnumAliasExp)
                        || (i >= 2 && group.Members[i - 2] is BfsEnumAliasExp))
                        b.Append("." + expVar.NameHierarchy[expVar.NameHierarchy.Count - 1]);
                }
                else if (node is BfsEnumAliasExp)
                {
                    //TODO
                    BfsEnumAliasExp enumAliasExp = node as BfsEnumAliasExp;
                    b.Append(enumAliasExp.EnumBlock.Name + "." + enumAliasExp.EnumBlock.Name + "Enum." + enumAliasExp.Alias.Name);
                }
                else if (node is BfsLocalField)
                {
                    BfsLocalField localField = node as BfsLocalField;
                    b.Append(localField.Name);
                }
                else
                    b.Append(" " + node + " ");
            }
            b.Append(")");
            return b.ToString();
        }
コード例 #10
0
        //Output C# code for an expression
        public static string MakeExpression(BfsExpression expression, IBfsDataBlock owner)
        {
            string exp = VisitExpGroup(expression.ExpressionGroup, owner);

            //Trim unnessecary parenthesis (BROKEN! not sure the parenthethis are matching)
            /*while (exp.StartsWith("(") && exp.EndsWith(")"))
                exp = exp.Substring(1, exp.Length - 2);*/

            return exp.Trim();
        }
コード例 #11
0
        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;
                }
            }
        }
コード例 #12
0
 private void CheckExpression(BfsExpression expression, IBfsDataBlock block)
 {
     CheckGroup(expression.ExpressionGroup, block);
     //BfsCompiler.ReportWarning(expression.ExpressionGroup.SourceRange, expression.ToString() + ": " + expression.PrimitiveType);
 }
コード例 #13
0
        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;
        }