use sourcetype

This commit is contained in:
Irmen de Jong 2020-08-23 11:07:35 +02:00
parent d9e3895c45
commit d2f0e74879
2 changed files with 64 additions and 56 deletions

View File

@ -36,7 +36,7 @@ internal class AsmAssignTarget(val type: AsmTargetStorageType,
val astMemory: DirectMemoryWrite?, val astMemory: DirectMemoryWrite?,
val register: RegisterOrPair?, val register: RegisterOrPair?,
val origAstTarget: AssignTarget?, // TODO get rid of this eventually? val origAstTarget: AssignTarget?, // TODO get rid of this eventually?
) )
{ {
val constMemoryAddress by lazy { astMemory?.addressExpression?.constValue(program)?.number?.toInt() ?: 0} val constMemoryAddress by lazy { astMemory?.addressExpression?.constValue(program)?.number?.toInt() ?: 0}
val constArrayIndexValue by lazy { astArray?.arrayspec?.size() ?: 0 } val constArrayIndexValue by lazy { astArray?.arrayspec?.size() ?: 0 }
@ -72,10 +72,11 @@ internal class AsmAssignTarget(val type: AsmTargetStorageType,
internal class AsmAssignSource(val type: AsmSourceStorageType, internal class AsmAssignSource(val type: AsmSourceStorageType,
private val program: Program, private val program: Program,
val datatype: DataType,
val astVariable: IdentifierReference? = null, val astVariable: IdentifierReference? = null,
val astArray: ArrayIndexedExpression? = null, val astArray: ArrayIndexedExpression? = null,
val astMemory: DirectMemoryRead? = null, val astMemory: DirectMemoryRead? = null,
val register: RegisterOrPair? = null, val register: CpuRegister? = null,
val numLitval: NumericLiteralValue? = null, val numLitval: NumericLiteralValue? = null,
val astExpression: Expression? = null val astExpression: Expression? = null
) )
@ -88,16 +89,27 @@ internal class AsmAssignSource(val type: AsmSourceStorageType,
fun fromAstSource(value: Expression, program: Program): AsmAssignSource { fun fromAstSource(value: Expression, program: Program): AsmAssignSource {
val cv = value.constValue(program) val cv = value.constValue(program)
if(cv!=null) if(cv!=null)
return AsmAssignSource(AsmSourceStorageType.LITERALNUMBER, program, numLitval = cv) return AsmAssignSource(AsmSourceStorageType.LITERALNUMBER, program, cv.type, numLitval = cv)
return when(value) { return when(value) {
is NumericLiteralValue -> AsmAssignSource(AsmSourceStorageType.LITERALNUMBER, program, numLitval = cv) is NumericLiteralValue -> AsmAssignSource(AsmSourceStorageType.LITERALNUMBER, program, value.type, numLitval = cv)
is StringLiteralValue -> throw AssemblyError("string literal value should not occur anymore for asm generation") is StringLiteralValue -> throw AssemblyError("string literal value should not occur anymore for asm generation")
is ArrayLiteralValue -> throw AssemblyError("array literal value should not occur anymore for asm generation") is ArrayLiteralValue -> throw AssemblyError("array literal value should not occur anymore for asm generation")
is IdentifierReference -> AsmAssignSource(AsmSourceStorageType.VARIABLE, program, astVariable = value) is IdentifierReference -> {
is DirectMemoryRead -> AsmAssignSource(AsmSourceStorageType.MEMORY, program, astMemory = value) val dt = value.inferType(program).typeOrElse(DataType.STRUCT)
is ArrayIndexedExpression -> AsmAssignSource(AsmSourceStorageType.ARRAY, program, astArray = value) AsmAssignSource(AsmSourceStorageType.VARIABLE, program, dt, astVariable = value)
else -> AsmAssignSource(AsmSourceStorageType.EXPRESSION, program, astExpression = value) }
is DirectMemoryRead -> {
AsmAssignSource(AsmSourceStorageType.MEMORY, program, DataType.UBYTE, astMemory = value)
}
is ArrayIndexedExpression -> {
val dt = value.inferType(program).typeOrElse(DataType.STRUCT)
AsmAssignSource(AsmSourceStorageType.ARRAY, program, dt, astArray = value)
}
else -> {
val dt = value.inferType(program).typeOrElse(DataType.STRUCT)
AsmAssignSource(AsmSourceStorageType.EXPRESSION, program, dt, astExpression = value)
}
} }
} }
} }

View File

@ -64,37 +64,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
internal fun translateOtherAssignment(assign: AsmAssignment) { internal fun translateOtherAssignment(assign: AsmAssignment) {
// source: expression, register, stack (only expression implemented for now) // source: expression, register, stack (only expression implemented for now)
// TODO use source type enum when(assign.source.type) {
val value=assign.source.getAstValue() AsmSourceStorageType.LITERALNUMBER,
when (value) { AsmSourceStorageType.VARIABLE -> {
is AddressOf -> { throw AssemblyError("assignment value type ${assign.source.type} should have been handled elsewhere")
assignFromAddressOf(assign.target, value.identifier)
} }
is DirectMemoryRead -> { AsmSourceStorageType.ARRAY -> {
when (value.addressExpression) { val value = assign.source.astArray!!
is NumericLiteralValue -> {
val address = (value.addressExpression as NumericLiteralValue).number.toInt()
assignFromMemoryByte(assign.target, address, null)
}
is IdentifierReference -> {
assignFromMemoryByte(assign.target, null, value.addressExpression as IdentifierReference)
}
else -> {
asmgen.translateExpression(value.addressExpression)
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | inx")
assignFromRegister(assign.target, CpuRegister.A)
}
}
}
is PrefixExpression -> {
asmgen.translateExpression(value)
assignFromEvalResult(assign.target)
}
is BinaryExpression -> {
asmgen.translateExpression(value)
assignFromEvalResult(assign.target)
}
is ArrayIndexedExpression -> {
val arrayDt = value.identifier.inferType(program).typeOrElse(DataType.STRUCT) val arrayDt = value.identifier.inferType(program).typeOrElse(DataType.STRUCT)
val index = value.arrayspec.index val index = value.arrayspec.index
if (index is NumericLiteralValue) { if (index is NumericLiteralValue) {
@ -117,28 +93,47 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
assignFromEvalResult(assign.target) assignFromEvalResult(assign.target)
} }
is TypecastExpression -> { AsmSourceStorageType.MEMORY -> {
val sourceType = value.expression.inferType(program) val value = assign.source.astMemory!!
if (sourceType.isKnown && when (value.addressExpression) {
(sourceType.typeOrElse(DataType.STRUCT) in ByteDatatypes && value.type in ByteDatatypes) || is NumericLiteralValue -> {
(sourceType.typeOrElse(DataType.STRUCT) in WordDatatypes && value.type in WordDatatypes)) { val address = (value.addressExpression as NumericLiteralValue).number.toInt()
// no need for a type cast assignFromMemoryByte(assign.target, address, null)
TODO("no typecast $value") }
// value = value.expression is IdentifierReference -> {
// val newAssign = AsmAssignment(assign.source, assign.target, assign.isAugmentable, assign.position) assignFromMemoryByte(assign.target, null, value.addressExpression as IdentifierReference)
// translate(newAssign) }
} else { else -> {
asmgen.translateExpression(value.addressExpression)
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | inx")
assignByteFromRegister(assign.target, CpuRegister.A)
}
}
}
AsmSourceStorageType.EXPRESSION -> {
val value = assign.source.astExpression!!
if (value is AddressOf) {
assignFromAddressOf(assign.target, value.identifier)
}
else {
asmgen.translateExpression(value) asmgen.translateExpression(value)
assignFromEvalResult(assign.target) assignFromEvalResult(assign.target)
} }
} }
is FunctionCall -> { AsmSourceStorageType.REGISTER -> {
asmgen.translateExpression(value) assignByteFromRegister(assign.target, assign.source.register!!)
assignFromEvalResult(assign.target) }
AsmSourceStorageType.STACK -> {
when(assign.source.datatype) {
in ByteDatatypes -> {
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | inx")
assignByteFromRegister(assign.target, CpuRegister.A)
}
in WordDatatypes -> TODO("assign word from stack")
DataType.FLOAT -> TODO("assign float from stack")
else -> throw AssemblyError("weird stack value type")
}
} }
is ArrayLiteralValue, is StringLiteralValue -> throw AssemblyError("no asm gen for string/array assignment $assign")
is RangeExpr -> throw AssemblyError("range expression should have been changed into array values ${value.position}")
else -> throw AssemblyError("assignment value type $value should have been handled elsewhere")
} }
} }
@ -302,7 +297,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
private fun assignFromRegister(target: AsmAssignTarget, register: CpuRegister) { private fun assignByteFromRegister(target: AsmAssignTarget, register: CpuRegister) {
require(target.datatype in ByteDatatypes)
when(target.type) { when(target.type) {
AsmTargetStorageType.VARIABLE -> { AsmTargetStorageType.VARIABLE -> {
asmgen.out(" st${register.name.toLowerCase()} ${target.asmName}") asmgen.out(" st${register.name.toLowerCase()} ${target.asmName}")