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

View File

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

View File

@ -26,6 +26,12 @@ struct location {
const char *plat_filename; // filename in platform style
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:

View File

@ -55,7 +55,7 @@ static void parse_ram_block(struct block *block)
{
// set line number to loop start
// set RAM read pointer to loop
inputchange_set_ram(block->start, block->body);
inputchange_set_ram(block->line_number, block->body);
// parse block
parse_until_eob_or_eof();
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)
{
struct inputchange_buf icb;
@ -124,7 +124,7 @@ void flow_forloop(struct for_loop *loop)
// remember input and set up new one:
inputchange_new_ram(&icb);
// 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) {
case FORALGO_OLDCOUNT:
@ -163,7 +163,7 @@ static void copy_condition(struct condition *condition, char terminator)
GetByte();
}
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
@ -173,10 +173,10 @@ static void copy_condition(struct condition *condition, char terminator)
void flow_store_doloop_condition(struct condition *condition, char terminator)
{
// write line number
condition->line = input_now->location.line_number;
condition->block.line_number = input_now->location.line_number;
// set defaults
condition->invert = FALSE;
condition->body = NULL;
condition->block.body = NULL;
// check for empty condition
if (GotByte == terminator)
return;
@ -202,7 +202,7 @@ void flow_store_doloop_condition(struct condition *condition, char terminator)
// call with GotByte = first interesting character
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;
copy_condition(condition, CHAR_SOB);
}
@ -214,11 +214,11 @@ static boolean check_condition(struct condition *condition)
struct number intresult;
// 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
// 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
ALU_defined_int(&intresult);
@ -247,11 +247,4 @@ void flow_do_while(struct do_while *loop)
}
// restore outer input
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"
struct block {
int start; // line number of start of block
char *body;
};
// struct to pass "!for" loop stuff from pseudoopcodes.c to flow.c
enum foralgo {
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
struct condition {
int line; // original line number
boolean invert; // only set for UNTIL conditions
char *body; // pointer to actual expression
// FIXME - add some "boolean given" and use that instead of checking for block.body == NULL
boolean invert; // only set for UNTIL conditions
struct block block;
};
struct do_while {
struct condition head_cond;

View File

@ -436,7 +436,7 @@ int parse_optional_block(void)
// "directory/basename.extension" on linux,
// "directory.basename/extension" on RISC OS, etc.
// 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;
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();
if (GotByte != CHAR_EOF)
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
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)
{
const char *resetcolor = "\033[0m";
struct location location;
if (!config.format_color) {
ansicolor = "";
resetcolor = "";
}
input_get_location(&location);
if (config.format_msvc) {
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,
section_now->type, section_now->title, message);
} else {
fprintf(config.msg_stream, "%s%s%s - File %s, line %d (%s %s): %s\n",
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);
}
}
@ -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
// data so error message is actually helpful
// FIXME: maybe better pass "old location" as an optional arg to throw_message!
// buffer old data
buffered_location = input_now->location;
input_get_location(&buffered_location);
buffered_section_type = section_now->type;
buffered_section_title = section_now->title;
// 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 RISC OS, etc.
// 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
extern bits parser_get_force_bit(void);

View File

@ -512,19 +512,21 @@ void input_block_skip(void)
{
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).
// After calling this function, GotByte holds '}'. Unless EOF was found first,
// 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();
// prepare to return copy of block
// add EOF, just to make sure block is never read too far
dynabuf_append(GlobalDynaBuf, CHAR_EOS);
dynabuf_append(GlobalDynaBuf, CHAR_EOF);
// return pointer to copy
return dynabuf_get_copy(GlobalDynaBuf);
// store pointer to copy
block->body = dynabuf_get_copy(GlobalDynaBuf);
}
// Append to GlobalDynaBuf while characters are legal for keywords.
@ -838,6 +840,12 @@ int input_read_output_filename(void)
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:
@ -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"):
// 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->src.ram_ptr = body;
}
// 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->src.ram_ptr = params;
input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others!
}
// 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->state = INPUTSTATE_NORMAL; // FIXME - fix others!

View File

@ -25,7 +25,7 @@ struct input {
int state; // state of input (type is really "enum inputstate")
union {
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;
};
struct filespecflags {
@ -80,11 +80,11 @@ extern int input_unescape_dynabuf(void);
// After calling this function, GotByte holds '}'. Unless EOF was found first,
// but then a serious error would have been thrown.
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).
// After calling this function, GotByte holds '}'. Unless EOF was found first,
// 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
// appending while characters are legal for keywords.
@ -145,6 +145,9 @@ extern int input_expect(int chr);
// (back end function for "!eof" pseudo opcode)
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:
@ -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
extern void inputchange_new_ram(struct inputchange_buf *icb);
// 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
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
extern void inputchange_macro2_body(char *macro_body);
extern void inputchange_macro2_body(const char *macro_body);
// restore input struct from buffer
extern void inputchange_back(const struct inputchange_buf *icb);

View File

@ -29,8 +29,8 @@
struct macro {
struct location definition; // for "macro twice" error
char *original_name, // as section title in error msgs
*parameter_list, // parameters (whole line)
*body; // RAM block containing macro body
*parameter_list; // parameters (whole line)
struct block body; // RAM block containing macro body
};
// 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
@ -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.
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->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
// 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
// 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();
if (GotByte != CHAR_EOB)
BUG("IllegalBlockTerminator", GotByte);

View File

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

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME
#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 HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME