/* Copyright (C) 1995 Bjoern Beutel. */
/* Description. =============================================================*/
/* This module defines the data types needed for Malaga rules. */
/* Constants ================================================================*/
/* The rule-internal state is described by the following variables:
* S is the value stack.
* SP (stack pointer) is the index of the first free element in S.
* BP (base pointer) is the index of the first element in S local to the
* current rule.
* I is information that is stored in the instruction itself.
* PC is the program counter, i.e., the index of the next code to be executed.
* BT is the backtrace stack, a stack of triples: (PC, BP, S).
* BTP is the top index of B. */
enum /* These are the opcodes of the rule instructions. */
{
/* control instructions */
INS_SYSTEM_ERROR, /* report error(I); terminate all paths. */
INS_ERROR, /* report error( S[SP - 1] ); terminate all paths. */
INS_TERMINATE, /* terminate this path. */
INS_NOP, /* do nothing. */
INS_TERMINATE_IF_NULL, /* if (S[SP - 1] == NULL) {terminate;} else {SP--;} */
/* result instructions */
INS_ADD_END_STATE, /* result = S[SP - 1]; rule_successful = TRUE; SP--; */
INS_ADD_STATE, /* result = S[SP - 1]; rules = rules[I];
* rule_successful = TRUE; SP--; */
INS_ADD_ALLO, /* surf = S[SP-2]; allo = S[SP - 1];
* rule_successful = TRUE; SP-= 2 */
INS_ACCEPT, /* rule_successful = TRUE; */
/* stack management instructions */
INS_PUSH_NULL, /* for (i = 0; i < I; i++) { S[SP + i] = NULL; } SP += I; */
INS_PUSH_VAR, /* S[SP] = S[I]; SP++; */
INS_PUSH_CONST, /* S[SP] = Const(I); SP++; */
INS_PUSH_SYMBOL, /* S[SP] = Symbol(I); SP++; */
INS_PUSH_PATTERN_VAR, /* S[SP] = Pattern_Var(I); SP++; */
INS_POP, /* SP -= I; */
INS_POP_TO, /* SP = BP + I; */
/* value instructions */
INS_BUILD_LIST, /* S[SP - I] = "<"S[SP - I],.., S[SP - 1]">"; SP -= I - 1; */
INS_DECOMPOSE_LIST, /* <S[SP - 1], .. , S[SP + I - 2]> = S[SP - 1];
* SP += I - 1; */
INS_BUILD_RECORD, /* S[SP - 2 * I] = "[" S[SP - 2 * I] : S[SP - 2 * I + 1]
* ...
* S[SP - 2] : S[SP - 1] "]";
* SP -= 2*I - 1; */
INS_BUILD_PATH, /* SP[SP - I] = S[SP - I] "." .. "." S[SP - 1]; SP -= I-1; */
INS_DOT_OPERATION, /* S[SP - 2] = S[SP - 2] "." S[SP - 1]; SP--; */
INS_PLUS_OPERATION, /* S[SP - 2] := S[SP - 2] "+" S[SP - 1]; SP--; */
INS_MINUS_OPERATION, /* S[SP - 2] = S[SP - 2] "-" S[SP - 1]; SP--; */
INS_ASTERISK_OPERATION, /* S[SP - 2] = S[SP - 2] "*" S[SP - 1]; SP--; */
INS_SLASH_OPERATION, /* S[SP - 2] = S[SP - 2] "/" S[SP - 1]; SP--; */
INS_UNARY_MINUS_OP, /* S[SP - 1] = "-" S[SP - 1]; */
INS_GET_ATTRIBUTE, /* S[SP - 1] = S[SP - 1] "." Symbol(I); */
INS_REMOVE_ATTRIBUTE, /* S[SP - 1] = S[SP - 1] "-" Symbol(I); */
INS_STD_FUNCTION, /* S[SP - 1] = function_I( S[SP - 1] ); */
INS_MATCH, /* S[SP - 1] = S[SP - 1] "match" String(I); (yes or no) */
/* instructions to modify variables */
INS_SET_VAR, /* S[I] = S[SP - 1]; SP--; */
INS_PLUS_VAR, /* S[I] = S[I] "+" S[SP - 1]; SP--; */
INS_MINUS_VAR, /* S[I] = S[I] "-" S[SP - 1]; SP--; */
INS_ASTERISK_VAR, /* S[I] = S[I] "*" S[SP - 1]; SP--; */
INS_SLASH_VAR, /* S[I] = S[I] "/" S[SP - 1]; SP--; */
INS_SET_VAR_PATH, /* (S[I] "." S[SP - 2]) = S[SP - 1]; SP -= 2; */
INS_PLUS_VAR_PATH, /* (S[I] "." S[SP-2]) = (S[I] "." S[SP-2]) "+" S[SP-1];
* SP -= 2; */
INS_MINUS_VAR_PATH, /* (S[I] "." S[SP-2]) = (S[I] "." S[SP-2]) "-" S[SP-1];
* SP -= 2; */
INS_ASTERISK_VAR_PATH, /* (S[I]"." S[SP-2]) = (S[I] "." S[SP-2]) "*" S[SP-1];
* SP -= 2; */
INS_SLASH_VAR_PATH, /* (S[I] "." S[SP-2]) = (S[I] "." S[SP-2]) "/" S[SP-1];
* SP -= 2; */
/* Instructions to support loops. */
INS_GET_1ST_ELEMENT, /* S[SP-1] = 1st element/attrib/ordinal of S[SP-1]; */
INS_ITERATE, /* S[I - 1] must be a list, a record, or a number
* and S[I] the n-th element/attrib/ordinal of S[I - 1].
* S[I] = (n+1)-th element/attr/ordinal of S[I - 1]; */
/* Jump instructions. */
INS_JUMP, /* PC = I. */
INS_JUMP_IF_EQUAL, /* if (S[SP-2] "=" S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_NOT_EQUAL, /* if (! S[SP-2] "=" S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_CONGR, /* if (S[SP-2] "~" S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_NOT_CONGR, /* if (! S[SP-2] "~" S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_IN, /* if (S[SP-2] "in" S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_NOT_IN, /* if (! S[SP-2] "in" S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_LESS, /* if (S[SP-2] < S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_NOT_LESS, /* if (! S[SP-2] < S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_GREATER, /* if (S[SP-2] > S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_NOT_GREATER, /* if (! S[SP-2] > S[SP-1]) {PC = I;} SP -= 2; */
INS_JUMP_IF_NULL, /* if (S[SP-1] == NULL) {PC = I;} SP--; */
INS_JUMP_IF_NOT_NULL, /* if (! S[SP-1] == NULL) {PC = I;} SP--; */
INS_JUMP_IF_YES, /* if (S[SP-1] == yes) {PC = I;} SP--; */
INS_JUMP_IF_NO, /* if (S[SP-1] == no) {PC = I;} SP--; */
INS_JUMP_NOW, /* BT[BTP] = {PC, BP, S}; PC = I; BTP++; */
INS_JUMP_LATER, /* BT[BTP] = {I, BP, S}; BTP++; */
INS_JUMP_SUBRULE, /* Push BP; Push PC+1; BP = TOP; PC = first_instr(I); */
INS_RETURN /* SP = BP; Pop PC; Pop BP; Pop (I-1); */
};
/* Types of INS_SYSTEM_ERROR. */
enum {ASSERTION_ERROR, NO_RETURN_ERROR};
/* Standard functions for INS_STANDARD_FUNCTION. */
enum {FUNC_TO_ATOMS, FUNC_IS_CAPITAL, FUNC_GET_LENGTH, FUNC_TO_MULTI,
FUNC_TO_SET, FUNC_GET_SWITCH, FUNC_GET_VALUE_TYPE, FUNC_GET_VALUE_STRING,
FUNC_TRANSMIT, FUNC_FLOOR, FUNC_SUBSTRING};
#define INSTR_INFO_MIN (-1L << 23)
#define INSTR_INFO_MAX ((1L << 23) - 1)
/* Never use an instruction info smaller than INSTR_INFO_MIN or
* greater than INSTR_INFO_MAX. */
enum {OPCODE_MAX = 255}; /* The largest opcode possible. */
/* Macros. ==================================================================*/
#define INSTR(opcode, instr_info) ((opcode) | (u_int_t) (instr_info) << 8)
/* Use this macro to create an instruction. */
#define OPCODE(instr) ((int_t) (instr) & OPCODE_MAX)
/* Use this macro to get the opcode of an instruction. */
#define INSTR_INFO(instr) ((int_t) (instr) >> 8)
/* Use this macro to get the info of an instruction. */
/* Types. ===================================================================*/
typedef u_int_t instr_t;
/* An instruction is an u_int_t whose lower 8 bits store the opcode.
* The upper 24 bits store a signed value, the Info value. */
typedef enum /* Rule types */
{ALLO_RULE, COMBI_RULE, END_RULE, FILTER_RULE, PRUNING_RULE, ROBUST_RULE,
SUBRULE} rule_type_t;
typedef struct /* A rule definition.*/
{
int_t name; /* String table index to rule name. */
int_t first_instr; /* Code index of rule start. */
rule_type_t type; /* Type of the rule. */
int_t param_count; /* Number of parameters the rule takes. */
} rule_t;
typedef struct
/* A correspondence between a source line and a rule code index. */
{
int_t line; /* Source line or -1 if instruction can't be
* associated with a specific source line */
int_t file; /* String table index to source file name or -1. */
int_t instr; /* Index of first instruction that belongs to LINE in FILE. */
} src_line_t;
typedef struct /* A variable name and all its scopes. */
{
int_t name; /* String table index of variable name. */
int_t first_scope; /* Index of first scope of this variable in VAR_SCOPES. */
int_t scope_count; /* Number of scopes of this variable. */
} var_t;
typedef struct /* A single scope of a variable. */
{
int_t first_instr; /* First instruction where variable is defined. */
int_t last_instr; /* Last instruction where variable is defined. */
int_t stack_index; /* Index of variable in value stack. */
} var_scope_t;
typedef struct /* A named constant. */
{
int_t name; /* String table index of constant name. */
int_t value; /* Value index. */
} constant_t;
/* End of file. =============================================================*/