mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-12-25 08:29:34 +00:00
a bit of internal cleanup of names and comments, no change in functionality
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@92 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
a6daa92e63
commit
47f09e9804
28
src/alu.c
28
src/alu.c
@ -47,8 +47,8 @@ static const char s_arctan[] = "arctan";
|
||||
// operator handles (FIXME - use function pointers instead? or too slow?)
|
||||
enum operator_handle {
|
||||
// special values (pseudo operators)
|
||||
OPHANDLE_END, // "reached end of expression"
|
||||
OPHANDLE_RETURN, // "return value to caller"
|
||||
OPHANDLE_EXPRSTART, // "start of expression"
|
||||
OPHANDLE_EXPREND, // "end of expression"
|
||||
// functions
|
||||
OPHANDLE_ADDR, // addr(v)
|
||||
OPHANDLE_INT, // int(v)
|
||||
@ -96,8 +96,8 @@ struct operator {
|
||||
#define IS_RIGHT_ASSOCIATIVE(p) ((p) & 1) // lsb of priority value signals right-associtivity
|
||||
|
||||
// operator structs (only hold handle and priority/associativity value)
|
||||
static struct operator ops_end = {OPHANDLE_END, 0}; // special
|
||||
static struct operator ops_return = {OPHANDLE_RETURN, 2}; // special
|
||||
static struct operator ops_exprend = {OPHANDLE_EXPREND, 0}; // special
|
||||
static struct operator ops_exprstart = {OPHANDLE_EXPRSTART, 2}; // special
|
||||
static struct operator ops_closing = {OPHANDLE_CLOSING, 4}; // dyadic
|
||||
static struct operator ops_opening = {OPHANDLE_OPENING, 6}; // monadic
|
||||
static struct operator ops_or = {OPHANDLE_OR, 8}; // dyadic
|
||||
@ -749,10 +749,12 @@ static void expect_operand_or_monadic_operator(void)
|
||||
}
|
||||
} else {
|
||||
// illegal character read - so don't go on
|
||||
// we found end-of-expression instead of an operand,
|
||||
// that's either an empty expression or an erroneous one!
|
||||
PUSH_INTOPERAND(0, 0, 0); // push dummy operand so stack is ok
|
||||
// push pseudo value, EXISTS flag is clear
|
||||
if (operator_stack[operator_sp - 1] == &ops_return) {
|
||||
PUSH_OPERATOR(&ops_end);
|
||||
if (operator_stack[operator_sp - 1] == &ops_exprstart) {
|
||||
PUSH_OPERATOR(&ops_exprend);
|
||||
alu_state = STATE_TRY_TO_REDUCE_STACKS;
|
||||
} else {
|
||||
Throw_error(exception_syntax);
|
||||
@ -905,7 +907,8 @@ static void expect_dyadic_operator(void)
|
||||
Throw_error("Unknown operator.");
|
||||
alu_state = STATE_ERROR;
|
||||
} else {
|
||||
operator = &ops_end;
|
||||
// we found end-of-expression when expecting an operator, that's ok.
|
||||
operator = &ops_exprend;
|
||||
goto push_dyadic;
|
||||
}
|
||||
|
||||
@ -999,6 +1002,7 @@ static void ensure_int_from_fp(void)
|
||||
|
||||
|
||||
// Try to reduce stacks by performing high-priority operations
|
||||
// (if the previous operator has a higher priority than the current one, do it)
|
||||
static void try_to_reduce_stacks(int *open_parentheses)
|
||||
{
|
||||
if (operator_sp < 2) {
|
||||
@ -1019,9 +1023,13 @@ static void try_to_reduce_stacks(int *open_parentheses)
|
||||
return;
|
||||
}
|
||||
|
||||
// process previous operator
|
||||
switch (operator_stack[operator_sp - 2]->handle) {
|
||||
// special (pseudo) operators
|
||||
case OPHANDLE_RETURN:
|
||||
case OPHANDLE_EXPRSTART:
|
||||
// the only operator with a lower priority than this
|
||||
// "start-of-expression" operator is "end-of-expression",
|
||||
// therefore we know we are done.
|
||||
// don't touch indirect_flag; needed for INDIRECT flag
|
||||
--operator_sp; // decrement operator stack pointer
|
||||
alu_state = STATE_END;
|
||||
@ -1033,7 +1041,7 @@ static void try_to_reduce_stacks(int *open_parentheses)
|
||||
operator_sp -= 2; // remove both of them
|
||||
alu_state = STATE_EXPECT_DYADIC_OPERATOR;
|
||||
break;
|
||||
case OPHANDLE_END: // unmatched parenthesis
|
||||
case OPHANDLE_EXPREND: // unmatched parenthesis
|
||||
++(*open_parentheses); // count
|
||||
goto RNTLObutDontTouchIndirectFlag;
|
||||
|
||||
@ -1399,7 +1407,7 @@ static int parse_expression(struct result *result)
|
||||
// begin by reading value (or monadic operator)
|
||||
alu_state = STATE_EXPECT_OPERAND_OR_MONADIC_OPERATOR;
|
||||
indirect_flag = 0; // Contains either 0 or MVALUE_INDIRECT
|
||||
PUSH_OPERATOR(&ops_return);
|
||||
PUSH_OPERATOR(&ops_exprstart);
|
||||
do {
|
||||
// check stack sizes. enlarge if needed
|
||||
if (operator_sp >= operator_stk_size)
|
||||
|
@ -47,6 +47,7 @@ const char s_scr[] = "scr";
|
||||
// Exception messages during assembly
|
||||
const char exception_cannot_open_input_file[] = "Cannot open input file.";
|
||||
const char exception_missing_string[] = "No string given.";
|
||||
const char exception_negative_size[] = "Negative size argument.";
|
||||
const char exception_no_left_brace[] = "Missing '{'.";
|
||||
const char exception_no_memory_left[] = "Out of memory.";
|
||||
const char exception_no_right_brace[] = "Found end-of-file instead of '}'.";
|
||||
|
@ -41,6 +41,7 @@ extern const char s_scr[];
|
||||
// error messages during assembly
|
||||
extern const char exception_cannot_open_input_file[];
|
||||
extern const char exception_missing_string[];
|
||||
extern const char exception_negative_size[];
|
||||
extern const char exception_no_left_brace[];
|
||||
extern const char exception_no_memory_left[];
|
||||
extern const char exception_no_right_brace[];
|
||||
|
@ -139,7 +139,7 @@ SCS jump_lind[] = { 0, 0, 0xdc00, 0, 0, 0, 0xdc0
|
||||
|
||||
// error message strings
|
||||
static const char exception_illegal_combination[] = "Illegal combination of command and addressing mode.";
|
||||
static const char exception_highbyte_zero[] = "Using oversized addressing mode.";
|
||||
static const char exception_oversized_addrmode[] = "Using oversized addressing mode.";
|
||||
|
||||
|
||||
// Variables
|
||||
@ -584,11 +584,11 @@ static int check_oversize(int size_bit, struct result *argument)
|
||||
if (size_bit == MVALUE_FORCE16) {
|
||||
// check 16-bit argument for high byte zero
|
||||
if ((argument->val.intval <= 255) && (argument->val.intval >= -128))
|
||||
Throw_warning(exception_highbyte_zero);
|
||||
Throw_warning(exception_oversized_addrmode);
|
||||
} else {
|
||||
// check 24-bit argument for bank byte zero
|
||||
if ((argument->val.intval <= 65535) && (argument->val.intval >= -32768))
|
||||
Throw_warning(exception_highbyte_zero);
|
||||
Throw_warning(exception_oversized_addrmode);
|
||||
}
|
||||
return size_bit; // pass on result
|
||||
}
|
||||
|
13
src/output.c
13
src/output.c
@ -157,13 +157,16 @@ static void no_output(intval_t byte)
|
||||
}
|
||||
|
||||
|
||||
// call this if really calling Output_byte would be a waste of time
|
||||
// FIXME - check all users of this, because future changes
|
||||
// ("several-projects-at-once") may be incompatible with this!
|
||||
void Output_fake(int size)
|
||||
// skip over some bytes in output buffer without starting a new segment
|
||||
// (used by "!skip", and also called by "!binary" if really calling
|
||||
// Output_byte would be a waste of time)
|
||||
void output_skip(int size)
|
||||
{
|
||||
if (size < 1)
|
||||
if (size < 1) {
|
||||
// FIXME - ok for zero, but why is there no error message
|
||||
// output for negative values?
|
||||
return;
|
||||
}
|
||||
|
||||
// check whether ptr undefined
|
||||
if (Output_byte == no_output) {
|
||||
|
13
src/output.h
13
src/output.h
@ -39,10 +39,16 @@ extern struct vcpu CPU_state; // current CPU state FIXME - restrict visibility t
|
||||
extern void Output_init(signed long fill_value);
|
||||
// clear segment list and disable output
|
||||
extern void Output_passinit(void);
|
||||
// call this if really calling Output_byte would be a waste of time
|
||||
extern void Output_fake(int size);
|
||||
// skip over some bytes in output buffer without starting a new segment
|
||||
// (used by "!skip", and also called by "!binary" if really calling
|
||||
// Output_byte would be a waste of time)
|
||||
extern void output_skip(int size);
|
||||
// Send low byte of arg to output buffer and advance pointer
|
||||
// FIXME - replace by output_sequence(char *src, size_t size)
|
||||
extern void (*Output_byte)(intval_t);
|
||||
// define default value for empty memory ("!initmem" pseudo opcode)
|
||||
// returns zero if ok, nonzero if already set
|
||||
extern int output_initmem(char content);
|
||||
// Output 8-bit value with range check
|
||||
extern void output_8(intval_t);
|
||||
// Output 16-bit value with range check big-endian
|
||||
@ -57,9 +63,6 @@ extern void output_le24(intval_t);
|
||||
extern void output_be32(intval_t);
|
||||
// Output 32-bit value (without range check) little-endian
|
||||
extern void output_le32(intval_t);
|
||||
// define default value for empty memory ("!initmem" pseudo opcode)
|
||||
// returns zero if ok, nonzero if already set
|
||||
extern int output_initmem(char content);
|
||||
// try to set output format held in DynaBuf. Returns zero on success.
|
||||
extern int outputfile_set_format(void);
|
||||
extern const char outputfile_formats[]; // string to show if outputfile_set_format() returns nonzero
|
||||
|
@ -201,6 +201,59 @@ static enum eos po_le32(void)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// Insert bytes given as pairs of hex digits (helper for source code generators)
|
||||
static enum eos po_hex(void) // now GotByte = illegal char
|
||||
{
|
||||
int digits = 0;
|
||||
unsigned char byte = 0;
|
||||
|
||||
for (;;) {
|
||||
if (digits == 2) {
|
||||
Output_byte(byte);
|
||||
digits = 0;
|
||||
byte = 0;
|
||||
}
|
||||
if (GotByte >= '0' && GotByte <= '9') {
|
||||
byte = (byte << 4) | (GotByte - '0');
|
||||
++digits;
|
||||
GetByte();
|
||||
continue;
|
||||
}
|
||||
if (GotByte >= 'a' && GotByte <= 'f') {
|
||||
byte = (byte << 4) | (GotByte - 'a' + 10);
|
||||
++digits;
|
||||
GetByte();
|
||||
continue;
|
||||
}
|
||||
if (GotByte >= 'A' && GotByte <= 'F') {
|
||||
byte = (byte << 4) | (GotByte - 'A' + 10);
|
||||
++digits;
|
||||
GetByte();
|
||||
continue;
|
||||
}
|
||||
// if we're here, the current character is not a hex digit,
|
||||
// which ist only allowed outside of pairs:
|
||||
if (digits == 1) {
|
||||
Throw_error("Hex digits are not given in pairs");
|
||||
return SKIP_REMAINDER; // error exit
|
||||
}
|
||||
switch (GotByte) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
GetByte(); // spaces and tabs are ignored (maybe add commas, too?)
|
||||
continue;
|
||||
case CHAR_EOS:
|
||||
return AT_EOS_ANYWAY; // normal exit
|
||||
default:
|
||||
Throw_error(exception_syntax); // all other characters are errors
|
||||
return SKIP_REMAINDER; // error exit
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// "!cbm" pseudo opcode (now obsolete)
|
||||
static enum eos obsolete_po_cbm(void)
|
||||
{
|
||||
@ -349,13 +402,15 @@ static enum eos po_binary(void)
|
||||
if (Input_accept_comma()) {
|
||||
if (ALU_optional_defined_int(&size)
|
||||
&& (size < 0))
|
||||
Throw_serious_error("Negative size argument.");
|
||||
Throw_serious_error(exception_negative_size);
|
||||
if (Input_accept_comma())
|
||||
ALU_optional_defined_int(&skip); // read skip
|
||||
}
|
||||
// check whether including is a waste of time
|
||||
// FIXME - future changes ("several-projects-at-once")
|
||||
// may be incompatible with this!
|
||||
if ((size >= 0) && (pass_undefined_count || pass_real_errors)) {
|
||||
Output_fake(size); // really including is useless anyway
|
||||
output_skip(size); // really including is useless anyway
|
||||
} else {
|
||||
// really insert file
|
||||
fseek(fd, skip, SEEK_SET); // set read pointer
|
||||
@ -403,6 +458,24 @@ static enum eos po_fill(void)
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// skip over some bytes in output without starting a new segment ("!skip" pseudo opcode)
|
||||
// in contrast to "*=*+AMOUNT", "!skip AMOUNT" does not start a new segment.
|
||||
// (...and it will be needed in future for assemble-to-end-address)
|
||||
static enum eos po_skip(void) // now GotByte = illegal char
|
||||
{
|
||||
struct result amount;
|
||||
|
||||
ALU_defined_int(&amount); // FIXME - forbid addresses!
|
||||
if (amount.val.intval < 0)
|
||||
Throw_serious_error(exception_negative_size);
|
||||
else
|
||||
output_skip(amount.val.intval);
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// insert byte until PC fits condition
|
||||
static enum eos po_align(void)
|
||||
{
|
||||
@ -538,6 +611,19 @@ static enum eos po_address(void) // now GotByte = illegal char
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// enumerate constants
|
||||
static enum eos po_enum(void) // now GotByte = illegal char
|
||||
{
|
||||
intval_t step = 1;
|
||||
|
||||
ALU_optional_defined_int(&step);
|
||||
Throw_serious_error("Not yet"); // FIXME
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// (re)set symbol
|
||||
static enum eos po_set(void) // now GotByte = illegal char
|
||||
{
|
||||
@ -600,13 +686,6 @@ static enum eos po_symbollist(void)
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO - add "!skip AMOUNT" pseudo opcode as alternative to "* = * + AMOUNT" (needed for assemble-to-end-address)
|
||||
// the new pseudo opcode would skip the given amount of bytes without starting a new segment
|
||||
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)
|
||||
@ -847,6 +926,16 @@ static enum eos po_do(void) // now GotByte = illegal char
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// looping assembly (alternative for people used to c-style loops)
|
||||
static enum eos po_while(void) // now GotByte = illegal char
|
||||
{
|
||||
Throw_serious_error("Not yet"); // FIXME
|
||||
return ENSURE_EOS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// macro definition ("!macro").
|
||||
static enum eos po_macro(void) // now GotByte = illegal char
|
||||
{
|
||||
@ -1014,7 +1103,6 @@ static struct ronode pseudo_opcode_list[] = {
|
||||
PREDEFNODE("set", po_set),
|
||||
PREDEFNODE(s_sl, po_symbollist),
|
||||
PREDEFNODE("symbollist", po_symbollist),
|
||||
// PREDEFNODE("skip", po_skip),
|
||||
PREDEFNODE("zn", po_zone),
|
||||
PREDEFNODE(s_zone, po_zone),
|
||||
PREDEFNODE("sz", obsolete_po_subzone),
|
||||
|
@ -53,10 +53,10 @@ static void dump_one_symbol(struct rwnode *node, FILE *fd)
|
||||
else
|
||||
fprintf(fd, "$%x", (unsigned) symbol->result.val.intval);
|
||||
} else {
|
||||
fprintf(fd, " ?");
|
||||
fprintf(fd, " ?"); // TODO - maybe write "UNDEFINED" instead? then the file could at least be parsed without errors
|
||||
}
|
||||
if (symbol->result.flags & MVALUE_UNSURE)
|
||||
fprintf(fd, "\t; ?");
|
||||
fprintf(fd, "\t; ?"); // TODO - write "forward" instead?
|
||||
if (symbol->usage == 0)
|
||||
fprintf(fd, "\t; unused");
|
||||
fprintf(fd, "\n");
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#define RELEASE "0.96.2" // update before release (FIXME)
|
||||
#define CODENAME "Fenchurch" // update before release
|
||||
#define CHANGE_DATE "10 Mar" // update before release
|
||||
#define CHANGE_DATE "21 Oct" // update before release
|
||||
#define CHANGE_YEAR "2017" // update before release
|
||||
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" // FIXME
|
||||
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME
|
||||
|
Loading…
Reference in New Issue
Block a user