mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
removed the -nostrictbool compiler option
boolean types and bytes are no longer implicitly interchangeable using this option
This commit is contained in:
parent
6516d7cb15
commit
bdeac74cfc
@ -27,7 +27,6 @@ class CompilationOptions(val output: OutputType,
|
|||||||
var slabsHighBank: Int? = null,
|
var slabsHighBank: Int? = null,
|
||||||
var slabsGolden: Boolean = false,
|
var slabsGolden: Boolean = false,
|
||||||
var splitWordArrays: Boolean = false,
|
var splitWordArrays: Boolean = false,
|
||||||
var strictBool: Boolean = true,
|
|
||||||
var breakpointCpuInstruction: String? = null,
|
var breakpointCpuInstruction: String? = null,
|
||||||
var outputDir: Path = Path(""),
|
var outputDir: Path = Path(""),
|
||||||
var symbolDefs: Map<String, String> = emptyMap()
|
var symbolDefs: Map<String, String> = emptyMap()
|
||||||
|
@ -232,7 +232,7 @@ class AsmGen6502Internal (
|
|||||||
private val functioncallAsmGen = FunctionCallAsmGen(program, this)
|
private val functioncallAsmGen = FunctionCallAsmGen(program, this)
|
||||||
private val programGen = ProgramAndVarsGen(program, options, errors, symbolTable, functioncallAsmGen, this, allocator, zeropage)
|
private val programGen = ProgramAndVarsGen(program, options, errors, symbolTable, functioncallAsmGen, this, allocator, zeropage)
|
||||||
private val anyExprGen = AnyExprAsmGen(this)
|
private val anyExprGen = AnyExprAsmGen(this)
|
||||||
private val assignmentAsmGen = AssignmentAsmGen(program, this, options, anyExprGen, allocator)
|
private val assignmentAsmGen = AssignmentAsmGen(program, this, anyExprGen, allocator)
|
||||||
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
|
private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen)
|
||||||
private val ifElseAsmgen = IfElseAsmGen(program, symbolTable, this, allocator, assignmentAsmGen, errors)
|
private val ifElseAsmgen = IfElseAsmGen(program, symbolTable, this, allocator, assignmentAsmGen, errors)
|
||||||
|
|
||||||
|
@ -11,11 +11,12 @@ import prog8.codegen.cpu6502.VariableAllocator
|
|||||||
import prog8.codegen.cpu6502.returnsWhatWhere
|
import prog8.codegen.cpu6502.returnsWhatWhere
|
||||||
|
|
||||||
|
|
||||||
internal class AssignmentAsmGen(private val program: PtProgram,
|
internal class AssignmentAsmGen(
|
||||||
|
private val program: PtProgram,
|
||||||
private val asmgen: AsmGen6502Internal,
|
private val asmgen: AsmGen6502Internal,
|
||||||
private val options: CompilationOptions,
|
|
||||||
private val anyExprGen: AnyExprAsmGen,
|
private val anyExprGen: AnyExprAsmGen,
|
||||||
private val allocator: VariableAllocator) {
|
private val allocator: VariableAllocator
|
||||||
|
) {
|
||||||
private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen, allocator)
|
private val augmentableAsmGen = AugmentableAssignmentAsmGen(program, this, asmgen, allocator)
|
||||||
|
|
||||||
fun translate(assignment: PtAssignment) {
|
fun translate(assignment: PtAssignment) {
|
||||||
@ -201,7 +202,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
val variable = assign.source.asmVarname
|
val variable = assign.source.asmVarname
|
||||||
when (assign.target.datatype) {
|
when (assign.target.datatype) {
|
||||||
DataType.BOOL -> {
|
DataType.BOOL -> {
|
||||||
if (assign.source.datatype == DataType.BOOL || !options.strictBool) assignVariableByte(assign.target, variable)
|
if (assign.source.datatype == DataType.BOOL) assignVariableByte(assign.target, variable)
|
||||||
else throw AssemblyError("assigning non-bool variable to boolean, should have been typecasted")
|
else throw AssemblyError("assigning non-bool variable to boolean, should have been typecasted")
|
||||||
}
|
}
|
||||||
DataType.UBYTE, DataType.BYTE -> assignVariableByte(assign.target, variable)
|
DataType.UBYTE, DataType.BYTE -> assignVariableByte(assign.target, variable)
|
||||||
|
@ -490,7 +490,6 @@ internal class ConstantIdentifierReplacer(
|
|||||||
if(numericLv!=null) {
|
if(numericLv!=null) {
|
||||||
// arraysize initializer is a single value, and we know the array size.
|
// arraysize initializer is a single value, and we know the array size.
|
||||||
if(numericLv.type!=DataType.BOOL) {
|
if(numericLv.type!=DataType.BOOL) {
|
||||||
if(options.strictBool || numericLv.type !in ByteDatatypes)
|
|
||||||
errors.err("initializer value is not a boolean", numericLv.position)
|
errors.err("initializer value is not a boolean", numericLv.position)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,9 @@ import prog8.ast.walk.IAstModification
|
|||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
import kotlin.math.log2
|
import kotlin.math.log2
|
||||||
import kotlin.math.pow
|
|
||||||
|
|
||||||
class ExpressionSimplifier(private val program: Program, private val options: CompilationOptions, private val errors: IErrorReporter) : AstWalker() {
|
|
||||||
|
class ExpressionSimplifier(private val program: Program, private val errors: IErrorReporter) : AstWalker() {
|
||||||
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
|
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
|
||||||
val mods = mutableListOf<IAstModification>()
|
val mods = mutableListOf<IAstModification>()
|
||||||
|
|
||||||
@ -246,23 +246,18 @@ class ExpressionSimplifier(private val program: Program, private val options: Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rightVal?.number == 1.0) {
|
if (rightVal?.number == 1.0) {
|
||||||
if (options.strictBool) {
|
|
||||||
if (rightDt != leftDt) {
|
if (rightDt != leftDt) {
|
||||||
val right = NumericLiteral(leftDt, rightVal.number, rightVal.position)
|
val right = NumericLiteral(leftDt, rightVal.number, rightVal.position)
|
||||||
return listOf(IAstModification.ReplaceNode(expr.right, right, expr))
|
return listOf(IAstModification.ReplaceNode(expr.right, right, expr))
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
return listOf(IAstModification.ReplaceNode(expr, expr.left, parent))
|
|
||||||
}
|
}
|
||||||
else if (rightVal?.number == 0.0) {
|
else if (rightVal?.number == 0.0) {
|
||||||
if (options.strictBool) {
|
|
||||||
if (rightDt != leftDt) {
|
if (rightDt != leftDt) {
|
||||||
val right = NumericLiteral(leftDt, rightVal.number, rightVal.position)
|
val right = NumericLiteral(leftDt, rightVal.number, rightVal.position)
|
||||||
return listOf(IAstModification.ReplaceNode(expr.right, right, expr))
|
return listOf(IAstModification.ReplaceNode(expr.right, right, expr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (expr.operator=="!=") {
|
if (expr.operator=="!=") {
|
||||||
if(rightDt==DataType.BOOL && leftDt==DataType.BOOL) {
|
if(rightDt==DataType.BOOL && leftDt==DataType.BOOL) {
|
||||||
val rightConstBool = rightVal?.asBooleanValue
|
val rightConstBool = rightVal?.asBooleanValue
|
||||||
@ -274,21 +269,16 @@ class ExpressionSimplifier(private val program: Program, private val options: Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rightVal?.number == 1.0) {
|
if (rightVal?.number == 1.0) {
|
||||||
if(options.strictBool) {
|
|
||||||
if(rightDt!=leftDt) {
|
if(rightDt!=leftDt) {
|
||||||
val right = NumericLiteral(leftDt, rightVal.number, rightVal.position)
|
val right = NumericLiteral(leftDt, rightVal.number, rightVal.position)
|
||||||
return listOf(IAstModification.ReplaceNode(expr.right, right, expr))
|
return listOf(IAstModification.ReplaceNode(expr.right, right, expr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (rightVal?.number == 0.0) {
|
else if (rightVal?.number == 0.0) {
|
||||||
if(options.strictBool) {
|
|
||||||
if(rightDt!=leftDt) {
|
if(rightDt!=leftDt) {
|
||||||
val right = NumericLiteral(leftDt, rightVal.number, rightVal.position)
|
val right = NumericLiteral(leftDt, rightVal.number, rightVal.position)
|
||||||
return listOf(IAstModification.ReplaceNode(expr.right, right, expr))
|
return listOf(IAstModification.ReplaceNode(expr.right, right, expr))
|
||||||
}
|
}
|
||||||
} else
|
|
||||||
return listOf(IAstModification.ReplaceNode(expr, expr.left, parent))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ fun Program.inlineSubroutines(options: CompilationOptions): Int {
|
|||||||
return inliner.applyModifications()
|
return inliner.applyModifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Program.simplifyExpressions(errors: IErrorReporter, options: CompilationOptions) : Int {
|
fun Program.simplifyExpressions(errors: IErrorReporter) : Int {
|
||||||
val opti = ExpressionSimplifier(this, options, errors)
|
val opti = ExpressionSimplifier(this, errors)
|
||||||
opti.visit(this)
|
opti.visit(this)
|
||||||
return opti.applyModifications()
|
return opti.applyModifications()
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,6 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
val dumpVariables by cli.option(ArgType.Boolean, fullName = "dumpvars", description = "print a dump of the variables in the program")
|
val dumpVariables by cli.option(ArgType.Boolean, fullName = "dumpvars", description = "print a dump of the variables in the program")
|
||||||
val dumpSymbols by cli.option(ArgType.Boolean, fullName = "dumpsymbols", description = "print a dump of the variable declarations and subroutine signatures")
|
val dumpSymbols by cli.option(ArgType.Boolean, fullName = "dumpsymbols", description = "print a dump of the variable declarations and subroutine signatures")
|
||||||
val dontWriteAssembly by cli.option(ArgType.Boolean, fullName = "noasm", description="don't create assembly code")
|
val dontWriteAssembly by cli.option(ArgType.Boolean, fullName = "noasm", description="don't create assembly code")
|
||||||
val noStrictBool by cli.option(ArgType.Boolean, fullName = "nostrictbool", description = "allow implicit conversions between bool and bytes")
|
|
||||||
val dontOptimize by cli.option(ArgType.Boolean, fullName = "noopt", description = "don't perform code optimizations")
|
val dontOptimize by cli.option(ArgType.Boolean, fullName = "noopt", description = "don't perform code optimizations")
|
||||||
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
||||||
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
|
||||||
@ -178,7 +177,6 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
breakpointCpuInstruction,
|
breakpointCpuInstruction,
|
||||||
printAst1 == true,
|
printAst1 == true,
|
||||||
printAst2 == true,
|
printAst2 == true,
|
||||||
noStrictBool != true,
|
|
||||||
processedSymbols,
|
processedSymbols,
|
||||||
srcdirs,
|
srcdirs,
|
||||||
outputPath
|
outputPath
|
||||||
@ -259,7 +257,6 @@ private fun compileMain(args: Array<String>): Boolean {
|
|||||||
breakpointCpuInstruction,
|
breakpointCpuInstruction,
|
||||||
printAst1 == true,
|
printAst1 == true,
|
||||||
printAst2 == true,
|
printAst2 == true,
|
||||||
noStrictBool != true,
|
|
||||||
processedSymbols,
|
processedSymbols,
|
||||||
srcdirs,
|
srcdirs,
|
||||||
outputPath
|
outputPath
|
||||||
|
@ -54,7 +54,6 @@ class CompilerArguments(val filepath: Path,
|
|||||||
val breakpointCpuInstruction: String?,
|
val breakpointCpuInstruction: String?,
|
||||||
val printAst1: Boolean,
|
val printAst1: Boolean,
|
||||||
val printAst2: Boolean,
|
val printAst2: Boolean,
|
||||||
val strictBool: Boolean,
|
|
||||||
val symbolDefs: Map<String, String>,
|
val symbolDefs: Map<String, String>,
|
||||||
val sourceDirs: List<String> = emptyList(),
|
val sourceDirs: List<String> = emptyList(),
|
||||||
val outputDir: Path = Path(""),
|
val outputDir: Path = Path(""),
|
||||||
@ -91,7 +90,6 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
|||||||
splitWordArrays = args.splitWordArrays
|
splitWordArrays = args.splitWordArrays
|
||||||
outputDir = args.outputDir.normalize()
|
outputDir = args.outputDir.normalize()
|
||||||
symbolDefs = args.symbolDefs
|
symbolDefs = args.symbolDefs
|
||||||
strictBool = args.strictBool
|
|
||||||
}
|
}
|
||||||
resultingProgram = program
|
resultingProgram = program
|
||||||
importedFiles = imported
|
importedFiles = imported
|
||||||
@ -412,7 +410,7 @@ private fun processAst(program: Program, errors: IErrorReporter, compilerOptions
|
|||||||
errors.report()
|
errors.report()
|
||||||
program.reorderStatements(errors)
|
program.reorderStatements(errors)
|
||||||
errors.report()
|
errors.report()
|
||||||
program.desugaring(errors, compilerOptions)
|
program.desugaring(errors)
|
||||||
errors.report()
|
errors.report()
|
||||||
program.changeNotExpressionAndIfComparisonExpr(errors, compilerOptions.compTarget)
|
program.changeNotExpressionAndIfComparisonExpr(errors, compilerOptions.compTarget)
|
||||||
errors.report()
|
errors.report()
|
||||||
@ -438,7 +436,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
|
|||||||
removeUnusedCode(program, errors,compilerOptions)
|
removeUnusedCode(program, errors,compilerOptions)
|
||||||
while (true) {
|
while (true) {
|
||||||
// keep optimizing expressions and statements until no more steps remain
|
// keep optimizing expressions and statements until no more steps remain
|
||||||
val optsDone1 = program.simplifyExpressions(errors, compilerOptions)
|
val optsDone1 = program.simplifyExpressions(errors)
|
||||||
val optsDone2 = program.optimizeStatements(errors, functions, compilerOptions)
|
val optsDone2 = program.optimizeStatements(errors, functions, compilerOptions)
|
||||||
val optsDone3 = program.inlineSubroutines(compilerOptions)
|
val optsDone3 = program.inlineSubroutines(compilerOptions)
|
||||||
program.constantFold(errors, compilerOptions) // because simplified statements and expressions can result in more constants that can be folded away
|
program.constantFold(errors, compilerOptions) // because simplified statements and expressions can result in more constants that can be folded away
|
||||||
@ -452,7 +450,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
|
|||||||
removeUnusedCode(program, errors, compilerOptions)
|
removeUnusedCode(program, errors, compilerOptions)
|
||||||
if(errors.noErrors()) {
|
if(errors.noErrors()) {
|
||||||
// last round of optimizations because constFold may have enabled more...
|
// last round of optimizations because constFold may have enabled more...
|
||||||
program.simplifyExpressions(errors, compilerOptions)
|
program.simplifyExpressions(errors)
|
||||||
program.optimizeStatements(errors, functions, compilerOptions)
|
program.optimizeStatements(errors, functions, compilerOptions)
|
||||||
program.constantFold(errors, compilerOptions) // because simplified statements and expressions can result in more constants that can be folded away
|
program.constantFold(errors, compilerOptions) // because simplified statements and expressions can result in more constants that can be folded away
|
||||||
}
|
}
|
||||||
@ -461,7 +459,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun postprocessAst(program: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) {
|
private fun postprocessAst(program: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) {
|
||||||
program.desugaring(errors, compilerOptions)
|
program.desugaring(errors)
|
||||||
program.addTypecasts(errors, compilerOptions)
|
program.addTypecasts(errors, compilerOptions)
|
||||||
errors.report()
|
errors.report()
|
||||||
program.variousCleanups(errors, compilerOptions)
|
program.variousCleanups(errors, compilerOptions)
|
||||||
|
@ -163,8 +163,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
|
|
||||||
override fun visit(ifElse: IfElse) {
|
override fun visit(ifElse: IfElse) {
|
||||||
if(!ifElse.condition.inferType(program).isBool) {
|
if(!ifElse.condition.inferType(program).isBool) {
|
||||||
val ctype = ifElse.condition.inferType(program).getOr(DataType.UNDEFINED)
|
|
||||||
if(compilerOptions.strictBool || ctype !in ByteDatatypes)
|
|
||||||
errors.err("condition should be a boolean", ifElse.condition.position)
|
errors.err("condition should be a boolean", ifElse.condition.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -506,8 +504,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
|
|
||||||
override fun visit(untilLoop: UntilLoop) {
|
override fun visit(untilLoop: UntilLoop) {
|
||||||
if(!untilLoop.condition.inferType(program).isBool) {
|
if(!untilLoop.condition.inferType(program).isBool) {
|
||||||
val ctype = untilLoop.condition.inferType(program).getOr(DataType.UNDEFINED)
|
|
||||||
if(compilerOptions.strictBool || ctype !in ByteDatatypes)
|
|
||||||
errors.err("condition should be a boolean", untilLoop.condition.position)
|
errors.err("condition should be a boolean", untilLoop.condition.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,8 +512,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
|
|
||||||
override fun visit(whileLoop: WhileLoop) {
|
override fun visit(whileLoop: WhileLoop) {
|
||||||
if(!whileLoop.condition.inferType(program).isBool) {
|
if(!whileLoop.condition.inferType(program).isBool) {
|
||||||
val ctype = whileLoop.condition.inferType(program).getOr(DataType.UNDEFINED)
|
|
||||||
if(compilerOptions.strictBool || ctype !in ByteDatatypes)
|
|
||||||
errors.err("condition should be a boolean", whileLoop.condition.position)
|
errors.err("condition should be a boolean", whileLoop.condition.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,12 +774,8 @@ internal class AstChecker(private val program: Program,
|
|||||||
if (iDt isnot decl.datatype) {
|
if (iDt isnot decl.datatype) {
|
||||||
if(decl.isArray) {
|
if(decl.isArray) {
|
||||||
val eltDt = ArrayToElementTypes.getValue(decl.datatype)
|
val eltDt = ArrayToElementTypes.getValue(decl.datatype)
|
||||||
if(iDt isnot eltDt) {
|
if(iDt isnot eltDt)
|
||||||
if(compilerOptions.strictBool)
|
|
||||||
err("initialisation value has incompatible type ($iDt) for the variable (${decl.datatype})")
|
err("initialisation value has incompatible type ($iDt) for the variable (${decl.datatype})")
|
||||||
else if(!(iDt.isBool && eltDt==DataType.UBYTE || iDt.istype(DataType.UBYTE) && eltDt==DataType.BOOL))
|
|
||||||
err("initialisation value has incompatible type ($iDt) for the variable (${decl.datatype})")
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(!(iDt.isBool && decl.datatype==DataType.UBYTE || iDt.istype(DataType.UBYTE) && decl.datatype==DataType.BOOL))
|
if(!(iDt.isBool && decl.datatype==DataType.UBYTE || iDt.istype(DataType.UBYTE) && decl.datatype==DataType.BOOL))
|
||||||
err("initialisation value has incompatible type ($iDt) for the variable (${decl.datatype})")
|
err("initialisation value has incompatible type ($iDt) for the variable (${decl.datatype})")
|
||||||
@ -1048,7 +1038,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
else if(expr.operator == "not") {
|
else if(expr.operator == "not") {
|
||||||
if(dt!=DataType.BOOL) {
|
if(dt!=DataType.BOOL) {
|
||||||
if(compilerOptions.strictBool || dt !in ByteDatatypes)
|
|
||||||
errors.err("logical not is for booleans", expr.position)
|
errors.err("logical not is for booleans", expr.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1168,7 +1157,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
|
|
||||||
if(expr.operator in LogicalOperators) {
|
if(expr.operator in LogicalOperators) {
|
||||||
if (leftDt != DataType.BOOL || rightDt != DataType.BOOL) {
|
if (leftDt != DataType.BOOL || rightDt != DataType.BOOL) {
|
||||||
if(compilerOptions.strictBool || leftDt !in ByteDatatypes || rightDt !in ByteDatatypes)
|
|
||||||
errors.err("logical operator requires boolean operands", expr.right.position)
|
errors.err("logical operator requires boolean operands", expr.right.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1248,7 +1236,7 @@ internal class AstChecker(private val program: Program,
|
|||||||
errors.warn("sgn() of unsigned type is always 0 or 1, this is perhaps not what was intended", functionCallExpr.args.first().position)
|
errors.warn("sgn() of unsigned type is always 0 or 1, this is perhaps not what was intended", functionCallExpr.args.first().position)
|
||||||
}
|
}
|
||||||
|
|
||||||
val error = VerifyFunctionArgTypes.checkTypes(functionCallExpr, program, compilerOptions)
|
val error = VerifyFunctionArgTypes.checkTypes(functionCallExpr, program)
|
||||||
if(error!=null)
|
if(error!=null)
|
||||||
errors.err(error.first, error.second)
|
errors.err(error.first, error.second)
|
||||||
|
|
||||||
@ -1339,7 +1327,7 @@ internal class AstChecker(private val program: Program,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val error = VerifyFunctionArgTypes.checkTypes(functionCallStatement, program, compilerOptions)
|
val error = VerifyFunctionArgTypes.checkTypes(functionCallStatement, program)
|
||||||
if(error!=null)
|
if(error!=null)
|
||||||
errors.err(error.first, error.second)
|
errors.err(error.first, error.second)
|
||||||
|
|
||||||
@ -1727,7 +1715,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
DataType.BOOL -> {
|
DataType.BOOL -> {
|
||||||
if (value.type!=DataType.BOOL) {
|
if (value.type!=DataType.BOOL) {
|
||||||
if (compilerOptions.strictBool || value.type !in ByteDatatypes)
|
|
||||||
err("type of value ${value.type} doesn't match target $targetDt")
|
err("type of value ${value.type} doesn't match target $targetDt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1829,11 +1816,9 @@ internal class AstChecker(private val program: Program,
|
|||||||
// this is allowed: a pass-by-reference datatype into a uword (pointer value).
|
// this is allowed: a pass-by-reference datatype into a uword (pointer value).
|
||||||
}
|
}
|
||||||
else if(sourceDatatype==DataType.BOOL && targetDatatype!=DataType.BOOL) {
|
else if(sourceDatatype==DataType.BOOL && targetDatatype!=DataType.BOOL) {
|
||||||
if(compilerOptions.strictBool || targetDatatype !in ByteDatatypes)
|
|
||||||
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
|
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
|
||||||
}
|
}
|
||||||
else if(targetDatatype==DataType.BOOL && sourceDatatype!=DataType.BOOL) {
|
else if(targetDatatype==DataType.BOOL && sourceDatatype!=DataType.BOOL) {
|
||||||
if(compilerOptions.strictBool || sourceDatatype !in ByteDatatypes)
|
|
||||||
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
|
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -92,8 +92,8 @@ internal fun Program.addTypecasts(errors: IErrorReporter, options: CompilationOp
|
|||||||
caster.applyModifications()
|
caster.applyModifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Program.desugaring(errors: IErrorReporter, options: CompilationOptions) {
|
fun Program.desugaring(errors: IErrorReporter) {
|
||||||
val desugar = CodeDesugarer(this, options, errors)
|
val desugar = CodeDesugarer(this, errors)
|
||||||
desugar.visit(this)
|
desugar.visit(this)
|
||||||
while(errors.noErrors() && desugar.applyModifications()>0)
|
while(errors.noErrors() && desugar.applyModifications()>0)
|
||||||
desugar.visit(this)
|
desugar.visit(this)
|
||||||
|
@ -8,7 +8,7 @@ import prog8.ast.walk.IAstModification
|
|||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
|
|
||||||
|
|
||||||
internal class CodeDesugarer(val program: Program, private val options: CompilationOptions, private val errors: IErrorReporter) : AstWalker() {
|
internal class CodeDesugarer(val program: Program, private val errors: IErrorReporter) : AstWalker() {
|
||||||
|
|
||||||
// Some more code shuffling to simplify the Ast that the codegenerator has to process.
|
// Some more code shuffling to simplify the Ast that the codegenerator has to process.
|
||||||
// Several changes have already been done by the StatementReorderer !
|
// Several changes have already been done by the StatementReorderer !
|
||||||
@ -123,8 +123,6 @@ if not CONDITION
|
|||||||
override fun after(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> {
|
override fun after(whileLoop: WhileLoop, parent: Node): Iterable<IAstModification> {
|
||||||
|
|
||||||
if(!whileLoop.condition.inferType(program).isBool) {
|
if(!whileLoop.condition.inferType(program).isBool) {
|
||||||
val ctype = whileLoop.condition.inferType(program).getOr(DataType.UNDEFINED)
|
|
||||||
if(options.strictBool || ctype !in ByteDatatypes)
|
|
||||||
errors.err("condition should be a boolean", whileLoop.condition.position)
|
errors.err("condition should be a boolean", whileLoop.condition.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
val valueDt = declValue.inferType(program)
|
val valueDt = declValue.inferType(program)
|
||||||
if(valueDt isnot decl.datatype) {
|
if(valueDt isnot decl.datatype) {
|
||||||
|
|
||||||
if(decl.isArray && !options.strictBool) {
|
|
||||||
if(tryConvertBooleanArrays(decl, declValue, parent))
|
|
||||||
return noModifications
|
|
||||||
}
|
|
||||||
|
|
||||||
if(valueDt.isInteger && decl.isArray) {
|
if(valueDt.isInteger && decl.isArray) {
|
||||||
if(decl.datatype == DataType.ARRAY_BOOL) {
|
if(decl.datatype == DataType.ARRAY_BOOL) {
|
||||||
val integer = declValue.constValue(program)?.number
|
val integer = declValue.constValue(program)?.number
|
||||||
@ -54,69 +49,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryConvertBooleanArrays(decl: VarDecl, declValue: Expression, parent: Node): Boolean {
|
|
||||||
val valueNumber = declValue.constValue(program)
|
|
||||||
val valueArray = declValue as? ArrayLiteral
|
|
||||||
when (decl.datatype) {
|
|
||||||
DataType.ARRAY_BOOL -> {
|
|
||||||
if(valueNumber!=null) {
|
|
||||||
decl.value = NumericLiteral.fromBoolean(valueNumber.number!=0.0, declValue.position)
|
|
||||||
decl.linkParents(parent)
|
|
||||||
return true
|
|
||||||
} else if(valueArray!=null) {
|
|
||||||
val newArray = valueArray.value.map {
|
|
||||||
if(it.inferType(program).isBytes) {
|
|
||||||
TypecastExpression(it, DataType.BOOL, false, it.position)
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
decl.value = ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_BOOL), newArray.toTypedArray(), valueArray.position)
|
|
||||||
decl.linkParents(parent)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DataType.ARRAY_B -> {
|
|
||||||
if(valueNumber!=null) {
|
|
||||||
decl.value = NumericLiteral(DataType.BYTE, if(valueNumber.asBooleanValue) 1.0 else 0.0, declValue.position)
|
|
||||||
decl.linkParents(parent)
|
|
||||||
return true
|
|
||||||
} else if(valueArray!=null) {
|
|
||||||
val newArray = valueArray.value.map {
|
|
||||||
if(it.inferType(program).isBool) {
|
|
||||||
TypecastExpression(it, DataType.BYTE, false, it.position)
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
decl.value = ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_B), newArray.toTypedArray(), valueArray.position)
|
|
||||||
decl.linkParents(parent)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DataType.ARRAY_UB -> {
|
|
||||||
if(valueNumber!=null) {
|
|
||||||
decl.value = NumericLiteral(DataType.UBYTE, if(valueNumber.asBooleanValue) 1.0 else 0.0, declValue.position)
|
|
||||||
decl.linkParents(parent)
|
|
||||||
return true
|
|
||||||
} else if(valueArray!=null) {
|
|
||||||
val newArray = valueArray.value.map {
|
|
||||||
if(it.inferType(program).isBool) {
|
|
||||||
TypecastExpression(it, DataType.UBYTE, false, it.position)
|
|
||||||
} else {
|
|
||||||
it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
decl.value = ArrayLiteral(InferredTypes.InferredType.known(DataType.ARRAY_UB), newArray.toTypedArray(), valueArray.position)
|
|
||||||
decl.linkParents(parent)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> { /* no casting possible */ }
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
|
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
|
||||||
val leftDt = expr.left.inferType(program)
|
val leftDt = expr.left.inferType(program)
|
||||||
val rightDt = expr.right.inferType(program)
|
val rightDt = expr.right.inferType(program)
|
||||||
@ -155,26 +87,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(leftDt!=rightDt) {
|
if(leftDt!=rightDt) {
|
||||||
if(!options.strictBool) {
|
|
||||||
if (expr.operator in LogicalOperators) {
|
|
||||||
if (leftDt.isBool) {
|
|
||||||
val cast = TypecastExpression(expr.right, DataType.BOOL, false, expr.right.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(expr.right, cast, expr))
|
|
||||||
} else {
|
|
||||||
val cast = TypecastExpression(expr.left, DataType.BOOL, false, expr.left.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(expr.left, cast, expr))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(leftDt.isBool && rightDt.isBytes) {
|
|
||||||
val cast = TypecastExpression(expr.left, rightDt.getOr(DataType.UNDEFINED), false, expr.left.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(expr.left, cast, expr))
|
|
||||||
} else if(rightDt.isBool && leftDt.isBytes) {
|
|
||||||
val cast = TypecastExpression(expr.right, leftDt.getOr(DataType.UNDEFINED), false, expr.right.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(expr.right, cast, expr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert a negative operand for bitwise operator to the 2's complement positive number instead
|
// convert a negative operand for bitwise operator to the 2's complement positive number instead
|
||||||
if(expr.operator in BitwiseOperators && leftDt.isInteger && rightDt.isInteger) {
|
if(expr.operator in BitwiseOperators && leftDt.isInteger && rightDt.isInteger) {
|
||||||
if(leftCv!=null && leftCv.number<0) {
|
if(leftCv!=null && leftCv.number<0) {
|
||||||
@ -280,16 +192,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
if(cvalue!=null) {
|
if(cvalue!=null) {
|
||||||
val number = cvalue.number
|
val number = cvalue.number
|
||||||
// more complex comparisons if the type is different, but the constant value is compatible
|
// more complex comparisons if the type is different, but the constant value is compatible
|
||||||
if(!options.strictBool) {
|
|
||||||
if (targettype == DataType.BOOL && valuetype in ByteDatatypes) {
|
|
||||||
val cast = NumericLiteral.fromBoolean(number!=0.0, cvalue.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(assignment.value, cast, assignment))
|
|
||||||
}
|
|
||||||
if (targettype in ByteDatatypes && valuetype == DataType.BOOL) {
|
|
||||||
val cast = NumericLiteral(targettype, if(cvalue.asBooleanValue) 1.0 else 0.0, cvalue.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(assignment.value, cast, assignment))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (valuetype == DataType.BYTE && targettype == DataType.UBYTE) {
|
if (valuetype == DataType.BYTE && targettype == DataType.UBYTE) {
|
||||||
if(number>0)
|
if(number>0)
|
||||||
return castLiteral(cvalue)
|
return castLiteral(cvalue)
|
||||||
@ -303,17 +205,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
if(number<0x8000)
|
if(number<0x8000)
|
||||||
return castLiteral(cvalue)
|
return castLiteral(cvalue)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if(!options.strictBool) {
|
|
||||||
if (targettype == DataType.BOOL && valuetype in ByteDatatypes) {
|
|
||||||
val cast = TypecastExpression(assignment.value, targettype, false, assignment.value.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(assignment.value, cast, assignment))
|
|
||||||
}
|
|
||||||
if (targettype in ByteDatatypes && valuetype == DataType.BOOL) {
|
|
||||||
val cast = TypecastExpression(assignment.value, targettype, false, assignment.value.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(assignment.value, cast, assignment))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,8 +256,7 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
} else if(argDt isAssignableTo targetDt) {
|
} else if(argDt isAssignableTo targetDt) {
|
||||||
if(argDt!=DataType.STR || targetDt!=DataType.UWORD)
|
if(argDt!=DataType.STR || targetDt!=DataType.UWORD)
|
||||||
addTypecastOrCastedValueModification(modifications, it.second, targetDt, call as Node)
|
addTypecastOrCastedValueModification(modifications, it.second, targetDt, call as Node)
|
||||||
} else if(!options.strictBool && targetDt in ByteDatatypes && argDt==DataType.BOOL)
|
}
|
||||||
addTypecastOrCastedValueModification(modifications, it.second, targetDt, call as Node)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val identifier = it.second as? IdentifierReference
|
val identifier = it.second as? IdentifierReference
|
||||||
@ -432,18 +322,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
if(subroutine.returntypes.size==1) {
|
if(subroutine.returntypes.size==1) {
|
||||||
val subReturnType = subroutine.returntypes.first()
|
val subReturnType = subroutine.returntypes.first()
|
||||||
val returnDt = returnValue.inferType(program)
|
val returnDt = returnValue.inferType(program)
|
||||||
|
|
||||||
if(!options.strictBool) {
|
|
||||||
if(subReturnType==DataType.BOOL && returnDt.isBytes) {
|
|
||||||
val cast = TypecastExpression(returnValue, DataType.BOOL, false, returnValue.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(returnValue, cast, returnStmt))
|
|
||||||
}
|
|
||||||
if(subReturnType in ByteDatatypes && returnDt.isBool) {
|
|
||||||
val cast = TypecastExpression(returnValue, subReturnType, false, returnValue.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(returnValue, cast, returnStmt))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (returnDt istype subReturnType or returnDt.isNotAssignableTo(subReturnType))
|
if (returnDt istype subReturnType or returnDt.isNotAssignableTo(subReturnType))
|
||||||
return noModifications
|
return noModifications
|
||||||
if (returnValue is NumericLiteral) {
|
if (returnValue is NumericLiteral) {
|
||||||
@ -488,14 +366,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
return modifications
|
return modifications
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun after(ifElse: IfElse, parent: Node): Iterable<IAstModification> {
|
|
||||||
if(!options.strictBool && ifElse.condition.inferType(program).isBytes) {
|
|
||||||
val cast = TypecastExpression(ifElse.condition, DataType.BOOL, false, ifElse.condition.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(ifElse.condition, cast, ifElse))
|
|
||||||
}
|
|
||||||
return noModifications
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addTypecastOrCastedValueModification(
|
private fun addTypecastOrCastedValueModification(
|
||||||
modifications: MutableList<IAstModification>,
|
modifications: MutableList<IAstModification>,
|
||||||
expressionToCast: Expression,
|
expressionToCast: Expression,
|
||||||
@ -505,18 +375,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
val sourceDt = expressionToCast.inferType(program).getOr(DataType.UNDEFINED)
|
val sourceDt = expressionToCast.inferType(program).getOr(DataType.UNDEFINED)
|
||||||
if(sourceDt == requiredType)
|
if(sourceDt == requiredType)
|
||||||
return
|
return
|
||||||
if(!options.strictBool) {
|
|
||||||
if(requiredType==DataType.BOOL && sourceDt in ByteDatatypes) {
|
|
||||||
val cast = TypecastExpression(expressionToCast, DataType.BOOL, false, expressionToCast.position)
|
|
||||||
modifications.add(IAstModification.ReplaceNode(expressionToCast, cast, parent))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(requiredType in ByteDatatypes && sourceDt==DataType.BOOL) {
|
|
||||||
val cast = TypecastExpression(expressionToCast, requiredType, false, expressionToCast.position)
|
|
||||||
modifications.add(IAstModification.ReplaceNode(expressionToCast, cast, parent))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(requiredType==DataType.BOOL) {
|
if(requiredType==DataType.BOOL) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -97,16 +97,6 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
|||||||
return listOf(IAstModification.ReplaceNode(expr, expr.expression, parent))
|
return listOf(IAstModification.ReplaceNode(expr, expr.expression, parent))
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!options.strictBool && expr.operator=="not") {
|
|
||||||
if(expr.expression.inferType(program).isBytes) {
|
|
||||||
// not bytevalue --> bytevalue==0
|
|
||||||
val cmp = BinaryExpression(expr.expression, "==",
|
|
||||||
NumericLiteral(expr.expression.inferType(program).getOr(DataType.UNDEFINED), 0.0, expr.expression.position),
|
|
||||||
expr.expression.position)
|
|
||||||
return listOf(IAstModification.ReplaceNode(expr, cmp, parent))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ internal class VerifyFunctionArgTypes(val program: Program, val options: Compila
|
|||||||
private val memorySlabs = mutableListOf<Slab>()
|
private val memorySlabs = mutableListOf<Slab>()
|
||||||
|
|
||||||
override fun visit(functionCallExpr: FunctionCallExpression) {
|
override fun visit(functionCallExpr: FunctionCallExpression) {
|
||||||
val error = checkTypes(functionCallExpr as IFunctionCall, program, options)
|
val error = checkTypes(functionCallExpr as IFunctionCall, program)
|
||||||
if(error!=null)
|
if(error!=null)
|
||||||
errors.err(error.first, error.second)
|
errors.err(error.first, error.second)
|
||||||
else {
|
else {
|
||||||
@ -62,7 +62,7 @@ internal class VerifyFunctionArgTypes(val program: Program, val options: Compila
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(functionCallStatement: FunctionCallStatement) {
|
override fun visit(functionCallStatement: FunctionCallStatement) {
|
||||||
val error = checkTypes(functionCallStatement as IFunctionCall, program, options)
|
val error = checkTypes(functionCallStatement as IFunctionCall, program)
|
||||||
if(error!=null)
|
if(error!=null)
|
||||||
errors.err(error.first, error.second)
|
errors.err(error.first, error.second)
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ internal class VerifyFunctionArgTypes(val program: Program, val options: Compila
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkTypes(call: IFunctionCall, program: Program, options: CompilationOptions): Pair<String, Position>? {
|
fun checkTypes(call: IFunctionCall, program: Program): Pair<String, Position>? {
|
||||||
val argITypes = call.args.map { it.inferType(program) }
|
val argITypes = call.args.map { it.inferType(program) }
|
||||||
val firstUnknownDt = argITypes.indexOfFirst { it.isUnknown }
|
val firstUnknownDt = argITypes.indexOfFirst { it.isUnknown }
|
||||||
if(firstUnknownDt>=0) {
|
if(firstUnknownDt>=0) {
|
||||||
@ -105,12 +105,7 @@ internal class VerifyFunctionArgTypes(val program: Program, val options: Compila
|
|||||||
if(mismatch>=0) {
|
if(mismatch>=0) {
|
||||||
val actual = argtypes[mismatch]
|
val actual = argtypes[mismatch]
|
||||||
val expected = consideredParamTypes[mismatch]
|
val expected = consideredParamTypes[mismatch]
|
||||||
return if(expected==DataType.BOOL && !options.strictBool && actual in ByteDatatypes)
|
return Pair("argument ${mismatch + 1} type mismatch, was: $actual expected: $expected", call.args[mismatch].position)
|
||||||
null
|
|
||||||
else if(expected in ByteDatatypes && !options.strictBool && actual==DataType.BOOL)
|
|
||||||
null
|
|
||||||
else
|
|
||||||
Pair("argument ${mismatch + 1} type mismatch, was: $actual expected: $expected", call.args[mismatch].position)
|
|
||||||
}
|
}
|
||||||
if(target.isAsmSubroutine) {
|
if(target.isAsmSubroutine) {
|
||||||
if(target.asmReturnvaluesRegisters.size>1) {
|
if(target.asmReturnvaluesRegisters.size>1) {
|
||||||
|
@ -43,7 +43,6 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat
|
|||||||
breakpointCpuInstruction = null,
|
breakpointCpuInstruction = null,
|
||||||
printAst1 = false,
|
printAst1 = false,
|
||||||
printAst2 = false,
|
printAst2 = false,
|
||||||
strictBool = true,
|
|
||||||
symbolDefs = emptyMap(),
|
symbolDefs = emptyMap(),
|
||||||
outputDir = outputDir
|
outputDir = outputDir
|
||||||
)
|
)
|
||||||
|
@ -41,7 +41,6 @@ class TestCompilerOptionSourcedirs: FunSpec({
|
|||||||
breakpointCpuInstruction = null,
|
breakpointCpuInstruction = null,
|
||||||
printAst1 = false,
|
printAst1 = false,
|
||||||
printAst2 = false,
|
printAst2 = false,
|
||||||
strictBool = true,
|
|
||||||
symbolDefs = emptyMap(),
|
symbolDefs = emptyMap(),
|
||||||
sourceDirs,
|
sourceDirs,
|
||||||
outputDir
|
outputDir
|
||||||
|
@ -43,7 +43,6 @@ internal fun compileFile(
|
|||||||
breakpointCpuInstruction = null,
|
breakpointCpuInstruction = null,
|
||||||
printAst1 = false,
|
printAst1 = false,
|
||||||
printAst2 = false,
|
printAst2 = false,
|
||||||
strictBool = true
|
|
||||||
)
|
)
|
||||||
return compileProgram(args)
|
return compileProgram(args)
|
||||||
}
|
}
|
||||||
|
@ -155,10 +155,6 @@ One or more .p8 module files
|
|||||||
Don't perform any code optimizations.
|
Don't perform any code optimizations.
|
||||||
Useful for debugging or faster compilation cycles.
|
Useful for debugging or faster compilation cycles.
|
||||||
|
|
||||||
``-nostrictbool``
|
|
||||||
Relax the strict boolean type checks: bytes and booleans can be interchanged again without explicit type casts.
|
|
||||||
*This option will likely disappear in a future prog8 version, so you may want to prepare for that in your code!*
|
|
||||||
|
|
||||||
``-optfloatx``
|
``-optfloatx``
|
||||||
Also optimize float expressions if optimizations are enabled.
|
Also optimize float expressions if optimizations are enabled.
|
||||||
Warning: can increase program size significantly if a lot of floating point expressions are used.
|
Warning: can increase program size significantly if a lot of floating point expressions are used.
|
||||||
|
@ -5,4 +5,4 @@ org.gradle.daemon=true
|
|||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
javaVersion=11
|
javaVersion=11
|
||||||
kotlinVersion=2.0.20
|
kotlinVersion=2.0.20
|
||||||
version=10.4
|
version=10.5-SNAPSHOT
|
||||||
|
Loading…
x
Reference in New Issue
Block a user