mirror of
https://github.com/irmen/prog8.git
synced 2025-01-14 17:31:01 +00:00
use sourcetype
This commit is contained in:
parent
d9e3895c45
commit
d2f0e74879
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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}")
|
||||
|
Loading…
x
Reference in New Issue
Block a user