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 register: RegisterOrPair?,
val origAstTarget: AssignTarget?, // TODO get rid of this eventually?
)
)
{
val constMemoryAddress by lazy { astMemory?.addressExpression?.constValue(program)?.number?.toInt() ?: 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,
private val program: Program,
val datatype: DataType,
val astVariable: IdentifierReference? = null,
val astArray: ArrayIndexedExpression? = null,
val astMemory: DirectMemoryRead? = null,
val register: RegisterOrPair? = null,
val register: CpuRegister? = null,
val numLitval: NumericLiteralValue? = null,
val astExpression: Expression? = null
)
@ -88,16 +89,27 @@ internal class AsmAssignSource(val type: AsmSourceStorageType,
fun fromAstSource(value: Expression, program: Program): AsmAssignSource {
val cv = value.constValue(program)
if(cv!=null)
return AsmAssignSource(AsmSourceStorageType.LITERALNUMBER, program, numLitval = cv)
return AsmAssignSource(AsmSourceStorageType.LITERALNUMBER, program, cv.type, numLitval = cv)
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 ArrayLiteralValue -> throw AssemblyError("array literal value should not occur anymore for asm generation")
is IdentifierReference -> AsmAssignSource(AsmSourceStorageType.VARIABLE, program, astVariable = value)
is DirectMemoryRead -> AsmAssignSource(AsmSourceStorageType.MEMORY, program, astMemory = value)
is ArrayIndexedExpression -> AsmAssignSource(AsmSourceStorageType.ARRAY, program, astArray = value)
else -> AsmAssignSource(AsmSourceStorageType.EXPRESSION, program, astExpression = value)
is IdentifierReference -> {
val dt = value.inferType(program).typeOrElse(DataType.STRUCT)
AsmAssignSource(AsmSourceStorageType.VARIABLE, program, dt, astVariable = 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) {
// source: expression, register, stack (only expression implemented for now)
// TODO use source type enum
val value=assign.source.getAstValue()
when (value) {
is AddressOf -> {
assignFromAddressOf(assign.target, value.identifier)
when(assign.source.type) {
AsmSourceStorageType.LITERALNUMBER,
AsmSourceStorageType.VARIABLE -> {
throw AssemblyError("assignment value type ${assign.source.type} should have been handled elsewhere")
}
is DirectMemoryRead -> {
when (value.addressExpression) {
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 -> {
AsmSourceStorageType.ARRAY -> {
val value = assign.source.astArray!!
val arrayDt = value.identifier.inferType(program).typeOrElse(DataType.STRUCT)
val index = value.arrayspec.index
if (index is NumericLiteralValue) {
@ -117,28 +93,47 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
assignFromEvalResult(assign.target)
}
is TypecastExpression -> {
val sourceType = value.expression.inferType(program)
if (sourceType.isKnown &&
(sourceType.typeOrElse(DataType.STRUCT) in ByteDatatypes && value.type in ByteDatatypes) ||
(sourceType.typeOrElse(DataType.STRUCT) in WordDatatypes && value.type in WordDatatypes)) {
// no need for a type cast
TODO("no typecast $value")
// value = value.expression
// val newAssign = AsmAssignment(assign.source, assign.target, assign.isAugmentable, assign.position)
// translate(newAssign)
} else {
AsmSourceStorageType.MEMORY -> {
val value = assign.source.astMemory!!
when (value.addressExpression) {
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")
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)
assignFromEvalResult(assign.target)
}
}
is FunctionCall -> {
asmgen.translateExpression(value)
assignFromEvalResult(assign.target)
AsmSourceStorageType.REGISTER -> {
assignByteFromRegister(assign.target, assign.source.register!!)
}
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) {
AsmTargetStorageType.VARIABLE -> {
asmgen.out(" st${register.name.toLowerCase()} ${target.asmName}")