mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-02-19 09:31:42 +00:00
cleanup (moved functions between files; no change in functionality!)
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@245 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
beb875ff2b
commit
5b37c4d24e
290
src/alu.c
290
src/alu.c
@ -693,11 +693,6 @@ static void list_append_list(struct listitem *selfhead, struct listitem *otherhe
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// expression parser
|
|
||||||
|
|
||||||
// prototype (FIXME, re-arrange code so this is no longer needed!)
|
|
||||||
static void push_dyadic_and_check(struct expression *expression, struct op *op);
|
|
||||||
|
|
||||||
// helper function for "monadic &" (either octal value or "unpseudo" operator)
|
// helper function for "monadic &" (either octal value or "unpseudo" operator)
|
||||||
// returns nonzero on error
|
// returns nonzero on error
|
||||||
static int parse_octal_or_unpseudo(void) // now GotByte = '&'
|
static int parse_octal_or_unpseudo(void) // now GotByte = '&'
|
||||||
@ -736,6 +731,150 @@ static int parse_octal_or_unpseudo(void) // now GotByte = '&'
|
|||||||
return 0; // ok
|
return 0; // ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// expression parser
|
||||||
|
|
||||||
|
|
||||||
|
// handler for special operators like parentheses and start/end of expression:
|
||||||
|
// returns whether caller can remove "previous" operator from stack
|
||||||
|
static boolean handle_special_operator(struct expression *expression, enum op_id previous)
|
||||||
|
{
|
||||||
|
// when this gets called, "current" operator is OPID_TERMINATOR
|
||||||
|
switch (previous) {
|
||||||
|
case OPID_START_EXPRESSION:
|
||||||
|
// therefore we know we are done.
|
||||||
|
// don't touch "is_parenthesized", because start/end are obviously not "real" operators
|
||||||
|
alu_state = STATE_END; // done
|
||||||
|
return TRUE; // caller can remove this operator (we are done, so not really needed, but there are sanity checks for stack pointers)
|
||||||
|
|
||||||
|
case OPID_SUBEXPR_PAREN:
|
||||||
|
expression->is_parenthesized = TRUE; // found parentheses. if this is not the outermost level, the outermost level will fix this flag later on.
|
||||||
|
if (GotByte == ')') {
|
||||||
|
// matching parenthesis
|
||||||
|
GetByte(); // eat char
|
||||||
|
op_sp -= 2; // remove both SUBEXPR_PAREN and TERMINATOR
|
||||||
|
alu_state = STATE_EXPECT_DYADIC_OP;
|
||||||
|
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
||||||
|
}
|
||||||
|
// unmatched parenthesis, as in "lda ($80,x)"
|
||||||
|
++(expression->open_parentheses); // count
|
||||||
|
return TRUE; // caller can remove "SUBEXPR_PAREN" operator from stack
|
||||||
|
|
||||||
|
case OPID_START_LIST:
|
||||||
|
if (GotByte == ',') {
|
||||||
|
GetByte(); // eat ','
|
||||||
|
op_stack[op_sp - 1] = &ops_list_append; // change "end of expression" to "append"
|
||||||
|
alu_state = STATE_EXPECT_ARG_OR_MONADIC_OP;
|
||||||
|
return FALSE; // stack remains, so caller shouldn't touch it
|
||||||
|
}
|
||||||
|
if (GotByte == ']') {
|
||||||
|
GetByte(); // eat ']'
|
||||||
|
op_sp -= 2; // remove both START_LIST and TERMINATOR
|
||||||
|
alu_state = STATE_EXPECT_DYADIC_OP;
|
||||||
|
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
||||||
|
}
|
||||||
|
Throw_error("Unterminated list.");
|
||||||
|
alu_state = STATE_ERROR;
|
||||||
|
return TRUE; // caller can remove START_LIST operator from stack
|
||||||
|
|
||||||
|
case OPID_SUBEXPR_BRACKET:
|
||||||
|
if (GotByte == ']') {
|
||||||
|
GetByte(); // eat ']'
|
||||||
|
op_sp -= 2; // remove both SUBEXPR_BRACKET and TERMINATOR
|
||||||
|
alu_state = STATE_EXPECT_DYADIC_OP;
|
||||||
|
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
||||||
|
}
|
||||||
|
Throw_error("Unterminated index spec.");
|
||||||
|
alu_state = STATE_ERROR;
|
||||||
|
return TRUE; // caller can remove SUBEXPR_BRACKET operator from stack
|
||||||
|
|
||||||
|
default:
|
||||||
|
Bug_found("IllegalOperatorId", previous);
|
||||||
|
}
|
||||||
|
// this is unreachable
|
||||||
|
return FALSE; // stack is done, so caller shouldn't touch it
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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 push_dyadic_and_check(struct expression *expression, struct op *op)
|
||||||
|
{
|
||||||
|
struct op *previous_op;
|
||||||
|
struct op *current_op;
|
||||||
|
|
||||||
|
PUSH_OP(op);
|
||||||
|
if (alu_state < STATE_MAX_GO_ON)
|
||||||
|
alu_state = STATE_TRY_TO_REDUCE_STACKS;
|
||||||
|
while (alu_state == STATE_TRY_TO_REDUCE_STACKS) {
|
||||||
|
if (op_sp < 2) {
|
||||||
|
// we only have one operator, which must be "start of expression",
|
||||||
|
// so there isn't anything left to do, so go on trying to parse the expression
|
||||||
|
alu_state = STATE_EXPECT_ARG_OR_MONADIC_OP;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
previous_op = op_stack[op_sp - 2];
|
||||||
|
current_op = op_stack[op_sp - 1];
|
||||||
|
|
||||||
|
// previous operator has lower piority than current one? then do nothing.
|
||||||
|
if (previous_op->priority < current_op->priority) {
|
||||||
|
alu_state = STATE_EXPECT_ARG_OR_MONADIC_OP;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// previous operator has same priority as current one? then check associativity
|
||||||
|
if ((previous_op->priority == current_op->priority)
|
||||||
|
&& (current_op->priority == PRIO_POWEROF)
|
||||||
|
&& (config.wanted_version >= VER_RIGHTASSOCIATIVEPOWEROF)) {
|
||||||
|
alu_state = STATE_EXPECT_ARG_OR_MONADIC_OP;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we now know that either
|
||||||
|
// - the previous operator has higher priority, or
|
||||||
|
// - it has the same priority and is left-associative,
|
||||||
|
// so perform that operation!
|
||||||
|
#define ARG_PREV (arg_stack[arg_sp - 2])
|
||||||
|
#define ARG_NOW (arg_stack[arg_sp - 1])
|
||||||
|
switch (previous_op->group) {
|
||||||
|
case OPGROUP_MONADIC: // monadic operators
|
||||||
|
if (arg_sp < 1)
|
||||||
|
Bug_found("ArgStackEmpty", arg_sp);
|
||||||
|
ARG_NOW.type->monadic_op(&ARG_NOW, previous_op);
|
||||||
|
// operation was something other than parentheses
|
||||||
|
expression->is_parenthesized = FALSE;
|
||||||
|
break;
|
||||||
|
case OPGROUP_DYADIC: // dyadic operators
|
||||||
|
if (arg_sp < 2)
|
||||||
|
Bug_found("NotEnoughArgs", arg_sp);
|
||||||
|
ARG_PREV.type->dyadic_op(&ARG_PREV, previous_op, &ARG_NOW);
|
||||||
|
// decrement argument stack pointer because dyadic operator merged two arguments into one
|
||||||
|
--arg_sp;
|
||||||
|
// operation was something other than parentheses
|
||||||
|
expression->is_parenthesized = FALSE;
|
||||||
|
break;
|
||||||
|
case OPGROUP_SPECIAL: // special (pseudo) operators
|
||||||
|
if (current_op->id != OPID_TERMINATOR)
|
||||||
|
Bug_found("StrangeOperator", current_op->id);
|
||||||
|
if (!handle_special_operator(expression, previous_op->id))
|
||||||
|
continue; // called fn has fixed the stack, so we don't touch it
|
||||||
|
|
||||||
|
// both monadics and dyadics clear "is_parenthesized", but here we don't touch it!
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Bug_found("IllegalOperatorGroup", previous_op->group);
|
||||||
|
}
|
||||||
|
// shared endings for "we did the operation indicated by previous operator":
|
||||||
|
// fix stack:
|
||||||
|
// remove previous operator and shift down current one
|
||||||
|
// CAUTION - fiddling with our local copies like "previous_op = current_op" is not enough... ;)
|
||||||
|
op_stack[op_sp - 2] = op_stack[op_sp - 1];
|
||||||
|
--op_sp; // decrement operator stack pointer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Expect argument or monadic operator (hopefully inlined)
|
// Expect argument or monadic operator (hopefully inlined)
|
||||||
// returns TRUE if it ate any non-space (-> so expression isn't empty)
|
// returns TRUE if it ate any non-space (-> so expression isn't empty)
|
||||||
// returns FALSE if first non-space is delimiter (-> end of expression)
|
// returns FALSE if first non-space is delimiter (-> end of expression)
|
||||||
@ -2144,6 +2283,7 @@ static void string_print(const struct object *self, struct dynabuf *db)
|
|||||||
DynaBuf_add_string(db, self->u.string->payload); // there is a terminator after the actual payload, so this works
|
DynaBuf_add_string(db, self->u.string->payload); // there is a terminator after the actual payload, so this works
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "class" definitions
|
||||||
struct type type_number = {
|
struct type type_number = {
|
||||||
"number",
|
"number",
|
||||||
number_is_defined,
|
number_is_defined,
|
||||||
@ -2176,146 +2316,6 @@ struct type type_string = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// handler for special operators like parentheses and start/end of expression:
|
|
||||||
// returns whether caller can remove "previous" operator from stack
|
|
||||||
static boolean handle_special_operator(struct expression *expression, enum op_id previous)
|
|
||||||
{
|
|
||||||
// when this gets called, "current" operator is OPID_TERMINATOR
|
|
||||||
switch (previous) {
|
|
||||||
case OPID_START_EXPRESSION:
|
|
||||||
// therefore we know we are done.
|
|
||||||
// don't touch "is_parenthesized", because start/end are obviously not "real" operators
|
|
||||||
alu_state = STATE_END; // done
|
|
||||||
return TRUE; // caller can remove this operator (we are done, so not really needed, but there are sanity checks for stack pointers)
|
|
||||||
|
|
||||||
case OPID_SUBEXPR_PAREN:
|
|
||||||
expression->is_parenthesized = TRUE; // found parentheses. if this is not the outermost level, the outermost level will fix this flag later on.
|
|
||||||
if (GotByte == ')') {
|
|
||||||
// matching parenthesis
|
|
||||||
GetByte(); // eat char
|
|
||||||
op_sp -= 2; // remove both SUBEXPR_PAREN and TERMINATOR
|
|
||||||
alu_state = STATE_EXPECT_DYADIC_OP;
|
|
||||||
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
|
||||||
}
|
|
||||||
// unmatched parenthesis, as in "lda ($80,x)"
|
|
||||||
++(expression->open_parentheses); // count
|
|
||||||
return TRUE; // caller can remove "SUBEXPR_PAREN" operator from stack
|
|
||||||
|
|
||||||
case OPID_START_LIST:
|
|
||||||
if (GotByte == ',') {
|
|
||||||
GetByte(); // eat ','
|
|
||||||
op_stack[op_sp - 1] = &ops_list_append; // change "end of expression" to "append"
|
|
||||||
alu_state = STATE_EXPECT_ARG_OR_MONADIC_OP;
|
|
||||||
return FALSE; // stack remains, so caller shouldn't touch it
|
|
||||||
}
|
|
||||||
if (GotByte == ']') {
|
|
||||||
GetByte(); // eat ']'
|
|
||||||
op_sp -= 2; // remove both START_LIST and TERMINATOR
|
|
||||||
alu_state = STATE_EXPECT_DYADIC_OP;
|
|
||||||
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
|
||||||
}
|
|
||||||
Throw_error("Unterminated list.");
|
|
||||||
alu_state = STATE_ERROR;
|
|
||||||
return TRUE; // caller can remove START_LIST operator from stack
|
|
||||||
|
|
||||||
case OPID_SUBEXPR_BRACKET:
|
|
||||||
if (GotByte == ']') {
|
|
||||||
GetByte(); // eat ']'
|
|
||||||
op_sp -= 2; // remove both SUBEXPR_BRACKET and TERMINATOR
|
|
||||||
alu_state = STATE_EXPECT_DYADIC_OP;
|
|
||||||
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
|
||||||
}
|
|
||||||
Throw_error("Unterminated index spec.");
|
|
||||||
alu_state = STATE_ERROR;
|
|
||||||
return TRUE; // caller can remove SUBEXPR_BRACKET operator from stack
|
|
||||||
|
|
||||||
default:
|
|
||||||
Bug_found("IllegalOperatorId", previous);
|
|
||||||
}
|
|
||||||
// this is unreachable
|
|
||||||
return FALSE; // stack is done, so caller shouldn't touch it
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 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 push_dyadic_and_check(struct expression *expression, struct op *op)
|
|
||||||
{
|
|
||||||
struct op *previous_op;
|
|
||||||
struct op *current_op;
|
|
||||||
|
|
||||||
PUSH_OP(op);
|
|
||||||
if (alu_state < STATE_MAX_GO_ON)
|
|
||||||
alu_state = STATE_TRY_TO_REDUCE_STACKS;
|
|
||||||
while (alu_state == STATE_TRY_TO_REDUCE_STACKS) {
|
|
||||||
if (op_sp < 2) {
|
|
||||||
// we only have one operator, which must be "start of expression",
|
|
||||||
// so there isn't anything left to do, so go on trying to parse the expression
|
|
||||||
alu_state = STATE_EXPECT_ARG_OR_MONADIC_OP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
previous_op = op_stack[op_sp - 2];
|
|
||||||
current_op = op_stack[op_sp - 1];
|
|
||||||
|
|
||||||
// previous operator has lower piority than current one? then do nothing.
|
|
||||||
if (previous_op->priority < current_op->priority) {
|
|
||||||
alu_state = STATE_EXPECT_ARG_OR_MONADIC_OP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// previous operator has same priority as current one? then check associativity
|
|
||||||
if ((previous_op->priority == current_op->priority)
|
|
||||||
&& (current_op->priority == PRIO_POWEROF)
|
|
||||||
&& (config.wanted_version >= VER_RIGHTASSOCIATIVEPOWEROF)) {
|
|
||||||
alu_state = STATE_EXPECT_ARG_OR_MONADIC_OP;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we now know that either
|
|
||||||
// - the previous operator has higher priority, or
|
|
||||||
// - it has the same priority and is left-associative,
|
|
||||||
// so perform that operation!
|
|
||||||
#define ARG_PREV (arg_stack[arg_sp - 2])
|
|
||||||
#define ARG_NOW (arg_stack[arg_sp - 1])
|
|
||||||
switch (previous_op->group) {
|
|
||||||
case OPGROUP_MONADIC: // monadic operators
|
|
||||||
if (arg_sp < 1)
|
|
||||||
Bug_found("ArgStackEmpty", arg_sp);
|
|
||||||
ARG_NOW.type->monadic_op(&ARG_NOW, previous_op);
|
|
||||||
// operation was something other than parentheses
|
|
||||||
expression->is_parenthesized = FALSE;
|
|
||||||
break;
|
|
||||||
case OPGROUP_DYADIC: // dyadic operators
|
|
||||||
if (arg_sp < 2)
|
|
||||||
Bug_found("NotEnoughArgs", arg_sp);
|
|
||||||
ARG_PREV.type->dyadic_op(&ARG_PREV, previous_op, &ARG_NOW);
|
|
||||||
// decrement argument stack pointer because dyadic operator merged two arguments into one
|
|
||||||
--arg_sp;
|
|
||||||
// operation was something other than parentheses
|
|
||||||
expression->is_parenthesized = FALSE;
|
|
||||||
break;
|
|
||||||
case OPGROUP_SPECIAL: // special (pseudo) operators
|
|
||||||
if (current_op->id != OPID_TERMINATOR)
|
|
||||||
Bug_found("StrangeOperator", current_op->id);
|
|
||||||
if (!handle_special_operator(expression, previous_op->id))
|
|
||||||
continue; // called fn has fixed the stack, so we don't touch it
|
|
||||||
|
|
||||||
// both monadics and dyadics clear "is_parenthesized", but here we don't touch it!
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Bug_found("IllegalOperatorGroup", previous_op->group);
|
|
||||||
}
|
|
||||||
// shared endings for "we did the operation indicated by previous operator":
|
|
||||||
// fix stack:
|
|
||||||
// remove previous operator and shift down current one
|
|
||||||
// CAUTION - fiddling with our local copies like "previous_op = current_op" is not enough... ;)
|
|
||||||
op_stack[op_sp - 2] = op_stack[op_sp - 1];
|
|
||||||
--op_sp; // decrement operator stack pointer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// this is what the exported functions call
|
// this is what the exported functions call
|
||||||
// returns nonzero on parse error
|
// returns nonzero on parse error
|
||||||
static int parse_expression(struct expression *expression)
|
static int parse_expression(struct expression *expression)
|
||||||
|
27
src/flow.c
27
src/flow.c
@ -24,7 +24,32 @@
|
|||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
|
||||||
|
|
||||||
// helper functions for "!for" and "!do"
|
// helper functions for if/ifdef/ifndef/else/for/do/while
|
||||||
|
|
||||||
|
|
||||||
|
// parse symbol name and return if symbol has defined value (called by ifdef/ifndef)
|
||||||
|
boolean check_ifdef_condition(void)
|
||||||
|
{
|
||||||
|
scope_t scope;
|
||||||
|
struct rwnode *node;
|
||||||
|
struct symbol *symbol;
|
||||||
|
|
||||||
|
// read symbol name
|
||||||
|
if (Input_read_scope_and_keyword(&scope) == 0) // skips spaces before
|
||||||
|
return FALSE; // there was an error, it has been reported, so return value is more or less meaningless anway
|
||||||
|
|
||||||
|
// look for it
|
||||||
|
Tree_hard_scan(&node, symbols_forest, scope, FALSE);
|
||||||
|
if (!node)
|
||||||
|
return FALSE; // not found -> no, not defined
|
||||||
|
|
||||||
|
symbol = (struct symbol *) node->body;
|
||||||
|
symbol->has_been_read = TRUE; // we did not really read the symbol's value, but checking for its existence still counts as "used it"
|
||||||
|
if (symbol->object.type == NULL)
|
||||||
|
Bug_found("ObjectHasNullType", 0); // FIXME - add to docs!
|
||||||
|
return symbol->object.type->is_defined(&symbol->object);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// parse a loop body (TODO - also use for macro body?)
|
// parse a loop body (TODO - also use for macro body?)
|
||||||
static void parse_ram_block(struct block *block)
|
static void parse_ram_block(struct block *block)
|
||||||
|
@ -43,6 +43,8 @@ struct do_while {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// parse symbol name and return if symbol has defined value (called by ifdef/ifndef)
|
||||||
|
extern boolean check_ifdef_condition(void);
|
||||||
// back end function for "!for" pseudo opcode
|
// back end function for "!for" pseudo opcode
|
||||||
extern void flow_forloop(struct for_loop *loop);
|
extern void flow_forloop(struct for_loop *loop);
|
||||||
// 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
|
||||||
|
88
src/global.c
88
src/global.c
@ -513,3 +513,91 @@ void output_object(struct object *object, struct iter_context *iter)
|
|||||||
Bug_found("IllegalObjectType9", 0); // FIXME - add to docs!
|
Bug_found("IllegalObjectType9", 0); // FIXME - add to docs!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// output 8-bit value with range check
|
||||||
|
void output_8(intval_t value)
|
||||||
|
{
|
||||||
|
if ((value <= 0xff) && (value >= -0x80))
|
||||||
|
Output_byte(value);
|
||||||
|
else
|
||||||
|
Throw_error(exception_number_out_of_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// output 16-bit value with range check big-endian
|
||||||
|
void output_be16(intval_t value)
|
||||||
|
{
|
||||||
|
if ((value <= 0xffff) && (value >= -0x8000)) {
|
||||||
|
Output_byte(value >> 8);
|
||||||
|
Output_byte(value);
|
||||||
|
} else {
|
||||||
|
Throw_error(exception_number_out_of_range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// output 16-bit value with range check little-endian
|
||||||
|
void output_le16(intval_t value)
|
||||||
|
{
|
||||||
|
if ((value <= 0xffff) && (value >= -0x8000)) {
|
||||||
|
Output_byte(value);
|
||||||
|
Output_byte(value >> 8);
|
||||||
|
} else {
|
||||||
|
Throw_error(exception_number_out_of_range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// output 24-bit value with range check big-endian
|
||||||
|
void output_be24(intval_t value)
|
||||||
|
{
|
||||||
|
if ((value <= 0xffffff) && (value >= -0x800000)) {
|
||||||
|
Output_byte(value >> 16);
|
||||||
|
Output_byte(value >> 8);
|
||||||
|
Output_byte(value);
|
||||||
|
} else {
|
||||||
|
Throw_error(exception_number_out_of_range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// output 24-bit value with range check little-endian
|
||||||
|
void output_le24(intval_t value)
|
||||||
|
{
|
||||||
|
if ((value <= 0xffffff) && (value >= -0x800000)) {
|
||||||
|
Output_byte(value);
|
||||||
|
Output_byte(value >> 8);
|
||||||
|
Output_byte(value >> 16);
|
||||||
|
} else {
|
||||||
|
Throw_error(exception_number_out_of_range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// output 32-bit value (without range check) big-endian
|
||||||
|
void output_be32(intval_t value)
|
||||||
|
{
|
||||||
|
// if ((Value <= 0x7fffffff) && (Value >= -0x80000000)) {
|
||||||
|
Output_byte(value >> 24);
|
||||||
|
Output_byte(value >> 16);
|
||||||
|
Output_byte(value >> 8);
|
||||||
|
Output_byte(value);
|
||||||
|
// } else {
|
||||||
|
// Throw_error(exception_number_out_of_range);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// output 32-bit value (without range check) little-endian
|
||||||
|
void output_le32(intval_t value)
|
||||||
|
{
|
||||||
|
// if ((Value <= 0x7fffffff) && (Value >= -0x80000000)) {
|
||||||
|
Output_byte(value);
|
||||||
|
Output_byte(value >> 8);
|
||||||
|
Output_byte(value >> 16);
|
||||||
|
Output_byte(value >> 24);
|
||||||
|
// } else {
|
||||||
|
// Throw_error(exception_number_out_of_range);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
15
src/global.h
15
src/global.h
@ -175,6 +175,21 @@ struct iter_context {
|
|||||||
char stringxor; // for !scrxor, 0 otherwise
|
char stringxor; // for !scrxor, 0 otherwise
|
||||||
};
|
};
|
||||||
extern void output_object(struct object *object, struct iter_context *iter);
|
extern void output_object(struct object *object, struct iter_context *iter);
|
||||||
|
// output 8-bit value with range check
|
||||||
|
extern void output_8(intval_t value);
|
||||||
|
// output 16-bit value with range check big-endian
|
||||||
|
extern void output_be16(intval_t value);
|
||||||
|
// output 16-bit value with range check little-endian
|
||||||
|
extern void output_le16(intval_t value);
|
||||||
|
// output 24-bit value with range check big-endian
|
||||||
|
extern void output_be24(intval_t value);
|
||||||
|
// output 24-bit value with range check little-endian
|
||||||
|
extern void output_le24(intval_t value);
|
||||||
|
// output 32-bit value (without range check) big-endian
|
||||||
|
extern void output_be32(intval_t value);
|
||||||
|
// output 32-bit value (without range check) little-endian
|
||||||
|
extern void output_le32(intval_t value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
88
src/output.c
88
src/output.c
@ -197,94 +197,6 @@ void output_skip(int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// output 8-bit value with range check
|
|
||||||
void output_8(intval_t value)
|
|
||||||
{
|
|
||||||
if ((value <= 0xff) && (value >= -0x80))
|
|
||||||
Output_byte(value);
|
|
||||||
else
|
|
||||||
Throw_error(exception_number_out_of_range);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// output 16-bit value with range check big-endian
|
|
||||||
void output_be16(intval_t value)
|
|
||||||
{
|
|
||||||
if ((value <= 0xffff) && (value >= -0x8000)) {
|
|
||||||
Output_byte(value >> 8);
|
|
||||||
Output_byte(value);
|
|
||||||
} else {
|
|
||||||
Throw_error(exception_number_out_of_range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// output 16-bit value with range check little-endian
|
|
||||||
void output_le16(intval_t value)
|
|
||||||
{
|
|
||||||
if ((value <= 0xffff) && (value >= -0x8000)) {
|
|
||||||
Output_byte(value);
|
|
||||||
Output_byte(value >> 8);
|
|
||||||
} else {
|
|
||||||
Throw_error(exception_number_out_of_range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// output 24-bit value with range check big-endian
|
|
||||||
void output_be24(intval_t value)
|
|
||||||
{
|
|
||||||
if ((value <= 0xffffff) && (value >= -0x800000)) {
|
|
||||||
Output_byte(value >> 16);
|
|
||||||
Output_byte(value >> 8);
|
|
||||||
Output_byte(value);
|
|
||||||
} else {
|
|
||||||
Throw_error(exception_number_out_of_range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// output 24-bit value with range check little-endian
|
|
||||||
void output_le24(intval_t value)
|
|
||||||
{
|
|
||||||
if ((value <= 0xffffff) && (value >= -0x800000)) {
|
|
||||||
Output_byte(value);
|
|
||||||
Output_byte(value >> 8);
|
|
||||||
Output_byte(value >> 16);
|
|
||||||
} else {
|
|
||||||
Throw_error(exception_number_out_of_range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// output 32-bit value (without range check) big-endian
|
|
||||||
void output_be32(intval_t value)
|
|
||||||
{
|
|
||||||
// if ((Value <= 0x7fffffff) && (Value >= -0x80000000)) {
|
|
||||||
Output_byte(value >> 24);
|
|
||||||
Output_byte(value >> 16);
|
|
||||||
Output_byte(value >> 8);
|
|
||||||
Output_byte(value);
|
|
||||||
// } else {
|
|
||||||
// Throw_error(exception_number_out_of_range);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// output 32-bit value (without range check) little-endian
|
|
||||||
void output_le32(intval_t value)
|
|
||||||
{
|
|
||||||
// if ((Value <= 0x7fffffff) && (Value >= -0x80000000)) {
|
|
||||||
Output_byte(value);
|
|
||||||
Output_byte(value >> 8);
|
|
||||||
Output_byte(value >> 16);
|
|
||||||
Output_byte(value >> 24);
|
|
||||||
// } else {
|
|
||||||
// Throw_error(exception_number_out_of_range);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// fill output buffer with given byte value
|
// fill output buffer with given byte value
|
||||||
static void fill_completely(char value)
|
static void fill_completely(char value)
|
||||||
{
|
{
|
||||||
|
17
src/output.h
17
src/output.h
@ -54,23 +54,6 @@ extern void (*Output_byte)(intval_t);
|
|||||||
// returns zero if ok, nonzero if already set
|
// returns zero if ok, nonzero if already set
|
||||||
extern int output_initmem(char content);
|
extern int output_initmem(char content);
|
||||||
|
|
||||||
// move elsewhere:
|
|
||||||
|
|
||||||
// Output 8-bit value with range check
|
|
||||||
extern void output_8(intval_t value);
|
|
||||||
// Output 16-bit value with range check big-endian
|
|
||||||
extern void output_be16(intval_t value);
|
|
||||||
// Output 16-bit value with range check little-endian
|
|
||||||
extern void output_le16(intval_t value);
|
|
||||||
// Output 24-bit value with range check big-endian
|
|
||||||
extern void output_be24(intval_t value);
|
|
||||||
// Output 24-bit value with range check little-endian
|
|
||||||
extern void output_le24(intval_t value);
|
|
||||||
// Output 32-bit value (without range check) big-endian
|
|
||||||
extern void output_be32(intval_t value);
|
|
||||||
// Output 32-bit value (without range check) little-endian
|
|
||||||
extern void output_le32(intval_t value);
|
|
||||||
|
|
||||||
// outfile stuff:
|
// outfile stuff:
|
||||||
|
|
||||||
// try to set output format held in DynaBuf. Returns zero on success.
|
// try to set output format held in DynaBuf. Returns zero on success.
|
||||||
|
@ -892,36 +892,14 @@ static enum eos po_source(void) // now GotByte = illegal char
|
|||||||
return ENSURE_EOS;
|
return ENSURE_EOS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - move this to flow.c!
|
// if/ifdef/ifndef/else
|
||||||
static boolean check_ifdef_condition(void)
|
|
||||||
{
|
|
||||||
scope_t scope;
|
|
||||||
struct rwnode *node;
|
|
||||||
struct symbol *symbol;
|
|
||||||
|
|
||||||
// read symbol name
|
|
||||||
if (Input_read_scope_and_keyword(&scope) == 0) // skips spaces before
|
|
||||||
return FALSE; // there was an error, it has been reported, so return value is more or less meaningless anway
|
|
||||||
|
|
||||||
// look for it
|
|
||||||
Tree_hard_scan(&node, symbols_forest, scope, FALSE);
|
|
||||||
if (!node)
|
|
||||||
return FALSE; // not found -> no, not defined
|
|
||||||
|
|
||||||
symbol = (struct symbol *) node->body;
|
|
||||||
symbol->has_been_read = TRUE; // we did not really read the symbol's value, but checking for its existence still counts as "used it"
|
|
||||||
if (symbol->object.type == NULL)
|
|
||||||
Bug_found("ObjectHasNullType", 0); // FIXME - add to docs!
|
|
||||||
return symbol->object.type->is_defined(&symbol->object);
|
|
||||||
}
|
|
||||||
// if/ifdef/ifndef/else function, to be able to do ELSE IF
|
|
||||||
enum ifmode {
|
enum ifmode {
|
||||||
IFMODE_IF, // parse expression, then block
|
IFMODE_IF, // parse expression, then block
|
||||||
IFMODE_IFDEF, // check symbol, then parse block or line
|
IFMODE_IFDEF, // check symbol, then parse block or line
|
||||||
IFMODE_IFNDEF, // check symbol, then parse block or line
|
IFMODE_IFNDEF, // check symbol, then parse block or line
|
||||||
IFMODE_ELSE // unconditional last block
|
IFMODE_ELSE // unconditional last block
|
||||||
};
|
};
|
||||||
// function for if/ifdef/ifndef/else. has to be re-entrant.
|
// has to be re-entrant
|
||||||
static enum eos ifelse(enum ifmode mode)
|
static enum eos ifelse(enum ifmode mode)
|
||||||
{
|
{
|
||||||
boolean nothing_done = TRUE; // once a block gets executed, this becomes FALSE, so all others will be skipped even if condition met
|
boolean nothing_done = TRUE; // once a block gets executed, this becomes FALSE, so all others will be skipped even if condition met
|
||||||
|
Loading…
x
Reference in New Issue
Block a user