The Relogix translation
Note: This is a 100% automatic translation, with no human intervention or cleaning-up of the code. Relogix has automatically chosen the function prototype, has detected the use of structures and pointers, has chosen the variable names itself, and has placed the assembler comments in the translated source allowing for the re-arrangement of the code flow.
In a real translation project, the translation could be further improved by providing user-defined header files to tune the names and types of variables, and the function prototypes. If you download the full sample translation you can see examples of this and read about the translation in detail.
/*
*************************************************************************
* ParseExpression *
*************************************************************************
*
*
* ParseExpression() - Build expression tree
*
* NOTES:
* 1. This routine builds an expression tree using standard operator
* precedence analysis. It is lifted from Bornat, "Understanding and
* Writing Compilers" Chpt 17 with various modifications.
* The structure of the tree is different from Bornat; to cater for
* multiple arguments, they are held in the form of a linked list of
* nodes; nodep->child points to the first argument (if any), with the
* arguments held in the linked list sibling->.
* node
* |
* +-------+
* |
* +-->node----->node----->node...
* | |
* +---------+ +----+
* | |
* +-->node... +-->node...
* 2. On entry:
* EDI -> environment
* EAX = priority
* On exit:
* ESI -> root node
*
* Parameters:
*
* long priority [Originally in eax; In]
* struct env *environment [Originally in edi; In]
*
* Result:
*
* struct node * [Originally in esi]
*/
struct node * ParseExpression (long priority, struct env *environment)
{
struct node *result; /* [Originally in esi] */
char buffer [MAX_TOKENLEN]; /* [Originally on stack at offset -528] */
unsigned char e; /* [Originally in cl] */
struct node *node_ptr; /* [Originally in esi] */
char *p; /* [Originally in edx] */
char *ptr_env_tokstr; /* [Originally in esi] */
long the_op_priority; /* [Originally in ebx] */
result = ParsePrimary (environment); /* Get ESI -> left node */
while (result != NULL) {
/* Get CL = token value, e.g. TOK_TIMES */
e = environment->env_tokval [0];
/* Get EBX priority if operator (-1 if other token, e.g TOK_IDENT) */
the_op_priority = (signed char) ((struct op *) ((signed char *) op_table + e * sizeof(struct op)))->op_priority;
if (the_op_priority == -1) {
/* Not an operator. TOK_END and TOK_COMMA are ok, else error */
if (e != TOK_END && e != TOK_COMMA) {
/* Oops, not an operator */
errmsg ("Operator expected"); /* Error: "Operator expected" */
result = NULL;
}
/* Arrive here with ESI -> left hand node (result) */
return result; /* Clean up stack */
}
/* Have:
CL = token value
EBX = operator priority
[ESP] = arg priority
ESI -> left node
EDI -> env */
if (e == TOK_RPAREN)
the_op_priority = 0; /* Adjust left priority of ) */
/* op_priority <= priority ? */
if (the_op_priority <= priority) {
/* Arrive here with ESI -> left hand node (result) */
return result; /* Clean up stack */
}
/* Copy token string to stack */
p = buffer;
ptr_env_tokstr = environment->env_tokstr;
while (True) {
*p = *ptr_env_tokstr;
if (*p == 0)
break;
ptr_env_tokstr++;
p++;
}
LexAnalyse (environment);
if (e == TOK_LPAREN)
the_op_priority = 0; /* Adjust right priority of ( */
/* Have:
CL = token value
EBX = operator priority
[ESP] = arg priority
[ESP+4] = token string
ESI -> left node
EDI -> env */
node_ptr = ParseExpression (the_op_priority, environment);
/* EAX = op priority
Get ESI -> right node */
if (node_ptr == NULL)
break;
/* Call newnode with:
EDI -> env
CL = token value
EDX -> token string
EBX -> left node
ESI -> right node
Returns ESI -> new node */
result = newnode (e, buffer, result, node_ptr);
/* EBX -> left node */
}
/* Arrive here with ESI -> left hand node (result) */
return NULL; /* Clean up stack */
}
/*
*************************************************************************
* ParsePrimary *
*************************************************************************
*
*
* ParsePrimary() - Mutually recursive routine of ParseExpression()
*
* NOTES:
* 1. This routine performs top down analysis of expression primaries.
* See ParseExpression() above.
* 2. On entry:
* EDI -> environment
* On exit:
* ESI -> root node
*
* Parameters:
*
* struct env *environment [Originally in edi; In]
*
* Result:
*
* struct node * [Originally in esi]
*/
struct node * ParsePrimary (struct env *environment)
{
struct node *result; /* [Originally in esi] */
char buffer [MAX_TOKENLEN]; /* [Originally on stack at offset -528] */
char *expression; /* [Originally in esi] */
struct node *node_ptr; /* [Originally in esi] */
char *p; /* [Originally in edx] */
char *ptr_env_tokstr; /* [Originally in esi] */
char *q; /* [Originally in edx] */
char **the_env_expptr; /* [Originally in ebx] */
unsigned long the_node_idx; /* [Originally in eax] */
unsigned char the_tok_int; /* [Originally in cl] */
expression = NULL;
/* Get CL = token value */
the_tok_int = environment->env_tokval [0];
/* A % operator occuring where an operand is expected is probably the result
of misinterpreting a binary operand like %10101. Try to correct ourselves now */
if (the_tok_int == TOK_MOD) {
the_env_expptr = environment->env_expptr;
/* EBX -> pointer to expression */
expression = *the_env_expptr; /* ESI -> expression */
/* AL = next char. Is it 0 or 1 ? */
if (*expression >= '0' && *expression <= '1') {
the_tok_int = TOK_INT; /* Aha, change to TOK_INT */
environment->env_tokval [0] = TOK_INT;
environment->env_tokstr [0] = '%'; /* Copy %10101 string */
p = &environment->env_tokstr [1];
while (*expression >= '0' && *expression <= '1')
*p++ = *expression++;
*the_env_expptr = expression; /* Update expression pointer */
*p = 0;
}
}
/* Identifier or integer ? */
switch (the_tok_int) {
case TOK_IDENT:
case TOK_INT:
result = endnode (the_tok_int, environment->env_tokstr);
/* EDI -> env, EDX -> token string, CL = token value */
if (result == NULL)
return NULL;
break;
case TOK_LPAREN:
LexAnalyse (environment); /* Get next token */
result = ParseExpression (0, environment);
/* Parse expression in () */
/* Parsed ok? */
if (result == NULL)
return NULL;
/* Got right ) ? */
if (environment->env_tokval [0] == TOK_RPAREN)
break;
errmsg ("Right parenthesis missing"); /* Error "Right parenthesis missing" */
return NULL;
default:
switch (the_tok_int) {
case TOK_BIT_NOT:
case TOK_LOGICAL_NOT:
break;
case TOK_PLUS:
the_tok_int = TOK_UNIPLUS;
environment->env_tokval [0] = TOK_UNIPLUS;
break;
case TOK_MINUS:
the_tok_int = TOK_NEGATE;
environment->env_tokval [0] = TOK_NEGATE;
break;
default:
/* Oops, expected an operand */
errmsg ("Operand expected"); /* Error : "Operand expected" */
return NULL;
}
/* Get here if we have unary operator, + - ! or ~ */
q = buffer; /* Copy token string to stack. LexAnalyse will kill it */
ptr_env_tokstr = environment->env_tokstr;
while (True) {
*q = *ptr_env_tokstr;
if (*q == 0)
break;
ptr_env_tokstr++;
q++;
}
LexAnalyse (environment); /* Consume token */
node_ptr = ParsePrimary (environment); /* Get ESI -> node tree for argument of unary operator */
if (node_ptr == NULL)
result = NULL;
else {
/* Call newnode with:
EDI -> env
CL = token value
EDX -> token string
EBX -> left node
ESI -> right node
Returns ESI -> new node */
result = newnode (the_tok_int, buffer, node_ptr, NULL);
}
return result;
}
LexAnalyse (environment);
/* Is this a function invocation ? */
if (result == NULL)
result = NULL;
else if (result->node_tokval [0] == TOK_IDENT) {
the_node_idx = check_function (result->node_tokstr);
/* EAX -> function name
EAX = function index, or -1 */
if (environment->env_tokval [0] == TOK_LPAREN) {
/* Have (, hopefully following function */
LexAnalyse (environment);
if ((long) the_node_idx == -1) {
errmsg ("Invalid function name");
/* Error : "Invalid function name" */
result = NULL;
} else {
result->node_tokval [0] = TOK_FUNC;
/* Change type to TOK_FUNC */
result->node_idx = the_node_idx; /* Store index into function table */
result = ParseArguments (result, environment);
/* Parse arguments in () */
}
} else if ((long) the_node_idx != -1) {
result->node_tokval [0] = TOK_FUNC; /* Yes, so just change type to TOK_FUNC */
result->node_idx = the_node_idx; /* and store index into function table */
}
}
return result;
}