mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
fix function arguments
This commit is contained in:
parent
7ddc01f883
commit
2f0c0f6fcd
@ -4,10 +4,12 @@ import prog8.ast.base.AstException
|
|||||||
import prog8.compiler.CompilationResult
|
import prog8.compiler.CompilationResult
|
||||||
import prog8.compiler.compileProgram
|
import prog8.compiler.compileProgram
|
||||||
import prog8.parser.ParsingFailedError
|
import prog8.parser.ParsingFailedError
|
||||||
import prog8.vm.astvm.AstVm
|
|
||||||
import prog8.repl.Repl
|
import prog8.repl.Repl
|
||||||
import java.lang.Exception
|
import prog8.vm.astvm.AstVm
|
||||||
import java.nio.file.*
|
import java.nio.file.FileSystems
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import java.nio.file.StandardWatchEventKinds
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.system.exitProcess
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
@ -103,12 +105,15 @@ private fun compileMain(args: Array<String>) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
compilationResult = compileProgram(filepath, optimize, optimizeInlining, writeAssembly)
|
compilationResult = compileProgram(filepath, optimize, optimizeInlining, writeAssembly)
|
||||||
|
if(!compilationResult.success)
|
||||||
|
exitProcess(1)
|
||||||
} catch (x: ParsingFailedError) {
|
} catch (x: ParsingFailedError) {
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
} catch (x: AstException) {
|
} catch (x: AstException) {
|
||||||
exitProcess(1)
|
exitProcess(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
println("LAUNCH VM!@")
|
||||||
if (launchAstVm) {
|
if (launchAstVm) {
|
||||||
println("\nLaunching AST-based vm...")
|
println("\nLaunching AST-based vm...")
|
||||||
val vm = AstVm(compilationResult.programAst)
|
val vm = AstVm(compilationResult.programAst)
|
||||||
|
@ -37,7 +37,7 @@ internal fun Program.anonscopeVarsCleanup() {
|
|||||||
|
|
||||||
|
|
||||||
internal fun Program.reorderStatements() {
|
internal fun Program.reorderStatements() {
|
||||||
val initvalueCreator = VarInitValueAndAddressOfCreator(namespace, heap)
|
val initvalueCreator = VarInitValueAndAddressOfCreator(this)
|
||||||
initvalueCreator.visit(this)
|
initvalueCreator.visit(this)
|
||||||
|
|
||||||
val checker = StatementReorderer(this)
|
val checker = StatementReorderer(this)
|
||||||
|
@ -240,7 +240,7 @@ data class AddressOf(var identifier: IdentifierReference, override val position:
|
|||||||
identifier.parent=this
|
identifier.parent=this
|
||||||
}
|
}
|
||||||
|
|
||||||
var scopedname: String? = null // will be set in a later state by the compiler
|
var scopedname: String? = null // will be set in a later state by the compiler // TODO get rid of this??
|
||||||
override fun constValue(program: Program): NumericLiteralValue? = null
|
override fun constValue(program: Program): NumericLiteralValue? = null
|
||||||
override fun referencesIdentifiers(vararg name: String) = false
|
override fun referencesIdentifiers(vararg name: String) = false
|
||||||
override fun inferType(program: Program) = DataType.UWORD
|
override fun inferType(program: Program) = DataType.UWORD
|
||||||
|
@ -3,13 +3,16 @@ package prog8.ast.processing
|
|||||||
import prog8.ast.INameScope
|
import prog8.ast.INameScope
|
||||||
import prog8.ast.Module
|
import prog8.ast.Module
|
||||||
import prog8.ast.Node
|
import prog8.ast.Node
|
||||||
|
import prog8.ast.Program
|
||||||
import prog8.ast.base.*
|
import prog8.ast.base.*
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.compiler.HeapValues
|
import prog8.compiler.CompilerException
|
||||||
|
import prog8.functions.BuiltinFunctions
|
||||||
|
import prog8.functions.FunctionSignature
|
||||||
|
|
||||||
|
|
||||||
internal class VarInitValueAndAddressOfCreator(private val namespace: INameScope, private val heap: HeapValues): IAstModifyingVisitor {
|
internal class VarInitValueAndAddressOfCreator(private val program: Program): IAstModifyingVisitor {
|
||||||
// For VarDecls that declare an initialization value:
|
// For VarDecls that declare an initialization value:
|
||||||
// Replace the vardecl with an assignment (to set the initial value),
|
// Replace the vardecl with an assignment (to set the initial value),
|
||||||
// and add a new vardecl with the default constant value of that type (usually zero) to the scope.
|
// and add a new vardecl with the default constant value of that type (usually zero) to the scope.
|
||||||
@ -42,7 +45,7 @@ internal class VarInitValueAndAddressOfCreator(private val namespace: INameScope
|
|||||||
val array = ReferenceLiteralValue(decl.datatype, null,
|
val array = ReferenceLiteralValue(decl.datatype, null,
|
||||||
Array(arraysize) { NumericLiteralValue.optimalInteger(0, decl.position) },
|
Array(arraysize) { NumericLiteralValue.optimalInteger(0, decl.position) },
|
||||||
null, decl.position)
|
null, decl.position)
|
||||||
array.addToHeap(heap)
|
array.addToHeap(program.heap)
|
||||||
decl.value = array
|
decl.value = array
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,20 +76,29 @@ internal class VarInitValueAndAddressOfCreator(private val namespace: INameScope
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(functionCall: FunctionCall): Expression {
|
override fun visit(functionCall: FunctionCall): Expression {
|
||||||
val targetStatement = functionCall.target.targetSubroutine(namespace)
|
var parentStatement: Node = functionCall
|
||||||
|
while(parentStatement !is Statement)
|
||||||
|
parentStatement = parentStatement.parent
|
||||||
|
val targetStatement = functionCall.target.targetSubroutine(program.namespace)
|
||||||
if(targetStatement!=null) {
|
if(targetStatement!=null) {
|
||||||
var node: Node = functionCall
|
addAddressOfExprIfNeeded(targetStatement, functionCall.arglist, parentStatement)
|
||||||
while(node !is Statement)
|
} else {
|
||||||
node=node.parent
|
val builtinFunc = BuiltinFunctions[functionCall.target.nameInSource.joinToString (".")]
|
||||||
addAddressOfExprIfNeeded(targetStatement, functionCall.arglist, node)
|
if(builtinFunc!=null)
|
||||||
|
addAddressOfExprIfNeededForBuiltinFuncs(builtinFunc, functionCall.arglist, parentStatement)
|
||||||
}
|
}
|
||||||
return functionCall
|
return functionCall
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(functionCallStatement: FunctionCallStatement): Statement {
|
override fun visit(functionCallStatement: FunctionCallStatement): Statement {
|
||||||
val targetStatement = functionCallStatement.target.targetSubroutine(namespace)
|
val targetStatement = functionCallStatement.target.targetSubroutine(program.namespace)
|
||||||
if(targetStatement!=null)
|
if(targetStatement!=null) {
|
||||||
addAddressOfExprIfNeeded(targetStatement, functionCallStatement.arglist, functionCallStatement)
|
addAddressOfExprIfNeeded(targetStatement, functionCallStatement.arglist, functionCallStatement)
|
||||||
|
} else {
|
||||||
|
val builtinFunc = BuiltinFunctions[functionCallStatement.target.nameInSource.joinToString (".")]
|
||||||
|
if(builtinFunc!=null)
|
||||||
|
addAddressOfExprIfNeededForBuiltinFuncs(builtinFunc, functionCallStatement.arglist, functionCallStatement)
|
||||||
|
}
|
||||||
return functionCallStatement
|
return functionCallStatement
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +111,7 @@ internal class VarInitValueAndAddressOfCreator(private val namespace: INameScope
|
|||||||
val idref = argparam.second as? IdentifierReference
|
val idref = argparam.second as? IdentifierReference
|
||||||
val strvalue = argparam.second as? ReferenceLiteralValue
|
val strvalue = argparam.second as? ReferenceLiteralValue
|
||||||
if(idref!=null) {
|
if(idref!=null) {
|
||||||
val variable = idref.targetVarDecl(namespace)
|
val variable = idref.targetVarDecl(program.namespace)
|
||||||
if(variable!=null && (variable.datatype in StringDatatypes || variable.datatype in ArrayDatatypes)) {
|
if(variable!=null && (variable.datatype in StringDatatypes || variable.datatype in ArrayDatatypes)) {
|
||||||
val pointerExpr = AddressOf(idref, idref.position)
|
val pointerExpr = AddressOf(idref, idref.position)
|
||||||
pointerExpr.scopedname = parent.makeScopedName(idref.nameInSource.single())
|
pointerExpr.scopedname = parent.makeScopedName(idref.nameInSource.single())
|
||||||
@ -110,7 +122,7 @@ internal class VarInitValueAndAddressOfCreator(private val namespace: INameScope
|
|||||||
else if(strvalue!=null) {
|
else if(strvalue!=null) {
|
||||||
if(strvalue.isString) {
|
if(strvalue.isString) {
|
||||||
// add a vardecl so that the autovar can be resolved in later lookups
|
// add a vardecl so that the autovar can be resolved in later lookups
|
||||||
val variable = VarDecl.createAuto(strvalue, heap)
|
val variable = VarDecl.createAuto(strvalue, program.heap)
|
||||||
addVarDecl(strvalue.definingScope(), variable)
|
addVarDecl(strvalue.definingScope(), variable)
|
||||||
// replace the argument with &autovar
|
// replace the argument with &autovar
|
||||||
val autoHeapvarRef = IdentifierReference(listOf(variable.name), strvalue.position)
|
val autoHeapvarRef = IdentifierReference(listOf(variable.name), strvalue.position)
|
||||||
@ -124,6 +136,22 @@ internal class VarInitValueAndAddressOfCreator(private val namespace: INameScope
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addAddressOfExprIfNeededForBuiltinFuncs(signature: FunctionSignature, args: MutableList<Expression>, parent: Statement) {
|
||||||
|
for(arg in args.withIndex().zip(signature.parameters)) {
|
||||||
|
val argvalue = arg.first.value
|
||||||
|
val argDt = argvalue.inferType(program)
|
||||||
|
if(DataType.UWORD in arg.second.possibleDatatypes && argDt in PassByReferenceDatatypes) {
|
||||||
|
if(argvalue !is IdentifierReference)
|
||||||
|
throw CompilerException("pass-by-reference parameter isn't an identifier? $argvalue")
|
||||||
|
val addrOf = AddressOf(argvalue, argvalue.position)
|
||||||
|
args[arg.first.index] = addrOf
|
||||||
|
addrOf.scopedname = parent.makeScopedName(argvalue.nameInSource.single())
|
||||||
|
addrOf.linkParents(parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun addVarDecl(scope: INameScope, variable: VarDecl) {
|
private fun addVarDecl(scope: INameScope, variable: VarDecl) {
|
||||||
if(scope !in vardeclsToAdd)
|
if(scope !in vardeclsToAdd)
|
||||||
vardeclsToAdd[scope] = mutableListOf()
|
vardeclsToAdd[scope] = mutableListOf()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package prog8.compiler
|
package prog8.compiler
|
||||||
|
|
||||||
|
import com.sun.org.apache.xpath.internal.functions.FuncFalse
|
||||||
import prog8.ast.AstToSourceCode
|
import prog8.ast.AstToSourceCode
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
import prog8.ast.base.*
|
import prog8.ast.base.*
|
||||||
@ -17,7 +18,10 @@ import java.nio.file.Path
|
|||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
|
|
||||||
class CompilationResult(val programAst: Program, val programName: String, val importedFiles: List<Path>)
|
class CompilationResult(val success: Boolean,
|
||||||
|
val programAst: Program,
|
||||||
|
val programName: String,
|
||||||
|
val importedFiles: List<Path>)
|
||||||
|
|
||||||
|
|
||||||
fun compileProgram(filepath: Path,
|
fun compileProgram(filepath: Path,
|
||||||
@ -27,6 +31,7 @@ fun compileProgram(filepath: Path,
|
|||||||
var programName: String? = null
|
var programName: String? = null
|
||||||
|
|
||||||
var importedFiles: List<Path> = emptyList()
|
var importedFiles: List<Path> = emptyList()
|
||||||
|
var success=false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val totalTime = measureTimeMillis {
|
val totalTime = measureTimeMillis {
|
||||||
@ -65,11 +70,6 @@ fun compileProgram(filepath: Path,
|
|||||||
//println(" time2: $time2")
|
//println(" time2: $time2")
|
||||||
val time3 = measureTimeMillis {
|
val time3 = measureTimeMillis {
|
||||||
programAst.removeNopsFlattenAnonScopes()
|
programAst.removeNopsFlattenAnonScopes()
|
||||||
|
|
||||||
// if you want to print the AST, do it before shuffling the statements around below
|
|
||||||
//printAst(programAst)
|
|
||||||
|
|
||||||
|
|
||||||
programAst.reorderStatements() // reorder statements and add type casts, to please the compiler later
|
programAst.reorderStatements() // reorder statements and add type casts, to please the compiler later
|
||||||
}
|
}
|
||||||
//println(" time3: $time3")
|
//println(" time3: $time3")
|
||||||
@ -95,7 +95,7 @@ fun compileProgram(filepath: Path,
|
|||||||
programAst.checkValid(compilerOptions) // check if final tree is valid
|
programAst.checkValid(compilerOptions) // check if final tree is valid
|
||||||
programAst.checkRecursion() // check if there are recursive subroutine calls
|
programAst.checkRecursion() // check if there are recursive subroutine calls
|
||||||
|
|
||||||
//printAst(programAst)
|
printAst(programAst)
|
||||||
|
|
||||||
if(writeAssembly) {
|
if(writeAssembly) {
|
||||||
// asm generation directly from the Ast, no need for intermediate code
|
// asm generation directly from the Ast, no need for intermediate code
|
||||||
@ -105,6 +105,7 @@ fun compileProgram(filepath: Path,
|
|||||||
assembly.assemble(compilerOptions)
|
assembly.assemble(compilerOptions)
|
||||||
programName = assembly.name
|
programName = assembly.name
|
||||||
}
|
}
|
||||||
|
success = true
|
||||||
}
|
}
|
||||||
println("\nTotal compilation+assemble time: ${totalTime / 1000.0} sec.")
|
println("\nTotal compilation+assemble time: ${totalTime / 1000.0} sec.")
|
||||||
|
|
||||||
@ -129,7 +130,7 @@ fun compileProgram(filepath: Path,
|
|||||||
System.out.flush()
|
System.out.flush()
|
||||||
throw x
|
throw x
|
||||||
}
|
}
|
||||||
return CompilationResult(programAst, programName ?: "", importedFiles)
|
return CompilationResult(success, programAst, programName ?: "", importedFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun printAst(programAst: Program) {
|
fun printAst(programAst: Program) {
|
||||||
|
@ -238,11 +238,6 @@ internal class AsmGen2(val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
throw AssemblyError("huh, var is already in zp $fullName")
|
|
||||||
// it was already allocated on the zp, what to do?
|
|
||||||
// out("${variable.name} = ${zpVar.first}\t; zp ${zpVar.second}")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,7 +642,7 @@ internal class AsmGen2(val program: Program,
|
|||||||
out(" ldx c64.SCRATCH_ZPREGX") // restore X again
|
out(" ldx c64.SCRATCH_ZPREGX") // restore X again
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateSubroutineArgument(arg: IndexedValue<SubroutineParameter>, value: Expression, sub: Subroutine) {
|
fun translateSubroutineArgument(arg: IndexedValue<SubroutineParameter>, value: Expression, sub: Subroutine) {
|
||||||
val sourceDt = value.inferType(program)!!
|
val sourceDt = value.inferType(program)!!
|
||||||
if(!argumentTypeCompatible(sourceDt, arg.value.type))
|
if(!argumentTypeCompatible(sourceDt, arg.value.type))
|
||||||
throw AssemblyError("argument type incompatible")
|
throw AssemblyError("argument type incompatible")
|
||||||
|
@ -54,11 +54,11 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"mkword" -> {
|
"mkword" -> {
|
||||||
translateFunctionArguments(fcall.arglist)
|
translateFunctionArguments(fcall.arglist, func)
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta $ESTACK_HI_PLUS1_HEX,x")
|
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta $ESTACK_HI_PLUS1_HEX,x")
|
||||||
}
|
}
|
||||||
"abs" -> {
|
"abs" -> {
|
||||||
translateFunctionArguments(fcall.arglist)
|
translateFunctionArguments(fcall.arglist, func)
|
||||||
val dt = fcall.arglist.single().inferType(program)!!
|
val dt = fcall.arglist.single().inferType(program)!!
|
||||||
when (dt) {
|
when (dt) {
|
||||||
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b")
|
in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b")
|
||||||
@ -72,7 +72,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
|||||||
"ln", "log2", "sqrt", "rad",
|
"ln", "log2", "sqrt", "rad",
|
||||||
"deg", "round", "floor", "ceil",
|
"deg", "round", "floor", "ceil",
|
||||||
"rdnf" -> {
|
"rdnf" -> {
|
||||||
translateFunctionArguments(fcall.arglist)
|
translateFunctionArguments(fcall.arglist, func)
|
||||||
asmgen.out(" jsr c64flt.func_$functionName")
|
asmgen.out(" jsr c64flt.func_$functionName")
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -224,14 +224,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
translateFunctionArguments(fcall.arglist)
|
translateFunctionArguments(fcall.arglist, func)
|
||||||
asmgen.out(" jsr prog8_lib.func_$functionName")
|
asmgen.out(" jsr prog8_lib.func_$functionName")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateFunctionArguments(args: MutableList<Expression>) {
|
private fun translateFunctionArguments(args: MutableList<Expression>, signature: FunctionSignature) {
|
||||||
args.forEach { asmgen.translateExpression(it) }
|
args.forEach {
|
||||||
|
asmgen.translateExpression(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import prog8.ast.expressions.Expression
|
|||||||
import prog8.ast.expressions.IdentifierReference
|
import prog8.ast.expressions.IdentifierReference
|
||||||
import prog8.ast.expressions.NumericLiteralValue
|
import prog8.ast.expressions.NumericLiteralValue
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
|
import prog8.compiler.IntegerOrAddressOf
|
||||||
import prog8.compiler.target.c64.MachineDefinition
|
import prog8.compiler.target.c64.MachineDefinition
|
||||||
import prog8.compiler.target.c64.Petscii
|
import prog8.compiler.target.c64.Petscii
|
||||||
import prog8.vm.RuntimeValue
|
import prog8.vm.RuntimeValue
|
||||||
@ -877,27 +878,31 @@ class AstVm(val program: Program) {
|
|||||||
RuntimeValue(DataType.UBYTE, args[0].str!!.length)
|
RuntimeValue(DataType.UBYTE, args[0].str!!.length)
|
||||||
}
|
}
|
||||||
"memset" -> {
|
"memset" -> {
|
||||||
val target = args[0].array!!
|
val heapId = args[0].wordval!!
|
||||||
|
val target = program.heap.get(heapId).array ?: throw VmExecutionException("memset target is not an array")
|
||||||
val amount = args[1].integerValue()
|
val amount = args[1].integerValue()
|
||||||
val value = args[2].integerValue()
|
val value = args[2].integerValue()
|
||||||
for (i in 0 until amount) {
|
for (i in 0 until amount) {
|
||||||
target[i] = value
|
target[i] = IntegerOrAddressOf(value, null)
|
||||||
}
|
}
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
"memsetw" -> {
|
"memsetw" -> {
|
||||||
val target = args[0].array!!
|
val heapId = args[0].wordval!!
|
||||||
|
val target = program.heap.get(heapId).array ?: throw VmExecutionException("memset target is not an array")
|
||||||
val amount = args[1].integerValue()
|
val amount = args[1].integerValue()
|
||||||
val value = args[2].integerValue()
|
val value = args[2].integerValue()
|
||||||
for (i in 0 until amount step 2) {
|
for (i in 0 until amount step 2) {
|
||||||
target[i * 2] = value and 255
|
target[i * 2] = IntegerOrAddressOf(value and 255, null)
|
||||||
target[i * 2 + 1] = value ushr 8
|
target[i * 2 + 1] = IntegerOrAddressOf(value ushr 8, null)
|
||||||
}
|
}
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
"memcopy" -> {
|
"memcopy" -> {
|
||||||
val source = args[0].array!!
|
val sourceHeapId = args[0].wordval!!
|
||||||
val dest = args[1].array!!
|
val destHeapId = args[1].wordval!!
|
||||||
|
val source = program.heap.get(sourceHeapId).array!!
|
||||||
|
val dest = program.heap.get(destHeapId).array!!
|
||||||
val amount = args[2].integerValue()
|
val amount = args[2].integerValue()
|
||||||
for(i in 0 until amount) {
|
for(i in 0 until amount) {
|
||||||
dest[i] = source[i]
|
dest[i] = source[i]
|
||||||
|
@ -1,45 +1,20 @@
|
|||||||
%import c64utils
|
%import c64utils
|
||||||
%zeropage basicsafe
|
%import c64lib
|
||||||
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
ubyte[256] sieve
|
|
||||||
ubyte candidate_prime = 2
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
memset(sieve, 256, false)
|
ending()
|
||||||
|
|
||||||
c64scr.print("prime numbers up to 255:\n\n")
|
|
||||||
ubyte amount=0
|
|
||||||
while true {
|
|
||||||
ubyte prime = find_next_prime()
|
|
||||||
if prime==0
|
|
||||||
break
|
|
||||||
c64scr.print_ub(prime)
|
|
||||||
c64scr.print(", ")
|
|
||||||
amount++
|
|
||||||
}
|
}
|
||||||
c64.CHROUT('\n')
|
sub ending() {
|
||||||
c64scr.print("number of primes (expected 54): ")
|
if A
|
||||||
c64scr.print_ub(amount)
|
c64scr.print("bla")
|
||||||
c64.CHROUT('\n')
|
else {
|
||||||
|
c64scr.print("bla")
|
||||||
|
c64scr.print("bla")
|
||||||
}
|
}
|
||||||
|
c64scr.print("bla")
|
||||||
|
|
||||||
sub find_next_prime() -> ubyte {
|
|
||||||
|
|
||||||
while sieve[candidate_prime] {
|
|
||||||
candidate_prime++
|
|
||||||
if candidate_prime==0
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
sieve[candidate_prime] = true
|
|
||||||
uword multiple = candidate_prime
|
|
||||||
while multiple < len(sieve) {
|
|
||||||
sieve[lsb(multiple)] = true
|
|
||||||
multiple += candidate_prime
|
|
||||||
}
|
|
||||||
return candidate_prime
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user