mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
added offsetof() to get the byte offset of struct members.
This commit is contained in:
parent
975af4764d
commit
997bc21feb
@ -102,6 +102,7 @@ private val functionSignatures: List<FSignature> = listOf(
|
||||
FSignature("abs" , true, listOf(FParam("value", NumericDatatypes)), null, ::builtinAbs), // type depends on argument
|
||||
FSignature("len" , true, listOf(FParam("values", IterableDatatypes)), null, ::builtinLen), // type is UBYTE or UWORD depending on actual length
|
||||
FSignature("sizeof" , true, listOf(FParam("object", DataType.values().toSet())), DataType.UBYTE, ::builtinSizeof),
|
||||
FSignature("offsetof" , true, listOf(FParam("object", DataType.values().toSet())), DataType.UBYTE, ::builtinOffsetof),
|
||||
// normal functions follow:
|
||||
FSignature("sgn" , true, listOf(FParam("value", NumericDatatypes)), DataType.BYTE, ::builtinSgn ),
|
||||
FSignature("sin" , true, listOf(FParam("rads", setOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg -> oneDoubleArg(a, p, prg, Math::sin) },
|
||||
@ -278,6 +279,28 @@ private fun builtinAbs(args: List<Expression>, position: Position, program: Prog
|
||||
}
|
||||
}
|
||||
|
||||
private fun builtinOffsetof(args: List<Expression>, position: Position, program: Program): NumericLiteralValue {
|
||||
// 1 arg, type = anything, result type = ubyte
|
||||
if(args.size!=1)
|
||||
throw SyntaxError("offsetof requires one argument", position)
|
||||
val idref = args[0] as? IdentifierReference
|
||||
?: throw SyntaxError("offsetof argument should be an identifier", position)
|
||||
|
||||
val vardecl = idref.targetVarDecl(program.namespace)!!
|
||||
val struct = vardecl.struct
|
||||
if (struct == null || vardecl.datatype == DataType.STRUCT)
|
||||
throw SyntaxError("offsetof can only be used on struct members", position)
|
||||
|
||||
val membername = idref.nameInSource.last()
|
||||
var offset = 0
|
||||
for(member in struct.statements) {
|
||||
if((member as VarDecl).name == membername)
|
||||
return NumericLiteralValue(DataType.UBYTE, offset, position)
|
||||
offset += member.datatype.memorySize()
|
||||
}
|
||||
throw SyntaxError("undefined struct member", position)
|
||||
}
|
||||
|
||||
private fun builtinSizeof(args: List<Expression>, position: Position, program: Program): NumericLiteralValue {
|
||||
// 1 arg, type = anything, result type = ubyte
|
||||
if(args.size!=1)
|
||||
|
@ -843,6 +843,11 @@ sizeof(name)
|
||||
For an 10 element array of floats, it is 50 (on the C-64, where a float is 5 bytes).
|
||||
Note: usually you will be interested in the number of elements in an array, use len() for that.
|
||||
|
||||
offsetof(membername)
|
||||
Number of bytes from the start of a struct variable that this member variable is located.
|
||||
For now, this only works on members of a declared struct variable and not yet on members
|
||||
referenced from the struct type itself. This might be improved in a future version of the language.
|
||||
|
||||
swap(x, y)
|
||||
Swap the values of numerical variables (or memory locations) x and y in a fast way.
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- add offsetof() to get the byte offset of struct members.
|
||||
- add any2(), all2(), max2(), min2(), reverse2(), sum2(), sort2() that take (array, startindex, length) arguments
|
||||
- optimize for loop iterations better to allow proper inx, cpx #value, bne loop instructions (like repeat loop)
|
||||
- why is there a beq _prog8_label_2_repeatend at the end of repeat loops? seems unused
|
||||
|
@ -1,6 +1,7 @@
|
||||
%import textio
|
||||
%import diskio
|
||||
%import string
|
||||
%import floats
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
@ -9,14 +10,41 @@ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
diskio.directory(8)
|
||||
diskio.save(8, "blabla", $2000, 1024)
|
||||
diskio.directory(8)
|
||||
diskio.rename(8, "blabla", "newname")
|
||||
diskio.directory(8)
|
||||
diskio.delete(8, "newname")
|
||||
diskio.directory(8)
|
||||
struct SaveData {
|
||||
ubyte galaxy
|
||||
ubyte planet
|
||||
uword cash
|
||||
float flt
|
||||
ubyte fuel
|
||||
}
|
||||
|
||||
SaveData data
|
||||
|
||||
txt.print("size of struct: ")
|
||||
txt.print_ub(sizeof(SaveData))
|
||||
txt.chrout(';')
|
||||
txt.print_ub(sizeof(data))
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("offset of galaxy: ")
|
||||
txt.print_ub(offsetof(data.galaxy))
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("offset of planet: ")
|
||||
txt.print_ub(offsetof(data.planet))
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("offset of cash: ")
|
||||
txt.print_ub(offsetof(data.cash))
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("offset of flt: ")
|
||||
txt.print_ub(offsetof(data.flt))
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("offset of fuel: ")
|
||||
txt.print_ub(offsetof(data.fuel))
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("---------------------------------\n")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user