mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-11-25 23:49:25 +00:00
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:
parent
c53505915d
commit
de896f41f2
@ -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
|
||||||
|
37
src/global.c
37
src/global.c
@ -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();
|
||||||
|
16
src/global.h
16
src/global.h
@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user