version 1.1, 2000/12/03 21:45:48 |
version 1.7, 2003/02/04 14:27:43 |
|
|
/* -*- mode: C; coding: euc-japan -*- */ |
/* -*- mode: C; coding: euc-japan -*- */ |
/* $OpenXM$ */ |
/* $OpenXM: OpenXM/src/ox_math/sm_ext.c,v 1.6 2003/01/15 10:16:10 ohara Exp $ */ |
|
|
/* |
/* |
Copyright (C) Katsuyoshi OHARA, 2000. |
Copyright (C) Katsuyoshi OHARA, 2000. |
|
|
See OpenXM/Copyright/Copyright.mathlink for detail. |
See OpenXM/Copyright/Copyright.mathlink for detail. |
*/ |
*/ |
|
|
/* |
|
Remarks: |
|
file descripter 3 and 4 are already opened by the parent process. |
|
*/ |
|
|
|
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <unistd.h> |
#include <gmp.h> |
#include <gmp.h> |
#include <mathlink.h> |
|
#include <ox_toolkit.h> |
#include <ox_toolkit.h> |
#include "sm.h" |
#include "sm.h" |
|
|
extern int flag_mlo_symbol; |
static struct { int (*func_ptr)(); int key; } tbl_smcmd[] = { |
|
{sm_executeFunction, SM_executeFunction}, |
|
{sm_executeStringByLocalParser, SM_executeStringByLocalParser}, |
|
{sm_executeStringByLocalParser, SM_executeStringByLocalParserInBatchMode}, |
|
{sm_mathcap, SM_mathcap}, |
|
{sm_set_mathcap, SM_setMathCap}, |
|
{sm_popString, SM_popString}, |
|
{sm_popCMO, SM_popCMO}, |
|
{sm_pops, SM_pops}, |
|
{shutdown, SM_shutdown}, |
|
{NULL, NULL} |
|
}; |
|
|
/* MathLink independent */ |
extern OXFILE *stack_oxfp; |
static cmo **stack = NULL; |
|
static int stack_ptr = 0; |
|
static int stack_size = 0; |
|
OXFILE *stack_oxfp = NULL; |
|
|
|
#define DIFFERENCE_OF_STACK 1024 |
int (*sm_search_f(int code))() |
|
|
void stack_extend() |
|
{ |
{ |
int newsize = stack_size + DIFFERENCE_OF_STACK; |
int i; |
cmo **newstack = (cmo **)malloc(sizeof(cmo *)*newsize); |
for (i=0; tbl_smcmd[i].key != NULL; i++) { |
if (stack != NULL) { |
if (code == tbl_smcmd[i].key) { |
memcpy(newstack, stack, sizeof(cmo *)*stack_size); |
return tbl_smcmd[i].func_ptr; |
free(stack); |
} |
} |
} |
stack_size = newsize; |
return NULL; |
stack = newstack; |
|
} |
} |
|
|
void push(cmo* m) |
|
{ |
|
#if DEBUG |
|
symbol_t symp; |
|
|
|
if (m->tag == CMO_STRING) { |
|
fprintf(stderr, "ox_math:: a CMO_STRING(%s) was pushed.\n", ((cmo_string *)m)->s); |
|
}else { |
|
symp = lookup_by_tag(m->tag); |
|
fprintf(stderr, "ox_math:: a %s was pushed.\n", symbol_get_key(symp)); |
|
} |
|
#endif |
|
if (stack_ptr >= stack_size) { |
|
stack_extend(); |
|
} |
|
stack[stack_ptr] = m; |
|
stack_ptr++; |
|
} |
|
|
|
/* if the stack is empty, then pop() returns (CMO_NULL). */ |
|
cmo *pop() |
|
{ |
|
if (stack_ptr > 0) { |
|
return stack[--stack_ptr]; |
|
} |
|
return new_cmo_null(); |
|
} |
|
|
|
void pops(int n) |
|
{ |
|
stack_ptr -= n; |
|
if (stack_ptr < 0) { |
|
stack_ptr = 0; |
|
} |
|
} |
|
|
|
void push_error(int errcode, cmo* pushback) |
|
{ |
|
return push((cmo *)make_error_object(errcode, pushback)); |
|
} |
|
|
|
/* |
|
If error occurs, then |
|
an sm_*() function returns non-zero and |
|
an error obect is set by a function which calls sm_*(). |
|
*/ |
|
int sm_popCMO(OXFILE* oxfp) |
|
{ |
|
cmo* m = pop(); |
|
#ifdef DEBUG |
|
symbol_t symp = lookup_by_tag(m->tag); |
|
fprintf(stderr, "ox_math:: opecode = SM_popCMO. (%s)\n", symbol_get_key(symp)); |
|
#endif |
|
|
|
if (m != NULL) { |
|
send_ox_cmo(oxfp, m); |
|
return 0; |
|
} |
|
return SM_popCMO; |
|
} |
|
|
|
int sm_pops(OXFILE* oxfp) |
|
{ |
|
cmo* m = pop(); |
|
if (m != NULL && m->tag == CMO_INT32) { |
|
pops(((cmo_int32 *)m)->i); |
|
return 0; |
|
} |
|
return ERROR_ID_UNKNOWN_SM; |
|
} |
|
|
|
/* MathLink dependent */ |
/* MathLink dependent */ |
int sm_popString(OXFILE* oxfp) |
void sm_popString() |
{ |
{ |
char *s; |
char *s; |
cmo *err; |
cmo *err; |
cmo *m; |
cmo *m = pop(); |
|
|
#ifdef DEBUG |
|
fprintf(stderr, "ox_math:: opecode = SM_popString.\n"); |
|
#endif |
|
|
|
m = pop(); |
|
if (m->tag == CMO_STRING) { |
if (m->tag == CMO_STRING) { |
send_ox_cmo(oxfp, m); |
send_ox_cmo(stack_oxfp, m); |
}else if ((s = new_string_set_cmo(m)) != NULL) { |
}else if ((s = new_string_set_cmo(m)) != NULL) { |
send_ox_cmo(oxfp, (cmo *)new_cmo_string(s)); |
send_ox_cmo(stack_oxfp, (cmo *)new_cmo_string(s)); |
}else { |
}else { |
err = make_error_object(SM_popString, m); |
err = make_error_object(SM_popString, m); |
send_ox_cmo(oxfp, err); |
send_ox_cmo(stack_oxfp, err); |
} |
} |
return 0; |
|
} |
} |
|
|
int local_execute(char *s) |
int local_execute(char *s) |
{ |
{ |
|
extern int flag_mlo_symbol; |
|
|
if(*s == 'i') { |
if(*s == 'i') { |
switch(s[1]) { |
switch(s[1]) { |
case '+': |
case '+': |
Line 156 int local_execute(char *s) |
|
Line 78 int local_execute(char *s) |
|
} |
} |
|
|
/* The following function is depend on an implementation of a server. */ |
/* The following function is depend on an implementation of a server. */ |
int sm_executeStringByLocalParser(OXFILE* oxfp) |
void sm_executeStringByLocalParser() |
{ |
{ |
symbol_t symp; |
|
cmo* m = pop(); |
cmo* m = pop(); |
char *s = NULL; |
char *s = NULL; |
#ifdef DEBUG |
|
fprintf(stderr, "ox_math:: opecode = SM_executeStringByLocalParser.\n"); |
|
#endif |
|
|
|
if (m->tag == CMO_STRING |
if (m->tag == CMO_STRING |
&& strlen(s = ((cmo_string *)m)->s) != 0) { |
&& strlen(s = ((cmo_string *)m)->s) != 0) { |
if (s[0] == ':') { |
if (s[0] == ':') { |
Line 173 int sm_executeStringByLocalParser(OXFILE* oxfp) |
|
Line 90 int sm_executeStringByLocalParser(OXFILE* oxfp) |
|
/* for mathematica */ |
/* for mathematica */ |
/* Sending the string `s' to mathematica for its evaluation. */ |
/* Sending the string `s' to mathematica for its evaluation. */ |
ml_evaluateStringByLocalParser(s); |
ml_evaluateStringByLocalParser(s); |
ml_select(); |
m = ml_return(); |
push(receive_mlo()); |
push(m); |
} |
} |
return 0; |
}else { |
} |
ox_printf(" <%s>", get_symbol_by_tag(m->tag)); |
#ifdef DEBUG |
push_error(SM_executeStringByLocalParser, m); |
symp = lookup_by_tag(m->tag); |
} |
fprintf(stderr, "ox_math:: error. the top of stack is %s.\n", symbol_get_key(symp)); |
|
#endif |
|
return SM_executeStringByLocalParser; |
|
} |
} |
|
|
int sm_executeFunction(OXFILE* oxfp) |
void sm_executeFunction() |
{ |
{ |
int i, argc; |
int i, argc; |
cmo **argv; |
cmo **argv; |
Line 193 int sm_executeFunction(OXFILE* oxfp) |
|
Line 107 int sm_executeFunction(OXFILE* oxfp) |
|
cmo* m; |
cmo* m; |
|
|
if ((m = pop()) == NULL || m->tag != CMO_STRING) { |
if ((m = pop()) == NULL || m->tag != CMO_STRING) { |
return SM_executeFunction; |
push_error(SM_executeFunction, m); |
} |
} |
func = ((cmo_string *)m)->s; |
func = ((cmo_string *)m)->s; |
|
|
if ((m = pop()) == NULL || m->tag != CMO_INT32) { |
if ((m = pop()) == NULL || m->tag != CMO_INT32) { |
return SM_executeFunction; |
push_error(SM_executeFunction, m); |
} |
} |
|
|
argc = ((cmo_int32 *)m)->i; |
argc = ((cmo_int32 *)m)->i; |
Line 207 int sm_executeFunction(OXFILE* oxfp) |
|
Line 121 int sm_executeFunction(OXFILE* oxfp) |
|
argv[i] = pop(); |
argv[i] = pop(); |
} |
} |
ml_executeFunction(func, argc, argv); |
ml_executeFunction(func, argc, argv); |
ml_select(); |
m = ml_return(); |
push(receive_mlo()); |
push(m); |
return 0; |
|
} |
} |
|
|
int sm_mathcap(OXFILE* oxfp) |
void sm_mathcap() |
{ |
{ |
push((cmo *)oxf_cmo_mathcap(oxfp)); |
push((cmo *)oxf_cmo_mathcap(stack_oxfp)); |
return 0; |
|
} |
} |
|
|
void sm_set_mathcap(OXFILE *oxfp) |
void sm_set_mathcap() |
{ |
{ |
cmo_mathcap *m = (cmo_mathcap *)pop(); |
cmo_mathcap *m = (cmo_mathcap *)pop(); |
if (m->tag == CMO_MATHCAP) { |
if (m->tag == CMO_MATHCAP) { |
oxf_mathcap_update(oxfp, m); |
oxf_mathcap_update(stack_oxfp, m); |
}else { |
}else { |
push_error(-1, m); |
push_error(-1, m); |
/* an error object must be pushed */ |
/* an error object must be pushed */ |
} |
} |
} |
|
|
|
int receive_sm_command(OXFILE* oxfp) |
|
{ |
|
return receive_int32(oxfp); |
|
} |
|
|
|
int execute_sm_command(OXFILE* oxfp, int code) |
|
{ |
|
int err = 0; |
|
#ifdef DEBUG |
|
symbol_t sp = lookup_by_tag(code); |
|
fprintf(stderr, "ox_math:: %s received.\n", symbol_get_key(sp)); |
|
#endif |
|
|
|
switch(code) { |
|
case SM_popCMO: |
|
err = sm_popCMO(oxfp); |
|
break; |
|
case SM_popString: |
|
err = sm_popString(oxfp); |
|
break; |
|
case SM_mathcap: |
|
err = sm_mathcap(oxfp); |
|
break; |
|
case SM_pops: |
|
err = sm_pops(oxfp); |
|
break; |
|
case SM_executeStringByLocalParser: |
|
case SM_executeStringByLocalParserInBatchMode: |
|
err = sm_executeStringByLocalParser(oxfp); |
|
break; |
|
case SM_executeFunction: |
|
err = sm_executeFunction(oxfp); |
|
break; |
|
case SM_shutdown: |
|
shutdown(); |
|
break; |
|
case SM_setMathCap: |
|
pop(); /* ignore */ |
|
break; |
|
default: |
|
fprintf(stderr, "unknown command: %d.\n", code); |
|
err = ERROR_ID_UNKNOWN_SM; |
|
} |
|
|
|
if (err != 0) { |
|
push((cmo *)make_error_object(err, new_cmo_null())); |
|
} |
|
} |
|
|
|
int sm_run(int code) |
|
{ |
|
return execute_sm_command(stack_oxfp, code); |
|
} |
} |