mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
removed '**' power-operator. Use floats.pow() instead.
This commit is contained in:
parent
12712ef812
commit
ed30108961
@ -70,7 +70,6 @@ class AsmGen(internal val program: Program,
|
||||
}
|
||||
|
||||
internal fun isTargetCpu(cpu: CpuType) = options.compTarget.machine.cpu == cpu
|
||||
internal fun haveFPWRcall() = options.compTarget.name=="cx16"
|
||||
|
||||
private var generatedLabelSequenceNumber: Int = 0
|
||||
|
||||
|
@ -735,7 +735,6 @@ internal class ExpressionsAsmGen(private val program: Program,
|
||||
|
||||
private fun translateBinaryOperatorBytes(operator: String, types: DataType) {
|
||||
when(operator) {
|
||||
"**" -> throw AssemblyError("** operator requires floats")
|
||||
"*" -> asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||
"/" -> asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
||||
"%" -> {
|
||||
@ -777,7 +776,6 @@ internal class ExpressionsAsmGen(private val program: Program,
|
||||
|
||||
private fun translateBinaryOperatorWords(operator: String, dt: DataType) {
|
||||
when(operator) {
|
||||
"**" -> throw AssemblyError("** operator requires floats")
|
||||
"*" -> asmgen.out(" jsr prog8_lib.mul_word")
|
||||
"/" -> asmgen.out(if(dt==DataType.UWORD) " jsr prog8_lib.idiv_uw" else " jsr prog8_lib.idiv_w")
|
||||
"%" -> {
|
||||
@ -812,7 +810,6 @@ internal class ExpressionsAsmGen(private val program: Program,
|
||||
|
||||
private fun translateBinaryOperatorFloats(operator: String) {
|
||||
when(operator) {
|
||||
"**" -> asmgen.out(" jsr floats.pow_f")
|
||||
"*" -> asmgen.out(" jsr floats.mul_f")
|
||||
"/" -> asmgen.out(" jsr floats.div_f")
|
||||
"+" -> asmgen.out(" jsr floats.add_f")
|
||||
|
@ -1590,14 +1590,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.FAC1)
|
||||
asmgen.saveRegisterLocal(CpuRegister.X, scope)
|
||||
when (operator) {
|
||||
"**" -> {
|
||||
asmgen.out("""
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr floats.CONUPK
|
||||
jsr floats.FPWRT
|
||||
""")
|
||||
}
|
||||
"+" -> {
|
||||
asmgen.out("""
|
||||
lda #<$name
|
||||
@ -1644,28 +1636,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
val otherName = asmgen.asmVariableName(ident)
|
||||
asmgen.saveRegisterLocal(CpuRegister.X, scope)
|
||||
when (operator) {
|
||||
"**" -> {
|
||||
if(asmgen.haveFPWRcall()) {
|
||||
asmgen.out("""
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr floats.CONUPK
|
||||
lda #<$otherName
|
||||
ldy #>$otherName
|
||||
jsr floats.FPWR
|
||||
""")
|
||||
} else
|
||||
// cx16 doesn't have FPWR() only FPWRT()
|
||||
asmgen.out("""
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr floats.CONUPK
|
||||
lda #<$otherName
|
||||
ldy #>$otherName
|
||||
jsr floats.MOVFM
|
||||
jsr floats.FPWRT
|
||||
""")
|
||||
}
|
||||
"+" -> {
|
||||
asmgen.out("""
|
||||
lda #<$name
|
||||
@ -1721,28 +1691,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
||||
val constValueName = allocator.getFloatAsmConst(value)
|
||||
asmgen.saveRegisterLocal(CpuRegister.X, scope)
|
||||
when (operator) {
|
||||
"**" -> {
|
||||
if(asmgen.haveFPWRcall()) {
|
||||
asmgen.out("""
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr floats.CONUPK
|
||||
lda #<$constValueName
|
||||
ldy #>$constValueName
|
||||
jsr floats.FPWR
|
||||
""")
|
||||
} else
|
||||
// cx16 doesn't have FPWR() only FPWRT()
|
||||
asmgen.out("""
|
||||
lda #<$name
|
||||
ldy #>$name
|
||||
jsr floats.CONUPK
|
||||
lda #<$constValueName
|
||||
ldy #>$constValueName
|
||||
jsr floats.MOVFM
|
||||
jsr floats.FPWRT
|
||||
""")
|
||||
}
|
||||
"+" -> {
|
||||
if (value == 0.0)
|
||||
return
|
||||
|
@ -231,7 +231,6 @@ internal class ExpressionGen(val codeGen: CodeGen) {
|
||||
">>" -> {
|
||||
code += VmCodeInstruction(Instruction(Opcode.LSR, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg))
|
||||
}
|
||||
"**" -> throw AssemblyError("** operator requires floating point ${binExpr.position}")
|
||||
// TODO the other operators: "==", "!=", "<", ">", "<=", ">="
|
||||
else -> TODO("operator ${binExpr.operator}")
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import prog8.ast.expressions.NumericLiteral
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.IntegerDatatypes
|
||||
import prog8.code.core.Position
|
||||
import kotlin.math.pow
|
||||
|
||||
|
||||
class ConstExprEvaluator {
|
||||
@ -20,7 +19,6 @@ class ConstExprEvaluator {
|
||||
"*" -> multiply(left, right)
|
||||
"/" -> divide(left, right)
|
||||
"%" -> remainder(left, right)
|
||||
"**" -> power(left, right)
|
||||
"&" -> bitwiseand(left, right)
|
||||
"|" -> bitwiseor(left, right)
|
||||
"^" -> bitwisexor(left, right)
|
||||
@ -150,23 +148,6 @@ class ConstExprEvaluator {
|
||||
throw ExpressionError("cannot calculate $left & $right", left.position)
|
||||
}
|
||||
|
||||
private fun power(left: NumericLiteral, right: NumericLiteral): NumericLiteral {
|
||||
val error = "cannot calculate $left ** $right"
|
||||
return when (left.type) {
|
||||
in IntegerDatatypes -> when (right.type) {
|
||||
in IntegerDatatypes -> NumericLiteral.optimalNumeric(left.number.toInt().toDouble().pow(right.number.toInt()), left.position)
|
||||
DataType.FLOAT -> NumericLiteral(DataType.FLOAT, left.number.toInt().toDouble().pow(right.number), left.position)
|
||||
else -> throw ExpressionError(error, left.position)
|
||||
}
|
||||
DataType.FLOAT -> when (right.type) {
|
||||
in IntegerDatatypes -> NumericLiteral(DataType.FLOAT, left.number.pow(right.number.toInt()), left.position)
|
||||
DataType.FLOAT -> NumericLiteral(DataType.FLOAT, left.number.pow(right.number), left.position)
|
||||
else -> throw ExpressionError(error, left.position)
|
||||
}
|
||||
else -> throw ExpressionError(error, left.position)
|
||||
}
|
||||
}
|
||||
|
||||
private fun plus(left: NumericLiteral, right: NumericLiteral): NumericLiteral {
|
||||
val error = "cannot add $left and $right"
|
||||
return when (left.type) {
|
||||
|
@ -6,7 +6,6 @@ import prog8.ast.base.ExpressionError
|
||||
import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.base.UndefinedSymbolError
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.Assignment
|
||||
import prog8.ast.statements.ForLoop
|
||||
import prog8.ast.statements.VarDecl
|
||||
import prog8.ast.statements.VarDeclType
|
||||
@ -14,7 +13,6 @@ import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.IntegerDatatypes
|
||||
import kotlin.math.pow
|
||||
|
||||
|
||||
class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
||||
@ -140,42 +138,6 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
||||
}
|
||||
}
|
||||
|
||||
if(expr.operator == "**" && leftconst!=null) {
|
||||
// optimize various simple cases of ** :
|
||||
// optimize away 1 ** x into just 1 and 0 ** x into just 0
|
||||
// optimize 2 ** x into (1<<x) if both operands are integer.
|
||||
val leftDt = leftconst.inferType(program).getOr(DataType.UNDEFINED)
|
||||
when (leftconst.number) {
|
||||
0.0 -> {
|
||||
val value = NumericLiteral(leftDt, 0.0, expr.position)
|
||||
modifications += IAstModification.ReplaceNode(expr, value, parent)
|
||||
}
|
||||
1.0 -> {
|
||||
val value = NumericLiteral(leftDt, 1.0, expr.position)
|
||||
modifications += IAstModification.ReplaceNode(expr, value, parent)
|
||||
}
|
||||
2.0 -> {
|
||||
if(rightconst!=null) {
|
||||
val value = NumericLiteral(leftDt, 2.0.pow(rightconst.number), expr.position)
|
||||
modifications += IAstModification.ReplaceNode(expr, value, parent)
|
||||
} else {
|
||||
val rightDt = expr.right.inferType(program).getOr(DataType.UNDEFINED)
|
||||
if(leftDt in IntegerDatatypes && rightDt in IntegerDatatypes) {
|
||||
val targetDt =
|
||||
when (parent) {
|
||||
is Assignment -> parent.target.inferType(program).getOr(DataType.UNDEFINED)
|
||||
is VarDecl -> parent.datatype
|
||||
else -> leftDt
|
||||
}
|
||||
val one = NumericLiteral(targetDt, 1.0, expr.position)
|
||||
val shift = BinaryExpression(one, "<<", expr.right, expr.position)
|
||||
modifications += IAstModification.ReplaceNode(expr, shift, parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(expr.inferType(program) istype DataType.FLOAT) {
|
||||
val subExpr: BinaryExpression? = when {
|
||||
leftconst != null -> expr.right as? BinaryExpression
|
||||
|
@ -256,7 +256,6 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
|
||||
"/" -> optimizeDivision(expr, leftVal, rightVal)
|
||||
"+" -> optimizeAdd(expr, leftVal, rightVal)
|
||||
"-" -> optimizeSub(expr, leftVal, rightVal)
|
||||
"**" -> optimizePower(expr, leftVal, rightVal)
|
||||
"%" -> optimizeRemainder(expr, leftVal, rightVal)
|
||||
">>" -> optimizeShiftRight(expr, rightVal)
|
||||
"<<" -> optimizeShiftLeft(expr, rightVal)
|
||||
@ -435,75 +434,6 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
|
||||
return null
|
||||
}
|
||||
|
||||
private fun optimizePower(expr: BinaryExpression, leftVal: NumericLiteral?, rightVal: NumericLiteral?): Expression? {
|
||||
if (leftVal == null && rightVal == null)
|
||||
return null
|
||||
|
||||
if (rightVal != null) {
|
||||
// right value is a constant, see if we can optimize
|
||||
val rightConst: NumericLiteral = rightVal
|
||||
when (rightConst.number) {
|
||||
-3.0 -> {
|
||||
// -1/(left*left*left)
|
||||
return BinaryExpression(NumericLiteral(DataType.FLOAT, -1.0, expr.position), "/",
|
||||
BinaryExpression(expr.left, "*", BinaryExpression(expr.left, "*", expr.left, expr.position), expr.position),
|
||||
expr.position)
|
||||
}
|
||||
-2.0 -> {
|
||||
// -1/(left*left)
|
||||
return BinaryExpression(NumericLiteral(DataType.FLOAT, -1.0, expr.position), "/",
|
||||
BinaryExpression(expr.left, "*", expr.left, expr.position),
|
||||
expr.position)
|
||||
}
|
||||
-1.0 -> {
|
||||
// -1/left
|
||||
return BinaryExpression(NumericLiteral(DataType.FLOAT, -1.0, expr.position), "/",
|
||||
expr.left, expr.position)
|
||||
}
|
||||
0.0 -> {
|
||||
// 1
|
||||
return NumericLiteral(rightConst.type, 1.0, expr.position)
|
||||
}
|
||||
0.5 -> {
|
||||
// sqrt(left)
|
||||
return FunctionCallExpression(IdentifierReference(listOf("sqrt"), expr.position), mutableListOf(expr.left), expr.position)
|
||||
}
|
||||
1.0 -> {
|
||||
// left
|
||||
return expr.left
|
||||
}
|
||||
2.0 -> {
|
||||
// left*left
|
||||
return BinaryExpression(expr.left, "*", expr.left, expr.position)
|
||||
}
|
||||
3.0 -> {
|
||||
// left*left*left
|
||||
return BinaryExpression(expr.left, "*", BinaryExpression(expr.left, "*", expr.left, expr.position), expr.position)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (leftVal != null) {
|
||||
// left value is a constant, see if we can optimize
|
||||
when (leftVal.number) {
|
||||
-1.0 -> {
|
||||
// -1
|
||||
return NumericLiteral(DataType.FLOAT, -1.0, expr.position)
|
||||
}
|
||||
0.0 -> {
|
||||
// 0
|
||||
return NumericLiteral(leftVal.type, 0.0, expr.position)
|
||||
}
|
||||
1.0 -> {
|
||||
//1
|
||||
return NumericLiteral(leftVal.type, 1.0, expr.position)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun optimizeRemainder(expr: BinaryExpression, leftVal: NumericLiteral?, rightVal: NumericLiteral?): Expression? {
|
||||
if (leftVal == null && rightVal == null)
|
||||
return null
|
||||
|
@ -425,7 +425,6 @@ class StatementOptimizer(private val program: Program,
|
||||
}
|
||||
"*" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
"/" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
"**" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
"|" -> if (rightCv == 0.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
"^" -> if (rightCv == 0.0) return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
"<<" -> {
|
||||
|
@ -328,25 +328,6 @@ _internal ldx #<fmath_float1
|
||||
jmp push_float
|
||||
.pend
|
||||
|
||||
|
||||
pow_f .proc
|
||||
; -- push f1 ** f2 on stack
|
||||
lda #<fmath_float2
|
||||
ldy #>fmath_float2
|
||||
jsr pop_float
|
||||
lda #<fmath_float1
|
||||
ldy #>fmath_float1
|
||||
jsr pop_float
|
||||
stx P8ZP_SCRATCH_REG
|
||||
lda #<fmath_float1
|
||||
ldy #>fmath_float1
|
||||
jsr ROMUPK ; fac2 = float1
|
||||
lda #<fmath_float2
|
||||
ldy #>fmath_float2
|
||||
jsr FPWR
|
||||
jmp push_fac1._internal
|
||||
.pend
|
||||
|
||||
div_f .proc
|
||||
; -- push f1/f2 on stack
|
||||
jsr pop_2_floats_f2_in_fac1
|
||||
|
@ -151,6 +151,23 @@ sub print_f (float value) {
|
||||
}}
|
||||
}
|
||||
|
||||
sub pow(float value, float power) -> float {
|
||||
%asm {{
|
||||
phx
|
||||
phy
|
||||
lda #<value
|
||||
ldy #>value
|
||||
jsr floats.CONUPK
|
||||
lda #<power
|
||||
ldy #>power
|
||||
jsr floats.FPWR
|
||||
ply
|
||||
plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
%asminclude "library:c128/floats.asm"
|
||||
%asminclude "library:c64/floats_funcs.asm"
|
||||
|
||||
|
@ -335,25 +335,6 @@ _internal ldx #<fmath_float1
|
||||
jmp push_float
|
||||
.pend
|
||||
|
||||
|
||||
pow_f .proc
|
||||
; -- push f1 ** f2 on stack
|
||||
lda #<fmath_float2
|
||||
ldy #>fmath_float2
|
||||
jsr pop_float
|
||||
lda #<fmath_float1
|
||||
ldy #>fmath_float1
|
||||
jsr pop_float
|
||||
stx P8ZP_SCRATCH_REG
|
||||
lda #<fmath_float1
|
||||
ldy #>fmath_float1
|
||||
jsr CONUPK ; fac2 = float1
|
||||
lda #<fmath_float2
|
||||
ldy #>fmath_float2
|
||||
jsr FPWR
|
||||
jmp push_fac1._internal
|
||||
.pend
|
||||
|
||||
div_f .proc
|
||||
; -- push f1/f2 on stack
|
||||
jsr pop_2_floats_f2_in_fac1
|
||||
|
@ -195,6 +195,22 @@ sub print_f (float value) {
|
||||
}}
|
||||
}
|
||||
|
||||
sub pow(float value, float power) -> float {
|
||||
%asm {{
|
||||
phx
|
||||
phy
|
||||
lda #<value
|
||||
ldy #>value
|
||||
jsr floats.CONUPK
|
||||
lda #<power
|
||||
ldy #>power
|
||||
jsr floats.FPWR
|
||||
ply
|
||||
plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
%asminclude "library:c64/floats.asm"
|
||||
%asminclude "library:c64/floats_funcs.asm"
|
||||
|
||||
|
@ -156,6 +156,23 @@ sub print_f (float value) {
|
||||
}}
|
||||
}
|
||||
|
||||
sub pow(float value, float power) -> float {
|
||||
%asm {{
|
||||
phx
|
||||
phy
|
||||
lda #<value
|
||||
ldy #>value
|
||||
jsr floats.CONUPK
|
||||
lda #<power
|
||||
ldy #>power
|
||||
jsr floats.MOVFM
|
||||
jsr floats.FPWRT ; cx16 doesn't have FPWR
|
||||
ply
|
||||
plx
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
%asminclude "library:c64/floats.asm"
|
||||
%asminclude "library:c64/floats_funcs.asm"
|
||||
|
||||
|
@ -83,8 +83,8 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
||||
importedFiles = imported
|
||||
processAst(program, args.errors, compilationOptions)
|
||||
if (compilationOptions.optimize) {
|
||||
// println("*********** AST RIGHT BEFORE OPTIMIZING *************")
|
||||
// printProgram(program)
|
||||
println("*********** AST RIGHT BEFORE OPTIMIZING *************")
|
||||
printProgram(program)
|
||||
|
||||
optimizeAst(
|
||||
program,
|
||||
|
@ -853,10 +853,6 @@ internal class AstChecker(private val program: Program,
|
||||
errors.err("remainder can only be used on unsigned integer operands", expr.right.position)
|
||||
}
|
||||
}
|
||||
"**" -> {
|
||||
if(leftDt in IntegerDatatypes)
|
||||
errors.err("power operator requires floating point operands", expr.position)
|
||||
}
|
||||
"and", "or", "xor" -> {
|
||||
// only integer numeric operands accepted, and if literal constants, only boolean values accepted (0 or 1)
|
||||
if(leftDt !in IntegerDatatypes || rightDt !in IntegerDatatypes)
|
||||
|
@ -15,7 +15,7 @@ import kotlin.math.round
|
||||
|
||||
val AssociativeOperators = setOf("+", "*", "&", "|", "^", "or", "and", "xor", "==", "!=")
|
||||
val ComparisonOperators = setOf("==", "!=", "<", ">", "<=", ">=")
|
||||
val AugmentAssignmentOperators = setOf("+", "-", "/", "*", "**", "&", "|", "^", "<<", ">>", "%", "and", "or", "xor")
|
||||
val AugmentAssignmentOperators = setOf("+", "-", "/", "*", "&", "|", "^", "<<", ">>", "%", "and", "or", "xor")
|
||||
val LogicalOperators = setOf("and", "or", "xor", "not")
|
||||
val BitwiseOperators = setOf("&", "|", "^")
|
||||
|
||||
@ -198,7 +198,7 @@ class BinaryExpression(var left: Expression, var operator: String, var right: Ex
|
||||
val leftDt = left.inferType(program)
|
||||
val rightDt = right.inferType(program)
|
||||
return when (operator) {
|
||||
"+", "-", "*", "**", "%", "/" -> {
|
||||
"+", "-", "*", "%", "/" -> {
|
||||
if (!leftDt.isKnown || !rightDt.isKnown)
|
||||
InferredTypes.unknown()
|
||||
else {
|
||||
|
@ -456,10 +456,9 @@ There are several escape sequences available to put special characters into your
|
||||
Operators
|
||||
---------
|
||||
|
||||
arithmetic: ``+`` ``-`` ``*`` ``/`` ``**`` ``%``
|
||||
arithmetic: ``+`` ``-`` ``*`` ``/`` ``%``
|
||||
``+``, ``-``, ``*``, ``/`` are the familiar arithmetic operations.
|
||||
``/`` is division (will result in integer division when using on integer operands, and a floating point division when at least one of the operands is a float)
|
||||
``**`` is the power operator: ``3 ** 5`` is equal to 3*3*3*3*3 and is 243. (it only works on floating point variables)
|
||||
``%`` is the remainder operator: ``25 % 7`` is 4. Be careful: without a space, %10 will be parsed as the binary number 2.
|
||||
Remainder is only supported on integer operands (not floats).
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
%import floats
|
||||
%import textio
|
||||
|
||||
; NOTE: meant to test to virtual machine output target (use -target vitual)
|
||||
@ -6,39 +7,34 @@ main {
|
||||
sub start() {
|
||||
txt.clear_screen()
|
||||
txt.print("Welcome to a prog8 pixel shader :-)\n")
|
||||
ubyte bb = 10
|
||||
uword ww = 123
|
||||
bb <<= 4
|
||||
ww <<= 5
|
||||
txt.print("bb=")
|
||||
txt.print_ub(bb)
|
||||
txt.nl()
|
||||
txt.print("ww=")
|
||||
txt.print_uw(ww)
|
||||
float fl = 9.9
|
||||
fl = floats.pow(fl, 3.0)
|
||||
txt.print("fl=")
|
||||
floats.print_f(fl)
|
||||
txt.nl()
|
||||
sys.exit(99)
|
||||
|
||||
|
||||
syscall1(8, 0) ; enable lo res creen
|
||||
ubyte shifter
|
||||
|
||||
shifter >>= 1
|
||||
|
||||
repeat {
|
||||
uword xx
|
||||
uword yy = 0
|
||||
repeat 240 {
|
||||
xx = 0
|
||||
repeat 320 {
|
||||
syscall3(10, xx, yy, xx*yy + shifter) ; plot pixel
|
||||
xx++
|
||||
}
|
||||
yy++
|
||||
}
|
||||
shifter+=4
|
||||
|
||||
txt.print_ub(shifter)
|
||||
txt.nl()
|
||||
}
|
||||
; syscall1(8, 0) ; enable lo res creen
|
||||
; ubyte shifter
|
||||
;
|
||||
; shifter >>= 1
|
||||
;
|
||||
; repeat {
|
||||
; uword xx
|
||||
; uword yy = 0
|
||||
; repeat 240 {
|
||||
; xx = 0
|
||||
; repeat 320 {
|
||||
; syscall3(10, xx, yy, xx*yy + shifter) ; plot pixel
|
||||
; xx++
|
||||
; }
|
||||
; yy++
|
||||
; }
|
||||
; shifter+=4
|
||||
;
|
||||
; txt.print_ub(shifter)
|
||||
; txt.nl()
|
||||
; }
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ arrayindex: '[' expression ']' ;
|
||||
assignment : assign_target '=' expression ;
|
||||
|
||||
augassignment :
|
||||
assign_target operator=('+=' | '-=' | '/=' | '*=' | '**=' | '&=' | '|=' | '^=' | '%=' | '<<=' | '>>=' ) expression
|
||||
assign_target operator=('+=' | '-=' | '/=' | '*=' | '&=' | '|=' | '^=' | '%=' | '<<=' | '>>=' ) expression
|
||||
;
|
||||
|
||||
assign_target:
|
||||
@ -162,7 +162,6 @@ expression :
|
||||
'(' expression ')'
|
||||
| functioncall
|
||||
| <assoc=right> prefix = ('+'|'-'|'~') expression
|
||||
| left = expression EOL? bop = '**' EOL? right = expression
|
||||
| left = expression EOL? bop = ('*' | '/' | '%' ) EOL? right = expression
|
||||
| left = expression EOL? bop = ('+' | '-' ) EOL? right = expression
|
||||
| left = expression EOL? bop = ('<<' | '>>' ) EOL? right = expression
|
||||
|
Loading…
Reference in New Issue
Block a user