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)); } }
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; }
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); }
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)); }
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); }