make sizeof(float) work, so you don't have to use sys.SIZEOF_FLOAT anymore etc.

define sys.SIZEOF_FLOAT in terms of sizeof(float)
This commit is contained in:
Irmen de Jong
2025-05-29 02:37:00 +02:00
parent 368387e1a7
commit 3b1b0985c1
18 changed files with 173 additions and 102 deletions

View File

@@ -25,7 +25,7 @@ internal class NormalMemSizer(val floatsize: Int): IMemSizer {
return when {
dt.isByteOrBool -> 1 * (numElements ?: 1)
dt.isFloat -> floatsize * (numElements ?: 1)
dt.isLong -> throw IllegalArgumentException("long can not yet be put into memory")
dt.isLong -> 4 * (numElements ?: 1)
dt.isUndefined -> throw IllegalArgumentException("undefined has no memory size")
else -> 2 * (numElements ?: 1)
}

View File

@@ -91,31 +91,6 @@ class VMTarget: ICompilationTarget,
zeropage = VirtualZeropage(compilerOptions)
golden = GoldenRam(compilerOptions, UIntRange.EMPTY)
}
override fun memorySize(dt: DataType, numElements: Int?): Int {
if(dt.isArray) {
if(numElements==null) return 2 // treat it as a pointer size
return when(dt.sub) {
BaseDataType.BOOL, BaseDataType.UBYTE, BaseDataType.BYTE -> numElements
BaseDataType.UWORD, BaseDataType.WORD, BaseDataType.STR -> numElements * 2
BaseDataType.FLOAT-> numElements * FLOAT_MEM_SIZE
BaseDataType.UNDEFINED -> throw IllegalArgumentException("undefined has no memory size")
else -> throw IllegalArgumentException("invalid sub type")
}
}
else if (dt.isString) {
return numElements // treat it as the size of the given string with the length
?: 2 // treat it as the size to store a string pointer
}
return when {
dt.isByteOrBool -> 1 * (numElements ?: 1)
dt.isFloat -> FLOAT_MEM_SIZE * (numElements ?: 1)
dt.isLong -> throw IllegalArgumentException("long can not yet be put into memory")
dt.isUndefined -> throw IllegalArgumentException("undefined has no memory size")
else -> 2 * (numElements ?: 1)
}
}
}

View File

@@ -16,12 +16,6 @@ class C128Zeropage(options: CompilationOptions) : Zeropage(options) {
override val SCRATCH_W2 = 0xfdu // temp storage 2 for a word $fd+$fe
init {
if (options.floats) {
throw InternalCompilerException("C128 target doesn't yet support floating point routines")
// note: in git commit labeled 'c128: remove floats module' the floats.p8 and floats.asm files are removed,
// they could be retrieved again at a later time if the compiler somehow *does* store the fp variables in bank1.
}
if (options.floats && options.zeropage !in arrayOf(
ZeropageType.FLOATSAFE,
ZeropageType.BASICSAFE,

View File

@@ -16,10 +16,6 @@ class PETZeropage(options: CompilationOptions) : Zeropage(options) {
override val SCRATCH_W2 = 0xb8u // temp storage 2 for a word
init {
if (options.floats) {
throw InternalCompilerException("PET target doesn't yet support floating point routines")
}
if (options.floats && options.zeropage !in arrayOf(
ZeropageType.FLOATSAFE,
ZeropageType.BASICSAFE,

View File

@@ -419,12 +419,13 @@ sys {
const ubyte target = 128 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
const ubyte SIZEOF_BOOL = 1
const ubyte SIZEOF_BYTE = 1
const ubyte SIZEOF_UBYTE = 1
const ubyte SIZEOF_WORD = 2
const ubyte SIZEOF_UWORD = 2
const ubyte SIZEOF_FLOAT = 5
const ubyte SIZEOF_BOOL = sizeof(bool)
const ubyte SIZEOF_BYTE = sizeof(byte)
const ubyte SIZEOF_UBYTE = sizeof(ubyte)
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127
const ubyte MIN_UBYTE = 0

View File

@@ -439,12 +439,13 @@ sys {
const ubyte target = 64 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
const ubyte SIZEOF_BOOL = 1
const ubyte SIZEOF_BYTE = 1
const ubyte SIZEOF_UBYTE = 1
const ubyte SIZEOF_WORD = 2
const ubyte SIZEOF_UWORD = 2
const ubyte SIZEOF_FLOAT = 5
const ubyte SIZEOF_BOOL = sizeof(bool)
const ubyte SIZEOF_BYTE = sizeof(byte)
const ubyte SIZEOF_UBYTE = sizeof(ubyte)
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127
const ubyte MIN_UBYTE = 0

View File

@@ -1515,12 +1515,13 @@ sys {
const ubyte target = 16 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
const ubyte SIZEOF_BOOL = 1
const ubyte SIZEOF_BYTE = 1
const ubyte SIZEOF_UBYTE = 1
const ubyte SIZEOF_WORD = 2
const ubyte SIZEOF_UWORD = 2
const ubyte SIZEOF_FLOAT = 5
const ubyte SIZEOF_BOOL = sizeof(bool)
const ubyte SIZEOF_BYTE = sizeof(byte)
const ubyte SIZEOF_UBYTE = sizeof(ubyte)
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127
const ubyte MIN_UBYTE = 0

View File

@@ -98,12 +98,13 @@ sys {
const ubyte target = 32 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
const ubyte SIZEOF_BOOL = 1
const ubyte SIZEOF_BYTE = 1
const ubyte SIZEOF_UBYTE = 1
const ubyte SIZEOF_WORD = 2
const ubyte SIZEOF_UWORD = 2
const ubyte SIZEOF_FLOAT = 0 ; undefined, no floats supported
const ubyte SIZEOF_BOOL = sizeof(bool)
const ubyte SIZEOF_BYTE = sizeof(byte)
const ubyte SIZEOF_UBYTE = sizeof(ubyte)
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127
const ubyte MIN_UBYTE = 0

View File

@@ -7,12 +7,13 @@ sys {
const ubyte target = 255 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
const ubyte SIZEOF_BOOL = 1
const ubyte SIZEOF_BYTE = 1
const ubyte SIZEOF_UBYTE = 1
const ubyte SIZEOF_WORD = 2
const ubyte SIZEOF_UWORD = 2
const ubyte SIZEOF_FLOAT = 8
const ubyte SIZEOF_BOOL = sizeof(bool)
const ubyte SIZEOF_BYTE = sizeof(byte)
const ubyte SIZEOF_UBYTE = sizeof(ubyte)
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_FLOAT = sizeof(float)
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127
const ubyte MIN_UBYTE = 0

View File

@@ -115,6 +115,19 @@ private fun builtinSizeof(args: List<Expression>, position: Position, program: P
else -> NumericLiteral(BaseDataType.UBYTE, program.memsizer.memorySize(dt.getOrUndef(), null).toDouble(), position)
}
} else {
val identifier = args[0] as? IdentifierReference
if(identifier?.nameInSource?.size==1) {
when(identifier.nameInSource[0]) {
"ubyte" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.UBYTE), position)
"byte" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.BYTE), position)
"uword" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.UWORD), position)
"word" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.WORD), position)
"long" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.LONG), position)
"float" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.FLOAT), position)
"bool" -> return NumericLiteral.optimalInteger(program.memsizer.memorySize(BaseDataType.BOOL), position)
}
}
throw SyntaxError("sizeof invalid argument type", position)
}
}

View File

@@ -5,7 +5,9 @@ import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.ast.walk.IAstVisitor
import prog8.code.core.*
import prog8.code.target.C128Target
import prog8.code.target.Cx16Target
import prog8.code.target.PETTarget
import prog8.code.target.VMTarget
import prog8.compiler.builtinFunctionReturnType
import java.io.CharConversionException
@@ -763,6 +765,9 @@ internal class AstChecker(private val program: Program,
// FLOATS enabled?
if(!compilerOptions.floats && (decl.datatype.isFloat || decl.datatype.isFloatArray) && decl.type != VarDeclType.MEMORY)
err("floating point used, but that is not enabled via options")
else if(compilerOptions.compTarget.name in arrayOf(PETTarget.NAME, C128Target.NAME) && decl.type != VarDeclType.CONST && (decl.datatype.isFloat || decl.datatype.isFloatArray)) {
err("pet32 and c128 target do not support floating point numbers yet")
}
// ARRAY without size specifier MUST have an iterable initializer value
if(decl.isArray && decl.arraysize==null) {

View File

@@ -262,12 +262,13 @@ class TestMemory: FunSpec({
shouldThrow<IllegalArgumentException> {
target.memorySize(BaseDataType.UNDEFINED)
}
shouldThrow<IllegalArgumentException> {
target.memorySize(BaseDataType.LONG)
shouldThrow<NoSuchElementException> {
target.memorySize(DataType.arrayFor(BaseDataType.LONG), 10)
}
target.memorySize(BaseDataType.BOOL) shouldBe 1
target.memorySize(BaseDataType.BYTE) shouldBe 1
target.memorySize(BaseDataType.WORD) shouldBe 2
target.memorySize(BaseDataType.LONG) shouldBe 4
target.memorySize(BaseDataType.FLOAT) shouldBe target.FLOAT_MEM_SIZE
target.memorySize(DataType.BOOL, null) shouldBe 1
@@ -283,13 +284,14 @@ class TestMemory: FunSpec({
target.memorySize(DataType.arrayFor(BaseDataType.BOOL), 10) shouldBe 10
target.memorySize(DataType.arrayFor(BaseDataType.BYTE), 10) shouldBe 10
target.memorySize(DataType.arrayFor(BaseDataType.WORD), 10) shouldBe 20
target.memorySize(DataType.arrayFor(BaseDataType.WORD), 10) shouldBe 20
target.memorySize(DataType.arrayFor(BaseDataType.UWORD), 10) shouldBe 20
target.memorySize(DataType.arrayFor(BaseDataType.FLOAT), 10) shouldBe 10*target.FLOAT_MEM_SIZE
target.memorySize(DataType.arrayFor(BaseDataType.WORD, true), 10) shouldBe 20
target.memorySize(DataType.arrayFor(BaseDataType.UWORD, true), 10) shouldBe 20
target.memorySize(DataType.BOOL, 10) shouldBe 10
target.memorySize(DataType.UWORD, 10) shouldBe 20
target.memorySize(DataType.LONG, 10) shouldBe 40
target.memorySize(DataType.FLOAT, 10) shouldBe 10*target.FLOAT_MEM_SIZE
}
}

View File

@@ -1062,4 +1062,47 @@ main {
st.size shouldBe 3
}
test("allow type name as argument for sizeof()") {
val src="""
%option enable_floats
main {
sub start() {
bool @shared b
float @shared f
word @shared w
const long ll = 9999999
ubyte @shared ub1, ub2
ub1 = sys.SIZEOF_BOOL
ub2 = sys.SIZEOF_WORD
ub1 = sys.SIZEOF_LONG
ub2 = sys.SIZEOF_FLOAT
ub1 = sizeof(true)
ub2 = sizeof(1234)
ub1 = sizeof(12345678)
ub2 = sizeof(9.999)
ub1 = sizeof(b)
ub2 = sizeof(w)
ub1 = sizeof(ll)
ub2 = sizeof(f)
ub1 = sizeof(bool)
ub2 = sizeof(word)
ub1 = sizeof(long)
ub2 = sizeof(float)
}
}"""
val result = compileText(VMTarget(), false, src, outputDir, writeAssembly = false)!!
val st = result.compilerAst.entrypoint.statements
st.size shouldBe 27
val assignments = st.dropLast(1).takeLast(16)
assignments.forEach { a ->
(a as Assignment).value shouldBe instanceOf<NumericLiteral>()
}
}
})

View File

@@ -628,6 +628,17 @@ private fun ExpressionContext.toAst(insideParentheses: Boolean=false) : Expressi
return IfExpression(condition.toAst(), truevalue.toAst(), falsevalue.toAst(), toPosition())
}
if(sizeof_expression!=null) {
val datatype = sizeof_argument().datatype()?.toAst()
val expression = sizeof_argument().expression()?.toAst()
val sizeof = IdentifierReference(listOf("sizeof"), toPosition())
val arg = if(expression!=null) expression else {
require(datatype!=null)
IdentifierReference(listOf(datatype.name.lowercase()), toPosition())
}
return FunctionCallExpression(sizeof, mutableListOf(arg), toPosition())
}
throw FatalAstException(text)
}

View File

@@ -23,12 +23,13 @@ sys {
const ubyte target = 8 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
const ubyte SIZEOF_BOOL = 1
const ubyte SIZEOF_BYTE = 1
const ubyte SIZEOF_UBYTE = 1
const ubyte SIZEOF_WORD = 2
const ubyte SIZEOF_UWORD = 2
const ubyte SIZEOF_FLOAT = 0 ; undefined, no float support
const ubyte SIZEOF_BOOL = sizeof(bool)
const ubyte SIZEOF_BYTE = sizeof(byte)
const ubyte SIZEOF_UBYTE = sizeof(ubyte)
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_FLOAT = 0 ; undefined, no floats supported
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127
const ubyte MIN_UBYTE = 0

View File

@@ -15,11 +15,12 @@ sys {
const ubyte target = 7 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
const ubyte SIZEOF_BOOL = 1
const ubyte SIZEOF_BYTE = 1
const ubyte SIZEOF_UBYTE = 1
const ubyte SIZEOF_WORD = 2
const ubyte SIZEOF_UWORD = 2
const ubyte SIZEOF_BOOL = sizeof(bool)
const ubyte SIZEOF_BYTE = sizeof(byte)
const ubyte SIZEOF_UBYTE = sizeof(ubyte)
const ubyte SIZEOF_WORD = sizeof(word)
const ubyte SIZEOF_UWORD = sizeof(uword)
const ubyte SIZEOF_LONG = sizeof(long)
const ubyte SIZEOF_FLOAT = 0 ; undefined, no floats supported
const byte MIN_BYTE = -128
const byte MAX_BYTE = 127

View File

@@ -1,28 +1,48 @@
%import math
%option enable_floats
%import textio
%zeropage basicsafe
main {
sub start() {
repeat {
sys.waitvsync()
sys.waitvsync()
txt.cls()
txt.print_ubbin(cx16.joysticks_detect(), true)
bool @shared b
float @shared f
word @shared w
const long ll = 9999999
txt.print_ub(sys.SIZEOF_BOOL)
txt.spc()
txt.print_ub(sys.SIZEOF_WORD)
txt.spc()
txt.print_ub(sys.SIZEOF_LONG)
txt.spc()
txt.print_ub(sys.SIZEOF_FLOAT)
txt.nl()
txt.print_ub(sizeof(true))
txt.spc()
txt.print_ub(sizeof(1234))
txt.spc()
txt.print_ub(sizeof(12345678))
txt.spc()
txt.print_ub(sizeof(9.999))
txt.nl()
txt.print_ub(sizeof(b))
txt.spc()
txt.print_ub(sizeof(w))
txt.spc()
txt.print_ub(sizeof(ll))
txt.spc()
txt.print_ub(sizeof(f))
txt.nl()
txt.print_ub(sizeof(bool))
txt.spc()
txt.print_ub(sizeof(word))
txt.spc()
txt.print_ub(sizeof(long))
txt.spc()
txt.print_ub(sizeof(float))
txt.nl()
txt.print_uwbin(cx16.joysticks_getall(true),true)
;
; ubyte joystick
; for joystick in 0 to 4 {
; bool present
; uword joy
; joy,present = cx16.joystick_get(joystick)
; txt.print_ub(joystick)
; txt.print(": ")
; txt.print_bool(present)
; txt.spc()
; txt.print_uwbin(joy, true)
; txt.nl()
; }
}
}
}

View File

@@ -185,6 +185,7 @@ postincrdecr : assign_target operator = ('++' | '--') ;
expression :
'(' expression ')'
| sizeof_expression = 'sizeof' '(' sizeof_argument ')'
| functioncall
| <assoc=right> prefix = ('+'|'-'|'~') expression
| left = expression EOL? bop = ('*' | '/' | '%' ) EOL? right = expression
@@ -211,6 +212,10 @@ expression :
| if_expression
;
sizeof_argument: datatype | expression ;
arrayindexed:
scoped_identifier arrayindex
;