mirror of
https://github.com/irmen/prog8.git
synced 2025-01-12 04:30:03 +00:00
tweak error reporting, expanded lines and circles example
This commit is contained in:
parent
9409f17372
commit
4929c198ba
@ -565,14 +565,9 @@ asmsub clear_screenchars (ubyte char @ A) clobbers(Y) {
|
||||
%asm {{
|
||||
ldy #0
|
||||
_loop sta c64.Screen,y
|
||||
sta c64.Screen+1,y
|
||||
sta c64.Screen+$0100,y
|
||||
sta c64.Screen+$0101,y
|
||||
sta c64.Screen+$0200,y
|
||||
sta c64.Screen+$0201,y
|
||||
sta c64.Screen+$02e8,y
|
||||
sta c64.Screen+$02e9,y
|
||||
iny
|
||||
iny
|
||||
bne _loop
|
||||
rts
|
||||
@ -585,14 +580,9 @@ asmsub clear_screencolors (ubyte color @ A) clobbers(Y) {
|
||||
%asm {{
|
||||
ldy #0
|
||||
_loop sta c64.Colors,y
|
||||
sta c64.Colors+1,y
|
||||
sta c64.Colors+$0100,y
|
||||
sta c64.Colors+$0101,y
|
||||
sta c64.Colors+$0200,y
|
||||
sta c64.Colors+$0201,y
|
||||
sta c64.Colors+$02e8,y
|
||||
sta c64.Colors+$02e9,y
|
||||
iny
|
||||
iny
|
||||
bne _loop
|
||||
rts
|
||||
|
@ -156,32 +156,22 @@ internal class ConstantFoldingOptimizer(private val program: Program, private va
|
||||
if(forloop!=null && identifier===forloop.loopVar)
|
||||
return identifier
|
||||
|
||||
return try {
|
||||
val cval = identifier.constValue(program) ?: return identifier
|
||||
return when (cval.type) {
|
||||
in NumericDatatypes -> {
|
||||
val copy = NumericLiteralValue(cval.type, cval.number, identifier.position)
|
||||
copy.parent = identifier.parent
|
||||
copy
|
||||
}
|
||||
in PassByReferenceDatatypes -> throw FatalAstException("pass-by-reference type should not be considered a constant")
|
||||
else -> identifier
|
||||
val cval = identifier.constValue(program) ?: return identifier
|
||||
return when (cval.type) {
|
||||
in NumericDatatypes -> {
|
||||
val copy = NumericLiteralValue(cval.type, cval.number, identifier.position)
|
||||
copy.parent = identifier.parent
|
||||
copy
|
||||
}
|
||||
} catch (ax: AstException) {
|
||||
errors.err("unhandled AST error: $ax", identifier.position)
|
||||
identifier
|
||||
in PassByReferenceDatatypes -> throw FatalAstException("pass-by-reference type should not be considered a constant")
|
||||
else -> identifier
|
||||
}
|
||||
}
|
||||
|
||||
override fun visit(functionCall: FunctionCall): Expression {
|
||||
super.visit(functionCall)
|
||||
typeCastConstArguments(functionCall)
|
||||
return try {
|
||||
functionCall.constValue(program) ?: functionCall
|
||||
} catch (ax: AstException) {
|
||||
errors.err("unhandled AST error: $ax", functionCall.position)
|
||||
functionCall
|
||||
}
|
||||
return functionCall.constValue(program) ?: functionCall
|
||||
}
|
||||
|
||||
override fun visit(functionCallStatement: FunctionCallStatement): Statement {
|
||||
@ -237,46 +227,41 @@ internal class ConstantFoldingOptimizer(private val program: Program, private va
|
||||
* For instance, the expression for "- 4.5" will be optimized into the float literal -4.5
|
||||
*/
|
||||
override fun visit(expr: PrefixExpression): Expression {
|
||||
return try {
|
||||
val prefixExpr=super.visit(expr)
|
||||
if(prefixExpr !is PrefixExpression)
|
||||
return prefixExpr
|
||||
|
||||
val subexpr = prefixExpr.expression
|
||||
if (subexpr is NumericLiteralValue) {
|
||||
// accept prefixed literal values (such as -3, not true)
|
||||
return when (prefixExpr.operator) {
|
||||
"+" -> subexpr
|
||||
"-" -> when (subexpr.type) {
|
||||
in IntegerDatatypes -> {
|
||||
optimizationsDone++
|
||||
NumericLiteralValue.optimalNumeric(-subexpr.number.toInt(), subexpr.position)
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
optimizationsDone++
|
||||
NumericLiteralValue(DataType.FLOAT, -subexpr.number.toDouble(), subexpr.position)
|
||||
}
|
||||
else -> throw ExpressionError("can only take negative of int or float", subexpr.position)
|
||||
}
|
||||
"~" -> when (subexpr.type) {
|
||||
in IntegerDatatypes -> {
|
||||
optimizationsDone++
|
||||
NumericLiteralValue.optimalNumeric(subexpr.number.toInt().inv(), subexpr.position)
|
||||
}
|
||||
else -> throw ExpressionError("can only take bitwise inversion of int", subexpr.position)
|
||||
}
|
||||
"not" -> {
|
||||
optimizationsDone++
|
||||
NumericLiteralValue.fromBoolean(subexpr.number.toDouble() == 0.0, subexpr.position)
|
||||
}
|
||||
else -> throw ExpressionError(prefixExpr.operator, subexpr.position)
|
||||
}
|
||||
}
|
||||
val prefixExpr=super.visit(expr)
|
||||
if(prefixExpr !is PrefixExpression)
|
||||
return prefixExpr
|
||||
} catch (ax: AstException) {
|
||||
errors.err("unhandled AST error: $ax", expr.position)
|
||||
expr
|
||||
|
||||
val subexpr = prefixExpr.expression
|
||||
if (subexpr is NumericLiteralValue) {
|
||||
// accept prefixed literal values (such as -3, not true)
|
||||
return when (prefixExpr.operator) {
|
||||
"+" -> subexpr
|
||||
"-" -> when (subexpr.type) {
|
||||
in IntegerDatatypes -> {
|
||||
optimizationsDone++
|
||||
NumericLiteralValue.optimalNumeric(-subexpr.number.toInt(), subexpr.position)
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
optimizationsDone++
|
||||
NumericLiteralValue(DataType.FLOAT, -subexpr.number.toDouble(), subexpr.position)
|
||||
}
|
||||
else -> throw ExpressionError("can only take negative of int or float", subexpr.position)
|
||||
}
|
||||
"~" -> when (subexpr.type) {
|
||||
in IntegerDatatypes -> {
|
||||
optimizationsDone++
|
||||
NumericLiteralValue.optimalNumeric(subexpr.number.toInt().inv(), subexpr.position)
|
||||
}
|
||||
else -> throw ExpressionError("can only take bitwise inversion of int", subexpr.position)
|
||||
}
|
||||
"not" -> {
|
||||
optimizationsDone++
|
||||
NumericLiteralValue.fromBoolean(subexpr.number.toDouble() == 0.0, subexpr.position)
|
||||
}
|
||||
else -> throw ExpressionError(prefixExpr.operator, subexpr.position)
|
||||
}
|
||||
}
|
||||
return prefixExpr
|
||||
}
|
||||
|
||||
/**
|
||||
@ -297,45 +282,40 @@ internal class ConstantFoldingOptimizer(private val program: Program, private va
|
||||
* (X + c1) - c2 -> X + (c1-c2)
|
||||
*/
|
||||
override fun visit(expr: BinaryExpression): Expression {
|
||||
return try {
|
||||
super.visit(expr)
|
||||
super.visit(expr)
|
||||
|
||||
if(expr.left is StringLiteralValue || expr.left is ArrayLiteralValue
|
||||
|| expr.right is StringLiteralValue || expr.right is ArrayLiteralValue)
|
||||
throw FatalAstException("binexpr with reference litval instead of numeric")
|
||||
if(expr.left is StringLiteralValue || expr.left is ArrayLiteralValue
|
||||
|| expr.right is StringLiteralValue || expr.right is ArrayLiteralValue)
|
||||
throw FatalAstException("binexpr with reference litval instead of numeric")
|
||||
|
||||
val leftconst = expr.left.constValue(program)
|
||||
val rightconst = expr.right.constValue(program)
|
||||
val leftconst = expr.left.constValue(program)
|
||||
val rightconst = expr.right.constValue(program)
|
||||
|
||||
val subExpr: BinaryExpression? = when {
|
||||
leftconst!=null -> expr.right as? BinaryExpression
|
||||
rightconst!=null -> expr.left as? BinaryExpression
|
||||
else -> null
|
||||
val subExpr: BinaryExpression? = when {
|
||||
leftconst!=null -> expr.right as? BinaryExpression
|
||||
rightconst!=null -> expr.left as? BinaryExpression
|
||||
else -> null
|
||||
}
|
||||
if(subExpr!=null) {
|
||||
val subleftconst = subExpr.left.constValue(program)
|
||||
val subrightconst = subExpr.right.constValue(program)
|
||||
if ((subleftconst != null && subrightconst == null) || (subleftconst==null && subrightconst!=null)) {
|
||||
// try reordering.
|
||||
return groupTwoConstsTogether(expr, subExpr,
|
||||
leftconst != null, rightconst != null,
|
||||
subleftconst != null, subrightconst != null)
|
||||
}
|
||||
if(subExpr!=null) {
|
||||
val subleftconst = subExpr.left.constValue(program)
|
||||
val subrightconst = subExpr.right.constValue(program)
|
||||
if ((subleftconst != null && subrightconst == null) || (subleftconst==null && subrightconst!=null)) {
|
||||
// try reordering.
|
||||
return groupTwoConstsTogether(expr, subExpr,
|
||||
leftconst != null, rightconst != null,
|
||||
subleftconst != null, subrightconst != null)
|
||||
}
|
||||
}
|
||||
|
||||
// const fold when both operands are a const
|
||||
return when {
|
||||
leftconst != null && rightconst != null -> {
|
||||
optimizationsDone++
|
||||
val evaluator = ConstExprEvaluator()
|
||||
evaluator.evaluate(leftconst, expr.operator, rightconst)
|
||||
}
|
||||
|
||||
// const fold when both operands are a const
|
||||
return when {
|
||||
leftconst != null && rightconst != null -> {
|
||||
optimizationsDone++
|
||||
val evaluator = ConstExprEvaluator()
|
||||
evaluator.evaluate(leftconst, expr.operator, rightconst)
|
||||
}
|
||||
|
||||
else -> expr
|
||||
}
|
||||
} catch (ax: AstException) {
|
||||
errors.err("unhandled AST error: $ax", expr.position)
|
||||
expr
|
||||
else -> expr
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,20 @@ TODO
|
||||
|
||||
- remove statements after an exit() or return
|
||||
- fix warnings about that unreachable code?
|
||||
- why are some programs for example cube3d increasing in size when compiling with optimizations???
|
||||
|
||||
- create real assembly routines for the bresenham line and circle code
|
||||
- also add assembly routines in c64scr for drawing rectangles (filled/open)
|
||||
- add these routines for bitmap screen modes as well
|
||||
- add a turtle example once we have highres drawing routines
|
||||
|
||||
- aliases for imported symbols for example perhaps '%alias print = c64scr.print'
|
||||
- option to load library files from a directory instead of the embedded ones
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Memory Block Operations integrated in language?
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -8,23 +8,63 @@ main {
|
||||
sub start() {
|
||||
c64scr.print("mid-point\ncircle\n and\nbresenham\nline\nalgorithms.\n")
|
||||
|
||||
const ubyte xcenter = 20
|
||||
const ubyte ycenter = 12
|
||||
ubyte r
|
||||
for r in 3 to 12 step 3 {
|
||||
circle(r)
|
||||
circle(20, 12, r)
|
||||
}
|
||||
;line(5,3, 30,3)
|
||||
;line(5,3, 5, 24)
|
||||
;line(30,3,30,24)
|
||||
;line(5,24,30,24)
|
||||
|
||||
c64scr.print("enter for disc:")
|
||||
void c64.CHRIN()
|
||||
c64.CHROUT('\n')
|
||||
c64scr.clear_screen(' ', 1)
|
||||
disc(20, 12, 12)
|
||||
|
||||
c64scr.print("enter for lines:")
|
||||
void c64.CHRIN()
|
||||
c64.CHROUT('\n')
|
||||
c64scr.clear_screen(' ', 1)
|
||||
|
||||
line(1, 10, 38, 24)
|
||||
line(1, 20, 38, 2)
|
||||
line(20, 4, 10, 24)
|
||||
line(39, 16, 12, 0)
|
||||
|
||||
c64scr.print("enter for rectangles:")
|
||||
void c64.CHRIN()
|
||||
c64.CHROUT('\n')
|
||||
c64scr.clear_screen(' ', 1)
|
||||
|
||||
rect(4, 8, 37, 23, false)
|
||||
rect(20, 12, 30, 20, true)
|
||||
rect(10, 10, 10, 10, false)
|
||||
rect(6, 0, 16, 20, true)
|
||||
|
||||
|
||||
sub rect(ubyte x1, ubyte y1, ubyte x2, ubyte y2, ubyte fill) {
|
||||
ubyte x
|
||||
ubyte y
|
||||
if fill {
|
||||
for y in y1 to y2 {
|
||||
for x in x1 to x2 {
|
||||
c64scr.setcc(x, y, 42, x+y)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for x in x1 to x2 {
|
||||
c64scr.setcc(x, y1, 42, 8)
|
||||
c64scr.setcc(x, y2, 42, 8)
|
||||
}
|
||||
if y2>y1 {
|
||||
for y in y1+1 to y2-1 {
|
||||
c64scr.setcc(x1, y, 42, 7)
|
||||
c64scr.setcc(x2, y, 42, 7)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub line(ubyte x1, ubyte y1, ubyte x2, ubyte y2) {
|
||||
; Bresenham algorithm
|
||||
byte d = 0
|
||||
ubyte dx = abs(x2 - x1)
|
||||
ubyte dy = abs(y2 - y1)
|
||||
@ -62,20 +102,55 @@ main {
|
||||
}
|
||||
}
|
||||
|
||||
sub circle(ubyte radius) {
|
||||
sub circle(ubyte xcenter, ubyte ycenter, ubyte radius) {
|
||||
; Midpoint algorithm
|
||||
byte x = radius as byte
|
||||
byte y = 0
|
||||
byte decisionOver2 = 1-x
|
||||
|
||||
while x>=y {
|
||||
c64scr.setcc(xcenter + x as ubyte, ycenter + y as ubyte, 81, 1)
|
||||
c64scr.setcc(xcenter - x as ubyte, ycenter + y as ubyte, 81, 1)
|
||||
c64scr.setcc(xcenter + x as ubyte, ycenter - y as ubyte, 81, 1)
|
||||
c64scr.setcc(xcenter - x as ubyte, ycenter - y as ubyte, 81, 1)
|
||||
c64scr.setcc(xcenter + y as ubyte, ycenter + x as ubyte, 81, 1)
|
||||
c64scr.setcc(xcenter - y as ubyte, ycenter + x as ubyte, 81, 1)
|
||||
c64scr.setcc(xcenter + y as ubyte, ycenter - x as ubyte, 81, 1)
|
||||
c64scr.setcc(xcenter - y as ubyte, ycenter - x as ubyte, 81, 1)
|
||||
c64scr.setcc(xcenter - x as ubyte, ycenter + y as ubyte, 81, 2)
|
||||
c64scr.setcc(xcenter + x as ubyte, ycenter - y as ubyte, 81, 3)
|
||||
c64scr.setcc(xcenter - x as ubyte, ycenter - y as ubyte, 81, 4)
|
||||
c64scr.setcc(xcenter + y as ubyte, ycenter + x as ubyte, 81, 5)
|
||||
c64scr.setcc(xcenter - y as ubyte, ycenter + x as ubyte, 81, 6)
|
||||
c64scr.setcc(xcenter + y as ubyte, ycenter - x as ubyte, 81, 7)
|
||||
c64scr.setcc(xcenter - y as ubyte, ycenter - x as ubyte, 81, 8)
|
||||
y++
|
||||
if decisionOver2<=0
|
||||
decisionOver2 += 2*y+1
|
||||
else {
|
||||
x--
|
||||
decisionOver2 += 2*(y-x)+1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub disc(ubyte cx, ubyte cy, ubyte radius) {
|
||||
; Midpoint algorithm, filled
|
||||
byte x = radius as byte
|
||||
byte y = 0
|
||||
byte decisionOver2 = 1-x
|
||||
byte xx
|
||||
|
||||
while x>=y {
|
||||
for xx in cx to cx+x {
|
||||
c64scr.setcc(xx as ubyte, cy + y as ubyte, 81, 1)
|
||||
c64scr.setcc(xx as ubyte, cy - y as ubyte, 81, 2)
|
||||
}
|
||||
for xx in cx-x to cx-1 {
|
||||
c64scr.setcc(xx as ubyte, cy + y as ubyte, 81, 3)
|
||||
c64scr.setcc(xx as ubyte, cy - y as ubyte, 81, 4)
|
||||
}
|
||||
for xx in cx to cx+y {
|
||||
c64scr.setcc(xx as ubyte, cy + x as ubyte, 81, 5)
|
||||
c64scr.setcc(xx as ubyte, cy - x as ubyte, 81, 6)
|
||||
}
|
||||
for xx in cx-y to cx {
|
||||
c64scr.setcc(xx as ubyte, cy + x as ubyte, 81, 7)
|
||||
c64scr.setcc(xx as ubyte, cy - x as ubyte, 81, 8)
|
||||
}
|
||||
y++
|
||||
if decisionOver2<=0
|
||||
decisionOver2 += 2*y+1
|
||||
|
@ -6,8 +6,9 @@
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
str input="???????"
|
||||
c64scr.clear_screen('*',7)
|
||||
c64.CHRIN()
|
||||
c64scr.clear_screen('.',2)
|
||||
|
||||
ubyte guess = lsb(c64utils.str2uword(input))
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user