mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
can now declare for loop variable on the spot
This commit is contained in:
parent
1d37841575
commit
6edd5f9b30
@ -253,7 +253,7 @@ branch_stmt : branchcondition EOL? (statement | statement_block) EOL? else_part?
|
||||
branchcondition: 'if_cs' | 'if_cc' | 'if_eq' | 'if_z' | 'if_ne' | 'if_nz' | 'if_pl' | 'if_pos' | 'if_mi' | 'if_neg' | 'if_vs' | 'if_vc' ;
|
||||
|
||||
|
||||
forloop : 'for' (register | identifier) 'in' expression EOL? statement_block ;
|
||||
forloop : 'for' datatype? (register | identifier) 'in' expression EOL? statement_block ;
|
||||
|
||||
whileloop: 'while' expression EOL? (statement | statement_block) ;
|
||||
|
||||
|
@ -69,8 +69,7 @@
|
||||
float Azy = cosb*sinc
|
||||
float Azz = cosb*cosc
|
||||
|
||||
byte i
|
||||
for i in 0 to len(xcoor)-1 {
|
||||
for byte i in 0 to len(xcoor)-1 {
|
||||
rotatedx[i] = Axx*xcoor[i] + Axy*ycoor[i] + Axz*zcoor[i]
|
||||
rotatedy[i] = Ayx*xcoor[i] + Ayy*ycoor[i] + Ayz*zcoor[i]
|
||||
rotatedz[i] = Azx*xcoor[i] + Azy*ycoor[i] + Azz*zcoor[i]
|
||||
@ -89,8 +88,7 @@
|
||||
}
|
||||
|
||||
; draw all edges of the object
|
||||
word edge
|
||||
for edge in edges {
|
||||
for word edge in edges {
|
||||
byte e_from = msb(edge)
|
||||
byte e_to = lsb(edge)
|
||||
_vm_gfx_line(toscreenx(rotatedx[e_from], rotatedz[e_from]), toscreeny(rotatedy[e_from], rotatedz[e_from]),
|
||||
@ -98,8 +96,7 @@
|
||||
}
|
||||
|
||||
; accentuate the vertices a bit with small boxes
|
||||
byte i
|
||||
for i in 0 to len(xcoor)-1 {
|
||||
for byte i in 0 to len(xcoor)-1 {
|
||||
word sx = toscreenx(rotatedx[i], rotatedz[i])
|
||||
word sy = toscreeny(rotatedy[i], rotatedz[i])
|
||||
byte color=i+2
|
||||
|
@ -10,12 +10,10 @@
|
||||
_vm_gfx_clearscr(11)
|
||||
_vm_gfx_text(2, 1, 1, "Calculating Mandelbrot Fractal...")
|
||||
|
||||
byte pixely ; @todo allow defining loopvar INSIDE loop scope ("for byte pixely in ...")
|
||||
for pixely in yoffset to yoffset+height-1 {
|
||||
for byte pixely in yoffset to yoffset+height-1 {
|
||||
float yy = flt((pixely-yoffset))/height/3.6+0.4
|
||||
|
||||
word pixelx ; @todo allow defining loopvar INSIDE loop scope ("for word pixelx in ...")
|
||||
for pixelx in xoffset to xoffset+width-1 {
|
||||
for word pixelx in xoffset to xoffset+width-1 {
|
||||
float xx = flt((pixelx-xoffset))/width/3.0+0.2
|
||||
float xsquared
|
||||
float ysquared
|
||||
|
@ -11,8 +11,7 @@
|
||||
_vm_write_str(name)
|
||||
_vm_write_str(".\nI am thinking of a number from 1 to 100! You'll have to guess it!\n")
|
||||
|
||||
byte attempts_left
|
||||
for attempts_left in 10 to 1 step -1 {
|
||||
for byte attempts_left in 10 to 1 step -1 {
|
||||
_vm_write_str("\nYou have ")
|
||||
_vm_write_num(attempts_left)
|
||||
_vm_write_str(" guess")
|
||||
|
@ -5,44 +5,14 @@
|
||||
~ main {
|
||||
|
||||
sub start() {
|
||||
byte x
|
||||
|
||||
for x in 0 to 20 {
|
||||
float xx = sin(flt(x))
|
||||
float yy = cos(flt(x))
|
||||
; word [20] prime_numbers = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71] ; todo array_w!!!
|
||||
word [20] fibonacci_numbers = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
|
||||
|
||||
for word fibnr in fibonacci_numbers {
|
||||
_vm_write_num(fibnr)
|
||||
_vm_write_char('\n')
|
||||
}
|
||||
|
||||
while(1) {
|
||||
float xx = sin(flt(x))
|
||||
float yy = cos(flt(x))
|
||||
}
|
||||
|
||||
repeat {
|
||||
float xx = sin(flt(x))
|
||||
float yy = cos(flt(x))
|
||||
} until(1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; for x in 0 to 30 {
|
||||
; float xx = 2123.33
|
||||
; float yy = 2444.55
|
||||
; xx = sin(flt(x))
|
||||
; yy = cos(flt(x))
|
||||
; r = xx*yy
|
||||
; }
|
||||
;
|
||||
; for x in 0 to 40 {
|
||||
; float xx = 3123.33
|
||||
; float yy = 3444.55
|
||||
; xx = sin(flt(x))
|
||||
; yy = cos(flt(x))
|
||||
; r = xx*yy
|
||||
; }
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -367,12 +367,6 @@ interface INameScope {
|
||||
printNames(0, this)
|
||||
}
|
||||
|
||||
fun removeStatement(statement: IStatement) {
|
||||
// remove a statement (most likely because it is never referenced such as a subroutine)
|
||||
val removed = statements.remove(statement)
|
||||
if(!removed) throw AstException("node to remove wasn't found")
|
||||
}
|
||||
|
||||
fun isEmpty() = statements.isEmpty()
|
||||
}
|
||||
|
||||
@ -1371,6 +1365,7 @@ class BranchStatement(var condition: BranchCondition,
|
||||
|
||||
|
||||
class ForLoop(val loopRegister: Register?,
|
||||
val decltype: DataType?,
|
||||
val loopVar: IdentifierReference?,
|
||||
var iterable: IExpression,
|
||||
var body: AnonymousScope,
|
||||
@ -1379,7 +1374,7 @@ class ForLoop(val loopRegister: Register?,
|
||||
|
||||
override fun linkParents(parent: Node) {
|
||||
this.parent=parent
|
||||
loopVar?.linkParents(this)
|
||||
loopVar?.linkParents(if(decltype==null) this else body)
|
||||
iterable.linkParents(this)
|
||||
body.linkParents(this)
|
||||
}
|
||||
@ -1856,10 +1851,11 @@ private fun prog8Parser.BranchconditionContext.toAst() = BranchCondition.valueOf
|
||||
|
||||
private fun prog8Parser.ForloopContext.toAst(): ForLoop {
|
||||
val loopregister = register()?.toAst()
|
||||
val datatype = datatype()?.toAst()
|
||||
val loopvar = identifier()?.toAst()
|
||||
val iterable = expression()!!.toAst()
|
||||
val scope = AnonymousScope(statement_block().toAst(), statement_block().toPosition())
|
||||
return ForLoop(loopregister, loopvar, iterable, scope, toPosition())
|
||||
return ForLoop(loopregister, datatype, loopvar, iterable, scope, toPosition())
|
||||
}
|
||||
|
||||
|
||||
|
@ -115,4 +115,29 @@ class AstIdentifiersChecker : IAstProcessor {
|
||||
}
|
||||
return super.process(label)
|
||||
}
|
||||
|
||||
override fun process(forLoop: ForLoop): IStatement {
|
||||
// if the for loop as a decltype, it means to declare the loopvar inside the loop body
|
||||
// rather than reusing an already declared loopvar from an outer scope.
|
||||
if(forLoop.loopRegister!=null && forLoop.decltype!=null) {
|
||||
checkResult.add(SyntaxError("register loop variables cannot be explicitly declared with a datatype", forLoop.position))
|
||||
} else {
|
||||
val loopVar = forLoop.loopVar!!
|
||||
val varName = loopVar.nameInSource.last()
|
||||
when (forLoop.decltype) {
|
||||
DataType.BYTE, DataType.WORD -> {
|
||||
val existing = if(forLoop.body.isEmpty()) null else forLoop.body.lookup(loopVar.nameInSource, forLoop.body.statements.first())
|
||||
if(existing==null) {
|
||||
val vardecl = VarDecl(VarDeclType.VAR, forLoop.decltype, null, varName, null, loopVar.position)
|
||||
vardecl.linkParents(forLoop.body)
|
||||
forLoop.body.statements.add(0, vardecl)
|
||||
forLoop.loopVar.parent = forLoop.body // loopvar 'is defined in the body'
|
||||
}
|
||||
}
|
||||
null -> {}
|
||||
else -> checkResult.add(SyntaxError("loop variables can only be a byte or word", forLoop.position))
|
||||
}
|
||||
}
|
||||
return super.process(forLoop)
|
||||
}
|
||||
}
|
||||
|
@ -1198,6 +1198,7 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
}
|
||||
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
DataType.ARRAY, DataType.ARRAY_W, DataType.ARRAY_F, DataType.MATRIX -> throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt")
|
||||
null -> throw CompilerException("could not determine targetdt")
|
||||
// todo: maybe if you assign byte or word to array/matrix, clear it with that value?
|
||||
}
|
||||
}
|
||||
@ -1474,10 +1475,10 @@ private class StatementTranslator(private val stackvmProg: StackVmProgram,
|
||||
val assignTarget = if(loop.loopRegister!=null)
|
||||
AssignTarget(loop.loopRegister, null, null, loop.position)
|
||||
else
|
||||
AssignTarget(null, loop.loopVar, null, loop.position)
|
||||
AssignTarget(null, loop.loopVar!!.copy(), null, loop.position)
|
||||
val arrayspec = ArraySpec(RegisterExpr(Register.valueOf(indexVar), loop.position), null, loop.position)
|
||||
val assignLv = Assignment(assignTarget, null, ArrayIndexedExpression(loop.iterable as IdentifierReference, null, arrayspec, loop.position), loop.position)
|
||||
assignLv.linkParents(loop.parent)
|
||||
val assignLv = Assignment(assignTarget, null, ArrayIndexedExpression((loop.iterable as IdentifierReference).copy(), null, arrayspec, loop.position), loop.position)
|
||||
assignLv.linkParents(loop.body)
|
||||
translate(assignLv)
|
||||
translate(loop.body)
|
||||
stackvmProg.label(continueLabel)
|
||||
|
@ -1,12 +1,13 @@
|
||||
// Generated from /home/irmen/Projects/prog8/compiler/antlr/prog8.g4 by ANTLR 4.7
|
||||
package prog8.parser;
|
||||
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.ATN;
|
||||
import org.antlr.v4.runtime.atn.ATNDeserializer;
|
||||
import org.antlr.v4.runtime.atn.LexerATNSimulator;
|
||||
import org.antlr.v4.runtime.atn.PredictionContextCache;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class prog8Lexer extends Lexer {
|
||||
|
@ -1,15 +1,13 @@
|
||||
// Generated from /home/irmen/Projects/prog8/compiler/antlr/prog8.g4 by ANTLR 4.7
|
||||
package prog8.parser;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.ATN;
|
||||
import org.antlr.v4.runtime.atn.ATNDeserializer;
|
||||
import org.antlr.v4.runtime.atn.ParserATNSimulator;
|
||||
import org.antlr.v4.runtime.atn.PredictionContextCache;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class prog8Parser extends Parser {
|
||||
@ -3897,6 +3895,9 @@ public class prog8Parser extends Parser {
|
||||
public IdentifierContext identifier() {
|
||||
return getRuleContext(IdentifierContext.class,0);
|
||||
}
|
||||
public DatatypeContext datatype() {
|
||||
return getRuleContext(DatatypeContext.class,0);
|
||||
}
|
||||
public TerminalNode EOL() { return getToken(prog8Parser.EOL, 0); }
|
||||
public ForloopContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
@ -3913,7 +3914,17 @@ public class prog8Parser extends Parser {
|
||||
{
|
||||
setState(571);
|
||||
match(T__99);
|
||||
setState(574);
|
||||
setState(573);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__16) | (1L << T__17) | (1L << T__18) | (1L << T__19) | (1L << T__20) | (1L << T__21) | (1L << T__22))) != 0)) {
|
||||
{
|
||||
setState(572);
|
||||
datatype();
|
||||
}
|
||||
}
|
||||
|
||||
setState(577);
|
||||
_errHandler.sync(this);
|
||||
switch (_input.LA(1)) {
|
||||
case T__64:
|
||||
@ -3923,34 +3934,34 @@ public class prog8Parser extends Parser {
|
||||
case T__68:
|
||||
case T__69:
|
||||
{
|
||||
setState(572);
|
||||
setState(575);
|
||||
register();
|
||||
}
|
||||
break;
|
||||
case NAME:
|
||||
{
|
||||
setState(573);
|
||||
setState(576);
|
||||
identifier();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
setState(576);
|
||||
match(T__100);
|
||||
setState(577);
|
||||
expression(0);
|
||||
setState(579);
|
||||
match(T__100);
|
||||
setState(580);
|
||||
expression(0);
|
||||
setState(582);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if (_la==EOL) {
|
||||
{
|
||||
setState(578);
|
||||
setState(581);
|
||||
match(EOL);
|
||||
}
|
||||
}
|
||||
|
||||
setState(581);
|
||||
setState(584);
|
||||
statement_block();
|
||||
}
|
||||
}
|
||||
@ -3989,21 +4000,21 @@ public class prog8Parser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(583);
|
||||
match(T__101);
|
||||
setState(584);
|
||||
expression(0);
|
||||
setState(586);
|
||||
match(T__101);
|
||||
setState(587);
|
||||
expression(0);
|
||||
setState(589);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if (_la==EOL) {
|
||||
{
|
||||
setState(585);
|
||||
setState(588);
|
||||
match(EOL);
|
||||
}
|
||||
}
|
||||
|
||||
setState(590);
|
||||
setState(593);
|
||||
_errHandler.sync(this);
|
||||
switch (_input.LA(1)) {
|
||||
case T__2:
|
||||
@ -4055,13 +4066,13 @@ public class prog8Parser extends Parser {
|
||||
case T__102:
|
||||
case NAME:
|
||||
{
|
||||
setState(588);
|
||||
setState(591);
|
||||
statement();
|
||||
}
|
||||
break;
|
||||
case T__80:
|
||||
{
|
||||
setState(589);
|
||||
setState(592);
|
||||
statement_block();
|
||||
}
|
||||
break;
|
||||
@ -4105,9 +4116,9 @@ public class prog8Parser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(592);
|
||||
match(T__102);
|
||||
setState(595);
|
||||
match(T__102);
|
||||
setState(598);
|
||||
_errHandler.sync(this);
|
||||
switch (_input.LA(1)) {
|
||||
case T__2:
|
||||
@ -4159,32 +4170,32 @@ public class prog8Parser extends Parser {
|
||||
case T__102:
|
||||
case NAME:
|
||||
{
|
||||
setState(593);
|
||||
setState(596);
|
||||
statement();
|
||||
}
|
||||
break;
|
||||
case T__80:
|
||||
{
|
||||
setState(594);
|
||||
setState(597);
|
||||
statement_block();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
setState(598);
|
||||
setState(601);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
if (_la==EOL) {
|
||||
{
|
||||
setState(597);
|
||||
setState(600);
|
||||
match(EOL);
|
||||
}
|
||||
}
|
||||
|
||||
setState(600);
|
||||
setState(603);
|
||||
match(T__103);
|
||||
setState(601);
|
||||
setState(604);
|
||||
expression(0);
|
||||
}
|
||||
}
|
||||
@ -4237,7 +4248,7 @@ public class prog8Parser extends Parser {
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3v\u025e\4\2\t\2\4"+
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3v\u0261\4\2\t\2\4"+
|
||||
"\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+
|
||||
"\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
|
||||
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
|
||||
@ -4278,53 +4289,53 @@ public class prog8Parser extends Parser {
|
||||
"\n\65\3\66\3\66\3\66\5\66\u0216\n\66\3\66\3\66\5\66\u021a\n\66\3\66\5"+
|
||||
"\66\u021d\n\66\3\66\5\66\u0220\n\66\3\66\3\66\3\67\3\67\5\67\u0226\n\67"+
|
||||
"\3\67\3\67\5\67\u022a\n\67\38\38\58\u022e\n8\38\38\58\u0232\n8\38\58\u0235"+
|
||||
"\n8\38\58\u0238\n8\38\38\39\39\3:\3:\3:\5:\u0241\n:\3:\3:\3:\5:\u0246"+
|
||||
"\n:\3:\3:\3;\3;\3;\5;\u024d\n;\3;\3;\5;\u0251\n;\3<\3<\3<\5<\u0256\n<"+
|
||||
"\3<\5<\u0259\n<\3<\3<\3<\3<\2\3&=\2\4\6\b\n\f\16\20\22\24\26\30\32\34"+
|
||||
"\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`bdfhjlnprtv\2\20\3\2\6\16"+
|
||||
"\3\2\23\31\3\2\34$\3\2%&\4\2\3\3)*\3\2,/\3\2)*\3\2\60\63\3\2\64\65\3\2"+
|
||||
"CH\3\2IL\3\2pr\3\2NO\3\2Ze\2\u0294\2|\3\2\2\2\4\u0083\3\2\2\2\6\u0085"+
|
||||
"\3\2\2\2\b\u00a3\3\2\2\2\n\u00a5\3\2\2\2\f\u00a8\3\2\2\2\16\u00ae\3\2"+
|
||||
"\2\2\20\u00bf\3\2\2\2\22\u00c1\3\2\2\2\24\u00c7\3\2\2\2\26\u00cf\3\2\2"+
|
||||
"\2\30\u00d2\3\2\2\2\32\u00d5\3\2\2\2\34\u00d7\3\2\2\2\36\u00df\3\2\2\2"+
|
||||
" \u00e3\3\2\2\2\"\u00eb\3\2\2\2$\u00ed\3\2\2\2&\u00ff\3\2\2\2(\u0131\3"+
|
||||
"\2\2\2*\u0137\3\2\2\2,\u0141\3\2\2\2.\u0149\3\2\2\2\60\u0154\3\2\2\2\62"+
|
||||
"\u0158\3\2\2\2\64\u015a\3\2\2\2\66\u015c\3\2\2\28\u015e\3\2\2\2:\u0165"+
|
||||
"\3\2\2\2<\u0167\3\2\2\2>\u0169\3\2\2\2@\u016d\3\2\2\2B\u016f\3\2\2\2D"+
|
||||
"\u0171\3\2\2\2F\u0185\3\2\2\2H\u0187\3\2\2\2J\u0189\3\2\2\2L\u0191\3\2"+
|
||||
"\2\2N\u0193\3\2\2\2P\u0196\3\2\2\2R\u01a3\3\2\2\2T\u01a6\3\2\2\2V\u01b1"+
|
||||
"\3\2\2\2X\u01bc\3\2\2\2Z\u01c0\3\2\2\2\\\u01cb\3\2\2\2^\u01e3\3\2\2\2"+
|
||||
"`\u01e6\3\2\2\2b\u01f1\3\2\2\2d\u01f9\3\2\2\2f\u0201\3\2\2\2h\u020c\3"+
|
||||
"\2\2\2j\u0212\3\2\2\2l\u0223\3\2\2\2n\u022b\3\2\2\2p\u023b\3\2\2\2r\u023d"+
|
||||
"\3\2\2\2t\u0249\3\2\2\2v\u0252\3\2\2\2x{\5\4\3\2y{\7n\2\2zx\3\2\2\2zy"+
|
||||
"\3\2\2\2{~\3\2\2\2|z\3\2\2\2|}\3\2\2\2}\177\3\2\2\2~|\3\2\2\2\177\u0080"+
|
||||
"\7\2\2\3\u0080\3\3\2\2\2\u0081\u0084\5\16\b\2\u0082\u0084\5\6\4\2\u0083"+
|
||||
"\u0081\3\2\2\2\u0083\u0082\3\2\2\2\u0084\5\3\2\2\2\u0085\u0086\7\3\2\2"+
|
||||
"\u0086\u0088\5\66\34\2\u0087\u0089\5> \2\u0088\u0087\3\2\2\2\u0088\u0089"+
|
||||
"\3\2\2\2\u0089\u008a\3\2\2\2\u008a\u008b\5T+\2\u008b\u008c\7n\2\2\u008c"+
|
||||
"\7\3\2\2\2\u008d\u00a4\5\16\b\2\u008e\u00a4\5\24\13\2\u008f\u00a4\5\22"+
|
||||
"\n\2\u0090\u00a4\5\26\f\2\u0091\u00a4\5\30\r\2\u0092\u00a4\5\36\20\2\u0093"+
|
||||
"\u00a4\5 \21\2\u0094\u00a4\5\f\7\2\u0095\u00a4\5$\23\2\u0096\u00a4\5,"+
|
||||
"\27\2\u0097\u00a4\5j\66\2\u0098\u00a4\5n8\2\u0099\u00a4\5P)\2\u009a\u00a4"+
|
||||
"\5\\/\2\u009b\u00a4\5N(\2\u009c\u00a4\5\60\31\2\u009d\u00a4\5r:\2\u009e"+
|
||||
"\u00a4\5t;\2\u009f\u00a4\5v<\2\u00a0\u00a4\5\62\32\2\u00a1\u00a4\5\64"+
|
||||
"\33\2\u00a2\u00a4\5\n\6\2\u00a3\u008d\3\2\2\2\u00a3\u008e\3\2\2\2\u00a3"+
|
||||
"\u008f\3\2\2\2\u00a3\u0090\3\2\2\2\u00a3\u0091\3\2\2\2\u00a3\u0092\3\2"+
|
||||
"\2\2\u00a3\u0093\3\2\2\2\u00a3\u0094\3\2\2\2\u00a3\u0095\3\2\2\2\u00a3"+
|
||||
"\u0096\3\2\2\2\u00a3\u0097\3\2\2\2\u00a3\u0098\3\2\2\2\u00a3\u0099\3\2"+
|
||||
"\2\2\u00a3\u009a\3\2\2\2\u00a3\u009b\3\2\2\2\u00a3\u009c\3\2\2\2\u00a3"+
|
||||
"\u009d\3\2\2\2\u00a3\u009e\3\2\2\2\u00a3\u009f\3\2\2\2\u00a3\u00a0\3\2"+
|
||||
"\2\2\u00a3\u00a1\3\2\2\2\u00a3\u00a2\3\2\2\2\u00a4\t\3\2\2\2\u00a5\u00a6"+
|
||||
"\5\66\34\2\u00a6\u00a7\7\4\2\2\u00a7\13\3\2\2\2\u00a8\u00ac\7\5\2\2\u00a9"+
|
||||
"\u00ad\5> \2\u00aa\u00ad\5\66\34\2\u00ab\u00ad\58\35\2\u00ac\u00a9\3\2"+
|
||||
"\2\2\u00ac\u00aa\3\2\2\2\u00ac\u00ab\3\2\2\2\u00ad\r\3\2\2\2\u00ae\u00ba"+
|
||||
"\t\2\2\2\u00af\u00b1\5\20\t\2\u00b0\u00af\3\2\2\2\u00b0\u00b1\3\2\2\2"+
|
||||
"\u00b1\u00bb\3\2\2\2\u00b2\u00b7\5\20\t\2\u00b3\u00b4\7\17\2\2\u00b4\u00b6"+
|
||||
"\5\20\t\2\u00b5\u00b3\3\2\2\2\u00b6\u00b9\3\2\2\2\u00b7\u00b5\3\2\2\2"+
|
||||
"\u00b7\u00b8\3\2\2\2\u00b8\u00bb\3\2\2\2\u00b9\u00b7\3\2\2\2\u00ba\u00b0"+
|
||||
"\3\2\2\2\u00ba\u00b2\3\2\2\2\u00bb\17\3\2\2\2\u00bc\u00c0\5F$\2\u00bd"+
|
||||
"\u00c0\5\66\34\2\u00be\u00c0\5> \2\u00bf\u00bc\3\2\2\2\u00bf\u00bd\3\2"+
|
||||
"\2\2\u00bf\u00be\3\2\2\2\u00c0\21\3\2\2\2\u00c1\u00c3\5\32\16\2\u00c2"+
|
||||
"\n8\38\58\u0238\n8\38\38\39\39\3:\3:\5:\u0240\n:\3:\3:\5:\u0244\n:\3:"+
|
||||
"\3:\3:\5:\u0249\n:\3:\3:\3;\3;\3;\5;\u0250\n;\3;\3;\5;\u0254\n;\3<\3<"+
|
||||
"\3<\5<\u0259\n<\3<\5<\u025c\n<\3<\3<\3<\3<\2\3&=\2\4\6\b\n\f\16\20\22"+
|
||||
"\24\26\30\32\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`bdfhjlnp"+
|
||||
"rtv\2\20\3\2\6\16\3\2\23\31\3\2\34$\3\2%&\4\2\3\3)*\3\2,/\3\2)*\3\2\60"+
|
||||
"\63\3\2\64\65\3\2CH\3\2IL\3\2pr\3\2NO\3\2Ze\2\u0298\2|\3\2\2\2\4\u0083"+
|
||||
"\3\2\2\2\6\u0085\3\2\2\2\b\u00a3\3\2\2\2\n\u00a5\3\2\2\2\f\u00a8\3\2\2"+
|
||||
"\2\16\u00ae\3\2\2\2\20\u00bf\3\2\2\2\22\u00c1\3\2\2\2\24\u00c7\3\2\2\2"+
|
||||
"\26\u00cf\3\2\2\2\30\u00d2\3\2\2\2\32\u00d5\3\2\2\2\34\u00d7\3\2\2\2\36"+
|
||||
"\u00df\3\2\2\2 \u00e3\3\2\2\2\"\u00eb\3\2\2\2$\u00ed\3\2\2\2&\u00ff\3"+
|
||||
"\2\2\2(\u0131\3\2\2\2*\u0137\3\2\2\2,\u0141\3\2\2\2.\u0149\3\2\2\2\60"+
|
||||
"\u0154\3\2\2\2\62\u0158\3\2\2\2\64\u015a\3\2\2\2\66\u015c\3\2\2\28\u015e"+
|
||||
"\3\2\2\2:\u0165\3\2\2\2<\u0167\3\2\2\2>\u0169\3\2\2\2@\u016d\3\2\2\2B"+
|
||||
"\u016f\3\2\2\2D\u0171\3\2\2\2F\u0185\3\2\2\2H\u0187\3\2\2\2J\u0189\3\2"+
|
||||
"\2\2L\u0191\3\2\2\2N\u0193\3\2\2\2P\u0196\3\2\2\2R\u01a3\3\2\2\2T\u01a6"+
|
||||
"\3\2\2\2V\u01b1\3\2\2\2X\u01bc\3\2\2\2Z\u01c0\3\2\2\2\\\u01cb\3\2\2\2"+
|
||||
"^\u01e3\3\2\2\2`\u01e6\3\2\2\2b\u01f1\3\2\2\2d\u01f9\3\2\2\2f\u0201\3"+
|
||||
"\2\2\2h\u020c\3\2\2\2j\u0212\3\2\2\2l\u0223\3\2\2\2n\u022b\3\2\2\2p\u023b"+
|
||||
"\3\2\2\2r\u023d\3\2\2\2t\u024c\3\2\2\2v\u0255\3\2\2\2x{\5\4\3\2y{\7n\2"+
|
||||
"\2zx\3\2\2\2zy\3\2\2\2{~\3\2\2\2|z\3\2\2\2|}\3\2\2\2}\177\3\2\2\2~|\3"+
|
||||
"\2\2\2\177\u0080\7\2\2\3\u0080\3\3\2\2\2\u0081\u0084\5\16\b\2\u0082\u0084"+
|
||||
"\5\6\4\2\u0083\u0081\3\2\2\2\u0083\u0082\3\2\2\2\u0084\5\3\2\2\2\u0085"+
|
||||
"\u0086\7\3\2\2\u0086\u0088\5\66\34\2\u0087\u0089\5> \2\u0088\u0087\3\2"+
|
||||
"\2\2\u0088\u0089\3\2\2\2\u0089\u008a\3\2\2\2\u008a\u008b\5T+\2\u008b\u008c"+
|
||||
"\7n\2\2\u008c\7\3\2\2\2\u008d\u00a4\5\16\b\2\u008e\u00a4\5\24\13\2\u008f"+
|
||||
"\u00a4\5\22\n\2\u0090\u00a4\5\26\f\2\u0091\u00a4\5\30\r\2\u0092\u00a4"+
|
||||
"\5\36\20\2\u0093\u00a4\5 \21\2\u0094\u00a4\5\f\7\2\u0095\u00a4\5$\23\2"+
|
||||
"\u0096\u00a4\5,\27\2\u0097\u00a4\5j\66\2\u0098\u00a4\5n8\2\u0099\u00a4"+
|
||||
"\5P)\2\u009a\u00a4\5\\/\2\u009b\u00a4\5N(\2\u009c\u00a4\5\60\31\2\u009d"+
|
||||
"\u00a4\5r:\2\u009e\u00a4\5t;\2\u009f\u00a4\5v<\2\u00a0\u00a4\5\62\32\2"+
|
||||
"\u00a1\u00a4\5\64\33\2\u00a2\u00a4\5\n\6\2\u00a3\u008d\3\2\2\2\u00a3\u008e"+
|
||||
"\3\2\2\2\u00a3\u008f\3\2\2\2\u00a3\u0090\3\2\2\2\u00a3\u0091\3\2\2\2\u00a3"+
|
||||
"\u0092\3\2\2\2\u00a3\u0093\3\2\2\2\u00a3\u0094\3\2\2\2\u00a3\u0095\3\2"+
|
||||
"\2\2\u00a3\u0096\3\2\2\2\u00a3\u0097\3\2\2\2\u00a3\u0098\3\2\2\2\u00a3"+
|
||||
"\u0099\3\2\2\2\u00a3\u009a\3\2\2\2\u00a3\u009b\3\2\2\2\u00a3\u009c\3\2"+
|
||||
"\2\2\u00a3\u009d\3\2\2\2\u00a3\u009e\3\2\2\2\u00a3\u009f\3\2\2\2\u00a3"+
|
||||
"\u00a0\3\2\2\2\u00a3\u00a1\3\2\2\2\u00a3\u00a2\3\2\2\2\u00a4\t\3\2\2\2"+
|
||||
"\u00a5\u00a6\5\66\34\2\u00a6\u00a7\7\4\2\2\u00a7\13\3\2\2\2\u00a8\u00ac"+
|
||||
"\7\5\2\2\u00a9\u00ad\5> \2\u00aa\u00ad\5\66\34\2\u00ab\u00ad\58\35\2\u00ac"+
|
||||
"\u00a9\3\2\2\2\u00ac\u00aa\3\2\2\2\u00ac\u00ab\3\2\2\2\u00ad\r\3\2\2\2"+
|
||||
"\u00ae\u00ba\t\2\2\2\u00af\u00b1\5\20\t\2\u00b0\u00af\3\2\2\2\u00b0\u00b1"+
|
||||
"\3\2\2\2\u00b1\u00bb\3\2\2\2\u00b2\u00b7\5\20\t\2\u00b3\u00b4\7\17\2\2"+
|
||||
"\u00b4\u00b6\5\20\t\2\u00b5\u00b3\3\2\2\2\u00b6\u00b9\3\2\2\2\u00b7\u00b5"+
|
||||
"\3\2\2\2\u00b7\u00b8\3\2\2\2\u00b8\u00bb\3\2\2\2\u00b9\u00b7\3\2\2\2\u00ba"+
|
||||
"\u00b0\3\2\2\2\u00ba\u00b2\3\2\2\2\u00bb\17\3\2\2\2\u00bc\u00c0\5F$\2"+
|
||||
"\u00bd\u00c0\5\66\34\2\u00be\u00c0\5> \2\u00bf\u00bc\3\2\2\2\u00bf\u00bd"+
|
||||
"\3\2\2\2\u00bf\u00be\3\2\2\2\u00c0\21\3\2\2\2\u00c1\u00c3\5\32\16\2\u00c2"+
|
||||
"\u00c4\5\34\17\2\u00c3\u00c2\3\2\2\2\u00c3\u00c4\3\2\2\2\u00c4\u00c5\3"+
|
||||
"\2\2\2\u00c5\u00c6\5\66\34\2\u00c6\23\3\2\2\2\u00c7\u00c9\5\32\16\2\u00c8"+
|
||||
"\u00ca\5\34\17\2\u00c9\u00c8\3\2\2\2\u00c9\u00ca\3\2\2\2\u00ca\u00cb\3"+
|
||||
@ -4450,22 +4461,23 @@ public class prog8Parser extends Parser {
|
||||
"\u0233\3\2\2\2\u0234\u0235\3\2\2\2\u0235\u0237\3\2\2\2\u0236\u0238\5l"+
|
||||
"\67\2\u0237\u0236\3\2\2\2\u0237\u0238\3\2\2\2\u0238\u0239\3\2\2\2\u0239"+
|
||||
"\u023a\7n\2\2\u023ao\3\2\2\2\u023b\u023c\t\17\2\2\u023cq\3\2\2\2\u023d"+
|
||||
"\u0240\7f\2\2\u023e\u0241\5:\36\2\u023f\u0241\5\66\34\2\u0240\u023e\3"+
|
||||
"\2\2\2\u0240\u023f\3\2\2\2\u0241\u0242\3\2\2\2\u0242\u0243\7g\2\2\u0243"+
|
||||
"\u0245\5&\24\2\u0244\u0246\7n\2\2\u0245\u0244\3\2\2\2\u0245\u0246\3\2"+
|
||||
"\2\2\u0246\u0247\3\2\2\2\u0247\u0248\5T+\2\u0248s\3\2\2\2\u0249\u024a"+
|
||||
"\7h\2\2\u024a\u024c\5&\24\2\u024b\u024d\7n\2\2\u024c\u024b\3\2\2\2\u024c"+
|
||||
"\u024d\3\2\2\2\u024d\u0250\3\2\2\2\u024e\u0251\5\b\5\2\u024f\u0251\5T"+
|
||||
"+\2\u0250\u024e\3\2\2\2\u0250\u024f\3\2\2\2\u0251u\3\2\2\2\u0252\u0255"+
|
||||
"\7i\2\2\u0253\u0256\5\b\5\2\u0254\u0256\5T+\2\u0255\u0253\3\2\2\2\u0255"+
|
||||
"\u0254\3\2\2\2\u0256\u0258\3\2\2\2\u0257\u0259\7n\2\2\u0258\u0257\3\2"+
|
||||
"\2\2\u0258\u0259\3\2\2\2\u0259\u025a\3\2\2\2\u025a\u025b\7j\2\2\u025b"+
|
||||
"\u025c\5&\24\2\u025cw\3\2\2\2Fz|\u0083\u0088\u00a3\u00ac\u00b0\u00b7\u00ba"+
|
||||
"\u023f\7f\2\2\u023e\u0240\5\32\16\2\u023f\u023e\3\2\2\2\u023f\u0240\3"+
|
||||
"\2\2\2\u0240\u0243\3\2\2\2\u0241\u0244\5:\36\2\u0242\u0244\5\66\34\2\u0243"+
|
||||
"\u0241\3\2\2\2\u0243\u0242\3\2\2\2\u0244\u0245\3\2\2\2\u0245\u0246\7g"+
|
||||
"\2\2\u0246\u0248\5&\24\2\u0247\u0249\7n\2\2\u0248\u0247\3\2\2\2\u0248"+
|
||||
"\u0249\3\2\2\2\u0249\u024a\3\2\2\2\u024a\u024b\5T+\2\u024bs\3\2\2\2\u024c"+
|
||||
"\u024d\7h\2\2\u024d\u024f\5&\24\2\u024e\u0250\7n\2\2\u024f\u024e\3\2\2"+
|
||||
"\2\u024f\u0250\3\2\2\2\u0250\u0253\3\2\2\2\u0251\u0254\5\b\5\2\u0252\u0254"+
|
||||
"\5T+\2\u0253\u0251\3\2\2\2\u0253\u0252\3\2\2\2\u0254u\3\2\2\2\u0255\u0258"+
|
||||
"\7i\2\2\u0256\u0259\5\b\5\2\u0257\u0259\5T+\2\u0258\u0256\3\2\2\2\u0258"+
|
||||
"\u0257\3\2\2\2\u0259\u025b\3\2\2\2\u025a\u025c\7n\2\2\u025b\u025a\3\2"+
|
||||
"\2\2\u025b\u025c\3\2\2\2\u025c\u025d\3\2\2\2\u025d\u025e\7j\2\2\u025e"+
|
||||
"\u025f\5&\24\2\u025fw\3\2\2\2Gz|\u0083\u0088\u00a3\u00ac\u00b0\u00b7\u00ba"+
|
||||
"\u00bf\u00c3\u00c9\u00db\u00eb\u00ff\u0127\u0129\u012b\u0131\u0137\u013b"+
|
||||
"\u0141\u0145\u014c\u0151\u0156\u0163\u016b\u0173\u0178\u017d\u0181\u0191"+
|
||||
"\u019a\u019e\u01aa\u01ac\u01b4\u01b9\u01c3\u01c8\u01cf\u01d6\u01dc\u01e1"+
|
||||
"\u01e9\u01ee\u01f7\u01fe\u0204\u0209\u0210\u0215\u0219\u021c\u021f\u0225"+
|
||||
"\u0229\u022d\u0231\u0234\u0237\u0240\u0245\u024c\u0250\u0255\u0258";
|
||||
"\u0229\u022d\u0231\u0234\u0237\u023f\u0243\u0248\u024f\u0253\u0258\u025b";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
@ -328,8 +328,9 @@ Loops
|
||||
-----
|
||||
|
||||
The *for*-loop is used to let a variable (or register) iterate over a range of values. Iteration is done in steps of 1, but you can change this.
|
||||
The loop variable must be declared as byte or word earlier. Floating point iteration is not supported,
|
||||
if you want to loop over a floating-point array, use a loop with an integer index variable instead.
|
||||
The loop variable can be declared as byte or word earlier so you can reuse it for multiple occasions,
|
||||
or you can declare one directly in the for statement which will only be visible in the for loop body.
|
||||
Iterating with a floating point variable is not supported. If you want to loop over a floating-point array, use a loop with an integer index variable instead.
|
||||
|
||||
The *while*-loop is used to repeat a piece of code while a certain condition is still true.
|
||||
The *repeat--until* loop is used to repeat a piece of code until a certain condition is true.
|
||||
|
@ -450,18 +450,34 @@ Loops
|
||||
for loop
|
||||
^^^^^^^^
|
||||
|
||||
The loop variable must be a register or a byte/word variable defined in the local scope.
|
||||
The loop variable must be a register or a byte/word variable. It must be defined in the local scope (to reuse
|
||||
an existing variable), or you can declare it in the for loop directly to make a new one that is only visible
|
||||
in the body of the for loop.
|
||||
The expression that you loop over can be anything that supports iteration (such as ranges like ``0 to 100``,
|
||||
array variables and strings) *except* floating-point arrays (because a floating-point loop variable is not supported).
|
||||
|
||||
You can use a single statement, or a statement block like in the example below::
|
||||
|
||||
for <loopvar> in <expression> [ step <amount> ] {
|
||||
for [byte | word] <loopvar> in <expression> [ step <amount> ] {
|
||||
; do something...
|
||||
break ; break out of the loop
|
||||
continue ; immediately enter next iteration
|
||||
}
|
||||
|
||||
For example, this is a for loop using the existing byte variable ``i`` to loop over a certain range of numbers::
|
||||
|
||||
for i in 20 to 155 {
|
||||
; do something
|
||||
}
|
||||
|
||||
And this is a loop over the values of the array ``fibonacci_numbers`` where the loop variable is declared in the loop itself::
|
||||
|
||||
word[20] fibonacci_numbers = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]
|
||||
|
||||
for word fibnr in fibonacci_numbers {
|
||||
; do something
|
||||
}
|
||||
|
||||
|
||||
while loop
|
||||
^^^^^^^^^^
|
||||
|
@ -3,112 +3,6 @@ TODO
|
||||
====
|
||||
|
||||
|
||||
IF_XX::
|
||||
|
||||
if[_XX] [<expression>] {
|
||||
...
|
||||
}
|
||||
[ else {
|
||||
... ; evaluated when the condition is not met
|
||||
} ]
|
||||
|
||||
|
||||
==> DESUGARING ==>
|
||||
|
||||
(no else:)::
|
||||
|
||||
if[_!XX] [<expression>] goto prog8_if_999_end ; !XX being the conditional inverse of XX
|
||||
.... (true part)
|
||||
prog8_if_999_end ; code continues after this
|
||||
|
||||
|
||||
(with else)::
|
||||
|
||||
if[_XX] [<expression>] goto prog8_if_999
|
||||
... (else part)
|
||||
goto prog8_if_999_end
|
||||
prog8_if_999 ... (true part)
|
||||
prog8_if_999_end ; code continues after this
|
||||
|
||||
|
||||
IF X <COMPARISON> Y
|
||||
|
||||
==> DESUGARING ==>::
|
||||
|
||||
compare X, Y
|
||||
if_XX goto ....
|
||||
XX based on <COMPARISON>.
|
||||
|
||||
|
||||
While::
|
||||
|
||||
while[_XX] <expression> {
|
||||
...
|
||||
continue
|
||||
break
|
||||
}
|
||||
|
||||
==> DESUGARING ==>::
|
||||
|
||||
goto prog8_while_999_check ; jump to the check
|
||||
prog8_while_999
|
||||
... (code)
|
||||
goto prog8_while_999 ;continue
|
||||
goto prog8_while_999_end ;break
|
||||
prog8_while_999_check
|
||||
if[_XX] <expression> goto prog8_while_999 ; loop condition
|
||||
prog8_while_999_end ; code continues after this
|
||||
|
||||
|
||||
Repeat::
|
||||
|
||||
repeat {
|
||||
...
|
||||
continue
|
||||
break
|
||||
} until[_XX] <expressoin>
|
||||
|
||||
==> DESUGARING ==>::
|
||||
|
||||
prog8_repeat_999
|
||||
... (code)
|
||||
goto prog8_repeat_999 ;continue
|
||||
goto prog8_repeat_999_end ;break
|
||||
if[_!XX] <expression> goto prog8_repeat_999 ; loop condition via conditional inverse of XX
|
||||
prog8_repeat_999_end ; code continues after this
|
||||
|
||||
|
||||
For::
|
||||
|
||||
for <loopvar> = <from_expression> to <to_expression> [step <step_expression>] {
|
||||
...
|
||||
break
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@todo how to do signed integer loopvars?
|
||||
|
||||
|
||||
==> DESUGARING ==>::
|
||||
|
||||
loopvar = <from_expression>
|
||||
compare loopvar, <to_expression>
|
||||
if_ge goto prog8_for_999_end ; loop condition
|
||||
step = <step_expression> ; (store only if step < -1 or step > 1)
|
||||
prog8_for_999
|
||||
goto prog8_for_999_end ;break
|
||||
goto prog8_for_999_loop ;continue
|
||||
.... (code)
|
||||
prog8_for_999_loop
|
||||
loopvar += step ; (if step > 1 or step < -1)
|
||||
loopvar++ ; (if step == 1)
|
||||
loopvar-- ; (if step == -1)
|
||||
goto prog8_for_999 ; continue the loop
|
||||
prog8_for_999_end ; code continues after this
|
||||
|
||||
|
||||
|
||||
### Macros
|
||||
|
||||
@todo macros are meta-code that is executed by the compiler, in a preprecessing step
|
||||
|
Loading…
Reference in New Issue
Block a user