can only call unary functions in pipe at this time

This commit is contained in:
Irmen de Jong 2022-03-02 23:10:20 +01:00
parent 38beebe720
commit 6f87f8706c
3 changed files with 24 additions and 23 deletions

View File

@ -447,11 +447,11 @@ class AsmGen(internal val program: Program,
internal fun translateBuiltinFunctionCallExpression(bfc: BuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?) = internal fun translateBuiltinFunctionCallExpression(bfc: BuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?) =
builtinFunctionsAsmGen.translateFunctioncallExpression(bfc, resultToStack, resultRegister) builtinFunctionsAsmGen.translateFunctioncallExpression(bfc, resultToStack, resultRegister)
internal fun translateBuiltinFunctionCallExpression(name: String, args: List<AsmAssignSource>, scope: Subroutine): DataType = private fun translateBuiltinFunctionCallExpression(name: String, singleArg:AsmAssignSource, scope: Subroutine): DataType =
builtinFunctionsAsmGen.translateFunctioncall(name, args, false, scope) builtinFunctionsAsmGen.translateUnaryFunctioncall(name, singleArg, false, scope)
internal fun translateBuiltinFunctionCallStatement(name: String, args: List<AsmAssignSource>, scope: Subroutine) = private fun translateBuiltinFunctionCallStatement(name: String, singleArg: AsmAssignSource, scope: Subroutine) =
builtinFunctionsAsmGen.translateFunctioncall(name, args, true, scope) builtinFunctionsAsmGen.translateUnaryFunctioncall(name, singleArg, true, scope)
internal fun translateFunctionCall(functionCallExpr: FunctionCallExpression, isExpression: Boolean) = internal fun translateFunctionCall(functionCallExpr: FunctionCallExpression, isExpression: Boolean) =
functioncallAsmGen.translateFunctionCall(functionCallExpr, isExpression) functioncallAsmGen.translateFunctionCall(functionCallExpr, isExpression)
@ -2887,14 +2887,14 @@ $repeatLabel lda $counterVar
} }
} }
private fun translateUnaryFunctionCallWithArgSource(target: IdentifierReference, arg: AsmAssignSource, isStatement: Boolean, scope: Subroutine): DataType { private fun translateUnaryFunctionCallWithArgSource(target: IdentifierReference, singleArg: AsmAssignSource, isStatement: Boolean, scope: Subroutine): DataType {
when(val targetStmt = target.targetStatement(program)!!) { when(val targetStmt = target.targetStatement(program)!!) {
is BuiltinFunctionPlaceholder -> { is BuiltinFunctionPlaceholder -> {
return if(isStatement) { return if(isStatement) {
translateBuiltinFunctionCallStatement(targetStmt.name, listOf(arg), scope) translateBuiltinFunctionCallStatement(targetStmt.name, singleArg, scope)
DataType.UNDEFINED DataType.UNDEFINED
} else { } else {
translateBuiltinFunctionCallExpression(targetStmt.name, listOf(arg), scope) translateBuiltinFunctionCallExpression(targetStmt.name, singleArg, scope)
} }
} }
is Subroutine -> { is Subroutine -> {
@ -2903,7 +2903,7 @@ $repeatLabel lda $counterVar
// argument via registers // argument via registers
val argRegister = targetStmt.asmParameterRegisters.single().registerOrPair!! val argRegister = targetStmt.asmParameterRegisters.single().registerOrPair!!
val assignArgument = AsmAssignment( val assignArgument = AsmAssignment(
arg, singleArg,
AsmAssignTarget.fromRegisters(argRegister, argDt in SignedDatatypes, scope, program, this), AsmAssignTarget.fromRegisters(argRegister, argDt in SignedDatatypes, scope, program, this),
false, program.memsizer, target.position false, program.memsizer, target.position
) )
@ -2919,7 +2919,7 @@ $repeatLabel lda $counterVar
else -> throw AssemblyError("invalid dt") else -> throw AssemblyError("invalid dt")
} }
AsmAssignment( AsmAssignment(
arg, singleArg,
AsmAssignTarget(TargetStorageKind.REGISTER, program, this, argDt, scope, register = paramReg), AsmAssignTarget(TargetStorageKind.REGISTER, program, this, argDt, scope, register = paramReg),
false, program.memsizer, target.position false, program.memsizer, target.position
) )
@ -2927,7 +2927,7 @@ $repeatLabel lda $counterVar
// arg goes via parameter variable // arg goes via parameter variable
val argVarName = asmVariableName(targetStmt.scopedName + targetStmt.parameters.single().name) val argVarName = asmVariableName(targetStmt.scopedName + targetStmt.parameters.single().name)
AsmAssignment( AsmAssignment(
arg, singleArg,
AsmAssignTarget(TargetStorageKind.VARIABLE, program, this, argDt, scope, argVarName), AsmAssignTarget(TargetStorageKind.VARIABLE, program, this, argDt, scope, argVarName),
false, program.memsizer, target.position false, program.memsizer, target.position
) )

View File

@ -29,21 +29,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
translateFunctioncall(fcall, func, discardResult = true, resultToStack = false, resultRegister = null) translateFunctioncall(fcall, func, discardResult = true, resultToStack = false, resultRegister = null)
} }
internal fun translateFunctioncall(name: String, args: List<AsmAssignSource>, isStatement: Boolean, scope: Subroutine): DataType { internal fun translateUnaryFunctioncall(name: String, singleArg: AsmAssignSource, isStatement: Boolean, scope: Subroutine): DataType {
val func = BuiltinFunctions.getValue(name) val func = BuiltinFunctions.getValue(name)
val argExpressions = args.map { src -> val argExpression =
when(src.kind) { when(singleArg.kind) {
SourceStorageKind.LITERALNUMBER -> src.number!! SourceStorageKind.LITERALNUMBER -> singleArg.number!!
SourceStorageKind.EXPRESSION -> src.expression!! SourceStorageKind.EXPRESSION -> singleArg.expression!!
SourceStorageKind.ARRAY -> src.array!! SourceStorageKind.ARRAY -> singleArg.array!!
else -> { else -> {
// TODO make it so that we can assign efficiently from something else as an expression....namely: register(s) // TODO make it so that we can assign efficiently from something else as an expression....namely: register(s)
// this is useful in pipe expressions for instance, to skip the use of a temporary variable // this is useful in pipe expressions for instance, to skip the use of a temporary variable
// but for now, just assign it to a temporary variable and use that as a source // but for now, just assign it to a temporary variable and use that as a source
val tempvar = asmgen.getTempVarName(src.datatype) val tempvar = asmgen.getTempVarName(singleArg.datatype)
val assignTempvar = AsmAssignment( val assignTempvar = AsmAssignment(
src, singleArg,
AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, src.datatype, scope, variableAsmName = asmgen.asmVariableName(tempvar)), AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, singleArg.datatype, scope, variableAsmName = asmgen.asmVariableName(tempvar)),
false, program.memsizer, Position.DUMMY false, program.memsizer, Position.DUMMY
) )
assignAsmGen.translateNormalAssignment(assignTempvar) assignAsmGen.translateNormalAssignment(assignTempvar)
@ -53,7 +53,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
ident ident
} }
} }
}.toMutableList() val argExpressions = mutableListOf(argExpression);
val fcall = BuiltinFunctionCall(IdentifierReference(listOf(name), Position.DUMMY), argExpressions, Position.DUMMY) val fcall = BuiltinFunctionCall(IdentifierReference(listOf(name), Position.DUMMY), argExpressions, Position.DUMMY)
fcall.linkParents(scope) fcall.linkParents(scope)
translateFunctioncall(fcall, func, discardResult = false, resultToStack = false, null) translateFunctioncall(fcall, func, discardResult = false, resultToStack = false, null)

View File

@ -27,7 +27,6 @@ Compiler:
- writeAssembly(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there. - writeAssembly(): make it possible to actually get rid of the VarDecl nodes by fixing the rest of the code mentioned there.
- make everything an expression? (get rid of Statements. Statements are expressions with void return types?). - make everything an expression? (get rid of Statements. Statements are expressions with void return types?).
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type - allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type
- for the pipe operator: make it 100% syntactic sugar so there's no need for asm codegen like translatePipeExpression
- make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment) - make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment)
but this requires all identifiers in the inlined expression to be changed to fully scoped names. but this requires all identifiers in the inlined expression to be changed to fully scoped names.
If we can do that why not perhaps also able to inline multi-line subroutines? Why would it be limited to just 1 line? Maybe to protect against code bloat. If we can do that why not perhaps also able to inline multi-line subroutines? Why would it be limited to just 1 line? Maybe to protect against code bloat.
@ -35,7 +34,7 @@ Compiler:
- simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation, but how does it know? - simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation, but how does it know?
- simplifyConditionalExpression() sometimes introduces needless assignment to r9 tempvar (scenario sought) - simplifyConditionalExpression() sometimes introduces needless assignment to r9 tempvar (scenario sought)
- consider adding McCarthy evaluation to shortcircuit and and or expressions. First do ifs by splitting them up? Then do expressions that compute a value? - consider adding McCarthy evaluation to shortcircuit and and or expressions. First do ifs by splitting them up? Then do expressions that compute a value?
- use more of Result<> and Either<> to handle errors/ nulls better? - use more of Result<> to handle errors/ nulls better?
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway) - make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway)
then we can get rid of the instruction lists in the machinedefinitions as well? then we can get rid of the instruction lists in the machinedefinitions as well?
- [problematic due to 64tass:] add a compiler option to not remove unused subroutines. this allows for building library programs. But this won't work with 64tass's .proc ... - [problematic due to 64tass:] add a compiler option to not remove unused subroutines. this allows for building library programs. But this won't work with 64tass's .proc ...
@ -69,9 +68,11 @@ Optimizations:
- VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served - VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served
- translateFunctioncall() in BuiltinFunctionsAsmGen: should be able to assign parameters to a builtin function directly from register(s), this will make the use of a builtin function in a pipe expression more efficient without using a temporary variable - translateFunctioncall() in BuiltinFunctionsAsmGen: should be able to assign parameters to a builtin function directly from register(s), this will make the use of a builtin function in a pipe expression more efficient without using a temporary variable
aa = startvalue(1) |> sin8u() |> cos8u() |> sin8u() |> cos8u()
versus: aa = cos8u(sin8u(cos8u(sin8u(startvalue(1))))) <--- this one contains no sta cx16.r9L in between.
- AssignmentAsmGen.assignExpression() -> better code gen for assigning boolean comparison expressions - AssignmentAsmGen.assignExpression() -> better code gen for assigning boolean comparison expressions
- when a for loop's loopvariable isn't referenced in the body, and the iterations are known, replace the loop by a repeatloop - when a for loop's loopvariable isn't referenced in the body, and the iterations are known, replace the loop by a repeatloop
but we have no efficient way right now to see if the body references a variable. but we have no efficient way right now to see if the body references a variable.
- AssignmentAsmGen: "real optimized code for comparison expressions that yield a boolean result value"
- automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements, instead of just a warning. - automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements, instead of just a warning.
- introduce byte-index operator to avoid index multiplications in loops over arrays? see github issue #4 - introduce byte-index operator to avoid index multiplications in loops over arrays? see github issue #4
- AssignmentAsmGen: "real optimized code for comparison expressions that yield a boolean result value"