mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-01-11 13:30:15 +00:00
Release 0.94.12: Finally created new "!for" syntax so counting can start at zero. Added "0b" as alternative prefix for binary values.
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@33 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
8b2c8187a2
commit
c8ff626943
@ -115,12 +115,12 @@ conversion table file, try using ACME:
|
|||||||
!to "asc2pet.ct", plain ; no load address
|
!to "asc2pet.ct", plain ; no load address
|
||||||
* = 0 ; pc = table index
|
* = 0 ; pc = table index
|
||||||
; first create "as-is" table
|
; first create "as-is" table
|
||||||
!for i, 256 {!byte i - 1}
|
!for i, 0, 255 {!byte i}
|
||||||
; now exchange upper and lower case characters
|
; now exchange upper and lower case characters
|
||||||
* = 65
|
* = 65, overlay
|
||||||
!for i, 91 - 65 {!byte * + 128}
|
!for i, 1, 26 {!byte * + 128}
|
||||||
* = 97
|
* = 97, overlay
|
||||||
!for i, 123 - 97 {!byte * - 32}
|
!for i, 1, 26 {!byte * - 32}
|
||||||
The resulting file can be used as a conversion table to convert to
|
The resulting file can be used as a conversion table to convert to
|
||||||
PetSCII (which is useless, because ACME can do so anyway. But you get
|
PetSCII (which is useless, because ACME can do so anyway. But you get
|
||||||
the idea).
|
the idea).
|
||||||
@ -358,42 +358,68 @@ Examples: ; this was taken from <6502/std.a>:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Call: !for LABEL, TIMES { BLOCK }
|
Call: !for LABEL, START, END { BLOCK }
|
||||||
Purpose: Looping assembly. The block of statements will be
|
Purpose: Looping assembly. The block of statements will be
|
||||||
parsed TIMES times. For a more flexible possibility,
|
parsed a fixed number of times, as specified by the
|
||||||
have a look at "!do" below.
|
values of START and END. For a more flexible
|
||||||
Parameters: LABEL: Any valid label name. The label's value will
|
possibility, have a look at "!do" below.
|
||||||
show the number of the current loop cycle:
|
Parameters: LABEL: Any valid label name.
|
||||||
In the first cycle it will have the value 1, in the
|
START: Any formula the value parser accepts, but it
|
||||||
last cycle it will have the value TIMES.
|
must be solvable even in the first pass. LABEL will
|
||||||
TIMES: Any formula the value parser accepts, but it
|
have this value during the first loop cycle.
|
||||||
must be solvable even in the first pass. Negative
|
END: Any formula the value parser accepts, but it must
|
||||||
values are forbidden, zero causes the block to be
|
be solvable even in the first pass. LABEL will have
|
||||||
skipped.
|
this value during the last loop cycle.
|
||||||
BLOCK: A block of assembler statements.
|
BLOCK: A block of assembler statements.
|
||||||
|
If START or END are floats, they will be converted to
|
||||||
|
integers (never use floats for loop counters). If
|
||||||
|
START is less than or equal to END, LABEL will get
|
||||||
|
incremented at the end of each cycle; if START is
|
||||||
|
greater than END, LABEL will get decremented at the
|
||||||
|
end of each cycle. So after leaving the loop, LABEL
|
||||||
|
will have an "illegal" value (END + 1 if counting up,
|
||||||
|
END - 1 if counting down).
|
||||||
Please note that it is impossible to change the number
|
Please note that it is impossible to change the number
|
||||||
of loop cycles "inside" the loop by fiddling with the
|
of loop cycles "inside" the loop by fiddling with the
|
||||||
counter (using the "!set" pseudo opcode): The "!for"
|
counter using the "!set" pseudo opcode: The "!for"
|
||||||
routine keeps its own copy of the counter value and
|
routine keeps its own copy of the counter value and
|
||||||
only sets the label value, it never reads it back.
|
only sets the label value, it never reads it back.
|
||||||
This was done to eliminate a possibility to hang ACME.
|
This was done to eliminate a possibility to hang ACME.
|
||||||
Examples: ; conversion table: integer to BCD
|
Examples:
|
||||||
int2BCD !for Outer, 10 {
|
int2BCD ; conversion table: integer to BCD
|
||||||
!for Inner, 10 {
|
!for Outer, 0, 9 {
|
||||||
!byte ((Outer - 1) << 4) OR (Inner - 1)
|
!for Inner, 0, 9 {
|
||||||
|
!byte (Outer << 4) OR Inner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
!fill 156, $ff ; values above 99 give 255 (invalid)
|
!fill 156, $ff ; values above 99 give 255 (invalid)
|
||||||
|
|
||||||
; conversion table: BCD to integer
|
BCD2int ; conversion table: BCD to integer
|
||||||
BCD2int !for Outer, 10 {
|
!for Outer, 0, 9 {
|
||||||
!for Inner, 10 {
|
!for Inner, 0, 9 {
|
||||||
!byte 10 * (Outer - 1) + (Inner - 1)
|
!byte 10 * Outer + Inner
|
||||||
}
|
}
|
||||||
!fill 6, $ff ; invalid BCD values give 255
|
!fill 6, $ff ; invalid BCD values give 255
|
||||||
}
|
}
|
||||||
!fill 96, $ff ; invalid BCD values give 255
|
!fill 96, $ff ; invalid BCD values give 255
|
||||||
|
|
||||||
|
quickclear ; generate speedcode to clear C64 screen
|
||||||
|
lda #' '
|
||||||
|
!for i, 0, 999 {
|
||||||
|
sta $0400 + i
|
||||||
|
}
|
||||||
|
|
||||||
|
Miscellaneous: The old syntax ("!for LABEL, END { BLOCK }" where
|
||||||
|
START was always implied to be 1) is still fully
|
||||||
|
supported, but gives a warning to get people to change
|
||||||
|
to the new syntax. When migrating your sources, bear
|
||||||
|
in mind that it is no longer possible to skip the
|
||||||
|
block completely by specifying a loop count of zero.
|
||||||
|
Also note that with the new algorithm, LABEL has a
|
||||||
|
different value after the block than during the last
|
||||||
|
loop cycle, while the old algorithm kept that last
|
||||||
|
value.
|
||||||
|
|
||||||
|
|
||||||
Call: !set LABEL = VALUE
|
Call: !set LABEL = VALUE
|
||||||
Purpose: Assign given value to label even if the label already
|
Purpose: Assign given value to label even if the label already
|
||||||
|
@ -12,6 +12,16 @@ platform used. There should be another help file in this archive
|
|||||||
outlining the platform specific changes.
|
outlining the platform specific changes.
|
||||||
|
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Section: New in release 0.94.12
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Finally created new "!for" syntax so counting can start at zero. The
|
||||||
|
old syntax still works, but gives a warning. See AllPOs.txt for
|
||||||
|
more info.
|
||||||
|
Added "0b" as alternative prefix for binary values.
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
Section: New in release 0.94.11
|
Section: New in release 0.94.11
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
@ -52,9 +52,13 @@ Bug in ACME, code follows
|
|||||||
A situation has been encountered implying there is a bug in ACME.
|
A situation has been encountered implying there is a bug in ACME.
|
||||||
See the last section in this file.
|
See the last section in this file.
|
||||||
|
|
||||||
C-style "==" comparison detected
|
C-style "==" comparison detected.
|
||||||
To check for equality, use a single '=' character instead.
|
To check for equality, use a single '=' character instead.
|
||||||
|
|
||||||
|
Found deprecated "!for" syntax.
|
||||||
|
Please update your sources to use the new "!for" syntax. See
|
||||||
|
AllPOs.txt for details.
|
||||||
|
|
||||||
Implicit label definition not in leftmost column.
|
Implicit label definition not in leftmost column.
|
||||||
An implicit label definition has blanks before the label name.
|
An implicit label definition has blanks before the label name.
|
||||||
Imagine this source code:
|
Imagine this source code:
|
||||||
@ -294,7 +298,8 @@ Found end-of-file instead of '}'.
|
|||||||
(because there was at least one block left open).
|
(because there was at least one block left open).
|
||||||
|
|
||||||
Loop count is negative.
|
Loop count is negative.
|
||||||
You used the "!for" command with a negative loop count.
|
You used the "!for" command with a negative loop count (getting
|
||||||
|
this error is only possible when using the now deprecated syntax).
|
||||||
|
|
||||||
Macro already defined.
|
Macro already defined.
|
||||||
Macros can only be defined once. If you define a macro twice, ACME
|
Macros can only be defined once. If you define a macro twice, ACME
|
||||||
|
@ -318,15 +318,16 @@ Examples Notes
|
|||||||
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
||||||
128 a decimal value, integer
|
128 a decimal value, integer
|
||||||
128.5 a decimal value, floating point
|
128.5 a decimal value, floating point
|
||||||
$d011 hexadecimal values are indicated by either
|
$d011 hexadecimal values are indicated by either a
|
||||||
0xffd2 leading "$" or leading "0x"
|
0xffd2 leading "$" or a leading "0x".
|
||||||
&1701 an octal value, indicated by "&"
|
&1701 an octal value, indicated by "&"
|
||||||
%010010 binary values are indicated by "%". In binary values,
|
%010010 binary values are indicated by either a leading "%"
|
||||||
%....#... you can substitute the characters "0" and "1" by
|
%....#... or a leading "0b". In binary values, you can
|
||||||
"." and "#" respectively. This way the values are
|
0b01100110 substitute the characters "0" and "1" by "." and
|
||||||
much more readable, especially when building
|
"#" respectively. This way the values are much
|
||||||
bitmapped objects (like C64 sprites or fonts) in
|
more readable, especially when building bitmapped
|
||||||
your source code.
|
objects (like C64 sprites or fonts) in your source
|
||||||
|
code.
|
||||||
"p" character values are indicated by double or single
|
"p" character values are indicated by double or single
|
||||||
'q' quotes. The actual numeric value depends on the
|
'q' quotes. The actual numeric value depends on the
|
||||||
current conversion table (none/petscii/screen),
|
current conversion table (none/petscii/screen),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
;ACME 0.93
|
;ACME 0.94.12
|
||||||
!to "trigono.o", plain
|
!to "trigono.o", plain
|
||||||
* = $c000
|
* = $c000
|
||||||
|
|
||||||
@ -7,10 +7,9 @@
|
|||||||
!raw "cos[0,pi/2] scaled to 0-255 range"
|
!raw "cos[0,pi/2] scaled to 0-255 range"
|
||||||
!align $f, 0, 0 ; make output file look better in hex editor :)
|
!align $f, 0, 0 ; make output file look better in hex editor :)
|
||||||
|
|
||||||
!for x, 256 {
|
!for x, 0, 255 {
|
||||||
!byte cos(float(x - 1) / 255 * PI/2) * 255 + 0.5
|
!byte cos(float(x) / 255 * PI/2) * 255 + 0.5
|
||||||
}
|
}
|
||||||
; "x-1" converts interval [1,256] to interval [0,255]
|
|
||||||
; "float()" makes sure this calculation is done in float mode now
|
; "float()" makes sure this calculation is done in float mode now
|
||||||
; "/255*half_PI" converts interval [0,255] to interval [0,PI/2]
|
; "/255*half_PI" converts interval [0,255] to interval [0,PI/2]
|
||||||
; "cos()" returns cosine. Wow.
|
; "cos()" returns cosine. Wow.
|
||||||
@ -21,8 +20,8 @@
|
|||||||
!raw "sin[-pi/2,pi/2] scaled to full range of 16b.16b fixed point"
|
!raw "sin[-pi/2,pi/2] scaled to full range of 16b.16b fixed point"
|
||||||
!align $f, 0, 0
|
!align $f, 0, 0
|
||||||
|
|
||||||
!for x, 1024 {
|
!for x, 0, 1023 {
|
||||||
!32 sin(float(x - 513) / 1024 * PI) * 65536 + 0.5
|
!32 sin(float(x - 512) / 1024 * PI) * 65536 + 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
;undefined = 0.0 / 0.0 ; throws error when active
|
;undefined = 0.0 / 0.0 ; throws error when active
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
// along with this program; if not, write to the Free Software
|
// along with this program; if not, write to the Free Software
|
||||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
#define RELEASE "0.94.11" // update before release (FIXME)
|
#define RELEASE "0.94.12" // update before release (FIXME)
|
||||||
#define CODENAME "Zarquon" // update before release
|
#define CODENAME "Zarquon" // update before release
|
||||||
#define CHANGE_DATE "28 May" // update before release
|
#define CHANGE_DATE "31 May" // update before release
|
||||||
#define CHANGE_YEAR "2014" // update before release
|
#define CHANGE_YEAR "2014" // update before release
|
||||||
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME
|
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME
|
||||||
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
|
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
|
||||||
|
97
src/alu.c
97
src/alu.c
@ -10,6 +10,7 @@
|
|||||||
// so a^b^c now means a^(b^c).
|
// so a^b^c now means a^(b^c).
|
||||||
// 7 May 2014 C-style "==" operators are now recognized (but
|
// 7 May 2014 C-style "==" operators are now recognized (but
|
||||||
// give a warning).
|
// give a warning).
|
||||||
|
// 31 May 2014 Added "0b" binary number prefix as alternative to "%".
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h> // only for fp support
|
#include <math.h> // only for fp support
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
@ -357,6 +358,46 @@ static void parse_quoted_character(char closing_quote)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parse binary value. Apart from '0' and '1', it also accepts the characters
|
||||||
|
// '.' and '#', this is much more readable. The current value is stored as soon
|
||||||
|
// as a character is read that is none of those given above.
|
||||||
|
static void parse_binary_value(void) // Now GotByte = "%" or "b"
|
||||||
|
{
|
||||||
|
intval_t value = 0;
|
||||||
|
int go_on = TRUE, // continue loop flag
|
||||||
|
flags = MVALUE_GIVEN,
|
||||||
|
digits = -1; // digit counter
|
||||||
|
|
||||||
|
do {
|
||||||
|
digits++;
|
||||||
|
switch (GetByte()) {
|
||||||
|
case '0':
|
||||||
|
case '.':
|
||||||
|
value <<= 1;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
case '#':
|
||||||
|
value = (value << 1) | 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
go_on = 0;
|
||||||
|
}
|
||||||
|
} while (go_on);
|
||||||
|
// set force bits
|
||||||
|
if (digits > 8) {
|
||||||
|
if (digits > 16) {
|
||||||
|
if (value < 65536)
|
||||||
|
flags |= MVALUE_FORCE24;
|
||||||
|
} else {
|
||||||
|
if (value < 256)
|
||||||
|
flags |= MVALUE_FORCE16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PUSH_INTOPERAND(value, flags);
|
||||||
|
// Now GotByte = non-binary char
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parse hexadecimal value. It accepts "0" to "9", "a" to "f" and "A" to "F".
|
// Parse hexadecimal value. It accepts "0" to "9", "a" to "f" and "A" to "F".
|
||||||
// Capital letters will be converted to lowercase letters using the flagtable.
|
// Capital letters will be converted to lowercase letters using the flagtable.
|
||||||
// The current value is stored as soon as a character is read that is none of
|
// The current value is stored as soon as a character is read that is none of
|
||||||
@ -434,10 +475,16 @@ static void parse_decimal_value(void) // Now GotByte = first digit
|
|||||||
intval_t intval = (GotByte & 15); // this works. it's ASCII.
|
intval_t intval = (GotByte & 15); // this works. it's ASCII.
|
||||||
|
|
||||||
GetByte();
|
GetByte();
|
||||||
// TODO - add "0b" prefix for binary values?
|
// check for "0b" (binary) and "0x" (hexadecimal) prefixes
|
||||||
if ((intval == 0) && (GotByte == 'x')) {
|
if (intval == 0) {
|
||||||
parse_hexadecimal_value();
|
if (GotByte == 'b') {
|
||||||
return;
|
parse_binary_value();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GotByte == 'x') {
|
||||||
|
parse_hexadecimal_value();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// parse digits until no more
|
// parse digits until no more
|
||||||
while ((GotByte >= '0') && (GotByte <= '9')) {
|
while ((GotByte >= '0') && (GotByte <= '9')) {
|
||||||
@ -496,46 +543,6 @@ static void parse_program_counter(void) // Now GotByte = "*"
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Parse binary value. Apart from '0' and '1', it also accepts the characters
|
|
||||||
// '.' and '#', this is much more readable. The current value is stored as soon
|
|
||||||
// as a character is read that is none of those given above.
|
|
||||||
static void parse_binary_value(void) // Now GotByte = "%"
|
|
||||||
{
|
|
||||||
intval_t value = 0;
|
|
||||||
int go_on = TRUE, // continue loop flag
|
|
||||||
flags = MVALUE_GIVEN,
|
|
||||||
digits = -1; // digit counter
|
|
||||||
|
|
||||||
do {
|
|
||||||
digits++;
|
|
||||||
switch (GetByte()) {
|
|
||||||
case '0':
|
|
||||||
case '.':
|
|
||||||
value <<= 1;
|
|
||||||
break;
|
|
||||||
case '1':
|
|
||||||
case '#':
|
|
||||||
value = (value << 1) | 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
go_on = 0;
|
|
||||||
}
|
|
||||||
} while (go_on);
|
|
||||||
// set force bits
|
|
||||||
if (digits > 8) {
|
|
||||||
if (digits > 16) {
|
|
||||||
if (value < 65536)
|
|
||||||
flags |= MVALUE_FORCE24;
|
|
||||||
} else {
|
|
||||||
if (value < 256)
|
|
||||||
flags |= MVALUE_FORCE16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PUSH_INTOPERAND(value, flags);
|
|
||||||
// Now GotByte = non-binary char
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Parse function call (sin(), cos(), arctan(), ...)
|
// Parse function call (sin(), cos(), arctan(), ...)
|
||||||
static void parse_function_call(void)
|
static void parse_function_call(void)
|
||||||
{
|
{
|
||||||
@ -768,7 +775,7 @@ static void expect_dyadic_operator(void)
|
|||||||
operator = &ops_equals;
|
operator = &ops_equals;
|
||||||
// if it's "==", accept but warn
|
// if it's "==", accept but warn
|
||||||
if (GetByte() == '=') {
|
if (GetByte() == '=') {
|
||||||
Throw_first_pass_warning("C-style \"==\" comparison detected");
|
Throw_first_pass_warning("C-style \"==\" comparison detected.");
|
||||||
goto get_byte_and_push_dyadic;
|
goto get_byte_and_push_dyadic;
|
||||||
}
|
}
|
||||||
goto push_dyadic;
|
goto push_dyadic;
|
||||||
|
@ -44,7 +44,7 @@ struct result_int_t {
|
|||||||
// Boolean values
|
// Boolean values
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
#define TRUE 1
|
#define TRUE (!FALSE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
61
src/flow.c
61
src/flow.c
@ -27,9 +27,9 @@
|
|||||||
// type definitions
|
// type definitions
|
||||||
|
|
||||||
struct loop_condition {
|
struct loop_condition {
|
||||||
int line; // original line number
|
int line; // original line number
|
||||||
int invert; // actually bool (0 for WHILE, 1 for UNTIL)
|
int invert; // actually bool (0 for WHILE, 1 for UNTIL)
|
||||||
char *body; // pointer to actual expression
|
char *body; // pointer to actual expression
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -179,12 +179,18 @@ static enum eos PO_do(void) // Now GotByte = illegal char
|
|||||||
|
|
||||||
|
|
||||||
// looping assembly ("!for"). Has to be re-entrant.
|
// looping assembly ("!for"). Has to be re-entrant.
|
||||||
|
// old syntax: !for VAR, END { BLOCK } VAR counts from 1 to END
|
||||||
|
// new syntax: !for VAR, START, END { BLOCK } VAR counts from START to END
|
||||||
static enum eos PO_for(void) // Now GotByte = illegal char
|
static enum eos PO_for(void) // Now GotByte = illegal char
|
||||||
{
|
{
|
||||||
struct input loop_input,
|
struct input loop_input,
|
||||||
*outer_input;
|
*outer_input;
|
||||||
struct result_t loop_counter;
|
struct result_t loop_counter;
|
||||||
intval_t maximum;
|
intval_t first_arg,
|
||||||
|
counter_first,
|
||||||
|
counter_last,
|
||||||
|
counter_increment;
|
||||||
|
int old_algo; // actually bool
|
||||||
char *loop_body; // pointer to loop's body block
|
char *loop_body; // pointer to loop's body block
|
||||||
struct label *label;
|
struct label *label;
|
||||||
zone_t zone;
|
zone_t zone;
|
||||||
@ -196,13 +202,25 @@ static enum eos PO_for(void) // Now GotByte = illegal char
|
|||||||
// Now GotByte = illegal char
|
// Now GotByte = illegal char
|
||||||
force_bit = Input_get_force_bit(); // skips spaces after
|
force_bit = Input_get_force_bit(); // skips spaces after
|
||||||
label = Label_find(zone, force_bit);
|
label = Label_find(zone, force_bit);
|
||||||
if (Input_accept_comma() == 0) {
|
if (!Input_accept_comma()) {
|
||||||
Throw_error(exception_syntax);
|
Throw_error(exception_syntax);
|
||||||
return SKIP_REMAINDER;
|
return SKIP_REMAINDER;
|
||||||
}
|
}
|
||||||
maximum = ALU_defined_int();
|
first_arg = ALU_defined_int();
|
||||||
if (maximum < 0)
|
if (Input_accept_comma()) {
|
||||||
Throw_serious_error("Loop count is negative.");
|
old_algo = FALSE; // new format - yay!
|
||||||
|
counter_first = first_arg; // use given argument
|
||||||
|
counter_last = ALU_defined_int(); // read second argument
|
||||||
|
counter_increment = (counter_last < counter_first) ? -1 : 1;
|
||||||
|
} else {
|
||||||
|
old_algo = TRUE; // old format - booo!
|
||||||
|
Throw_first_pass_warning("Found deprecated \"!for\" syntax.");
|
||||||
|
if (first_arg < 0)
|
||||||
|
Throw_serious_error("Loop count is negative.");
|
||||||
|
counter_first = 0; // CAUTION - old algo pre-increments and therefore starts with 1!
|
||||||
|
counter_last = first_arg; // use given argument
|
||||||
|
counter_increment = 1;
|
||||||
|
}
|
||||||
if (GotByte != CHAR_SOB)
|
if (GotByte != CHAR_SOB)
|
||||||
Throw_serious_error(exception_no_left_brace);
|
Throw_serious_error(exception_no_left_brace);
|
||||||
// remember line number of loop pseudo opcode
|
// remember line number of loop pseudo opcode
|
||||||
@ -220,16 +238,25 @@ static enum eos PO_for(void) // Now GotByte = illegal char
|
|||||||
Input_now = &loop_input;
|
Input_now = &loop_input;
|
||||||
// init counter
|
// init counter
|
||||||
loop_counter.flags = MVALUE_DEFINED | MVALUE_EXISTS;
|
loop_counter.flags = MVALUE_DEFINED | MVALUE_EXISTS;
|
||||||
loop_counter.val.intval = 0;
|
loop_counter.val.intval = counter_first;
|
||||||
// if count == 0, skip loop
|
Label_set_value(label, &loop_counter, TRUE);
|
||||||
if (maximum) {
|
if (old_algo) {
|
||||||
do {
|
// old algo for old syntax:
|
||||||
loop_counter.val.intval++; // increment counter
|
// if count == 0, skip loop
|
||||||
Label_set_value(label, &loop_counter, TRUE);
|
if (counter_last) {
|
||||||
parse_ram_block(loop_start, loop_body);
|
do {
|
||||||
} while (loop_counter.val.intval < maximum);
|
loop_counter.val.intval += counter_increment;
|
||||||
|
Label_set_value(label, &loop_counter, TRUE);
|
||||||
|
parse_ram_block(loop_start, loop_body);
|
||||||
|
} while (loop_counter.val.intval < counter_last);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Label_set_value(label, &loop_counter, TRUE);
|
// new algo for new syntax:
|
||||||
|
do {
|
||||||
|
parse_ram_block(loop_start, loop_body);
|
||||||
|
loop_counter.val.intval += counter_increment;
|
||||||
|
Label_set_value(label, &loop_counter, TRUE);
|
||||||
|
} while (loop_counter.val.intval != (counter_last + counter_increment));
|
||||||
}
|
}
|
||||||
// Free memory
|
// Free memory
|
||||||
free(loop_body);
|
free(loop_body);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user