mirror of
https://github.com/irmen/prog8.git
synced 2025-02-25 20:29:04 +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 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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}")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user