yet more refactoring

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@387 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-08-04 09:53:16 +00:00
parent a53aa01a1e
commit 7015508538
12 changed files with 84 additions and 85 deletions

View File

@ -10,7 +10,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> // for strlen and memmove #include <string.h> // for strlen and memmove
#include <kernel.h> #include <kernel.h>
#include "input.h" // for input_now->location.plat_filename #include "input.h" // for input_get_location()
// constants // constants
@ -124,12 +124,15 @@ void RISCOS_set_filetype(const char *filename, int file_type)
// throwback protocol: "type" can be 0, 1 or 2 (DDEUtils message types) // throwback protocol: "type" can be 0, 1 or 2 (DDEUtils message types)
void RISCOS_throwback(const char *message, int type) void RISCOS_throwback(const char *message, int type)
{ {
struct location location;
_kernel_swi_regs regs; _kernel_swi_regs regs;
// only use throwback protocol if wanted // only use throwback protocol if wanted
if ((RISCOS_flags & RISCOSFLAG_THROWBACK) == 0) if ((RISCOS_flags & RISCOSFLAG_THROWBACK) == 0)
return; return;
input_get_location(&location);
// if this is the first throwback, set it up and send info // if this is the first throwback, set it up and send info
if ((RISCOS_flags & RISCOSFLAG_THROWN) == 0) { if ((RISCOS_flags & RISCOSFLAG_THROWN) == 0) {
RISCOS_flags |= RISCOSFLAG_THROWN; RISCOS_flags |= RISCOSFLAG_THROWN;
@ -137,14 +140,14 @@ void RISCOS_throwback(const char *message, int type)
regs.r[0] = 0; regs.r[0] = 0;
regs.r[1] = 0; regs.r[1] = 0;
// regs.r[2] = (int) toplevel_source; // regs.r[2] = (int) toplevel_source;
regs.r[2] = (int) input_now->location.plat_filename; regs.r[2] = (int) location.plat_filename;
_kernel_swi(XDDEUTILS_THROWBACKSEND, &regs, &regs); _kernel_swi(XDDEUTILS_THROWBACKSEND, &regs, &regs);
} }
// send throwback message // send throwback message
regs.r[0] = 1; regs.r[0] = 1;
regs.r[1] = 0; regs.r[1] = 0;
regs.r[2] = (int) input_now->location.plat_filename; regs.r[2] = (int) location.plat_filename;
regs.r[3] = input_now->location.line_number; regs.r[3] = location.line_number;
regs.r[4] = type; regs.r[4] = type;
regs.r[5] = (int) message; regs.r[5] = (int) message;
_kernel_swi(XDDEUTILS_THROWBACKSEND, &regs, &regs); _kernel_swi(XDDEUTILS_THROWBACKSEND, &regs, &regs);

View File

@ -348,8 +348,10 @@ static void perform_pass(void)
pass.warning_count = 0; pass.warning_count = 0;
// Process toplevel files // Process toplevel files
for (ii = 0; ii < toplevel_src_count; ++ii) { for (ii = 0; ii < toplevel_src_count; ++ii) {
if ((fd = fopen(toplevel_sources_plat[ii], FILE_READBINARY))) { fd = fopen(toplevel_sources_plat[ii], FILE_READBINARY);
parse_and_close_platform_file(fd, toplevel_sources_plat[ii]); if (fd) {
parse_source_code_file(fd, toplevel_sources_plat[ii]);
fclose(fd);
} else { } else {
fprintf(stderr, "Error: Cannot open toplevel file \"%s\".\n", toplevel_sources_plat[ii]); fprintf(stderr, "Error: Cannot open toplevel file \"%s\".\n", toplevel_sources_plat[ii]);
if (toplevel_sources_plat[ii][0] == '-') if (toplevel_sources_plat[ii][0] == '-')

View File

@ -26,6 +26,12 @@ struct location {
const char *plat_filename; // filename in platform style const char *plat_filename; // filename in platform style
int line_number; int line_number;
}; };
// struct for code blocks (loop conditions, loop bodies and macro bodies)
struct block {
int line_number; // start of block
char *body;
};
// stuff for results from expression parser: // stuff for results from expression parser:

View File

@ -55,7 +55,7 @@ static void parse_ram_block(struct block *block)
{ {
// set line number to loop start // set line number to loop start
// set RAM read pointer to loop // set RAM read pointer to loop
inputchange_set_ram(block->start, block->body); inputchange_set_ram(block->line_number, block->body);
// parse block // parse block
parse_until_eob_or_eof(); parse_until_eob_or_eof();
if (GotByte != CHAR_EOB) if (GotByte != CHAR_EOB)
@ -116,7 +116,7 @@ static void iterating_for(struct for_loop *loop)
} }
// back end function for "!for" pseudo opcode // back end function for "!for" pseudo opcode, called with GotByte = '}'
void flow_forloop(struct for_loop *loop) void flow_forloop(struct for_loop *loop)
{ {
struct inputchange_buf icb; struct inputchange_buf icb;
@ -124,7 +124,7 @@ void flow_forloop(struct for_loop *loop)
// remember input and set up new one: // remember input and set up new one:
inputchange_new_ram(&icb); inputchange_new_ram(&icb);
// fix line number (not for block, but in case symbol handling throws errors) // fix line number (not for block, but in case symbol handling throws errors)
inputchange_set_ram(loop->block.start, NULL); inputchange_set_ram(loop->block.line_number, NULL);
switch (loop->algorithm) { switch (loop->algorithm) {
case FORALGO_OLDCOUNT: case FORALGO_OLDCOUNT:
@ -163,7 +163,7 @@ static void copy_condition(struct condition *condition, char terminator)
GetByte(); GetByte();
} }
dynabuf_append(GlobalDynaBuf, CHAR_EOS); // ensure terminator dynabuf_append(GlobalDynaBuf, CHAR_EOS); // ensure terminator
condition->body = dynabuf_get_copy(GlobalDynaBuf); condition->block.body = dynabuf_get_copy(GlobalDynaBuf);
} }
// try to read a condition into DynaBuf and store pointer to copy in // try to read a condition into DynaBuf and store pointer to copy in
@ -173,10 +173,10 @@ static void copy_condition(struct condition *condition, char terminator)
void flow_store_doloop_condition(struct condition *condition, char terminator) void flow_store_doloop_condition(struct condition *condition, char terminator)
{ {
// write line number // write line number
condition->line = input_now->location.line_number; condition->block.line_number = input_now->location.line_number;
// set defaults // set defaults
condition->invert = FALSE; condition->invert = FALSE;
condition->body = NULL; condition->block.body = NULL;
// check for empty condition // check for empty condition
if (GotByte == terminator) if (GotByte == terminator)
return; return;
@ -202,7 +202,7 @@ void flow_store_doloop_condition(struct condition *condition, char terminator)
// call with GotByte = first interesting character // call with GotByte = first interesting character
void flow_store_while_condition(struct condition *condition) void flow_store_while_condition(struct condition *condition)
{ {
condition->line = input_now->location.line_number; condition->block.line_number = input_now->location.line_number;
condition->invert = FALSE; condition->invert = FALSE;
copy_condition(condition, CHAR_SOB); copy_condition(condition, CHAR_SOB);
} }
@ -214,11 +214,11 @@ static boolean check_condition(struct condition *condition)
struct number intresult; struct number intresult;
// first, check whether there actually *is* a condition // first, check whether there actually *is* a condition
if (condition->body == NULL) if (condition->block.body == NULL)
return TRUE; // non-existing conditions are always true return TRUE; // non-existing conditions are always true
// set up input for expression evaluation // set up input for expression evaluation
inputchange_set_ram(condition->line, condition->body); inputchange_set_ram(condition->block.line_number, condition->block.body); // FIXME - just pass condition->block!)
GetByte(); // proceed with next char GetByte(); // proceed with next char
ALU_defined_int(&intresult); ALU_defined_int(&intresult);
@ -247,11 +247,4 @@ void flow_do_while(struct do_while *loop)
} }
// restore outer input // restore outer input
inputchange_back(&icb); inputchange_back(&icb);
// FIXME - the line above also restores GotByte, so this is no longer necessary,
// but check before removing:
GotByte = CHAR_EOS; // CAUTION! Very ugly kluge.
// But by switching input, we lost the outer input's GotByte. We know
// it was CHAR_EOS. We could just call GetByte() to get real input, but
// then the main loop could choke on unexpected bytes. So we pretend
// that we got the outer input's GotByte value magically back.
} }

View File

@ -11,11 +11,6 @@
#include "config.h" #include "config.h"
struct block {
int start; // line number of start of block
char *body;
};
// struct to pass "!for" loop stuff from pseudoopcodes.c to flow.c // struct to pass "!for" loop stuff from pseudoopcodes.c to flow.c
enum foralgo { enum foralgo {
FORALGO_OLDCOUNT, // block can be skipped by passing zero, counter keeps value after block FORALGO_OLDCOUNT, // block can be skipped by passing zero, counter keeps value after block
@ -42,9 +37,9 @@ struct for_loop {
// structs to pass "!do"/"!while" stuff from pseudoopcodes.c to flow.c // structs to pass "!do"/"!while" stuff from pseudoopcodes.c to flow.c
struct condition { struct condition {
int line; // original line number // FIXME - add some "boolean given" and use that instead of checking for block.body == NULL
boolean invert; // only set for UNTIL conditions boolean invert; // only set for UNTIL conditions
char *body; // pointer to actual expression struct block block;
}; };
struct do_while { struct do_while {
struct condition head_cond; struct condition head_cond;

View File

@ -436,7 +436,7 @@ int parse_optional_block(void)
// "directory/basename.extension" on linux, // "directory/basename.extension" on linux,
// "directory.basename/extension" on RISC OS, etc. // "directory.basename/extension" on RISC OS, etc.
// and the pointer must remain valid forever! // and the pointer must remain valid forever!
void parse_and_close_platform_file(FILE *fd, const char *eternal_plat_filename) void parse_source_code_file(FILE *fd, const char *eternal_plat_filename)
{ {
struct inputchange_buf icb; struct inputchange_buf icb;
const char *ppb; // path buffer in platform format const char *ppb; // path buffer in platform format
@ -455,10 +455,6 @@ void parse_and_close_platform_file(FILE *fd, const char *eternal_plat_filename)
parse_until_eob_or_eof(); parse_until_eob_or_eof();
if (GotByte != CHAR_EOF) if (GotByte != CHAR_EOF)
Throw_error("Expected EOF, found '}' instead." ); Throw_error("Expected EOF, found '}' instead." );
// close sublevel src
// (this looks like we could just use "fd" as arg, but maybe the file
// has been replaced with a different one in the meantime...)
fclose(input_now->src.fd);
// restore outer input // restore outer input
inputchange_back(&icb); inputchange_back(&icb);
@ -498,21 +494,24 @@ bits parser_get_force_bit(void)
static void throw_msg(const char *message, const char *ansicolor, const char *type) static void throw_msg(const char *message, const char *ansicolor, const char *type)
{ {
const char *resetcolor = "\033[0m"; const char *resetcolor = "\033[0m";
struct location location;
if (!config.format_color) { if (!config.format_color) {
ansicolor = ""; ansicolor = "";
resetcolor = ""; resetcolor = "";
} }
input_get_location(&location);
if (config.format_msvc) { if (config.format_msvc) {
fprintf(config.msg_stream, "%s(%d) : %s%s%s (%s %s): %s\n", fprintf(config.msg_stream, "%s(%d) : %s%s%s (%s %s): %s\n",
input_now->location.plat_filename, input_now->location.line_number, location.plat_filename, location.line_number,
ansicolor, type, resetcolor, ansicolor, type, resetcolor,
section_now->type, section_now->title, message); section_now->type, section_now->title, message);
} else { } else {
fprintf(config.msg_stream, "%s%s%s - File %s, line %d (%s %s): %s\n", fprintf(config.msg_stream, "%s%s%s - File %s, line %d (%s %s): %s\n",
ansicolor, type, resetcolor, ansicolor, type, resetcolor,
input_now->location.plat_filename, input_now->location.line_number, location.plat_filename, location.line_number,
section_now->type, section_now->title, message); section_now->type, section_now->title, message);
} }
} }
@ -579,8 +578,9 @@ void throw_redef_error(struct location *old_def, const char msg[])
// CAUTION, ugly kluge: fiddle with input_now and section_now // CAUTION, ugly kluge: fiddle with input_now and section_now
// data so error message is actually helpful // data so error message is actually helpful
// FIXME: maybe better pass "old location" as an optional arg to throw_message!
// buffer old data // buffer old data
buffered_location = input_now->location; input_get_location(&buffered_location);
buffered_section_type = section_now->type; buffered_section_type = section_now->type;
buffered_section_title = section_now->title; buffered_section_title = section_now->title;
// set new (fake) data // set new (fake) data

View File

@ -195,7 +195,7 @@ extern int parse_optional_block(void);
// "directory/basename.extension" on linux, // "directory/basename.extension" on linux,
// "directory.basename/extension" on RISC OS, etc. // "directory.basename/extension" on RISC OS, etc.
// and the pointer must remain valid forever! // and the pointer must remain valid forever!
extern void parse_and_close_platform_file(FILE *fd, const char *eternal_plat_filename); extern void parse_source_code_file(FILE *fd, const char *eternal_plat_filename);
// read optional info about parameter length // read optional info about parameter length
extern bits parser_get_force_bit(void); extern bits parser_get_force_bit(void);

View File

@ -512,19 +512,21 @@ void input_block_skip(void)
{ {
block_to_dynabuf(); block_to_dynabuf();
} }
// Read block into GlobalDynabuf, make a copy and return a pointer to that // Read block into GlobalDynabuf, make a copy and store pointer in struct.
// (reading starts with next byte, so call directly after reading opening brace). // (reading starts with next byte, so call directly after reading opening brace).
// After calling this function, GotByte holds '}'. Unless EOF was found first, // After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown. // but then a serious error would have been thrown.
char *input_block_getcopy(void) void input_block_getcopy(struct block *block)
{ {
// first store line number...
block->line_number = input_now->location.line_number;
// ...then get block
block_to_dynabuf(); block_to_dynabuf();
// prepare to return copy of block
// add EOF, just to make sure block is never read too far // add EOF, just to make sure block is never read too far
dynabuf_append(GlobalDynaBuf, CHAR_EOS); dynabuf_append(GlobalDynaBuf, CHAR_EOS);
dynabuf_append(GlobalDynaBuf, CHAR_EOF); dynabuf_append(GlobalDynaBuf, CHAR_EOF);
// return pointer to copy // store pointer to copy
return dynabuf_get_copy(GlobalDynaBuf); block->body = dynabuf_get_copy(GlobalDynaBuf);
} }
// Append to GlobalDynaBuf while characters are legal for keywords. // Append to GlobalDynaBuf while characters are legal for keywords.
@ -838,6 +840,12 @@ int input_read_output_filename(void)
return 0; // ok return 0; // ok
} }
// write current "location" (file name and line number) to given target
void input_get_location(struct location *target)
{
*target = input_now->location;
}
// "input change" stuff: // "input change" stuff:
@ -872,20 +880,20 @@ void inputchange_new_ram(struct inputchange_buf *icb)
} }
// FIXME - merge these three functions into a single one (by always using a "location"): // FIXME - merge these three functions into a single one (by always using a "location"):
// setup for reading from RAM (for parsing loop conditions etc.) // setup for reading from RAM (for parsing loop conditions etc.)
void inputchange_set_ram(int line_num, char *body) void inputchange_set_ram(int line_num, const char *body)
{ {
input_now->location.line_number = line_num; input_now->location.line_number = line_num;
input_now->src.ram_ptr = body; input_now->src.ram_ptr = body;
} }
// switch input to macro parameters // switch input to macro parameters
void inputchange_macro1_params(struct location *def, char *params) void inputchange_macro1_params(const struct location *def, const char *params)
{ {
input_now->location = *def; input_now->location = *def;
input_now->src.ram_ptr = params; input_now->src.ram_ptr = params;
input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others! input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others!
} }
// switch from macro parameters to macro body // switch from macro parameters to macro body
void inputchange_macro2_body(char *macro_body) void inputchange_macro2_body(const char *macro_body)
{ {
input_now->src.ram_ptr = macro_body; input_now->src.ram_ptr = macro_body;
input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others! input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others!

View File

@ -25,7 +25,7 @@ struct input {
int state; // state of input (type is really "enum inputstate") int state; // state of input (type is really "enum inputstate")
union { union {
FILE *fd; // file descriptor FILE *fd; // file descriptor
char *ram_ptr; // RAM read ptr (loop or macro block) const char *ram_ptr; // RAM read ptr (loop or macro block)
} src; } src;
}; };
struct filespecflags { struct filespecflags {
@ -80,11 +80,11 @@ extern int input_unescape_dynabuf(void);
// After calling this function, GotByte holds '}'. Unless EOF was found first, // After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown. // but then a serious error would have been thrown.
extern void input_block_skip(void); extern void input_block_skip(void);
// Read block into GlobalDynabuf, make a copy and return a pointer to that // Read block into GlobalDynabuf, make a copy and store pointer in struct.
// (reading starts with next byte, so call directly after reading opening brace). // (reading starts with next byte, so call directly after reading opening brace).
// After calling this function, GotByte holds '}'. Unless EOF was found first, // After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown. // but then a serious error would have been thrown.
extern char *input_block_getcopy(void); extern void input_block_getcopy(struct block *block);
// append optional '.'/'@' prefix to GlobalDynaBuf, then keep // append optional '.'/'@' prefix to GlobalDynaBuf, then keep
// appending while characters are legal for keywords. // appending while characters are legal for keywords.
@ -145,6 +145,9 @@ extern int input_expect(int chr);
// (back end function for "!eof" pseudo opcode) // (back end function for "!eof" pseudo opcode)
extern void input_force_eof(void); extern void input_force_eof(void);
// write current "location" (file name and line number) to given target
extern void input_get_location(struct location *target);
// "input change" stuff: // "input change" stuff:
@ -159,11 +162,11 @@ extern void inputchange_new_file(struct inputchange_buf *icb, FILE *fd, const ch
// save current input struct in buffer, then switch to RAM // save current input struct in buffer, then switch to RAM
extern void inputchange_new_ram(struct inputchange_buf *icb); extern void inputchange_new_ram(struct inputchange_buf *icb);
// setup for reading from RAM (for parsing loop conditions etc.) // setup for reading from RAM (for parsing loop conditions etc.)
extern void inputchange_set_ram(int line_num, char *body); extern void inputchange_set_ram(int line_num, const char *body);
// switch input to macro parameters // switch input to macro parameters
extern void inputchange_macro1_params(struct location *def, char *params); extern void inputchange_macro1_params(const struct location *def, const char *params);
// switch from macro parameters to macro body // switch from macro parameters to macro body
extern void inputchange_macro2_body(char *macro_body); extern void inputchange_macro2_body(const char *macro_body);
// restore input struct from buffer // restore input struct from buffer
extern void inputchange_back(const struct inputchange_buf *icb); extern void inputchange_back(const struct inputchange_buf *icb);

View File

@ -29,8 +29,8 @@
struct macro { struct macro {
struct location definition; // for "macro twice" error struct location definition; // for "macro twice" error
char *original_name, // as section title in error msgs char *original_name, // as section title in error msgs
*parameter_list, // parameters (whole line) *parameter_list; // parameters (whole line)
*body; // RAM block containing macro body struct block body; // RAM block containing macro body
}; };
// there's no need to make this a struct and add a type component: // there's no need to make this a struct and add a type component:
// when the macro has been found, accessing its parameter_list component // when the macro has been found, accessing its parameter_list component
@ -166,10 +166,10 @@ void macro_parse_definition(void) // Now GotByte = illegal char after "!macro"
} }
// Create new macro struct and set it up. Finally we'll read the body. // Create new macro struct and set it up. Finally we'll read the body.
new_macro = safe_malloc(sizeof(*new_macro)); new_macro = safe_malloc(sizeof(*new_macro));
new_macro->definition = input_now->location;
new_macro->original_name = dynabuf_get_copy(user_macro_name); new_macro->original_name = dynabuf_get_copy(user_macro_name);
new_macro->parameter_list = formal_parameters; new_macro->parameter_list = formal_parameters;
new_macro->body = input_block_getcopy(); // changes line number! input_get_location(&new_macro->definition); // includes line number
input_block_getcopy(&new_macro->body); // also includes line number (and then changes it)
macro_node->body = new_macro; // link macro struct to tree node macro_node->body = new_macro; // link macro struct to tree node
// and that about sums it up // and that about sums it up
} }
@ -287,7 +287,7 @@ void macro_parse_call(void) // Now GotByte = first char of macro name
// and now, finally, parse the actual macro body // and now, finally, parse the actual macro body
// maybe call parse_ram_block(actual_macro->definition.line_number, actual_macro->body) // maybe call parse_ram_block(actual_macro->definition.line_number, actual_macro->body)
inputchange_macro2_body(actual_macro->body); inputchange_macro2_body(actual_macro->body.body);
parse_until_eob_or_eof(); parse_until_eob_or_eof();
if (GotByte != CHAR_EOB) if (GotByte != CHAR_EOB)
BUG("IllegalBlockTerminator", GotByte); BUG("IllegalBlockTerminator", GotByte);

View File

@ -911,7 +911,8 @@ static enum eos po_source(void) // now GotByte = illegal char
stream = includepaths_open_ro(&flags); stream = includepaths_open_ro(&flags);
if (stream) { if (stream) {
eternal_plat_filename = dynabuf_get_copy(GlobalDynaBuf); eternal_plat_filename = dynabuf_get_copy(GlobalDynaBuf);
parse_and_close_platform_file(stream, eternal_plat_filename); parse_source_code_file(stream, eternal_plat_filename);
fclose(stream);
} }
// leave nesting level // leave nesting level
++sanity.source_recursions_left; ++sanity.source_recursions_left;
@ -1141,16 +1142,11 @@ does not fail. */
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 input_block_getcopy(&loop.block); // "body" must be freed afterward...
loop.block.start = input_now->location.line_number;
// read loop body into DynaBuf and get copy
// reading block changes line number!
loop.block.body = input_block_getcopy(); // must be freed!
flow_forloop(&loop); flow_forloop(&loop);
// free memory free(loop.block.body); // ...so free it
free(loop.block.body);
// GotByte of OuterInput would be '}' (if it would still exist) // GotByte is '}'
GetByte(); // fetch next byte GetByte(); // fetch next byte
return ENSURE_EOS; return ENSURE_EOS;
} }
@ -1166,11 +1162,8 @@ static enum eos po_do(void) // now GotByte = illegal char
flow_store_doloop_condition(&loop.head_cond, CHAR_SOB); // must be freed! flow_store_doloop_condition(&loop.head_cond, CHAR_SOB); // must be freed!
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 body,
// then read block and get copy input_block_getcopy(&loop.block); // "body" must be freed!
loop.block.start = input_now->location.line_number;
// reading block changes line number!
loop.block.body = input_block_getcopy(); // must be freed!
// now GotByte = '}' // now GotByte = '}'
NEXTANDSKIPSPACE(); // now GotByte = first non-blank char after block NEXTANDSKIPSPACE(); // now GotByte = first non-blank char after block
// read tail condition to buffer // read tail condition to buffer
@ -1178,9 +1171,9 @@ static enum eos po_do(void) // now GotByte = illegal char
// now GotByte = CHAR_EOS // now GotByte = CHAR_EOS
flow_do_while(&loop); flow_do_while(&loop);
// free memory // free memory
free(loop.head_cond.body); free(loop.tail_cond.block.body);
free(loop.block.body); free(loop.block.body);
free(loop.tail_cond.body); free(loop.head_cond.block.body);
return AT_EOS_ANYWAY; return AT_EOS_ANYWAY;
} }
@ -1192,22 +1185,18 @@ static enum eos po_while(void) // now GotByte = illegal char
// read condition to buffer // read condition to buffer
SKIPSPACE(); SKIPSPACE();
flow_store_while_condition(&loop.head_cond); // must be freed! flow_store_while_condition(&loop.head_cond); // "body" must be freed!
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 body, // read block
// then read block and get copy input_block_getcopy(&loop.block); // "body" must be freed!
loop.block.start = input_now->location.line_number;
// reading block changes line number!
loop.block.body = input_block_getcopy(); // must be freed!
// clear tail condition // clear tail condition
loop.tail_cond.body = NULL; loop.tail_cond.block.body = NULL;
flow_do_while(&loop); flow_do_while(&loop);
// free memory // free memory
free(loop.head_cond.body);
free(loop.block.body); free(loop.block.body);
// GotByte of OuterInput would be '}' (if it would still exist) free(loop.head_cond.block.body);
GetByte(); // fetch next byte GetByte(); // fetch next byte (last byte read was '}')
return ENSURE_EOS; return ENSURE_EOS;
} }

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME #define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release #define CODENAME "Zem" // update before release
#define CHANGE_DATE "23 Jul" // update before release FIXME #define CHANGE_DATE "24 Jul" // update before release FIXME
#define CHANGE_YEAR "2024" // update before release #define CHANGE_YEAR "2024" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME