Refactoring only; no change in functionality.

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@48 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2014-12-04 11:26:42 +00:00
parent c53505915d
commit de896f41f2
7 changed files with 98 additions and 110 deletions

View File

@ -17,7 +17,7 @@
#define RELEASE "0.95.4" // update before release (FIXME) #define RELEASE "0.95.4" // update before release (FIXME)
#define CODENAME "Fenchurch" // update before release #define CODENAME "Fenchurch" // update before release
#define CHANGE_DATE "3 Dec" // update before release #define CHANGE_DATE "4 Dec" // 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
@ -562,7 +562,6 @@ int main(int argc, const char *argv[])
Mnemo_init(); Mnemo_init();
Output_init(fill_value); Output_init(fill_value);
pseudoopcodes_init(); // setup keyword tree for pseudo opcodes pseudoopcodes_init(); // setup keyword tree for pseudo opcodes
Section_init();
if (do_actual_work()) if (do_actual_work())
save_output_file(); save_output_file();
return ACME_finalize(EXIT_SUCCESS); // dump labels, if wanted return ACME_finalize(EXIT_SUCCESS); // dump labels, if wanted

View File

@ -37,6 +37,9 @@ const char s_eor[] = "eor";
const char s_error[] = "error"; const char s_error[] = "error";
const char s_lsr[] = "lsr"; const char s_lsr[] = "lsr";
const char s_scrxor[] = "scrxor"; const char s_scrxor[] = "scrxor";
char s_untitled[] = "<untitled>"; // FIXME - this is actually const
const char s_Zone[] = "Zone";
const char s_subzone[] = "subzone";
// Exception messages during assembly // Exception messages during assembly
const char exception_cannot_open_input_file[] = "Cannot open input file."; const char exception_cannot_open_input_file[] = "Cannot open input file.";
const char exception_missing_string[] = "No string given."; const char exception_missing_string[] = "No string given.";
@ -145,38 +148,6 @@ static void parse_pc_def(void) // Now GotByte = "*"
} }
// Parse pseudo opcodes. Has to be re-entrant.
static void parse_pseudo_opcode(void) // Now GotByte = "!"
{
void *node_body;
enum eos (*fn)(void),
then = SKIP_REMAINDER; // prepare for errors
GetByte(); // read next byte
// on missing keyword, return (complaining will have been done)
if (Input_read_and_lower_keyword()) {
// move this to pseudoopcodes.c:
// search for tree item
if ((Tree_easy_scan(pseudo_opcode_tree, &node_body, GlobalDynaBuf))
&& node_body) {
fn = (enum eos (*)(void)) node_body;
SKIPSPACE();
// call function
then = fn();
} else {
Throw_error("Unknown pseudo opcode.");
}
}
if (then == SKIP_REMAINDER)
Input_skip_remainder();
else if (then == ENSURE_EOS)
Input_ensure_EOS();
// the other two possibilities (PARSE_REMAINDER and AT_EOS_ANYWAY)
// will lead to the remainder of the line being parsed by the mainloop.
}
// Check and return whether first label of statement. Complain if not. // Check and return whether first label of statement. Complain if not.
static int first_label_of_statement(int *statement_flags) static int first_label_of_statement(int *statement_flags)
{ {
@ -292,7 +263,7 @@ void Parse_until_eob_or_eof(void)
parse_forward_anon_def(&statement_flags); parse_forward_anon_def(&statement_flags);
break; break;
case PSEUDO_OPCODE_PREFIX: case PSEUDO_OPCODE_PREFIX:
parse_pseudo_opcode(); pseudoopcode_parse();
break; break;
case '*': case '*':
parse_pc_def(); parse_pc_def();

View File

@ -32,7 +32,11 @@ extern const char s_eor[];
extern const char s_error[]; extern const char s_error[];
extern const char s_lsr[]; extern const char s_lsr[];
extern const char s_scrxor[]; extern const char s_scrxor[];
// Error messages during assembly extern char s_untitled[];
extern const char s_Zone[];
#define s_zone (s_subzone + 3) // Yes, I know I'm sick
extern const char s_subzone[];
// error messages during assembly
extern const char exception_cannot_open_input_file[]; extern const char exception_cannot_open_input_file[];
extern const char exception_missing_string[]; extern const char exception_missing_string[];
extern const char exception_no_left_brace[]; extern const char exception_no_left_brace[];
@ -42,7 +46,7 @@ extern const char exception_no_right_brace[];
extern const char exception_number_out_of_range[]; extern const char exception_number_out_of_range[];
extern const char exception_pc_undefined[]; extern const char exception_pc_undefined[];
extern const char exception_syntax[]; extern const char exception_syntax[];
// Byte flags table // byte flags table
extern const char Byte_flags[]; extern const char Byte_flags[];
#define BYTEFLAGS(c) (Byte_flags[(unsigned char) c]) #define BYTEFLAGS(c) (Byte_flags[(unsigned char) c])
#define STARTS_KEYWORD (1u << 7) // Byte is allowed to start a keyword #define STARTS_KEYWORD (1u << 7) // Byte is allowed to start a keyword
@ -55,7 +59,7 @@ extern const char Byte_flags[];
// structures // structures
// different ways to handle end-of-statement: // different ways to handle end-of-statement: (FIXME - after grouping all pseudo opcodes, move to pseudoopcodes.c)
enum eos { enum eos {
SKIP_REMAINDER, // skip remainder of line - (after errors) SKIP_REMAINDER, // skip remainder of line - (after errors)
ENSURE_EOS, // make sure there's nothing left in statement ENSURE_EOS, // make sure there's nothing left in statement
@ -68,7 +72,7 @@ extern int warn_on_indented_labels; // warn if indented label is encountered
extern int warn_on_old_for; // warn if "!for" with old syntax is found extern int warn_on_old_for; // warn if "!for" with old syntax is found
extern int warn_on_type_mismatch; // use type-checking system extern int warn_on_type_mismatch; // use type-checking system
extern char GotByte; // Last byte read (processed) extern char GotByte; // Last byte read (processed)
// Global counters // global counters
extern int pass_undefined_count; // "NeedValue" type errors in current pass extern int pass_undefined_count; // "NeedValue" type errors in current pass
extern int pass_real_errors; // Errors yet extern int pass_real_errors; // Errors yet
extern signed long max_errors; // errors before giving up extern signed long max_errors; // errors before giving up
@ -104,7 +108,7 @@ do { \
// Prototypes // Prototypes
// Allocate memory and die if not available // allocate memory and die if not available
extern void *safe_malloc(size_t); extern void *safe_malloc(size_t);
// Parse block, beginning with next byte. // Parse block, beginning with next byte.
// End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards // End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards
@ -132,7 +136,7 @@ extern void Throw_error(const char *);
// assembly. Example: "!fill" without a parameter - the program counter cannot // assembly. Example: "!fill" without a parameter - the program counter cannot
// be set correctly in this case, so proceeding would be of no use at all. // be set correctly in this case, so proceeding would be of no use at all.
extern void Throw_serious_error(const char *); extern void Throw_serious_error(const char *);
// Handle bugs // handle bugs
extern void Bug_found(const char *, int); extern void Bug_found(const char *, int);

View File

@ -13,6 +13,7 @@
#include "input.h" #include "input.h"
#include "global.h" #include "global.h"
#include "output.h" #include "output.h"
#include "section.h"
#include "tree.h" #include "tree.h"
#include "typesystem.h" #include "typesystem.h"
#include "pseudoopcodes.h" #include "pseudoopcodes.h"
@ -251,6 +252,51 @@ static enum eos po_skip(void) // now GotByte = illegal char
} }
*/ */
// switch to new zone ("!zone" or "!zn"). has to be re-entrant.
static enum eos po_zone(void)
{
struct section entry_values; // buffer for outer zone
char *new_title;
int allocated;
// remember everything about current structure
entry_values = *Section_now;
// set default values in case there is no valid title
new_title = s_untitled;
allocated = FALSE;
// Check whether a zone title is given. If yes and it can be read,
// get copy, remember pointer and remember to free it later on.
if (BYTEFLAGS(GotByte) & CONTS_KEYWORD) {
// Because we know of one character for sure,
// there's no need to check the return value.
Input_read_keyword();
new_title = DynaBuf_get_copy(GlobalDynaBuf);
allocated = TRUE;
}
// setup new section
// section type is "subzone", just in case a block follows
Section_new_zone(Section_now, "Subzone", new_title, allocated);
if (Parse_optional_block()) {
// Block has been parsed, so it was a SUBzone.
Section_finalize(Section_now); // end inner zone
*Section_now = entry_values; // restore entry values
} else {
// no block found, so it's a normal zone change
Section_finalize(&entry_values); // end outer zone
Section_now->type = s_Zone; // change type to "Zone"
}
return ENSURE_EOS;
}
// "!subzone" or "!sz" pseudo opcode (now obsolete)
static enum eos po_subzone(void)
{
Throw_error("\"!subzone {}\" is obsolete; use \"!zone {}\" instead.");
// call "!zone" instead
return po_zone();
}
// constants // constants
#define USERMSG_DYNABUF_INITIALSIZE 80 #define USERMSG_DYNABUF_INITIALSIZE 80
@ -364,6 +410,10 @@ static struct ronode pseudo_opcodes[] = {
PREDEFNODE("addr", po_addr), PREDEFNODE("addr", po_addr),
PREDEFNODE("address", po_addr), PREDEFNODE("address", po_addr),
// PREDEFNODE("skip", po_skip), // PREDEFNODE("skip", po_skip),
PREDEFNODE(s_zone, po_zone),
PREDEFNODE("zn", po_zone),
PREDEFNODE(s_subzone, po_subzone),
PREDEFNODE("sz", po_subzone),
// PREDEFNODE("debug", po_debug), // PREDEFNODE("debug", po_debug),
// PREDEFNODE("info", po_info), // PREDEFNODE("info", po_info),
PREDEFNODE("warn", po_warn), PREDEFNODE("warn", po_warn),
@ -379,3 +429,33 @@ void pseudoopcodes_init(void)
user_message = DynaBuf_create(USERMSG_DYNABUF_INITIALSIZE); user_message = DynaBuf_create(USERMSG_DYNABUF_INITIALSIZE);
Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes); Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes);
} }
// parse a pseudo opcode. has to be re-entrant.
void pseudoopcode_parse(void) // Now GotByte = "!"
{
void *node_body;
enum eos (*fn)(void),
then = SKIP_REMAINDER; // prepare for errors
GetByte(); // read next byte
// on missing keyword, return (complaining will have been done)
if (Input_read_and_lower_keyword()) {
// search for tree item
if ((Tree_easy_scan(pseudo_opcode_tree, &node_body, GlobalDynaBuf))
&& node_body) {
fn = (enum eos (*)(void)) node_body;
SKIPSPACE();
// call function
then = fn();
} else {
Throw_error("Unknown pseudo opcode.");
}
}
if (then == SKIP_REMAINDER)
Input_skip_remainder();
else if (then == ENSURE_EOS)
Input_ensure_EOS();
// the other two possibilities (PARSE_REMAINDER and AT_EOS_ANYWAY)
// will lead to the remainder of the line being parsed by the mainloop.
}

View File

@ -15,6 +15,8 @@ extern struct ronode *pseudo_opcode_tree; // tree to hold pseudo opcodes
extern void notreallypo_setpc(void); extern void notreallypo_setpc(void);
// register pseudo opcodes // register pseudo opcodes
extern void pseudoopcodes_init(void); extern void pseudoopcodes_init(void);
// parse pseudo opcode. has to be re-entrant.
extern void pseudoopcode_parse(void);
#endif #endif

View File

@ -12,13 +12,6 @@
#include "section.h" #include "section.h"
// Constants
static const char type_zone[] = "Zone";
static const char s_subzone[] = "subzone";
#define s_zone (s_subzone + 3) // Yes, I know I'm sick
static char untitled[] = "<untitled>";
// ...is actually constant, but flagging it "const" results in heap of warnings
// fake section structure (for error msgs before any real section is in use) // fake section structure (for error msgs before any real section is in use)
static struct section initial_section = { static struct section initial_section = {
0, // zone value 0, // zone value
@ -53,68 +46,9 @@ void Section_finalize(struct section *section)
free(section->title); free(section->title);
} }
// Switch to new zone ("!zone" or "!zn"). Has to be re-entrant.
static enum eos PO_zone(void)
{
struct section entry_values; // buffer for outer zone
char *new_title;
int allocated;
// remember everything about current structure
entry_values = *Section_now;
// set default values in case there is no valid title
new_title = untitled;
allocated = FALSE;
// Check whether a zone title is given. If yes and it can be read,
// get copy, remember pointer and remember to free it later on.
if (BYTEFLAGS(GotByte) & CONTS_KEYWORD) {
// Because we know of one character for sure,
// there's no need to check the return value.
Input_read_keyword();
new_title = DynaBuf_get_copy(GlobalDynaBuf);
allocated = TRUE;
}
// setup new section
// section type is "subzone", just in case a block follows
Section_new_zone(Section_now, "Subzone", new_title, allocated);
if (Parse_optional_block()) {
// Block has been parsed, so it was a SUBzone.
Section_finalize(Section_now); // end inner zone
*Section_now = entry_values; // restore entry values
} else {
// no block found, so it's a normal zone change
Section_finalize(&entry_values); // end outer zone
Section_now->type = type_zone; // change type to "zone"
}
return ENSURE_EOS;
}
// "!subzone" or "!sz" pseudo opcode (now obsolete)
static enum eos PO_subzone(void)
{
Throw_error("\"!subzone {}\" is obsolete; use \"!zone {}\" instead.");
// call "!zone" instead
return PO_zone();
}
// predefined stuff
static struct ronode pseudo_opcodes[] = {
PREDEFNODE(s_zone, PO_zone),
PREDEFNODE("zn", PO_zone),
PREDEFNODE(s_subzone, PO_subzone),
PREDEFLAST("sz", PO_subzone),
// ^^^^ this marks the last element
};
// register pseudo opcodes
void Section_init(void)
{
Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes);
}
// Setup outermost section // Setup outermost section
void Section_passinit(void) void Section_passinit(void)
{ {
zone_max = ZONE_GLOBAL; // will be incremented by next line zone_max = ZONE_GLOBAL; // will be incremented by next line
Section_new_zone(&outer_section, type_zone, untitled, FALSE); Section_new_zone(&outer_section, s_Zone, s_untitled, FALSE);
} }

View File

@ -33,8 +33,6 @@ extern struct section *Section_now;
// Write given info into given zone structure and activate it // Write given info into given zone structure and activate it
extern void Section_new_zone(struct section *section, const char *type, char *title, int allocated); extern void Section_new_zone(struct section *section, const char *type, char *title, int allocated);
// register pseudo opcodes
extern void Section_init(void);
// Setup outermost section // Setup outermost section
extern void Section_passinit(void); extern void Section_passinit(void);
// Tidy up: If necessary, release section title. // Tidy up: If necessary, release section title.