コード例 #1
0
        ExprNode FindSymbol(AstScope scope)
        {
            if (Arguments == null)
            {
                // Simple symbol
                var symbol = scope.FindSymbol(_name);
                if (symbol == null)
                {
                    throw new CodeException($"Unrecognized symbol: '{_name}'", SourcePosition);
                }
                var expr = symbol as ExprNode;
                if (expr == null)
                {
                    throw new CodeException($"Invalid expression: '{_name}' is not a value", SourcePosition);
                }
                return(expr);
            }
            else
            {
                // Parameterized symbol
                var symbol = scope.FindSymbol(_name + ExprNodeParameterized.MakeSuffix(Arguments.Length)) as ExprNodeParameterized;
                if (symbol == null)
                {
                    throw new CodeException($"Unrecognized symbol: '{_name}' (with {Arguments.Length} arguments)", SourcePosition);
                }

                // Resolve it
                return(symbol.Resolve(SourcePosition, Arguments));
            }
        }
コード例 #2
0
        public void BuildType(AstScope definingScope, ref int offset)
        {
            // Store offset
            _offset = offset;

            // Find the field's type
            var symbol = definingScope.FindSymbol(_typename);

            if (symbol == null)
            {
                throw new CodeException($"Unknown type: '{_typename}'", SourcePosition);
            }
            _type = symbol as AstType;
            if (_type == null)
            {
                throw new CodeException($"Invalid type declaration: '{_typename}' is not a type");
            }

            // Resolve the array size
            _arraySize = 0;
            foreach (var d in _initializer.EnumData(definingScope))
            {
                if (!(d is ExprNodeUninitialized))
                {
                    throw new CodeException($"Invalid struct definition: all fields must be declared with uninitialized data", SourcePosition);
                }
                _arraySize++;
            }


            // Update the size
            offset += _type.SizeOf * _arraySize;
        }
コード例 #3
0
        public override void Layout(AstScope currentScope, LayoutContext ctx)
        {
            // Is it a data declaration?
            _dataType = currentScope.FindSymbol(_macroOrDataTypeName) as AstType;
            if (_dataType != null)
            {
                // Work out how many elements in total
                int totalElements = 0;
                foreach (var n in _operands)
                {
                    totalElements += n.EnumData(currentScope).Count();
                }

                // Reserve space
                ctx.ReserveBytes(_reservedBytes = totalElements * _dataType.SizeOf);

                return;
            }

            // Is it a macro invocation?
            _macroDefinition = currentScope.FindSymbol(_macroOrDataTypeName + ExprNodeParameterized.MakeSuffix(_operands.Count)) as AstMacroDefinition;
            if (_macroDefinition != null)
            {
                // Create resolved scope
                _resolvedScope = _macroDefinition.Resolve(currentScope, _operands.ToArray());

                // Define macro symbols
                _macroDefinition.DefineSymbolsResolved(_resolvedScope);

                // Layout
                _macroDefinition.LayoutResolved(_resolvedScope, ctx);

                return;
            }

            throw new CodeException($"Unrecognized symbol: '{_macroOrDataTypeName}' is not a known data type or macro (with {_operands.Count} arguments)", SourcePosition);
        }
コード例 #4
0
        public override object Evaluate(AstScope scope)
        {
            if (Arguments == null)
            {
                // Simple symbol
                var symbol = scope.FindSymbol(_name);
                if (symbol == null)
                {
                    throw new CodeException($"Unrecognized symbol: '{_name}'", SourcePosition);
                }
                return(symbol);
            }

            return(base.Evaluate(scope));
        }
コード例 #5
0
        public override void Layout(AstScope currentScope, LayoutContext ctx)
        {
            // Work out width and height
            int blockWidth  = (int)_width.EvaluateNumber(currentScope);
            int blockHeight = (int)_height.EvaluateNumber(currentScope);

            if (blockWidth < 1)
            {
                throw new CodeException("Invalid bitmap block width", SourcePosition);
            }
            if (blockHeight < 1)
            {
                throw new CodeException("Invalid bitmap block height", SourcePosition);
            }

            // Build the bitmap
            List <string> bits = new List <string>();

            for (int i = 0; i < _strings.Count; i++)
            {
                var row = new StringBuilder();

                foreach (var ch in _strings[i])
                {
                    // Find the bit definition
                    var bitdef = currentScope.FindSymbol($"bitpattern'{ch}'") as AstDefBits;
                    if (bitdef == null)
                    {
                        throw new CodeException($"No bit definition for character '{ch}'", SourcePosition);
                    }

                    row.Append(bitdef.GetBitPattern(currentScope));
                }

                bits.Add(row.ToString());
            }

            if (bits.Select(x => x.Length).Distinct().Count() != 1)
            {
                throw new CodeException("All rows in a bitmap must the same length", SourcePosition);
            }

            if ((bits[0].Length % blockWidth) != 0)
            {
                throw new CodeException("Bitmap width must be a multiple of the block width", SourcePosition);
            }

            if ((bits.Count % blockHeight) != 0)
            {
                throw new CodeException("Bitmap height must be a multiple of the block height", SourcePosition);
            }

            if (((blockWidth * bits.Count) % 8) != 0)
            {
                throw new CodeException("Bitmap block width multiplied by bitmap height must be a multiple of 8", SourcePosition);
            }

            int blocksAcross = bits[0].Length / blockWidth;
            int blocksDown   = bits.Count / blockHeight;

            int  bitCounter    = 0;
            byte assembledByte = 0;
            var  bytes         = new List <byte>();

            for (int blockY = 0; blockY < blocksDown; blockY++)
            {
                for (int blockX = 0; blockX < blocksAcross; blockX++)
                {
                    for (int bitY = 0; bitY < blockHeight; bitY++)
                    {
                        for (int bitX = 0; bitX < blockWidth; bitX++)
                        {
                            var bit = bits[blockY * blockHeight + bitY][blockX * blockWidth + bitX];
                            if (_msbFirst)
                            {
                                assembledByte = (byte)(assembledByte << 1 | (bit == '1' ? 1 : 0));
                            }
                            else
                            {
                                assembledByte = (byte)(assembledByte >> 1 | (bit == '1' ? 0x80 : 0));
                            }

                            bitCounter++;
                            if (bitCounter == 8)
                            {
                                bitCounter = 0;
                                bytes.Add(assembledByte);
                            }
                        }
                    }
                }
            }

            _bytes = bytes.ToArray();
            ctx.ReserveBytes(_bytes.Length);
        }